Search in sources :

Example 1 with Http2Settings

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

the class HttpUtils method decodeSettings.

static Http2Settings decodeSettings(String base64Settings) {
    try {
        Http2Settings settings = new Http2Settings();
        Buffer buffer = Buffer.buffer(Base64.getUrlDecoder().decode(base64Settings));
        int pos = 0;
        int len = buffer.length();
        while (pos < len) {
            int i = buffer.getUnsignedShort(pos);
            pos += 2;
            long j = buffer.getUnsignedInt(pos);
            pos += 4;
            settings.put((char) i, (Long) j);
        }
        return settings;
    } catch (Exception ignore) {
    }
    return null;
}
Also used : Buffer(io.vertx.core.buffer.Buffer) Http2Settings(io.netty.handler.codec.http2.Http2Settings) URISyntaxException(java.net.URISyntaxException)

Example 2 with Http2Settings

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

the class Http2ConnectionBase method updateSettings.

protected synchronized void updateSettings(Http2Settings settingsUpdate, Handler<AsyncResult<Void>> completionHandler) {
    Context completionContext = completionHandler != null ? context.owner().getOrCreateContext() : null;
    Http2Settings current = handler.decoder().localSettings();
    for (Map.Entry<Character, Long> entry : current.entrySet()) {
        Character key = entry.getKey();
        if (Objects.equals(settingsUpdate.get(key), entry.getValue())) {
            settingsUpdate.remove(key);
        }
    }
    handler.writeSettings(settingsUpdate).addListener(fut -> {
        if (fut.isSuccess()) {
            synchronized (Http2ConnectionBase.this) {
                updateSettingsHandlers.add(() -> {
                    serverSettings.putAll(settingsUpdate);
                    if (completionHandler != null) {
                        completionContext.runOnContext(v -> {
                            completionHandler.handle(Future.succeededFuture());
                        });
                    }
                });
            }
        } else {
            if (completionHandler != null) {
                completionContext.runOnContext(v -> {
                    completionHandler.handle(Future.failedFuture(fut.cause()));
                });
            }
        }
    });
}
Also used : Context(io.vertx.core.Context) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) Http2Settings(io.netty.handler.codec.http2.Http2Settings) IntObjectMap(io.netty.util.collection.IntObjectMap) Map(java.util.Map) IntObjectHashMap(io.netty.util.collection.IntObjectHashMap)

Example 3 with Http2Settings

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

the class Http2ServerTest method testServerSettings.

@Test
public void testServerSettings() throws Exception {
    waitFor(2);
    io.vertx.core.http.Http2Settings expectedSettings = TestUtils.randomHttp2Settings();
    expectedSettings.setHeaderTableSize((int) io.vertx.core.http.Http2Settings.DEFAULT_HEADER_TABLE_SIZE);
    server.close();
    server = vertx.createHttpServer(serverOptions);
    Context otherContext = vertx.getOrCreateContext();
    server.connectionHandler(conn -> {
        otherContext.runOnContext(v -> {
            conn.updateSettings(expectedSettings, ar -> {
                assertSame(otherContext, Vertx.currentContext());
                io.vertx.core.http.Http2Settings ackedSettings = conn.settings();
                assertEquals(expectedSettings.getMaxHeaderListSize(), ackedSettings.getMaxHeaderListSize());
                assertEquals(expectedSettings.getMaxFrameSize(), ackedSettings.getMaxFrameSize());
                assertEquals(expectedSettings.getInitialWindowSize(), ackedSettings.getInitialWindowSize());
                assertEquals(expectedSettings.getMaxConcurrentStreams(), ackedSettings.getMaxConcurrentStreams());
                assertEquals(expectedSettings.getHeaderTableSize(), ackedSettings.getHeaderTableSize());
                assertEquals(expectedSettings.get(''), ackedSettings.get(7));
                complete();
            });
        });
    });
    server.requestHandler(req -> {
        fail();
    });
    startServer();
    TestClient client = new TestClient();
    ChannelFuture fut = client.connect(DEFAULT_HTTPS_PORT, DEFAULT_HTTPS_HOST, request -> {
        request.decoder.frameListener(new Http2FrameAdapter() {

            AtomicInteger count = new AtomicInteger();

            @Override
            public void onSettingsRead(ChannelHandlerContext ctx, Http2Settings newSettings) throws Http2Exception {
                vertx.runOnContext(v -> {
                    switch(count.getAndIncrement()) {
                        case 0:
                            break;
                        case 1:
                            assertEquals((Long) expectedSettings.getMaxHeaderListSize(), newSettings.maxHeaderListSize());
                            assertEquals((Integer) expectedSettings.getMaxFrameSize(), newSettings.maxFrameSize());
                            assertEquals((Integer) expectedSettings.getInitialWindowSize(), newSettings.initialWindowSize());
                            assertEquals((Long) expectedSettings.getMaxConcurrentStreams(), newSettings.maxConcurrentStreams());
                            assertEquals(null, newSettings.headerTableSize());
                            complete();
                            break;
                        default:
                            fail();
                    }
                });
            }
        });
    });
    fut.sync();
    await();
}
Also used : Context(io.vertx.core.Context) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) ChannelFuture(io.netty.channel.ChannelFuture) Arrays(java.util.Arrays) GZIPInputStream(java.util.zip.GZIPInputStream) HttpServer(io.vertx.core.http.HttpServer) MultiMap(io.vertx.core.MultiMap) Http2ConnectionEncoder(io.netty.handler.codec.http2.Http2ConnectionEncoder) DefaultHttp2Connection(io.netty.handler.codec.http2.DefaultHttp2Connection) Context(io.vertx.core.Context) Unpooled(io.netty.buffer.Unpooled) Http2ConnectionDecoder(io.netty.handler.codec.http2.Http2ConnectionDecoder) ByteArrayInputStream(java.io.ByteArrayInputStream) HttpVersion(io.vertx.core.http.HttpVersion) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Http2Exception(io.netty.handler.codec.http2.Http2Exception) Map(java.util.Map) ApplicationProtocolNegotiationHandler(io.netty.handler.ssl.ApplicationProtocolNegotiationHandler) ReadStream(io.vertx.core.streams.ReadStream) AbstractHttp2ConnectionHandlerBuilder(io.netty.handler.codec.http2.AbstractHttp2ConnectionHandlerBuilder) Http2FrameAdapter(io.netty.handler.codec.http2.Http2FrameAdapter) StreamResetException(io.vertx.core.http.StreamResetException) ChannelDuplexHandler(io.netty.channel.ChannelDuplexHandler) ChannelInitializer(io.netty.channel.ChannelInitializer) Http2Flags(io.netty.handler.codec.http2.Http2Flags) Set(java.util.Set) ChannelPipeline(io.netty.channel.ChannelPipeline) Http2ConnectionHandler(io.netty.handler.codec.http2.Http2ConnectionHandler) Future(io.vertx.core.Future) InetSocketAddress(java.net.InetSocketAddress) Collectors(java.util.stream.Collectors) NioEventLoopGroup(io.netty.channel.nio.NioEventLoopGroup) StandardCharsets(java.nio.charset.StandardCharsets) Base64(java.util.Base64) List(java.util.List) Buffer(io.vertx.core.buffer.Buffer) SslHandler(io.netty.handler.ssl.SslHandler) Http2Headers(io.netty.handler.codec.http2.Http2Headers) HttpServerResponse(io.vertx.core.http.HttpServerResponse) Http2Error(io.netty.handler.codec.http2.Http2Error) HttpClient(io.vertx.core.http.HttpClient) NetSocket(io.vertx.core.net.NetSocket) Trust(io.vertx.test.core.tls.Trust) NioSocketChannel(io.netty.channel.socket.nio.NioSocketChannel) HttpServerRequest(io.vertx.core.http.HttpServerRequest) ByteArrayOutputStream(java.io.ByteArrayOutputStream) Http2EventAdapter(io.netty.handler.codec.http2.Http2EventAdapter) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) HttpClientRequest(io.vertx.core.http.HttpClientRequest) ByteBuf(io.netty.buffer.ByteBuf) WriteStream(io.vertx.core.streams.WriteStream) Http2Stream(io.netty.handler.codec.http2.Http2Stream) BiConsumer(java.util.function.BiConsumer) AsyncResult(io.vertx.core.AsyncResult) HttpClientOptions(io.vertx.core.http.HttpClientOptions) HttpConnection(io.vertx.core.http.HttpConnection) EventLoopGroup(io.netty.channel.EventLoopGroup) VertxInternal(io.vertx.core.impl.VertxInternal) ClosedChannelException(java.nio.channels.ClosedChannelException) Vertx(io.vertx.core.Vertx) FileOutputStream(java.io.FileOutputStream) ApplicationProtocolNames(io.netty.handler.ssl.ApplicationProtocolNames) Test(org.junit.Test) IOException(java.io.IOException) SSLHelper(io.vertx.core.net.impl.SSLHelper) File(java.io.File) ChannelFuture(io.netty.channel.ChannelFuture) Channel(io.netty.channel.Channel) Http2Settings(io.netty.handler.codec.http2.Http2Settings) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) Bootstrap(io.netty.bootstrap.Bootstrap) AtomicLong(java.util.concurrent.atomic.AtomicLong) Http2Connection(io.netty.handler.codec.http2.Http2Connection) HttpMethod(io.vertx.core.http.HttpMethod) HttpUtils(io.vertx.core.http.impl.HttpUtils) HttpServerOptions(io.vertx.core.http.HttpServerOptions) HttpHeaderNames(io.netty.handler.codec.http.HttpHeaderNames) Handler(io.vertx.core.Handler) Collections(java.util.Collections) TestUtils.assertIllegalStateException(io.vertx.test.core.TestUtils.assertIllegalStateException) DefaultHttp2Headers(io.netty.handler.codec.http2.DefaultHttp2Headers) Http2Exception(io.netty.handler.codec.http2.Http2Exception) Http2FrameAdapter(io.netty.handler.codec.http2.Http2FrameAdapter) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AtomicLong(java.util.concurrent.atomic.AtomicLong) Http2Settings(io.netty.handler.codec.http2.Http2Settings) Test(org.junit.Test)

Example 4 with Http2Settings

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

the class Http2ConnectionRoundtripTest method encodeViolatesMaxHeaderListSizeCanStillUseConnection.

@Test
public void encodeViolatesMaxHeaderListSizeCanStillUseConnection() throws Exception {
    bootstrapEnv(1, 2, 1, 0, 0);
    final CountDownLatch serverSettingsAckLatch1 = new CountDownLatch(2);
    final CountDownLatch serverSettingsAckLatch2 = new CountDownLatch(3);
    final CountDownLatch clientSettingsLatch1 = new CountDownLatch(3);
    final CountDownLatch serverRevHeadersLatch = new CountDownLatch(1);
    final CountDownLatch clientHeadersLatch = new CountDownLatch(1);
    final CountDownLatch clientDataWrite = new CountDownLatch(1);
    final AtomicReference<Throwable> clientHeadersWriteException = new AtomicReference<Throwable>();
    final AtomicReference<Throwable> clientHeadersWriteException2 = new AtomicReference<Throwable>();
    final AtomicReference<Throwable> clientDataWriteException = new AtomicReference<Throwable>();
    final Http2Headers headers = dummyHeaders();
    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<Void>() {

        @Override
        public Void answer(InvocationOnMock invocationOnMock) throws Throwable {
            clientSettingsLatch1.countDown();
            return null;
        }
    }).when(clientListener).onSettingsRead(any(ChannelHandlerContext.class), any(Http2Settings.class));
    // Manually add a listener for when we receive the expected headers on the server.
    doAnswer(new Answer<Void>() {

        @Override
        public Void answer(InvocationOnMock invocationOnMock) throws Throwable {
            serverRevHeadersLatch.countDown();
            return null;
        }
    }).when(serverListener).onHeadersRead(any(ChannelHandlerContext.class), eq(5), eq(headers), anyInt(), anyShort(), anyBoolean(), eq(0), eq(true));
    // Set the maxHeaderListSize to 100 so we may be able to write some headers, but not all. We want to verify
    // that we don't corrupt state if some can be written but not all.
    runInChannel(serverConnectedChannel, new Http2Runnable() {

        @Override
        public void run() throws Http2Exception {
            http2Server.encoder().writeSettings(serverCtx(), new Http2Settings().copyFrom(http2Server.decoder().localSettings()).maxHeaderListSize(100), serverNewPromise());
            http2Server.flush(serverCtx());
        }
    });
    assertTrue(serverSettingsAckLatch1.await(DEFAULT_AWAIT_TIMEOUT_SECONDS, SECONDS));
    runInChannel(clientChannel, new Http2Runnable() {

        @Override
        public void run() throws Http2Exception {
            http2Client.encoder().writeHeaders(ctx(), 3, headers, 0, false, newPromise()).addListener(new ChannelFutureListener() {

                @Override
                public void operationComplete(ChannelFuture future) throws Exception {
                    clientHeadersWriteException.set(future.cause());
                }
            });
            // It is expected that this write should fail locally and the remote peer will never see this.
            http2Client.encoder().writeData(ctx(), 3, Unpooled.buffer(), 0, true, newPromise()).addListener(new ChannelFutureListener() {

                @Override
                public void operationComplete(ChannelFuture future) throws Exception {
                    clientDataWriteException.set(future.cause());
                    clientDataWrite.countDown();
                }
            });
            http2Client.flush(ctx());
        }
    });
    assertTrue(clientDataWrite.await(DEFAULT_AWAIT_TIMEOUT_SECONDS, SECONDS));
    assertNotNull("Header encode should have exceeded maxHeaderListSize!", clientHeadersWriteException.get());
    assertNotNull("Data on closed stream should fail!", clientDataWriteException.get());
    // Set the maxHeaderListSize to the max value so we can send the headers.
    runInChannel(serverConnectedChannel, new Http2Runnable() {

        @Override
        public void run() throws Http2Exception {
            http2Server.encoder().writeSettings(serverCtx(), new Http2Settings().copyFrom(http2Server.decoder().localSettings()).maxHeaderListSize(Http2CodecUtil.MAX_HEADER_LIST_SIZE), serverNewPromise());
            http2Server.flush(serverCtx());
        }
    });
    assertTrue(clientSettingsLatch1.await(DEFAULT_AWAIT_TIMEOUT_SECONDS, SECONDS));
    assertTrue(serverSettingsAckLatch2.await(DEFAULT_AWAIT_TIMEOUT_SECONDS, SECONDS));
    runInChannel(clientChannel, new Http2Runnable() {

        @Override
        public void run() throws Http2Exception {
            http2Client.encoder().writeHeaders(ctx(), 5, headers, 0, true, newPromise()).addListener(new ChannelFutureListener() {

                @Override
                public void operationComplete(ChannelFuture future) throws Exception {
                    clientHeadersWriteException2.set(future.cause());
                    clientHeadersLatch.countDown();
                }
            });
            http2Client.flush(ctx());
        }
    });
    assertTrue(clientHeadersLatch.await(DEFAULT_AWAIT_TIMEOUT_SECONDS, SECONDS));
    assertNull("Client write of headers should succeed with increased header list size!", clientHeadersWriteException2.get());
    assertTrue(serverRevHeadersLatch.await(DEFAULT_AWAIT_TIMEOUT_SECONDS, SECONDS));
    verify(serverListener, never()).onDataRead(any(ChannelHandlerContext.class), anyInt(), any(ByteBuf.class), anyInt(), anyBoolean());
    // 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 : ChannelFuture(io.netty.channel.ChannelFuture) Http2Runnable(io.netty.handler.codec.http2.Http2TestUtil.Http2Runnable) AtomicReference(java.util.concurrent.atomic.AtomicReference) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) CountDownLatch(java.util.concurrent.CountDownLatch) ByteBuf(io.netty.buffer.ByteBuf) ChannelFutureListener(io.netty.channel.ChannelFutureListener) InvocationOnMock(org.mockito.invocation.InvocationOnMock) Test(org.junit.Test)

Example 5 with Http2Settings

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

the class InboundHttp2ToHttpAdapterTest method propagateSettings.

@Test
public void propagateSettings() throws Exception {
    boostrapEnv(1, 1, 2);
    final Http2Settings settings = new Http2Settings().pushEnabled(true);
    runInChannel(clientChannel, new Http2Runnable() {

        @Override
        public void run() {
            clientHandler.encoder().writeSettings(ctxClient(), settings, newPromiseClient());
            clientChannel.flush();
        }
    });
    assertTrue(settingsLatch.await(5, SECONDS));
    ArgumentCaptor<Http2Settings> settingsCaptor = ArgumentCaptor.forClass(Http2Settings.class);
    verify(settingsListener, times(2)).messageReceived(settingsCaptor.capture());
    assertEquals(settings, settingsCaptor.getValue());
}
Also used : Http2Runnable(io.netty.handler.codec.http2.Http2TestUtil.Http2Runnable) 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