Search in sources :

Example 11 with LiveHttpResponse

use of com.hotels.styx.api.LiveHttpResponse in project styx by ExpediaGroup.

the class NettyToStyxResponsePropagator method channelRead0.

@Override
protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
    FlowControllingHttpContentProducer producer = getContentProducer(ctx);
    if (msg instanceof io.netty.handler.codec.http.HttpResponse) {
        io.netty.handler.codec.http.HttpResponse nettyResponse = (io.netty.handler.codec.http.HttpResponse) msg;
        if (!responseReceived.compareAndSet(false, true)) {
            LOGGER.warn("Unexpected additional response received: " + nettyResponse);
            ctx.channel().close();
            return;
        }
        if (nettyResponse.getDecoderResult().isFailure()) {
            emitResponseError(new BadHttpResponseException(origin, nettyResponse.getDecoderResult().cause()));
            return;
        }
        ctx.channel().config().setAutoRead(false);
        ctx.channel().read();
        // Can be started with flow controlling disabled
        EventLoop eventLoop = ctx.channel().eventLoop();
        Publisher<Buffer> contentPublisher = new ContentPublisher(eventLoop, producer);
        if ("close".equalsIgnoreCase(nettyResponse.headers().get(CONNECTION))) {
            toBeClosed = true;
        }
        LiveHttpResponse response = toStyxResponse(nettyResponse, contentPublisher, origin);
        this.sink.next(response);
    }
    if (msg instanceof HttpContent) {
        ByteBuf content = ((ByteBufHolder) msg).content();
        if (content.isReadable()) {
            producer.newChunk(retain(content));
        }
        if (msg instanceof LastHttpContent) {
            // Note: Netty may send a LastHttpContent as a response to TCP connection close.
            // In this case channelReadComplete event will _not_ follow the LastHttpContent.
            producer.lastHttpContent();
            if (toBeClosed) {
                ctx.channel().close();
            }
        }
    }
}
Also used : Buffer(com.hotels.styx.api.Buffer) LiveHttpResponse(com.hotels.styx.api.LiveHttpResponse) LiveHttpResponse(com.hotels.styx.api.LiveHttpResponse) ByteBuf(io.netty.buffer.ByteBuf) LastHttpContent(io.netty.handler.codec.http.LastHttpContent) EventLoop(io.netty.channel.EventLoop) ByteBufHolder(io.netty.buffer.ByteBufHolder) BadHttpResponseException(com.hotels.styx.client.BadHttpResponseException) LastHttpContent(io.netty.handler.codec.http.LastHttpContent) HttpContent(io.netty.handler.codec.http.HttpContent)

Example 12 with LiveHttpResponse

use of com.hotels.styx.api.LiveHttpResponse in project styx by ExpediaGroup.

the class StyxHttpClientTest method sendsSecureStreamingRequests.

/*
     * HttpClient.StreamingTransaction
     * - Sends LiveHttpRequest messages created from StyxHttpClientTransactions
     */
@Test
public void sendsSecureStreamingRequests() throws ExecutionException, InterruptedException {
    LiveHttpResponse response = new StyxHttpClient.Builder().build().secure(true).streaming().send(secureRequest.stream()).get();
    assertThat(response.status(), is(OK));
    Mono.from(response.aggregate(10000)).block();
    server.verify(getRequestedFor(urlEqualTo("/")).withHeader("Host", equalTo(hostString(server.httpsPort()))));
}
Also used : LiveHttpResponse(com.hotels.styx.api.LiveHttpResponse) Test(org.junit.jupiter.api.Test)

Example 13 with LiveHttpResponse

use of com.hotels.styx.api.LiveHttpResponse in project styx by ExpediaGroup.

the class StyxHttpClientTest method sendsStreamingRequests.

/*
     * HttpClient.StreamingTransaction
     * - Sends LiveHttpRequest messages
     */
@Test
public void sendsStreamingRequests() throws ExecutionException, InterruptedException {
    LiveHttpResponse response = new StyxHttpClient.Builder().build().streaming().send(httpRequest.stream()).get();
    assertThat(response.status(), is(OK));
    Mono.from(response.aggregate(10000)).block();
    server.verify(getRequestedFor(urlEqualTo("/")).withHeader("Host", equalTo(hostString(server.port()))));
}
Also used : LiveHttpResponse(com.hotels.styx.api.LiveHttpResponse) Test(org.junit.jupiter.api.Test)

Example 14 with LiveHttpResponse

use of com.hotels.styx.api.LiveHttpResponse in project styx by ExpediaGroup.

the class StyxHostHttpClientTest method terminatesConnectionDueToUnsubscribedBody.

@Test
public void terminatesConnectionDueToUnsubscribedBody() {
    TestPublisher<Buffer> testPublisher = TestPublisher.create();
    Connection connection = mockConnection(just(LiveHttpResponse.response(OK).body(new ByteStream(testPublisher)).build()));
    ConnectionPool pool = mockPool(connection);
    Context context = mockContext();
    AtomicReference<LiveHttpResponse> receivedResponse = new AtomicReference<>();
    StyxHostHttpClient hostClient = new StyxHostHttpClient(pool);
    StepVerifier.create(hostClient.sendRequest(request, context)).consumeNextWith(receivedResponse::set).expectComplete().verify();
    StepVerifier.create(receivedResponse.get().body()).thenCancel().verify();
    verify(pool).closeConnection(any(Connection.class));
    verify(context).add(ORIGINID_CONTEXT_KEY, Id.id("mockorigin"));
}
Also used : Buffer(com.hotels.styx.api.Buffer) ConnectionPool(com.hotels.styx.client.connectionpool.ConnectionPool) HttpInterceptorContext(com.hotels.styx.server.HttpInterceptorContext) Support.requestContext(com.hotels.styx.support.Support.requestContext) Context(com.hotels.styx.api.HttpInterceptor.Context) ByteStream(com.hotels.styx.api.ByteStream) AtomicReference(java.util.concurrent.atomic.AtomicReference) LiveHttpResponse(com.hotels.styx.api.LiveHttpResponse) Test(org.junit.jupiter.api.Test)

Example 15 with LiveHttpResponse

use of com.hotels.styx.api.LiveHttpResponse in project styx by ExpediaGroup.

the class StyxHostHttpClientTest method ignoresCancelledHeaders.

@Test
public void ignoresCancelledHeaders() {
    // Request observable unsubscribe/cancel has to be ignored after "onNext" event.
    // This is because Reactor Mono will automatically cancel after an event has
    // been published.
    Connection connection = mockConnection(just(response));
    ConnectionPool pool = mockPool(connection);
    Context context = mockContext();
    AtomicReference<LiveHttpResponse> transformedResponse = new AtomicReference<>();
    StyxHostHttpClient hostClient = new StyxHostHttpClient(pool);
    // The StepVerifier consumes the response event and then unsubscribes
    // from the response observable.
    StepVerifier.create(hostClient.sendRequest(request, context)).consumeNextWith(transformedResponse::set).verifyComplete();
    // The response is still alive...
    verify(pool, never()).returnConnection(any(Connection.class));
    verify(pool, never()).closeConnection(any(Connection.class));
    // ... until response body is consumed:
    transformedResponse.get().consume();
    // Finally, the connection is returned after the response body is fully consumed:
    verify(pool).returnConnection(any(Connection.class));
    verify(context).add(ORIGINID_CONTEXT_KEY, Id.id("mockorigin"));
}
Also used : ConnectionPool(com.hotels.styx.client.connectionpool.ConnectionPool) HttpInterceptorContext(com.hotels.styx.server.HttpInterceptorContext) Support.requestContext(com.hotels.styx.support.Support.requestContext) Context(com.hotels.styx.api.HttpInterceptor.Context) AtomicReference(java.util.concurrent.atomic.AtomicReference) LiveHttpResponse(com.hotels.styx.api.LiveHttpResponse) Test(org.junit.jupiter.api.Test)

Aggregations

LiveHttpResponse (com.hotels.styx.api.LiveHttpResponse)80 Test (org.junit.jupiter.api.Test)69 LiveHttpRequest (com.hotels.styx.api.LiveHttpRequest)25 Support.requestContext (com.hotels.styx.support.Support.requestContext)21 Eventual (com.hotels.styx.api.Eventual)15 MatcherAssert.assertThat (org.hamcrest.MatcherAssert.assertThat)15 HttpHandler (com.hotels.styx.api.HttpHandler)14 EmbeddedChannel (io.netty.channel.embedded.EmbeddedChannel)14 Mono (reactor.core.publisher.Mono)14 ByteStream (com.hotels.styx.api.ByteStream)13 Context (com.hotels.styx.api.HttpInterceptor.Context)13 OK (com.hotels.styx.api.HttpResponseStatus.OK)13 LiveHttpResponse.response (com.hotels.styx.api.LiveHttpResponse.response)13 TransportLostException (com.hotels.styx.api.exceptions.TransportLostException)12 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)12 CompletableFuture (java.util.concurrent.CompletableFuture)12 Matchers.is (org.hamcrest.Matchers.is)12 Buffer (com.hotels.styx.api.Buffer)11 LiveHttpRequest.get (com.hotels.styx.api.LiveHttpRequest.get)11 HttpInterceptorContext (com.hotels.styx.server.HttpInterceptorContext)11