Search in sources :

Example 16 with Http2Settings

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

the class Http2ConnectionRoundtripTest method testSettingsAckIsSentBeforeUsingFlowControl.

@Test
public void testSettingsAckIsSentBeforeUsingFlowControl() throws Exception {
    bootstrapEnv(1, 1, 1, 1);
    final CountDownLatch serverSettingsAckLatch1 = new CountDownLatch(1);
    final CountDownLatch serverSettingsAckLatch2 = new CountDownLatch(2);
    final CountDownLatch serverDataLatch = new CountDownLatch(1);
    final CountDownLatch clientWriteDataLatch = new CountDownLatch(1);
    final byte[] data = new byte[] { 1, 2, 3, 4, 5 };
    final ByteArrayOutputStream out = new ByteArrayOutputStream(data.length);
    doAnswer(new Answer<Void>() {

        @Override
        public Void answer(InvocationOnMock invocationOnMock) throws Throwable {
            serverSettingsAckLatch1.countDown();
            serverSettingsAckLatch2.countDown();
            return null;
        }
    }).when(serverListener).onSettingsAckRead(any(ChannelHandlerContext.class));
    doAnswer(new Answer<Integer>() {

        @Override
        public Integer answer(InvocationOnMock in) throws Throwable {
            ByteBuf buf = (ByteBuf) in.getArguments()[2];
            int padding = (Integer) in.getArguments()[3];
            int processedBytes = buf.readableBytes() + padding;
            buf.readBytes(out, buf.readableBytes());
            serverDataLatch.countDown();
            return processedBytes;
        }
    }).when(serverListener).onDataRead(any(ChannelHandlerContext.class), eq(3), any(ByteBuf.class), eq(0), anyBoolean());
    final Http2Headers headers = dummyHeaders();
    // The server initially reduces the connection flow control window to 0.
    runInChannel(serverConnectedChannel, new Http2Runnable() {

        @Override
        public void run() throws Http2Exception {
            http2Server.encoder().writeSettings(serverCtx(), new Http2Settings().copyFrom(http2Server.decoder().localSettings()).initialWindowSize(0), serverNewPromise());
            http2Server.flush(serverCtx());
        }
    });
    assertTrue(serverSettingsAckLatch1.await(DEFAULT_AWAIT_TIMEOUT_SECONDS, SECONDS));
    // The client should now attempt to send data, but the window size is 0 so it will be queued in the flow
    // controller.
    runInChannel(clientChannel, new Http2Runnable() {

        @Override
        public void run() throws Http2Exception {
            http2Client.encoder().writeHeaders(ctx(), 3, headers, 0, (short) 16, false, 0, false, newPromise());
            http2Client.encoder().writeData(ctx(), 3, Unpooled.wrappedBuffer(data), 0, true, newPromise());
            http2Client.flush(ctx());
            clientWriteDataLatch.countDown();
        }
    });
    assertTrue(clientWriteDataLatch.await(DEFAULT_AWAIT_TIMEOUT_SECONDS, SECONDS));
    // Now the server opens up the connection window to allow the client to send the pending data.
    runInChannel(serverConnectedChannel, new Http2Runnable() {

        @Override
        public void run() throws Http2Exception {
            http2Server.encoder().writeSettings(serverCtx(), new Http2Settings().copyFrom(http2Server.decoder().localSettings()).initialWindowSize(data.length), serverNewPromise());
            http2Server.flush(serverCtx());
        }
    });
    assertTrue(serverSettingsAckLatch2.await(DEFAULT_AWAIT_TIMEOUT_SECONDS, SECONDS));
    assertTrue(serverDataLatch.await(DEFAULT_AWAIT_TIMEOUT_SECONDS, SECONDS));
    assertArrayEquals(data, out.toByteArray());
    // Verify that no errors have been received.
    verify(serverListener, never()).onGoAwayRead(any(ChannelHandlerContext.class), anyInt(), anyLong(), any(ByteBuf.class));
    verify(serverListener, never()).onRstStreamRead(any(ChannelHandlerContext.class), anyInt(), anyLong());
    verify(clientListener, never()).onGoAwayRead(any(ChannelHandlerContext.class), anyInt(), anyLong(), any(ByteBuf.class));
    verify(clientListener, never()).onRstStreamRead(any(ChannelHandlerContext.class), anyInt(), anyLong());
}
Also used : Http2Runnable(io.netty.handler.codec.http2.Http2TestUtil.Http2Runnable) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) ByteArrayOutputStream(java.io.ByteArrayOutputStream) CountDownLatch(java.util.concurrent.CountDownLatch) ByteBuf(io.netty.buffer.ByteBuf) InvocationOnMock(org.mockito.invocation.InvocationOnMock) Test(org.junit.Test)

Aggregations

Http2Settings (io.netty.handler.codec.http2.Http2Settings)12 ByteBuf (io.netty.buffer.ByteBuf)7 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)6 Test (org.junit.Test)5 Http2ConnectionDecoder (io.netty.handler.codec.http2.Http2ConnectionDecoder)4 Buffer (io.vertx.core.buffer.Buffer)4 ChannelFuture (io.netty.channel.ChannelFuture)3 DefaultHttp2Connection (io.netty.handler.codec.http2.DefaultHttp2Connection)3 DefaultHttp2Headers (io.netty.handler.codec.http2.DefaultHttp2Headers)3 Http2Connection (io.netty.handler.codec.http2.Http2Connection)3 Http2ConnectionEncoder (io.netty.handler.codec.http2.Http2ConnectionEncoder)3 VisibleForTesting (com.google.common.annotations.VisibleForTesting)2 Bootstrap (io.netty.bootstrap.Bootstrap)2 Unpooled (io.netty.buffer.Unpooled)2 Channel (io.netty.channel.Channel)2 ChannelDuplexHandler (io.netty.channel.ChannelDuplexHandler)2 ChannelInitializer (io.netty.channel.ChannelInitializer)2 ChannelPipeline (io.netty.channel.ChannelPipeline)2 EventLoopGroup (io.netty.channel.EventLoopGroup)2 NioEventLoopGroup (io.netty.channel.nio.NioEventLoopGroup)2