use of io.helidon.common.http.Http in project helidon by oracle.
the class AbstractCorsTest method test2PreFlightForbiddenOrigin.
@Test
void test2PreFlightForbiddenOrigin() throws ExecutionException, InterruptedException {
WebClientRequestBuilder reqBuilder = client().options().path(path(SERVICE_2));
Headers headers = reqBuilder.headers();
headers.add(ORIGIN, "http://not.allowed");
headers.add(ACCESS_CONTROL_REQUEST_METHOD, "PUT");
WebClientResponse res = reqBuilder.request().toCompletableFuture().get();
Http.ResponseStatus status = res.status();
assertThat(status.code(), is(Http.Status.FORBIDDEN_403.code()));
assertThat(status.reasonPhrase(), is("CORS origin is not in allowed list"));
}
use of io.helidon.common.http.Http in project helidon by oracle.
the class AbstractCorsTest method test2PreFlightForbiddenMethod.
@Test
void test2PreFlightForbiddenMethod() throws ExecutionException, InterruptedException {
WebClientRequestBuilder reqBuilder = client().options().path(path(SERVICE_2));
Headers headers = reqBuilder.headers();
headers.add(ORIGIN, "http://foo.bar");
headers.add(ACCESS_CONTROL_REQUEST_METHOD, "POST");
WebClientResponse res = reqBuilder.request().toCompletableFuture().get();
Http.ResponseStatus status = res.status();
assertThat(status.code(), is(Http.Status.FORBIDDEN_403.code()));
assertThat(status.reasonPhrase(), is("CORS origin is denied"));
}
use of io.helidon.common.http.Http in project helidon by oracle.
the class NettyClientHandler method channelRead0.
@Override
protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws IOException {
Channel channel = ctx.channel();
if (msg instanceof HttpResponse) {
channel.config().setAutoRead(false);
HttpResponse response = (HttpResponse) msg;
this.requestId = channel.attr(REQUEST_ID).get();
channel.attr(RESPONSE_RECEIVED).set(true);
WebClientRequestImpl clientRequest = channel.attr(REQUEST).get();
RequestConfiguration requestConfiguration = clientRequest.configuration();
LOGGER.finest(() -> "(client reqID: " + requestId + ") Initial http response message received");
this.publisher = new HttpResponsePublisher(ctx);
channel.attr(PUBLISHER).set(this.publisher);
this.responseCloser = new ResponseCloser(ctx);
WebClientResponseImpl.Builder responseBuilder = WebClientResponseImpl.builder();
responseBuilder.contentPublisher(publisher).readerContext(requestConfiguration.readerContext()).status(helidonStatus(response.status())).httpVersion(Http.Version.create(response.protocolVersion().toString())).responseCloser(responseCloser).lastEndpointURI(requestConfiguration.requestURI());
HttpHeaders nettyHeaders = response.headers();
for (String name : nettyHeaders.names()) {
List<String> values = nettyHeaders.getAll(name);
responseBuilder.addHeader(name, values);
}
String connection = nettyHeaders.get(Http.Header.CONNECTION, HttpHeaderValues.CLOSE.toString());
if (connection.equals(HttpHeaderValues.CLOSE.toString())) {
ctx.channel().attr(WILL_CLOSE).set(true);
}
// we got a response, we can safely complete the future
// all errors are now fed only to the publisher
WebClientResponse clientResponse = responseBuilder.build();
channel.attr(RESPONSE).set(clientResponse);
for (HttpInterceptor interceptor : HTTP_INTERCEPTORS) {
if (interceptor.shouldIntercept(response.status(), requestConfiguration)) {
boolean continueAfter = !interceptor.continueAfterInterception();
if (continueAfter) {
responseCloser.close().thenAccept(future -> LOGGER.finest(() -> "Response closed due to redirection"));
}
interceptor.handleInterception(response, clientRequest, channel.attr(RESULT).get());
if (continueAfter) {
return;
}
}
}
requestConfiguration.cookieManager().put(requestConfiguration.requestURI(), clientResponse.headers().toMap());
WebClientServiceResponse clientServiceResponse = new WebClientServiceResponseImpl(requestConfiguration.context().get(), clientResponse.headers(), clientResponse.status());
channel.attr(SERVICE_RESPONSE).set(clientServiceResponse);
List<WebClientService> services = requestConfiguration.services();
CompletionStage<WebClientServiceResponse> csr = CompletableFuture.completedFuture(clientServiceResponse);
for (WebClientService service : services) {
csr = csr.thenCompose(clientSerResponse -> service.response(clientRequest, clientSerResponse));
}
CompletableFuture<WebClientServiceResponse> responseReceived = channel.attr(RECEIVED).get();
CompletableFuture<WebClientResponse> responseFuture = channel.attr(RESULT).get();
csr.whenComplete((clientSerResponse, throwable) -> {
if (throwable != null) {
responseReceived.completeExceptionally(throwable);
responseFuture.completeExceptionally(throwable);
responseCloser.close();
} else {
responseReceived.complete(clientServiceResponse);
responseReceived.thenRun(() -> {
if (shouldResponseAutomaticallyClose(clientResponse)) {
responseCloser.close().thenAccept(aVoid -> {
LOGGER.finest(() -> "Response automatically closed. No entity expected");
});
}
responseFuture.complete(clientResponse);
});
}
});
}
if (responseCloser.isClosed()) {
if (!channel.attr(WILL_CLOSE).get() && channel.hasAttr(RETURN)) {
if (msg instanceof LastHttpContent) {
LOGGER.finest(() -> "(client reqID: " + requestId + ") Draining finished");
if (channel.isActive()) {
channel.attr(RETURN).get().set(true);
}
} else {
LOGGER.finest(() -> "(client reqID: " + requestId + ") Draining not finished, requesting new chunk");
}
channel.read();
}
return;
}
// never "else-if" - msg may be an instance of more than one type, we must process all of them
if (msg instanceof HttpContent) {
HttpContent content = (HttpContent) msg;
publisher.emit(content.content());
}
if (msg instanceof LastHttpContent) {
LOGGER.finest(() -> "(client reqID: " + requestId + ") Last http content received");
if (channel.hasAttr(RETURN)) {
channel.attr(RETURN).get().set(true);
responseCloser.close();
channel.read();
} else {
responseCloser.close();
}
}
}
use of io.helidon.common.http.Http in project helidon by oracle.
the class MainTest method runJsonFunctionalTest.
/**
* Run some basic CRUD operations on the server. The server supports
* running with any of our three JSON libraries: jsonp, jsonb, jackson.
* So we set a system property to select the library to use before starting
* the server
*
* @param edition "mp", "se"
* @param jsonLibrary "jsonp", "jsonb" or "jackson"
* @throws Exception on test failure
*/
private void runJsonFunctionalTest(String edition, String jsonLibrary) throws Exception {
JsonObject json = getBookAsJsonObject();
int numberOfBooks = 1000;
List<String> systemPropertyArgs = new LinkedList<>();
systemPropertyArgs.add("-Dbookstore.size=" + numberOfBooks);
if (jsonLibrary != null && !jsonLibrary.isEmpty()) {
systemPropertyArgs.add("-Dapp.json-library=" + jsonLibrary);
}
HelidonApplication application = startTheApplication(editionToJarPath(edition), systemPropertyArgs);
WebClient webClient = WebClient.builder().baseUri(application.getBaseUrl()).addMediaSupport(JsonpSupport.create()).build();
webClient.get().path("/books").request(JsonArray.class).thenAccept(bookArray -> assertThat("Number of books", bookArray.size(), is(numberOfBooks))).toCompletableFuture().get();
webClient.post().path("/books").submit(json).thenAccept(it -> assertThat("HTTP response POST", it.status(), is(Http.Status.OK_200))).thenCompose(it -> webClient.get().path("/books/123456").request(JsonObject.class)).thenAccept(it -> assertThat("Checking if correct ISBN", it.getString("isbn"), is("123456"))).toCompletableFuture().get();
webClient.get().path("/books/0000").request().thenAccept(it -> assertThat("HTTP response GET bad ISBN", it.status(), is(Http.Status.NOT_FOUND_404))).toCompletableFuture().get();
webClient.get().path("/books").request().thenApply(it -> {
assertThat("HTTP response list books", it.status(), is(Http.Status.OK_200));
return it;
}).thenCompose(WebClientResponse::close).toCompletableFuture().get();
webClient.delete().path("/books/123456").request().thenAccept(it -> assertThat("HTTP response delete book", it.status(), is(Http.Status.OK_200))).toCompletableFuture().get();
application.stop();
}
use of io.helidon.common.http.Http in project helidon by oracle.
the class GreetService method contextCheck.
/**
* Checks the existence of a {@code Context} object in a WebClient thread.
*
* @param request the request
* @param response the response
*/
private void contextCheck(ServerRequest request, ServerResponse response) {
WebClient webClient = WebClient.builder().baseUri("http://localhost:" + Main.serverPort + "/").build();
Optional<Context> context = Contexts.context();
// Verify that context was propagated with auth enabled
if (context.isEmpty()) {
response.status(Http.Status.INTERNAL_SERVER_ERROR_500).send();
return;
}
// Register instance in context
context.get().register(this);
// Ensure context is available in webclient threads
webClient.get().request().thenAccept(clientResponse -> {
Context singleContext = Contexts.context().orElseThrow();
Objects.requireNonNull(singleContext.get(GreetService.class));
response.status(Http.Status.OK_200);
response.send();
}).exceptionally(throwable -> {
response.status(Http.Status.INTERNAL_SERVER_ERROR_500);
response.send();
return null;
});
}
Aggregations