Search in sources :

Example 26 with LastHttpContent

use of org.apache.flink.shaded.netty4.io.netty.handler.codec.http.LastHttpContent in project ambry by linkedin.

the class MockChannelHandlerContext method responsesWithContentLengthTest.

/**
 * Tests the common workflow of the {@link NettyResponseChannel} i.e., add some content to response body via
 * {@link NettyResponseChannel#write(ByteBuffer, Callback)} and then complete the response.
 * <p/>
 * These responses have the header Content-Length set.
 * @throws Exception
 */
@Test
public void responsesWithContentLengthTest() throws Exception {
    EmbeddedChannel channel = createEmbeddedChannel();
    MockNettyMessageProcessor processor = channel.pipeline().get(MockNettyMessageProcessor.class);
    final int ITERATIONS = 10;
    for (int i = 0; i < ITERATIONS; i++) {
        boolean isKeepAlive = i != (ITERATIONS - 1);
        HttpHeaders httpHeaders = new DefaultHttpHeaders();
        httpHeaders.set(MockNettyMessageProcessor.CHUNK_COUNT_HEADER_NAME, i);
        HttpRequest httpRequest = RestTestUtils.createRequest(HttpMethod.POST, TestingUri.ResponseWithContentLength.toString(), httpHeaders);
        HttpUtil.setKeepAlive(httpRequest, isKeepAlive);
        channel.writeInbound(httpRequest);
        verifyCallbacks(processor);
        // first outbound has to be response.
        HttpResponse response = channel.readOutbound();
        assertEquals("Unexpected response status", HttpResponseStatus.OK, response.status());
        long contentLength = HttpUtil.getContentLength(response, NettyRequest.UNKNOWN_CONTENT_LENGTH);
        assertEquals("Unexpected Content-Length", MockNettyMessageProcessor.CHUNK.length * i, contentLength);
        if (contentLength == 0) {
            // special case. Since Content-Length is set, the response should be an instance of FullHttpResponse.
            assertTrue("Response not instance of FullHttpResponse", response instanceof FullHttpResponse);
        } else {
            HttpContent httpContent = null;
            for (int j = 0; j < i; j++) {
                httpContent = channel.readOutbound();
                byte[] returnedContent = new byte[httpContent.content().readableBytes()];
                httpContent.content().readBytes(returnedContent);
                httpContent.release();
                assertArrayEquals("Content does not match with expected content", MockNettyMessageProcessor.CHUNK, returnedContent);
            }
            // When we know the content-length, the last httpContent would be an instance of LastHttpContent and there is no
            // empty last http content following it.
            // the last HttpContent should also be an instance of LastHttpContent
            assertTrue("The last part of the content is not LastHttpContent", httpContent instanceof LastHttpContent);
        }
        assertEquals("Unexpected channel state on the server", isKeepAlive, channel.isActive());
    }
}
Also used : HttpRequest(io.netty.handler.codec.http.HttpRequest) HttpHeaders(io.netty.handler.codec.http.HttpHeaders) DefaultHttpHeaders(io.netty.handler.codec.http.DefaultHttpHeaders) EmbeddedChannel(io.netty.channel.embedded.EmbeddedChannel) HttpResponse(io.netty.handler.codec.http.HttpResponse) FullHttpResponse(io.netty.handler.codec.http.FullHttpResponse) LastHttpContent(io.netty.handler.codec.http.LastHttpContent) DefaultLastHttpContent(io.netty.handler.codec.http.DefaultLastHttpContent) DefaultHttpHeaders(io.netty.handler.codec.http.DefaultHttpHeaders) FullHttpResponse(io.netty.handler.codec.http.FullHttpResponse) LastHttpContent(io.netty.handler.codec.http.LastHttpContent) HttpContent(io.netty.handler.codec.http.HttpContent) DefaultHttpContent(io.netty.handler.codec.http.DefaultHttpContent) DefaultLastHttpContent(io.netty.handler.codec.http.DefaultLastHttpContent) Test(org.junit.Test)

Example 27 with LastHttpContent

use of org.apache.flink.shaded.netty4.io.netty.handler.codec.http.LastHttpContent in project ambry by linkedin.

the class MockChannelHandlerContext method responsesWithTransferEncodingChunkedTest.

/**
 * Tests the common workflow of the {@link NettyResponseChannel} i.e., add some content to response body via
 * {@link NettyResponseChannel#write(ByteBuf, Callback)} and then complete the response.
 * <p/>
 * These responses have the header Transfer-Encoding set to chunked.
 * @throws Exception
 */
@Test
public void responsesWithTransferEncodingChunkedTest() throws Exception {
    String content = "@@randomContent@@@";
    String lastContent = "@@randomLastContent@@@";
    EmbeddedChannel channel = createEmbeddedChannel();
    MockNettyMessageProcessor processor = channel.pipeline().get(MockNettyMessageProcessor.class);
    AtomicLong contentIdGenerator = new AtomicLong(0);
    final int ITERATIONS = 10;
    for (int i = 0; i < ITERATIONS; i++) {
        boolean isKeepAlive = i != (ITERATIONS - 1);
        HttpRequest httpRequest = RestTestUtils.createRequest(HttpMethod.POST, "/", null);
        HttpUtil.setKeepAlive(httpRequest, isKeepAlive);
        channel.writeInbound(httpRequest);
        ArrayList<String> contents = new ArrayList<>();
        for (int j = 0; j <= i; j++) {
            String contentToSend = content + contentIdGenerator.getAndIncrement();
            channel.writeInbound(createContent(contentToSend, false));
            contents.add(contentToSend);
        }
        channel.writeInbound(createContent(lastContent, true));
        verifyCallbacks(processor);
        // first outbound has to be response.
        HttpResponse response = channel.readOutbound();
        assertEquals("Unexpected response status", HttpResponseStatus.OK, response.status());
        assertTrue("Response must say 'Transfer-Encoding : chunked'", HttpUtil.isTransferEncodingChunked(response));
        // content echoed back.
        for (String srcOfTruth : contents) {
            HttpContent responseContent = channel.readOutbound();
            String returnedContent = RestTestUtils.getContentString(responseContent);
            responseContent.release();
            assertEquals("Content does not match with expected content", srcOfTruth, returnedContent);
        }
        HttpContent responseContent = channel.readOutbound();
        // last content echoed back.
        String returnedContent = RestTestUtils.getContentString(responseContent);
        responseContent.release();
        assertEquals("Content does not match with expected content", lastContent, returnedContent);
        // When the Transfer-Encoding is Chunked, response channel would send the last http content in the request as
        // regular http content and then send an empty last http content after that.
        assertTrue("Did not receive end marker", channel.readOutbound() instanceof LastHttpContent);
        assertEquals("Unexpected channel state on the server", isKeepAlive, channel.isActive());
    }
}
Also used : HttpRequest(io.netty.handler.codec.http.HttpRequest) AtomicLong(java.util.concurrent.atomic.AtomicLong) ArrayList(java.util.ArrayList) EmbeddedChannel(io.netty.channel.embedded.EmbeddedChannel) HttpResponse(io.netty.handler.codec.http.HttpResponse) FullHttpResponse(io.netty.handler.codec.http.FullHttpResponse) LastHttpContent(io.netty.handler.codec.http.LastHttpContent) DefaultLastHttpContent(io.netty.handler.codec.http.DefaultLastHttpContent) LastHttpContent(io.netty.handler.codec.http.LastHttpContent) HttpContent(io.netty.handler.codec.http.HttpContent) DefaultHttpContent(io.netty.handler.codec.http.DefaultHttpContent) DefaultLastHttpContent(io.netty.handler.codec.http.DefaultLastHttpContent) Test(org.junit.Test)

Example 28 with LastHttpContent

use of org.apache.flink.shaded.netty4.io.netty.handler.codec.http.LastHttpContent in project ambry by linkedin.

the class PublicAccessLogHandler method write.

@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
    long startTimeInMs = System.currentTimeMillis();
    boolean shouldReset = msg instanceof LastHttpContent;
    boolean isHttpContent = msg instanceof HttpContent;
    if (request != null) {
        if (msg instanceof HttpResponse) {
            HttpResponse response = (HttpResponse) msg;
            logHeaders("Response", response, publicAccessLogger.getResponseHeaders());
            logMessage.append(", ");
            logMessage.append("status=").append(response.status().code());
            logMessage.append(", ");
            if (HttpUtil.isTransferEncodingChunked(response)) {
                responseFirstChunkStartTimeInMs = System.currentTimeMillis();
            } else {
                shouldReset = true;
            }
        } else if (!(msg instanceof HttpContent)) {
            logger.error("Sending response that is not of type HttpResponse or HttpContent. Sending response to {}. Request is of type {}. No action being taken other than logging this unexpected state.", ctx.channel().remoteAddress(), msg.getClass());
        }
        if (isHttpContent) {
            HttpContent httpContent = (HttpContent) msg;
            responseBytesSent += httpContent.content().readableBytes();
        }
        if (shouldReset) {
            logDurations();
            publicAccessLogger.logInfo(logMessage.toString());
            reset();
        }
    }
    nettyMetrics.publicAccessLogResponseProcessingTimeInMs.update(System.currentTimeMillis() - startTimeInMs);
    super.write(ctx, msg, promise);
}
Also used : HttpResponse(io.netty.handler.codec.http.HttpResponse) LastHttpContent(io.netty.handler.codec.http.LastHttpContent) HttpContent(io.netty.handler.codec.http.HttpContent) LastHttpContent(io.netty.handler.codec.http.LastHttpContent)

Example 29 with LastHttpContent

use of org.apache.flink.shaded.netty4.io.netty.handler.codec.http.LastHttpContent in project ambry by linkedin.

the class NettyMessageProcessorTest method sendRequestCheckResponse.

/**
 * Sends the provided {@code httpRequest} and verifies that the response is an echo of the {@code restMethod}.
 * @param channel the {@link EmbeddedChannel} to send the request over.
 * @param httpMethod the {@link HttpMethod} for the request.
 * @param restMethod the equivalent {@link RestMethod} for {@code httpMethod}. Used to check for correctness of
 *                   response.
 * @param isKeepAlive if the request needs to be keep-alive.
 * @throws IOException
 */
private void sendRequestCheckResponse(EmbeddedChannel channel, HttpMethod httpMethod, RestMethod restMethod, boolean isKeepAlive) throws IOException {
    long requestId = REQUEST_ID_GENERATOR.getAndIncrement();
    String uri = MockRestRequestService.ECHO_REST_METHOD + requestId;
    HttpRequest httpRequest = RestTestUtils.createRequest(httpMethod, uri, null);
    HttpUtil.setKeepAlive(httpRequest, isKeepAlive);
    channel.writeInbound(httpRequest);
    channel.writeInbound(new DefaultLastHttpContent());
    HttpResponse response = (HttpResponse) channel.readOutbound();
    assertEquals("Unexpected response status", HttpResponseStatus.OK, response.status());
    // MockRestRequestService echoes the RestMethod + request id.
    String expectedResponse = restMethod.toString() + requestId;
    assertEquals("Unexpected content", expectedResponse, RestTestUtils.getContentString((HttpContent) channel.readOutbound()));
    assertTrue("End marker was expected", channel.readOutbound() instanceof LastHttpContent);
}
Also used : DefaultFullHttpRequest(io.netty.handler.codec.http.DefaultFullHttpRequest) HttpRequest(io.netty.handler.codec.http.HttpRequest) DefaultLastHttpContent(io.netty.handler.codec.http.DefaultLastHttpContent) DefaultHttpResponse(io.netty.handler.codec.http.DefaultHttpResponse) HttpResponse(io.netty.handler.codec.http.HttpResponse) LastHttpContent(io.netty.handler.codec.http.LastHttpContent) DefaultLastHttpContent(io.netty.handler.codec.http.DefaultLastHttpContent) LastHttpContent(io.netty.handler.codec.http.LastHttpContent) HttpContent(io.netty.handler.codec.http.HttpContent) DefaultHttpContent(io.netty.handler.codec.http.DefaultHttpContent) DefaultLastHttpContent(io.netty.handler.codec.http.DefaultLastHttpContent)

Example 30 with LastHttpContent

use of org.apache.flink.shaded.netty4.io.netty.handler.codec.http.LastHttpContent in project ambry by linkedin.

the class CopyForcingByteBuf method doHeaderAndContentSizeMismatchTest.

/**
 * Tests reaction of NettyRequest when content size is different from the size specified in the headers.
 * @param httpHeaders {@link HttpHeaders} that need to be a part of the request.
 * @param httpContents the {@link List<HttpContent>} that needs to be added to {@code nettyRequest}.
 * @throws Exception
 */
private void doHeaderAndContentSizeMismatchTest(HttpHeaders httpHeaders, List<HttpContent> httpContents) throws Exception {
    Channel channel = new MockChannel();
    NettyRequest nettyRequest = createNettyRequest(HttpMethod.POST, "/", httpHeaders, channel);
    AsyncWritableChannel writeChannel = new ByteBufferAsyncWritableChannel();
    ReadIntoCallback callback = new ReadIntoCallback();
    Future<Long> future = nettyRequest.readInto(writeChannel, callback);
    int bytesAdded = 0;
    HttpContent httpContentToAdd = null;
    for (HttpContent httpContent : httpContents) {
        httpContentToAdd = httpContent;
        int contentBytes = httpContentToAdd.content().readableBytes();
        if (!(httpContentToAdd instanceof LastHttpContent) && (bytesAdded + contentBytes <= nettyRequest.getSize())) {
            nettyRequest.addContent(httpContentToAdd);
            assertEquals("Reference count is not as expected", 2, httpContentToAdd.refCnt());
            bytesAdded += contentBytes;
        } else {
            break;
        }
    }
    // the addition of the next content should throw an exception.
    try {
        nettyRequest.addContent(httpContentToAdd);
        fail("Adding content should have failed because there was a mismatch in size");
    } catch (RestServiceException e) {
        assertEquals("Unexpected RestServiceErrorCode", RestServiceErrorCode.BadRequest, e.getErrorCode());
    }
    closeRequestAndValidate(nettyRequest, channel);
    writeChannel.close();
    verifyRefCnts(httpContents);
    callback.awaitCallback();
    assertNotNull("There should be a RestServiceException in the callback", callback.exception);
    assertEquals("Unexpected RestServiceErrorCode", RestServiceErrorCode.BadRequest, ((RestServiceException) callback.exception).getErrorCode());
    try {
        future.get();
        fail("Should have thrown exception because the future is expected to have been given one");
    } catch (ExecutionException e) {
        RestServiceException restServiceException = (RestServiceException) Utils.getRootCause(e);
        assertNotNull("There should be a RestServiceException in the future", restServiceException);
        assertEquals("Unexpected RestServiceErrorCode", RestServiceErrorCode.BadRequest, restServiceException.getErrorCode());
    }
}
Also used : AsyncWritableChannel(com.github.ambry.router.AsyncWritableChannel) ByteBufferAsyncWritableChannel(com.github.ambry.commons.ByteBufferAsyncWritableChannel) EmbeddedChannel(io.netty.channel.embedded.EmbeddedChannel) Channel(io.netty.channel.Channel) AsyncWritableChannel(com.github.ambry.router.AsyncWritableChannel) ByteBufferAsyncWritableChannel(com.github.ambry.commons.ByteBufferAsyncWritableChannel) LastHttpContent(io.netty.handler.codec.http.LastHttpContent) DefaultLastHttpContent(io.netty.handler.codec.http.DefaultLastHttpContent) ByteBufferAsyncWritableChannel(com.github.ambry.commons.ByteBufferAsyncWritableChannel) ExecutionException(java.util.concurrent.ExecutionException) LastHttpContent(io.netty.handler.codec.http.LastHttpContent) HttpContent(io.netty.handler.codec.http.HttpContent) DefaultHttpContent(io.netty.handler.codec.http.DefaultHttpContent) DefaultLastHttpContent(io.netty.handler.codec.http.DefaultLastHttpContent)

Aggregations

LastHttpContent (io.netty.handler.codec.http.LastHttpContent)137 DefaultLastHttpContent (io.netty.handler.codec.http.DefaultLastHttpContent)63 HttpContent (io.netty.handler.codec.http.HttpContent)55 ByteBuf (io.netty.buffer.ByteBuf)49 EmbeddedChannel (io.netty.channel.embedded.EmbeddedChannel)43 HttpResponse (io.netty.handler.codec.http.HttpResponse)42 HttpRequest (io.netty.handler.codec.http.HttpRequest)34 Test (org.junit.Test)27 Test (org.junit.jupiter.api.Test)24 DefaultHttpContent (io.netty.handler.codec.http.DefaultHttpContent)23 HttpHeaders (io.netty.handler.codec.http.HttpHeaders)20 FullHttpResponse (io.netty.handler.codec.http.FullHttpResponse)18 DefaultFullHttpResponse (io.netty.handler.codec.http.DefaultFullHttpResponse)13 IOException (java.io.IOException)12 ChannelFuture (io.netty.channel.ChannelFuture)11 FullHttpRequest (io.netty.handler.codec.http.FullHttpRequest)10 HttpObject (io.netty.handler.codec.http.HttpObject)10 JsonObjectDecoder (io.netty.handler.codec.json.JsonObjectDecoder)10 HttpProcessingState (com.nike.riposte.server.http.HttpProcessingState)9 DefaultFullHttpRequest (io.netty.handler.codec.http.DefaultFullHttpRequest)9