Search in sources :

Example 1 with Http2DataFrame

use of io.netty.handler.codec.http2.Http2DataFrame in project netty by netty.

the class Http2MultiplexTest method endOfStreamDoesNotDiscardData.

@Test
public void endOfStreamDoesNotDiscardData() {
    AtomicInteger numReads = new AtomicInteger(1);
    final AtomicBoolean shouldDisableAutoRead = new AtomicBoolean();
    Consumer<ChannelHandlerContext> ctxConsumer = new Consumer<ChannelHandlerContext>() {

        @Override
        public void accept(ChannelHandlerContext obj) {
            if (shouldDisableAutoRead.get()) {
                obj.channel().config().setAutoRead(false);
            }
        }
    };
    LastInboundHandler inboundHandler = new LastInboundHandler(ctxConsumer);
    Http2StreamChannel childChannel = newInboundStream(3, false, numReads, inboundHandler);
    childChannel.config().setAutoRead(false);
    Http2DataFrame dataFrame1 = new DefaultHttp2DataFrame(bb("1")).stream(childChannel.stream());
    Http2DataFrame dataFrame2 = new DefaultHttp2DataFrame(bb("2")).stream(childChannel.stream());
    Http2DataFrame dataFrame3 = new DefaultHttp2DataFrame(bb("3")).stream(childChannel.stream());
    Http2DataFrame dataFrame4 = new DefaultHttp2DataFrame(bb("4")).stream(childChannel.stream());
    assertEquals(new DefaultHttp2HeadersFrame(request).stream(childChannel.stream()), inboundHandler.readInbound());
    ChannelHandler readCompleteSupressHandler = new ChannelInboundHandlerAdapter() {

        @Override
        public void channelReadComplete(ChannelHandlerContext ctx) {
        // We want to simulate the parent channel calling channelRead and delay calling channelReadComplete.
        }
    };
    parentChannel.pipeline().addFirst(readCompleteSupressHandler);
    frameInboundWriter.writeInboundData(childChannel.stream().id(), bb("1"), 0, false);
    assertEqualsAndRelease(dataFrame1, inboundHandler.<Http2DataFrame>readInbound());
    // Deliver frames, and then a stream closed while read is inactive.
    frameInboundWriter.writeInboundData(childChannel.stream().id(), bb("2"), 0, false);
    frameInboundWriter.writeInboundData(childChannel.stream().id(), bb("3"), 0, false);
    frameInboundWriter.writeInboundData(childChannel.stream().id(), bb("4"), 0, false);
    shouldDisableAutoRead.set(true);
    childChannel.config().setAutoRead(true);
    numReads.set(1);
    frameInboundWriter.writeInboundRstStream(childChannel.stream().id(), Http2Error.NO_ERROR.code());
    // Detecting EOS should flush all pending data regardless of read calls.
    assertEqualsAndRelease(dataFrame2, inboundHandler.<Http2DataFrame>readInbound());
    assertNull(inboundHandler.readInbound());
    // As we limited the number to 1 we also need to call read() again.
    childChannel.read();
    assertEqualsAndRelease(dataFrame3, inboundHandler.<Http2DataFrame>readInbound());
    assertEqualsAndRelease(dataFrame4, inboundHandler.<Http2DataFrame>readInbound());
    Http2ResetFrame resetFrame = useUserEventForResetFrame() ? inboundHandler.<Http2ResetFrame>readUserEvent() : inboundHandler.<Http2ResetFrame>readInbound();
    assertEquals(childChannel.stream(), resetFrame.stream());
    assertEquals(Http2Error.NO_ERROR.code(), resetFrame.errorCode());
    assertNull(inboundHandler.readInbound());
    // Now we want to call channelReadComplete and simulate the end of the read loop.
    parentChannel.pipeline().remove(readCompleteSupressHandler);
    parentChannel.flushInbound();
    childChannel.closeFuture().syncUninterruptibly();
}
Also used : ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) ChannelHandler(io.netty.channel.ChannelHandler) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Consumer(io.netty.handler.codec.http2.LastInboundHandler.Consumer) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ChannelInboundHandlerAdapter(io.netty.channel.ChannelInboundHandlerAdapter) Test(org.junit.jupiter.api.Test)

Example 2 with Http2DataFrame

use of io.netty.handler.codec.http2.Http2DataFrame in project netty by netty.

the class Http2FrameCodecTest method upgradeWithoutFlowControlling.

@Test
public void upgradeWithoutFlowControlling() throws Exception {
    channel.pipeline().addAfter(frameCodec.ctx.name(), null, new ChannelInboundHandlerAdapter() {

        @Override
        public void channelRead(final ChannelHandlerContext ctx, Object msg) throws Exception {
            if (msg instanceof Http2DataFrame) {
                // Simulate consuming the frame and update the flow-controller.
                Http2DataFrame data = (Http2DataFrame) msg;
                ctx.writeAndFlush(new DefaultHttp2WindowUpdateFrame(data.initialFlowControlledBytes()).stream(data.stream())).addListener(new ChannelFutureListener() {

                    @Override
                    public void operationComplete(ChannelFuture future) throws Exception {
                        Throwable cause = future.cause();
                        if (cause != null) {
                            ctx.fireExceptionCaught(cause);
                        }
                    }
                });
            }
            ReferenceCountUtil.release(msg);
        }
    });
    frameInboundWriter.writeInboundHeaders(Http2CodecUtil.HTTP_UPGRADE_STREAM_ID, request, 31, false);
    // Using reflect as the constructor is package-private and the class is final.
    Constructor<UpgradeEvent> constructor = UpgradeEvent.class.getDeclaredConstructor(CharSequence.class, FullHttpRequest.class);
    // Check if we could make it accessible which may fail on java9.
    Assumptions.assumeTrue(ReflectionUtil.trySetAccessible(constructor, true) == null);
    String longString = new String(new char[70000]).replace("\0", "*");
    DefaultFullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/", bb(longString));
    HttpServerUpgradeHandler.UpgradeEvent upgradeEvent = constructor.newInstance("HTTP/2", request);
    channel.pipeline().fireUserEventTriggered(upgradeEvent);
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) DefaultFullHttpRequest(io.netty.handler.codec.http.DefaultFullHttpRequest) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) AsciiString(io.netty.util.AsciiString) HttpServerUpgradeHandler(io.netty.handler.codec.http.HttpServerUpgradeHandler) ChannelFutureListener(io.netty.channel.ChannelFutureListener) StreamException(io.netty.handler.codec.http2.Http2Exception.StreamException) UnsupportedMessageTypeException(io.netty.handler.codec.UnsupportedMessageTypeException) UpgradeEvent(io.netty.handler.codec.http.HttpServerUpgradeHandler.UpgradeEvent) UpgradeEvent(io.netty.handler.codec.http.HttpServerUpgradeHandler.UpgradeEvent) ChannelInboundHandlerAdapter(io.netty.channel.ChannelInboundHandlerAdapter) Test(org.junit.jupiter.api.Test)

Example 3 with Http2DataFrame

use of io.netty.handler.codec.http2.Http2DataFrame in project netty by netty.

the class Http2MultiplexTest method channelReadShouldRespectAutoReadAndNotProduceNPE.

@Test
public void channelReadShouldRespectAutoReadAndNotProduceNPE() throws Exception {
    LastInboundHandler inboundHandler = new LastInboundHandler();
    Http2StreamChannel childChannel = newInboundStream(3, false, inboundHandler);
    assertTrue(childChannel.config().isAutoRead());
    Http2HeadersFrame headersFrame = inboundHandler.readInbound();
    assertNotNull(headersFrame);
    childChannel.config().setAutoRead(false);
    childChannel.pipeline().addFirst(new ChannelInboundHandlerAdapter() {

        private int count;

        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            ctx.fireChannelRead(msg);
            // Close channel after 2 reads so there is still something in the inboundBuffer when the close happens.
            if (++count == 2) {
                ctx.close();
            }
        }
    });
    frameInboundWriter.writeInboundData(childChannel.stream().id(), bb("hello world"), 0, false);
    Http2DataFrame dataFrame0 = inboundHandler.readInbound();
    assertNotNull(dataFrame0);
    release(dataFrame0);
    frameInboundWriter.writeInboundData(childChannel.stream().id(), bb("foo"), 0, false);
    frameInboundWriter.writeInboundData(childChannel.stream().id(), bb("bar"), 0, false);
    frameInboundWriter.writeInboundData(childChannel.stream().id(), bb("bar"), 0, false);
    assertNull(inboundHandler.readInbound());
    childChannel.config().setAutoRead(true);
    verifyFramesMultiplexedToCorrectChannel(childChannel, inboundHandler, 3);
    inboundHandler.checkException();
}
Also used : ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) StreamException(io.netty.handler.codec.http2.Http2Exception.StreamException) ClosedChannelException(java.nio.channels.ClosedChannelException) ChannelInboundHandlerAdapter(io.netty.channel.ChannelInboundHandlerAdapter) Test(org.junit.jupiter.api.Test)

Example 4 with Http2DataFrame

use of io.netty.handler.codec.http2.Http2DataFrame in project netty by netty.

the class Http2StaticFileServerHandler method sendError.

private void sendError(ChannelHandlerContext ctx, HttpResponseStatus status) {
    Http2Headers headers = new DefaultHttp2Headers();
    headers.status(status.toString());
    headers.add(HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=UTF-8");
    Http2HeadersFrame headersFrame = new DefaultHttp2HeadersFrame(headers);
    headersFrame.stream(stream);
    Http2DataFrame dataFrame = new DefaultHttp2DataFrame(Unpooled.copiedBuffer("Failure: " + status + "\r\n", CharsetUtil.UTF_8), true);
    dataFrame.stream(stream);
    ctx.write(headersFrame);
    ctx.writeAndFlush(dataFrame);
}
Also used : DefaultHttp2HeadersFrame(io.netty.handler.codec.http2.DefaultHttp2HeadersFrame) DefaultHttp2DataFrame(io.netty.handler.codec.http2.DefaultHttp2DataFrame) DefaultHttp2DataFrame(io.netty.handler.codec.http2.DefaultHttp2DataFrame) Http2DataFrame(io.netty.handler.codec.http2.Http2DataFrame) DefaultHttp2HeadersFrame(io.netty.handler.codec.http2.DefaultHttp2HeadersFrame) Http2HeadersFrame(io.netty.handler.codec.http2.Http2HeadersFrame) Http2Headers(io.netty.handler.codec.http2.Http2Headers) DefaultHttp2Headers(io.netty.handler.codec.http2.DefaultHttp2Headers) DefaultHttp2Headers(io.netty.handler.codec.http2.DefaultHttp2Headers)

Example 5 with Http2DataFrame

use of io.netty.handler.codec.http2.Http2DataFrame in project ambry by linkedin.

the class Http2ClientStreamStatsHandler method channelRead0.

@Override
protected void channelRead0(ChannelHandlerContext ctx, Http2Frame frame) throws Exception {
    ReferenceCountUtil.retain(frame);
    RequestInfo requestInfo = ctx.channel().attr(Http2NetworkClient.REQUEST_INFO).get();
    requestInfo.responseFramesCount++;
    long time = System.currentTimeMillis() - requestInfo.getStreamSendTime();
    if (frame instanceof Http2HeadersFrame) {
        http2ClientMetrics.http2StreamRoundTripTime.update(time);
        requestInfo.setStreamHeaderFrameReceiveTime(System.currentTimeMillis());
        logger.debug("Header Frame received. Time from send: {}ms. Request: {}", time, requestInfo);
    } else if (frame instanceof Http2DataFrame) {
        logger.debug("Data Frame size: {}. Time from send: {}ms. Request: {}", ((Http2DataFrame) frame).content().readableBytes(), time, requestInfo);
    }
    if (frame instanceof Http2DataFrame && ((Http2DataFrame) frame).isEndStream()) {
        http2ClientMetrics.http2StreamFirstToLastFrameTime.update(time);
        http2ClientMetrics.http2ResponseFrameCount.update(requestInfo.responseFramesCount);
        logger.debug("All Frame received. Time from send: {}ms. Request: {}", time, requestInfo);
    }
    ctx.fireChannelRead(frame);
}
Also used : Http2DataFrame(io.netty.handler.codec.http2.Http2DataFrame) Http2HeadersFrame(io.netty.handler.codec.http2.Http2HeadersFrame) RequestInfo(com.github.ambry.network.RequestInfo)

Aggregations

ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)5 ChannelInboundHandlerAdapter (io.netty.channel.ChannelInboundHandlerAdapter)5 Test (org.junit.jupiter.api.Test)5 ChannelHandler (io.netty.channel.ChannelHandler)3 Consumer (io.netty.handler.codec.http2.LastInboundHandler.Consumer)3 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)3 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)3 Http2DataFrame (io.netty.handler.codec.http2.Http2DataFrame)2 StreamException (io.netty.handler.codec.http2.Http2Exception.StreamException)2 Http2HeadersFrame (io.netty.handler.codec.http2.Http2HeadersFrame)2 RequestInfo (com.github.ambry.network.RequestInfo)1 ChannelFuture (io.netty.channel.ChannelFuture)1 ChannelFutureListener (io.netty.channel.ChannelFutureListener)1 UnsupportedMessageTypeException (io.netty.handler.codec.UnsupportedMessageTypeException)1 DefaultFullHttpRequest (io.netty.handler.codec.http.DefaultFullHttpRequest)1 HttpServerUpgradeHandler (io.netty.handler.codec.http.HttpServerUpgradeHandler)1 UpgradeEvent (io.netty.handler.codec.http.HttpServerUpgradeHandler.UpgradeEvent)1 DefaultHttp2DataFrame (io.netty.handler.codec.http2.DefaultHttp2DataFrame)1 DefaultHttp2Headers (io.netty.handler.codec.http2.DefaultHttp2Headers)1 DefaultHttp2HeadersFrame (io.netty.handler.codec.http2.DefaultHttp2HeadersFrame)1