From f9037152e5326b1b94b7e70e4d22c3bf0039eeb6 Mon Sep 17 00:00:00 2001 From: Julien Viet Date: Sat, 5 Mar 2016 22:20:04 +0100 Subject: [PATCH] Allow to setup http2settings in client options --- src/main/asciidoc/dataobjects.adoc | 1 + .../core/http/HttpClientOptionsConverter.java | 6 +++ .../io/vertx/core/http/HttpClientOptions.java | 11 +++++ .../io/vertx/core/http/impl/Http2Pool.java | 22 ++++++++- .../io/vertx/test/core/Http2ClientTest.java | 49 ++++++++++++++++++- .../io/vertx/test/core/Http2ServerTest.java | 17 ------- .../io/vertx/test/core/Http2TestBase.java | 18 +++++++ 7 files changed, 104 insertions(+), 20 deletions(-) diff --git a/src/main/asciidoc/dataobjects.adoc b/src/main/asciidoc/dataobjects.adoc index 74517cfd3e4..27d02ea3f4d 100644 --- a/src/main/asciidoc/dataobjects.adoc +++ b/src/main/asciidoc/dataobjects.adoc @@ -1279,6 +1279,7 @@ Set the default port to be used by this client in requests if none is provided w +++ Add an enabled cipher suite +++ +|[[http2Settings]]`http2Settings`|`link:dataobjects.html#Http2Settings[Http2Settings]`|- |[[idleTimeout]]`idleTimeout`|`Number (int)`| +++ Set the idle timeout, in seconds. zero means don't timeout. diff --git a/src/main/generated/io/vertx/core/http/HttpClientOptionsConverter.java b/src/main/generated/io/vertx/core/http/HttpClientOptionsConverter.java index 872ea3ccc09..5dfc133befb 100644 --- a/src/main/generated/io/vertx/core/http/HttpClientOptionsConverter.java +++ b/src/main/generated/io/vertx/core/http/HttpClientOptionsConverter.java @@ -36,6 +36,9 @@ public static void fromJson(JsonObject json, HttpClientOptions obj) { if (json.getValue("defaultPort") instanceof Number) { obj.setDefaultPort(((Number)json.getValue("defaultPort")).intValue()); } + if (json.getValue("http2Settings") instanceof JsonObject) { + obj.setHttp2Settings(new io.vertx.core.http.Http2Settings((JsonObject)json.getValue("http2Settings"))); + } if (json.getValue("keepAlive") instanceof Boolean) { obj.setKeepAlive((Boolean)json.getValue("keepAlive")); } @@ -73,6 +76,9 @@ public static void toJson(HttpClientOptions obj, JsonObject json) { json.put("defaultHost", obj.getDefaultHost()); } json.put("defaultPort", obj.getDefaultPort()); + if (obj.getHttp2Settings() != null) { + json.put("http2Settings", obj.getHttp2Settings().toJson()); + } json.put("keepAlive", obj.isKeepAlive()); json.put("maxChunkSize", obj.getMaxChunkSize()); json.put("maxPoolSize", obj.getMaxPoolSize()); diff --git a/src/main/java/io/vertx/core/http/HttpClientOptions.java b/src/main/java/io/vertx/core/http/HttpClientOptions.java index 331b663d20c..9a0b91fb49c 100644 --- a/src/main/java/io/vertx/core/http/HttpClientOptions.java +++ b/src/main/java/io/vertx/core/http/HttpClientOptions.java @@ -111,6 +111,7 @@ public class HttpClientOptions extends ClientOptionsBase { private int maxChunkSize; private int maxWaitQueueSize; private HttpVersion alpnFallbackProtocolVersion; + private Http2Settings http2Settings; /** * Default constructor @@ -139,6 +140,7 @@ public HttpClientOptions(HttpClientOptions other) { this.maxChunkSize = other.maxChunkSize; this.maxWaitQueueSize = other.maxWaitQueueSize; this.alpnFallbackProtocolVersion = other.alpnFallbackProtocolVersion; + this.http2Settings = other.http2Settings != null ? new Http2Settings(other.http2Settings) : null; } /** @@ -522,6 +524,15 @@ public HttpClientOptions setAlpnFallbackProtocolVersion(HttpVersion alpnFallback return this; } + public Http2Settings getHttp2Settings() { + return http2Settings; + } + + public HttpClientOptions setHttp2Settings(Http2Settings http2Settings) { + this.http2Settings = http2Settings; + return this; + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/src/main/java/io/vertx/core/http/impl/Http2Pool.java b/src/main/java/io/vertx/core/http/impl/Http2Pool.java index bac246c65cf..91ba3b88bab 100644 --- a/src/main/java/io/vertx/core/http/impl/Http2Pool.java +++ b/src/main/java/io/vertx/core/http/impl/Http2Pool.java @@ -409,7 +409,27 @@ protected VertxClientHandler build(Http2ConnectionDecoder decoder, Http2Connecti public VertxClientHandler build(Http2Connection conn) { connection(conn); - initialSettings(new Http2Settings()); + io.vertx.core.http.Http2Settings initialSettings = client.getOptions().getHttp2Settings(); + if (initialSettings != null) { + if (initialSettings.getHeaderTableSize() != null) { + initialSettings().headerTableSize(initialSettings.getHeaderTableSize()); + } + if (initialSettings.getInitialWindowSize() != null) { + initialSettings().initialWindowSize(initialSettings.getInitialWindowSize()); + } + if (initialSettings.getMaxConcurrentStreams() != null) { + initialSettings().maxConcurrentStreams(initialSettings.getMaxConcurrentStreams()); + } + if (initialSettings.getMaxFrameSize() != null) { + initialSettings().maxFrameSize(initialSettings.getMaxFrameSize()); + } + if (initialSettings.getMaxHeaderListSize() != null) { + initialSettings().maxHeaderListSize(initialSettings.getMaxHeaderListSize()); + } + if (initialSettings.getEnablePush() != null) { + initialSettings().pushEnabled(initialSettings.getEnablePush()); + } + } frameListener(new Http2EventAdapter() { @Override public int onDataRead(ChannelHandlerContext ctx, int streamId, ByteBuf data, int padding, boolean endOfStream) throws Http2Exception { diff --git a/src/test/java/io/vertx/test/core/Http2ClientTest.java b/src/test/java/io/vertx/test/core/Http2ClientTest.java index 7da5b6d1d0b..d0a1a7c3e89 100644 --- a/src/test/java/io/vertx/test/core/Http2ClientTest.java +++ b/src/test/java/io/vertx/test/core/Http2ClientTest.java @@ -23,6 +23,7 @@ import io.netty.handler.codec.http2.Http2Error; import io.netty.handler.codec.http2.Http2Exception; import io.netty.handler.codec.http2.Http2FrameAdapter; +import io.netty.handler.codec.http2.Http2Settings; import io.vertx.core.Context; import io.vertx.core.Future; import io.vertx.core.Handler; @@ -50,13 +51,57 @@ */ public class Http2ClientTest extends Http2TestBase { + HttpClientOptions clientOptions; + @Override public void setUp() throws Exception { super.setUp(); - client = vertx.createHttpClient(new HttpClientOptions(). + clientOptions = new HttpClientOptions(). setUseAlpn(true). setTrustStoreOptions((JksOptions) getClientTrustOptions(Trust.JKS)). - setProtocolVersion(HttpVersion.HTTP_2)); + setProtocolVersion(HttpVersion.HTTP_2); + client = vertx.createHttpClient(clientOptions); + } + + @Test + public void testClientSettings() throws Exception { + Http2Settings initialSettings = randomSettings(); +// Http2Settings updatedSettings = randomSettings(); +// Future settingsRead = Future.future(); + server.requestHandler(req -> { + io.vertx.core.http.Http2Settings settings = req.connection().clientSettings(); + assertEquals(initialSettings.maxHeaderListSize(), settings.getMaxHeaderListSize()); + assertEquals(initialSettings.maxFrameSize(), settings.getMaxFrameSize()); + assertEquals(initialSettings.initialWindowSize(), settings.getInitialWindowSize()); + assertEquals(initialSettings.maxConcurrentStreams(), settings.getMaxConcurrentStreams()); + assertEquals((long) initialSettings.headerTableSize(), (long) settings.getHeaderTableSize()); +/* + req.connection().clientSettingsHandler(update -> { + assertOnIOContext(ctx); + assertEquals(updatedSettings.maxHeaderListSize(), update.getMaxHeaderListSize()); + assertEquals(updatedSettings.maxFrameSize(), update.getMaxFrameSize()); + assertEquals(updatedSettings.initialWindowSize(), update.getInitialWindowSize()); + assertEquals(updatedSettings.maxConcurrentStreams(), update.getMaxConcurrentStreams()); + assertEquals((long) updatedSettings.headerTableSize(), (long) update.getHeaderTableSize()); + testComplete(); + }); + settingsRead.complete(); +*/ + testComplete(); + }); + startServer(); + client.close(); + client = vertx.createHttpClient(clientOptions.setHttp2Settings(new io.vertx.core.http.Http2Settings(). + setEnablePush(initialSettings.pushEnabled()). + setHeaderTableSize((int)(long)initialSettings.headerTableSize()). + setInitialWindowSize(initialSettings.initialWindowSize()). + setMaxConcurrentStreams(initialSettings.maxConcurrentStreams()). + setMaxFrameSize(initialSettings.maxFrameSize()). + setMaxHeaderListSize(initialSettings.maxHeaderListSize()))); + client.getNow(4043, "localhost", "/somepath", resp -> { + + }); + await(); } @Test diff --git a/src/test/java/io/vertx/test/core/Http2ServerTest.java b/src/test/java/io/vertx/test/core/Http2ServerTest.java index ed32d0e2af7..934a40c87c8 100644 --- a/src/test/java/io/vertx/test/core/Http2ServerTest.java +++ b/src/test/java/io/vertx/test/core/Http2ServerTest.java @@ -316,23 +316,6 @@ public void testClientSettings() throws Exception { await(); } - private Http2Settings randomSettings() { - int headerTableSize = 10 + TestUtils.randomPositiveInt() % (Http2CodecUtil.MAX_HEADER_TABLE_SIZE - 10); - boolean enablePush = TestUtils.randomBoolean(); - long maxConcurrentStreams = TestUtils.randomPositiveLong() % (Http2CodecUtil.MAX_CONCURRENT_STREAMS - 10); - int initialWindowSize = 10 + TestUtils.randomPositiveInt() % (Http2CodecUtil.MAX_INITIAL_WINDOW_SIZE - 10); - int maxFrameSize = Http2CodecUtil.MAX_FRAME_SIZE_LOWER_BOUND + TestUtils.randomPositiveInt() % (Http2CodecUtil.MAX_FRAME_SIZE_UPPER_BOUND - Http2CodecUtil.MAX_FRAME_SIZE_LOWER_BOUND); - int maxHeaderListSize = 10 + TestUtils.randomPositiveInt() % (int) (Http2CodecUtil.MAX_HEADER_LIST_SIZE - 10); - Http2Settings settings = new Http2Settings(); - settings.headerTableSize(headerTableSize); - settings.pushEnabled(enablePush); - settings.maxConcurrentStreams(maxConcurrentStreams); - settings.initialWindowSize(initialWindowSize); - settings.maxFrameSize(maxFrameSize); - settings.maxHeaderListSize(maxHeaderListSize); - return settings; - } - @Test public void testGet() throws Exception { String expected = TestUtils.randomAlphaString(1000); diff --git a/src/test/java/io/vertx/test/core/Http2TestBase.java b/src/test/java/io/vertx/test/core/Http2TestBase.java index a51d2f69df7..10842f56f8a 100644 --- a/src/test/java/io/vertx/test/core/Http2TestBase.java +++ b/src/test/java/io/vertx/test/core/Http2TestBase.java @@ -16,6 +16,8 @@ package io.vertx.test.core; +import io.netty.handler.codec.http2.Http2CodecUtil; +import io.netty.handler.codec.http2.Http2Settings; import io.vertx.core.Context; import io.vertx.core.Vertx; import io.vertx.core.http.HttpServerOptions; @@ -81,4 +83,20 @@ protected SSLContext createSSLContext() throws Exception { return context; } + protected Http2Settings randomSettings() { + int headerTableSize = 10 + TestUtils.randomPositiveInt() % (Http2CodecUtil.MAX_HEADER_TABLE_SIZE - 10); + boolean enablePush = TestUtils.randomBoolean(); + long maxConcurrentStreams = TestUtils.randomPositiveLong() % (Http2CodecUtil.MAX_CONCURRENT_STREAMS - 10); + int initialWindowSize = 10 + TestUtils.randomPositiveInt() % (Http2CodecUtil.MAX_INITIAL_WINDOW_SIZE - 10); + int maxFrameSize = Http2CodecUtil.MAX_FRAME_SIZE_LOWER_BOUND + TestUtils.randomPositiveInt() % (Http2CodecUtil.MAX_FRAME_SIZE_UPPER_BOUND - Http2CodecUtil.MAX_FRAME_SIZE_LOWER_BOUND); + int maxHeaderListSize = 10 + TestUtils.randomPositiveInt() % (int) (Http2CodecUtil.MAX_HEADER_LIST_SIZE - 10); + Http2Settings settings = new Http2Settings(); + settings.headerTableSize(headerTableSize); + settings.pushEnabled(enablePush); + settings.maxConcurrentStreams(maxConcurrentStreams); + settings.initialWindowSize(initialWindowSize); + settings.maxFrameSize(maxFrameSize); + settings.maxHeaderListSize(maxHeaderListSize); + return settings; + } }