use of io.netty.handler.codec.http.HttpRequest in project flink by apache.
the class HttpTestClient method sendGetRequest.
/**
* Sends a simple GET request to the given path. You only specify the $path part of
* http://$host:$host/$path.
*
* @param path The $path to GET (http://$host:$host/$path)
*/
public void sendGetRequest(String path, Duration timeout) throws TimeoutException, InterruptedException {
if (!path.startsWith("/")) {
path = "/" + path;
}
HttpRequest getRequest = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, path);
getRequest.headers().set(HttpHeaders.Names.HOST, host);
getRequest.headers().set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.CLOSE);
sendRequest(getRequest, timeout);
}
use of io.netty.handler.codec.http.HttpRequest in project flink by apache.
the class HttpRequestHandler method channelRead0.
@Override
public void channelRead0(ChannelHandlerContext ctx, HttpObject msg) {
try {
if (msg instanceof HttpRequest) {
currentRequest = (HttpRequest) msg;
currentRequestPath = null;
if (currentDecoder != null) {
currentDecoder.destroy();
currentDecoder = null;
}
if (currentRequest.getMethod() == HttpMethod.GET || currentRequest.getMethod() == HttpMethod.DELETE) {
// directly delegate to the router
ctx.fireChannelRead(currentRequest);
} else if (currentRequest.getMethod() == HttpMethod.POST) {
// POST comes in multiple objects. First the request, then the contents
// keep the request and path for the remaining objects of the POST request
currentRequestPath = new QueryStringDecoder(currentRequest.getUri(), ENCODING).path();
currentDecoder = new HttpPostRequestDecoder(DATA_FACTORY, currentRequest, ENCODING);
} else {
throw new IOException("Unsupported HTTP method: " + currentRequest.getMethod().name());
}
} else if (currentDecoder != null && msg instanceof HttpContent) {
// received new chunk, give it to the current decoder
HttpContent chunk = (HttpContent) msg;
currentDecoder.offer(chunk);
try {
while (currentDecoder.hasNext()) {
InterfaceHttpData data = currentDecoder.next();
if (data.getHttpDataType() == HttpDataType.FileUpload && tmpDir != null) {
DiskFileUpload file = (DiskFileUpload) data;
if (file.isCompleted()) {
String name = file.getFilename();
File target = new File(tmpDir, UUID.randomUUID() + "_" + name);
if (!tmpDir.exists()) {
logExternalUploadDirDeletion(tmpDir);
checkAndCreateUploadDir(tmpDir);
}
file.renameTo(target);
QueryStringEncoder encoder = new QueryStringEncoder(currentRequestPath);
encoder.addParam("filepath", target.getAbsolutePath());
encoder.addParam("filename", name);
currentRequest.setUri(encoder.toString());
}
}
}
} catch (EndOfDataDecoderException ignored) {
}
if (chunk instanceof LastHttpContent) {
HttpRequest request = currentRequest;
currentRequest = null;
currentRequestPath = null;
currentDecoder.destroy();
currentDecoder = null;
// fire next channel handler
ctx.fireChannelRead(request);
}
} else {
ctx.fireChannelRead(ReferenceCountUtil.retain(msg));
}
} catch (Throwable t) {
currentRequest = null;
currentRequestPath = null;
if (currentDecoder != null) {
currentDecoder.destroy();
currentDecoder = null;
}
if (ctx.channel().isActive()) {
byte[] bytes = ExceptionUtils.stringifyException(t).getBytes(ENCODING);
DefaultFullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.INTERNAL_SERVER_ERROR, Unpooled.wrappedBuffer(bytes));
response.headers().set(HttpHeaders.Names.CONTENT_TYPE, "text/plain");
response.headers().set(HttpHeaders.Names.CONTENT_LENGTH, response.content().readableBytes());
ctx.writeAndFlush(response);
}
}
}
use of io.netty.handler.codec.http.HttpRequest in project flink by apache.
the class RestClient method createRequest.
private static Request createRequest(String targetAddress, String targetUrl, HttpMethod httpMethod, ByteBuf jsonPayload, Collection<FileUpload> fileUploads) throws IOException {
if (fileUploads.isEmpty()) {
HttpRequest httpRequest = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, httpMethod, targetUrl, jsonPayload);
httpRequest.headers().set(HttpHeaders.Names.HOST, targetAddress).set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.CLOSE).add(HttpHeaders.Names.CONTENT_LENGTH, jsonPayload.capacity()).add(HttpHeaders.Names.CONTENT_TYPE, RestConstants.REST_CONTENT_TYPE);
return new SimpleRequest(httpRequest);
} else {
HttpRequest httpRequest = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, httpMethod, targetUrl);
httpRequest.headers().set(HttpHeaders.Names.HOST, targetAddress).set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.CLOSE);
// takes care of splitting the request into multiple parts
HttpPostRequestEncoder bodyRequestEncoder;
try {
// we could use mixed attributes here but we have to ensure that the minimum size is
// greater than
// any file as the upload otherwise fails
DefaultHttpDataFactory httpDataFactory = new DefaultHttpDataFactory(true);
// the FileUploadHandler explicitly checks for multipart headers
bodyRequestEncoder = new HttpPostRequestEncoder(httpDataFactory, httpRequest, true);
Attribute requestAttribute = new MemoryAttribute(FileUploadHandler.HTTP_ATTRIBUTE_REQUEST);
requestAttribute.setContent(jsonPayload);
bodyRequestEncoder.addBodyHttpData(requestAttribute);
int fileIndex = 0;
for (FileUpload fileUpload : fileUploads) {
Path path = fileUpload.getFile();
if (Files.isDirectory(path)) {
throw new IllegalArgumentException("Upload of directories is not supported. Dir=" + path);
}
File file = path.toFile();
LOG.trace("Adding file {} to request.", file);
bodyRequestEncoder.addBodyFileUpload("file_" + fileIndex, file, fileUpload.getContentType(), false);
fileIndex++;
}
} catch (HttpPostRequestEncoder.ErrorDataEncoderException e) {
throw new IOException("Could not encode request.", e);
}
try {
httpRequest = bodyRequestEncoder.finalizeRequest();
} catch (HttpPostRequestEncoder.ErrorDataEncoderException e) {
throw new IOException("Could not finalize request.", e);
}
return new MultipartRequest(httpRequest, bodyRequestEncoder);
}
}
use of io.netty.handler.codec.http.HttpRequest in project flink by apache.
the class RestClient method sendRequest.
public <M extends MessageHeaders<R, P, U>, U extends MessageParameters, R extends RequestBody, P extends ResponseBody> CompletableFuture<P> sendRequest(String targetAddress, int targetPort, M messageHeaders, U messageParameters, R request, Collection<FileUpload> fileUploads, RestAPIVersion apiVersion) throws IOException {
Preconditions.checkNotNull(targetAddress);
Preconditions.checkArgument(NetUtils.isValidHostPort(targetPort), "The target port " + targetPort + " is not in the range [0, 65535].");
Preconditions.checkNotNull(messageHeaders);
Preconditions.checkNotNull(request);
Preconditions.checkNotNull(messageParameters);
Preconditions.checkNotNull(fileUploads);
Preconditions.checkState(messageParameters.isResolved(), "Message parameters were not resolved.");
if (!messageHeaders.getSupportedAPIVersions().contains(apiVersion)) {
throw new IllegalArgumentException(String.format("The requested version %s is not supported by the request (method=%s URL=%s). Supported versions are: %s.", apiVersion, messageHeaders.getHttpMethod(), messageHeaders.getTargetRestEndpointURL(), messageHeaders.getSupportedAPIVersions().stream().map(RestAPIVersion::getURLVersionPrefix).collect(Collectors.joining(","))));
}
String versionedHandlerURL = "/" + apiVersion.getURLVersionPrefix() + messageHeaders.getTargetRestEndpointURL();
String targetUrl = MessageParameters.resolveUrl(versionedHandlerURL, messageParameters);
LOG.debug("Sending request of class {} to {}:{}{}", request.getClass(), targetAddress, targetPort, targetUrl);
// serialize payload
StringWriter sw = new StringWriter();
objectMapper.writeValue(sw, request);
ByteBuf payload = Unpooled.wrappedBuffer(sw.toString().getBytes(ConfigConstants.DEFAULT_CHARSET));
Request httpRequest = createRequest(targetAddress + ':' + targetPort, targetUrl, messageHeaders.getHttpMethod().getNettyHttpMethod(), payload, fileUploads);
final JavaType responseType;
final Collection<Class<?>> typeParameters = messageHeaders.getResponseTypeParameters();
if (typeParameters.isEmpty()) {
responseType = objectMapper.constructType(messageHeaders.getResponseClass());
} else {
responseType = objectMapper.getTypeFactory().constructParametricType(messageHeaders.getResponseClass(), typeParameters.toArray(new Class<?>[typeParameters.size()]));
}
return submitRequest(targetAddress, targetPort, httpRequest, responseType);
}
use of io.netty.handler.codec.http.HttpRequest in project flink by apache.
the class RestClient method submitRequest.
private <P extends ResponseBody> CompletableFuture<P> submitRequest(String targetAddress, int targetPort, Request httpRequest, JavaType responseType) {
final ChannelFuture connectFuture = bootstrap.connect(targetAddress, targetPort);
final CompletableFuture<Channel> channelFuture = new CompletableFuture<>();
connectFuture.addListener((ChannelFuture future) -> {
if (future.isSuccess()) {
channelFuture.complete(future.channel());
} else {
channelFuture.completeExceptionally(future.cause());
}
});
return channelFuture.thenComposeAsync(channel -> {
ClientHandler handler = channel.pipeline().get(ClientHandler.class);
CompletableFuture<JsonResponse> future;
boolean success = false;
try {
if (handler == null) {
throw new IOException("Netty pipeline was not properly initialized.");
} else {
httpRequest.writeTo(channel);
future = handler.getJsonFuture();
success = true;
}
} catch (IOException e) {
future = FutureUtils.completedExceptionally(new ConnectionException("Could not write request.", e));
} finally {
if (!success) {
channel.close();
}
}
return future;
}, executor).thenComposeAsync((JsonResponse rawResponse) -> parseResponse(rawResponse, responseType), executor);
}
Aggregations