diff --git a/vertx-core/pom.xml b/vertx-core/pom.xml
index 856e90afc92..9306df4455c 100644
--- a/vertx-core/pom.xml
+++ b/vertx-core/pom.xml
@@ -98,6 +98,11 @@
netty-transport-classes-kqueue
true
+
+ io.netty.incubator
+ netty-incubator-codec-http3
+ 0.0.28.Final
+
diff --git a/vertx-core/src/main/generated/io/vertx/core/http/Http3SettingsConverter.java b/vertx-core/src/main/generated/io/vertx/core/http/Http3SettingsConverter.java
new file mode 100644
index 00000000000..33751dab151
--- /dev/null
+++ b/vertx-core/src/main/generated/io/vertx/core/http/Http3SettingsConverter.java
@@ -0,0 +1,63 @@
+package io.vertx.core.http;
+
+import io.vertx.core.json.JsonObject;
+import io.vertx.core.json.JsonArray;
+import java.time.Instant;
+import java.time.format.DateTimeFormatter;
+
+/**
+ * Converter and mapper for {@link io.vertx.core.http.Http3Settings}.
+ * NOTE: This class has been automatically generated from the {@link io.vertx.core.http.Http3Settings} original class using Vert.x codegen.
+ */
+public class Http3SettingsConverter {
+
+ static void fromJson(Iterable> json, Http3Settings obj) {
+ for (java.util.Map.Entry member : json) {
+ switch (member.getKey()) {
+ case "qpackMaxTableCapacity":
+ if (member.getValue() instanceof Number) {
+ obj.setQpackMaxTableCapacity(((Number)member.getValue()).longValue());
+ }
+ break;
+ case "maxFieldSectionSize":
+ if (member.getValue() instanceof Number) {
+ obj.setMaxFieldSectionSize(((Number)member.getValue()).longValue());
+ }
+ break;
+ case "qpackMaxBlockedStreams":
+ if (member.getValue() instanceof Number) {
+ obj.setQpackMaxBlockedStreams(((Number)member.getValue()).longValue());
+ }
+ break;
+ case "enableConnectProtocol":
+ if (member.getValue() instanceof Number) {
+ obj.setEnableConnectProtocol(((Number)member.getValue()).longValue());
+ }
+ break;
+ case "h3Datagram":
+ if (member.getValue() instanceof Number) {
+ obj.setH3Datagram(((Number)member.getValue()).longValue());
+ }
+ break;
+ case "enableMetadata":
+ if (member.getValue() instanceof Number) {
+ obj.setEnableMetadata(((Number)member.getValue()).longValue());
+ }
+ break;
+ }
+ }
+ }
+
+ static void toJson(Http3Settings obj, JsonObject json) {
+ toJson(obj, json.getMap());
+ }
+
+ static void toJson(Http3Settings obj, java.util.Map json) {
+ json.put("qpackMaxTableCapacity", obj.getQpackMaxTableCapacity());
+ json.put("maxFieldSectionSize", obj.getMaxFieldSectionSize());
+ json.put("qpackMaxBlockedStreams", obj.getQpackMaxBlockedStreams());
+ json.put("enableConnectProtocol", obj.getEnableConnectProtocol());
+ json.put("h3Datagram", obj.getH3Datagram());
+ json.put("enableMetadata", obj.getEnableMetadata());
+ }
+}
diff --git a/vertx-core/src/main/generated/io/vertx/core/http/HttpClientOptionsConverter.java b/vertx-core/src/main/generated/io/vertx/core/http/HttpClientOptionsConverter.java
index 87eeef5dd92..c521f22a08f 100644
--- a/vertx-core/src/main/generated/io/vertx/core/http/HttpClientOptionsConverter.java
+++ b/vertx-core/src/main/generated/io/vertx/core/http/HttpClientOptionsConverter.java
@@ -69,11 +69,6 @@ static void fromJson(Iterable> json, HttpCli
obj.setDefaultPort(((Number)member.getValue()).intValue());
}
break;
- case "protocolVersion":
- if (member.getValue() instanceof String) {
- obj.setProtocolVersion(io.vertx.core.http.HttpVersion.valueOf((String)member.getValue()));
- }
- break;
case "maxChunkSize":
if (member.getValue() instanceof Number) {
obj.setMaxChunkSize(((Number)member.getValue()).intValue());
@@ -94,6 +89,11 @@ static void fromJson(Iterable> json, HttpCli
obj.setInitialSettings(new io.vertx.core.http.Http2Settings((io.vertx.core.json.JsonObject)member.getValue()));
}
break;
+ case "initialHttp3Settings":
+ if (member.getValue() instanceof JsonObject) {
+ obj.setInitialHttp3Settings(new io.vertx.core.http.Http3Settings((io.vertx.core.json.JsonObject)member.getValue()));
+ }
+ break;
case "alpnVersions":
if (member.getValue() instanceof JsonArray) {
java.util.ArrayList list = new java.util.ArrayList<>();
@@ -144,6 +144,11 @@ static void fromJson(Iterable> json, HttpCli
obj.setName((String)member.getValue());
}
break;
+ case "http3MultiplexingLimit":
+ if (member.getValue() instanceof Number) {
+ obj.setHttp3MultiplexingLimit(((Number)member.getValue()).intValue());
+ }
+ break;
}
}
}
@@ -166,15 +171,15 @@ static void toJson(HttpClientOptions obj, java.util.Map json) {
json.put("defaultHost", obj.getDefaultHost());
}
json.put("defaultPort", obj.getDefaultPort());
- if (obj.getProtocolVersion() != null) {
- json.put("protocolVersion", obj.getProtocolVersion().name());
- }
json.put("maxChunkSize", obj.getMaxChunkSize());
json.put("maxInitialLineLength", obj.getMaxInitialLineLength());
json.put("maxHeaderSize", obj.getMaxHeaderSize());
if (obj.getInitialSettings() != null) {
json.put("initialSettings", obj.getInitialSettings().toJson());
}
+ if (obj.getInitialHttp3Settings() != null) {
+ json.put("initialHttp3Settings", obj.getInitialHttp3Settings().toJson());
+ }
if (obj.getAlpnVersions() != null) {
JsonArray array = new JsonArray();
obj.getAlpnVersions().forEach(item -> array.add(item.name()));
@@ -192,5 +197,6 @@ static void toJson(HttpClientOptions obj, java.util.Map json) {
if (obj.getName() != null) {
json.put("name", obj.getName());
}
+ json.put("http3MultiplexingLimit", obj.getHttp3MultiplexingLimit());
}
}
diff --git a/vertx-core/src/main/generated/io/vertx/core/http/HttpServerOptionsConverter.java b/vertx-core/src/main/generated/io/vertx/core/http/HttpServerOptionsConverter.java
index 6cd748f33bc..574016b922e 100644
--- a/vertx-core/src/main/generated/io/vertx/core/http/HttpServerOptionsConverter.java
+++ b/vertx-core/src/main/generated/io/vertx/core/http/HttpServerOptionsConverter.java
@@ -94,6 +94,11 @@ static void fromJson(Iterable> json, HttpSer
obj.setInitialSettings(new io.vertx.core.http.Http2Settings((io.vertx.core.json.JsonObject)member.getValue()));
}
break;
+ case "initialHttp3Settings":
+ if (member.getValue() instanceof JsonObject) {
+ obj.setInitialHttp3Settings(new io.vertx.core.http.Http3Settings((io.vertx.core.json.JsonObject)member.getValue()));
+ }
+ break;
case "alpnVersions":
if (member.getValue() instanceof JsonArray) {
java.util.ArrayList list = new java.util.ArrayList<>();
@@ -209,6 +214,9 @@ static void toJson(HttpServerOptions obj, java.util.Map json) {
if (obj.getInitialSettings() != null) {
json.put("initialSettings", obj.getInitialSettings().toJson());
}
+ if (obj.getInitialHttp3Settings() != null) {
+ json.put("initialHttp3Settings", obj.getInitialHttp3Settings().toJson());
+ }
if (obj.getAlpnVersions() != null) {
JsonArray array = new JsonArray();
obj.getAlpnVersions().forEach(item -> array.add(item.name()));
diff --git a/vertx-core/src/main/generated/io/vertx/core/http/HttpSettingsConverter.java b/vertx-core/src/main/generated/io/vertx/core/http/HttpSettingsConverter.java
new file mode 100644
index 00000000000..1709990d29e
--- /dev/null
+++ b/vertx-core/src/main/generated/io/vertx/core/http/HttpSettingsConverter.java
@@ -0,0 +1,27 @@
+package io.vertx.core.http;
+
+import io.vertx.core.json.JsonObject;
+import io.vertx.core.json.JsonArray;
+import java.time.Instant;
+import java.time.format.DateTimeFormatter;
+
+/**
+ * Converter and mapper for {@link io.vertx.core.http.HttpSettings}.
+ * NOTE: This class has been automatically generated from the {@link io.vertx.core.http.HttpSettings} original class using Vert.x codegen.
+ */
+public class HttpSettingsConverter {
+
+ static void fromJson(Iterable> json, HttpSettings obj) {
+ for (java.util.Map.Entry member : json) {
+ switch (member.getKey()) {
+ }
+ }
+ }
+
+ static void toJson(HttpSettings obj, JsonObject json) {
+ toJson(obj, json.getMap());
+ }
+
+ static void toJson(HttpSettings obj, java.util.Map json) {
+ }
+}
diff --git a/vertx-core/src/main/generated/io/vertx/core/http/StreamPriorityBaseConverter.java b/vertx-core/src/main/generated/io/vertx/core/http/StreamPriorityBaseConverter.java
new file mode 100644
index 00000000000..925cb9be161
--- /dev/null
+++ b/vertx-core/src/main/generated/io/vertx/core/http/StreamPriorityBaseConverter.java
@@ -0,0 +1,48 @@
+package io.vertx.core.http;
+
+import io.vertx.core.json.JsonObject;
+import io.vertx.core.json.JsonArray;
+import java.time.Instant;
+import java.time.format.DateTimeFormatter;
+
+/**
+ * Converter and mapper for {@link io.vertx.core.http.StreamPriorityBase}.
+ * NOTE: This class has been automatically generated from the {@link io.vertx.core.http.StreamPriorityBase} original class using Vert.x codegen.
+ */
+public class StreamPriorityBaseConverter {
+
+ static void fromJson(Iterable> json, StreamPriorityBase obj) {
+ for (java.util.Map.Entry member : json) {
+ switch (member.getKey()) {
+ case "weight":
+ if (member.getValue() instanceof Number) {
+ obj.setWeight(((Number)member.getValue()).shortValue());
+ }
+ break;
+ case "dependency":
+ if (member.getValue() instanceof Number) {
+ obj.setDependency(((Number)member.getValue()).intValue());
+ }
+ break;
+ case "exclusive":
+ if (member.getValue() instanceof Boolean) {
+ obj.setExclusive((Boolean)member.getValue());
+ }
+ break;
+ case "incremental":
+ break;
+ }
+ }
+ }
+
+ static void toJson(StreamPriorityBase obj, JsonObject json) {
+ toJson(obj, json.getMap());
+ }
+
+ static void toJson(StreamPriorityBase obj, java.util.Map json) {
+ json.put("weight", obj.getWeight());
+ json.put("dependency", obj.getDependency());
+ json.put("exclusive", obj.isExclusive());
+ json.put("incremental", obj.isIncremental());
+ }
+}
diff --git a/vertx-core/src/main/generated/io/vertx/core/net/ClientOptionsBaseConverter.java b/vertx-core/src/main/generated/io/vertx/core/net/ClientOptionsBaseConverter.java
index 7e60cb6312f..d4bc5fef035 100644
--- a/vertx-core/src/main/generated/io/vertx/core/net/ClientOptionsBaseConverter.java
+++ b/vertx-core/src/main/generated/io/vertx/core/net/ClientOptionsBaseConverter.java
@@ -19,6 +19,11 @@ static void fromJson(Iterable> json, ClientO
obj.setTrustAll((Boolean)member.getValue());
}
break;
+ case "protocolVersion":
+ if (member.getValue() instanceof String) {
+ obj.setProtocolVersion(io.vertx.core.http.HttpVersion.valueOf((String)member.getValue()));
+ }
+ break;
case "connectTimeout":
if (member.getValue() instanceof Number) {
obj.setConnectTimeout(((Number)member.getValue()).intValue());
@@ -59,6 +64,9 @@ static void toJson(ClientOptionsBase obj, JsonObject json) {
static void toJson(ClientOptionsBase obj, java.util.Map json) {
json.put("trustAll", obj.isTrustAll());
+ if (obj.getProtocolVersion() != null) {
+ json.put("protocolVersion", obj.getProtocolVersion().name());
+ }
json.put("connectTimeout", obj.getConnectTimeout());
if (obj.getMetricsName() != null) {
json.put("metricsName", obj.getMetricsName());
diff --git a/vertx-core/src/main/generated/io/vertx/core/net/ProxyOptionsConverter.java b/vertx-core/src/main/generated/io/vertx/core/net/ProxyOptionsConverter.java
index df1db5de65d..0c1c435cc16 100644
--- a/vertx-core/src/main/generated/io/vertx/core/net/ProxyOptionsConverter.java
+++ b/vertx-core/src/main/generated/io/vertx/core/net/ProxyOptionsConverter.java
@@ -39,6 +39,16 @@ static void fromJson(Iterable> json, ProxyOp
obj.setType(io.vertx.core.net.ProxyType.valueOf((String)member.getValue()));
}
break;
+ case "connectTimeout":
+ if (member.getValue() instanceof Number) {
+ obj.setConnectTimeout(((Number)member.getValue()).longValue());
+ }
+ break;
+ case "connectTimeoutUnit":
+ if (member.getValue() instanceof String) {
+ obj.setConnectTimeoutUnit(java.util.concurrent.TimeUnit.valueOf((String)member.getValue()));
+ }
+ break;
}
}
}
@@ -61,5 +71,9 @@ static void toJson(ProxyOptions obj, java.util.Map json) {
if (obj.getType() != null) {
json.put("type", obj.getType().name());
}
+ json.put("connectTimeout", obj.getConnectTimeout());
+ if (obj.getConnectTimeoutUnit() != null) {
+ json.put("connectTimeoutUnit", obj.getConnectTimeoutUnit().name());
+ }
}
}
diff --git a/vertx-core/src/main/generated/io/vertx/core/net/SSLOptionsConverter.java b/vertx-core/src/main/generated/io/vertx/core/net/SSLOptionsConverter.java
index e171533dc5a..7e19bf8c64e 100644
--- a/vertx-core/src/main/generated/io/vertx/core/net/SSLOptionsConverter.java
+++ b/vertx-core/src/main/generated/io/vertx/core/net/SSLOptionsConverter.java
@@ -43,6 +43,41 @@ static void fromJson(Iterable> json, SSLOpti
obj.setUseAlpn((Boolean)member.getValue());
}
break;
+ case "http3":
+ if (member.getValue() instanceof Boolean) {
+ obj.setHttp3((Boolean)member.getValue());
+ }
+ break;
+ case "http3InitialMaxStreamsBidirectional":
+ if (member.getValue() instanceof Number) {
+ obj.setHttp3InitialMaxStreamsBidirectional(((Number)member.getValue()).longValue());
+ }
+ break;
+ case "http3InitialMaxData":
+ if (member.getValue() instanceof Number) {
+ obj.setHttp3InitialMaxData(((Number)member.getValue()).longValue());
+ }
+ break;
+ case "http3InitialMaxStreamDataBidirectionalLocal":
+ if (member.getValue() instanceof Number) {
+ obj.setHttp3InitialMaxStreamDataBidirectionalLocal(((Number)member.getValue()).longValue());
+ }
+ break;
+ case "http3InitialMaxStreamDataBidirectionalRemote":
+ if (member.getValue() instanceof Number) {
+ obj.setHttp3InitialMaxStreamDataBidirectionalRemote(((Number)member.getValue()).longValue());
+ }
+ break;
+ case "http3InitialMaxStreamDataUnidirectional":
+ if (member.getValue() instanceof Number) {
+ obj.setHttp3InitialMaxStreamDataUnidirectional(((Number)member.getValue()).longValue());
+ }
+ break;
+ case "http3InitialMaxStreamsUnidirectional":
+ if (member.getValue() instanceof Number) {
+ obj.setHttp3InitialMaxStreamsUnidirectional(((Number)member.getValue()).longValue());
+ }
+ break;
case "enabledSecureTransportProtocols":
if (member.getValue() instanceof JsonArray) {
java.util.LinkedHashSet list = new java.util.LinkedHashSet<>();
@@ -98,6 +133,13 @@ static void toJson(SSLOptions obj, java.util.Map json) {
json.put("crlValues", array);
}
json.put("useAlpn", obj.isUseAlpn());
+ json.put("http3", obj.isHttp3());
+ json.put("http3InitialMaxStreamsBidirectional", obj.getHttp3InitialMaxStreamsBidirectional());
+ json.put("http3InitialMaxData", obj.getHttp3InitialMaxData());
+ json.put("http3InitialMaxStreamDataBidirectionalLocal", obj.getHttp3InitialMaxStreamDataBidirectionalLocal());
+ json.put("http3InitialMaxStreamDataBidirectionalRemote", obj.getHttp3InitialMaxStreamDataBidirectionalRemote());
+ json.put("http3InitialMaxStreamDataUnidirectional", obj.getHttp3InitialMaxStreamDataUnidirectional());
+ json.put("http3InitialMaxStreamsUnidirectional", obj.getHttp3InitialMaxStreamsUnidirectional());
if (obj.getEnabledSecureTransportProtocols() != null) {
JsonArray array = new JsonArray();
obj.getEnabledSecureTransportProtocols().forEach(item -> array.add(item));
diff --git a/vertx-core/src/main/generated/io/vertx/core/net/TCPSSLOptionsConverter.java b/vertx-core/src/main/generated/io/vertx/core/net/TCPSSLOptionsConverter.java
index 220b7886f37..b3a932cff6d 100644
--- a/vertx-core/src/main/generated/io/vertx/core/net/TCPSSLOptionsConverter.java
+++ b/vertx-core/src/main/generated/io/vertx/core/net/TCPSSLOptionsConverter.java
@@ -83,6 +83,11 @@ static void fromJson(Iterable> json, TCPSSLO
obj.setUseAlpn((Boolean)member.getValue());
}
break;
+ case "http3":
+ if (member.getValue() instanceof Boolean) {
+ obj.setHttp3((Boolean)member.getValue());
+ }
+ break;
case "enabledSecureTransportProtocols":
if (member.getValue() instanceof JsonArray) {
java.util.LinkedHashSet list = new java.util.LinkedHashSet<>();
@@ -158,6 +163,7 @@ static void toJson(TCPSSLOptions obj, java.util.Map json) {
json.put("crlValues", array);
}
json.put("useAlpn", obj.isUseAlpn());
+ json.put("http3", obj.isHttp3());
if (obj.getEnabledSecureTransportProtocols() != null) {
JsonArray array = new JsonArray();
obj.getEnabledSecureTransportProtocols().forEach(item -> array.add(item));
diff --git a/vertx-core/src/main/java/examples/HTTP2Examples.java b/vertx-core/src/main/java/examples/HTTP2Examples.java
index 34527cd1226..0657fbbc5f4 100644
--- a/vertx-core/src/main/java/examples/HTTP2Examples.java
+++ b/vertx-core/src/main/java/examples/HTTP2Examples.java
@@ -220,17 +220,17 @@ public void example19(Vertx vertx, HttpClientOptions options) {
}
public void example20(HttpConnection connection) {
- connection.updateSettings(new Http2Settings().setMaxConcurrentStreams(100));
+ connection.updateHttpSettings(new Http2Settings().setMaxConcurrentStreams(100));
}
public void example21(HttpConnection connection) {
connection
- .updateSettings(new Http2Settings().setMaxConcurrentStreams(100))
+ .updateHttpSettings(new Http2Settings().setMaxConcurrentStreams(100))
.onSuccess(v -> System.out.println("The settings update has been acknowledged "));
}
public void example22(HttpConnection connection) {
- connection.remoteSettingsHandler(settings -> {
+ connection.remoteHttpSettingsHandler(settings -> {
System.out.println("Received new settings");
});
}
diff --git a/vertx-core/src/main/java/examples/h3devexamples/HTTP2ClientExamplesVertxHandler.java b/vertx-core/src/main/java/examples/h3devexamples/HTTP2ClientExamplesVertxHandler.java
new file mode 100644
index 00000000000..7cd4c3574b3
--- /dev/null
+++ b/vertx-core/src/main/java/examples/h3devexamples/HTTP2ClientExamplesVertxHandler.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2011-2019 Contributors to the Eclipse Foundation
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+ * which is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+ */
+
+package examples.h3devexamples;
+
+import io.netty.buffer.ByteBuf;
+import io.vertx.core.Vertx;
+import io.vertx.core.VertxOptions;
+import io.vertx.core.buffer.Buffer;
+import io.vertx.core.internal.net.NetSocketInternal;
+import io.vertx.core.net.JdkSSLEngineOptions;
+import io.vertx.core.net.NetClient;
+import io.vertx.core.net.NetClientOptions;
+import io.vertx.core.net.SocketAddress;
+
+/**
+ * @author Iman Zolfaghari
+ */
+public class HTTP2ClientExamplesVertxHandler {
+ protected NetClientOptions createNetClientOptions() {
+ NetClientOptions options = new NetClientOptions();
+ options
+ .setSslEngineOptions(new JdkSSLEngineOptions())
+ .setUseAlpn(true)
+ .setSsl(true)
+ .setTrustAll(true)
+// .setHostnameVerificationAlgorithm("HTTPS")
+ .setHostnameVerificationAlgorithm("")
+// .setTrustOptions(Trust.SERVER_JKS.get())
+ ;
+
+ return options;
+ }
+
+ public void example02Local(Vertx vertx) {
+ String path = "/";
+ int port = 8090;
+ String host = "localhost";
+
+/*
+ AtomicInteger requests = new AtomicInteger();
+
+ int n = 5;
+
+ for (int i = 0; i < n; i++) {
+ int counter = i + 1;
+ client.request(HttpMethod.GET, port, host, path)
+ .compose(req -> req.send("Msg " + counter))
+ .compose(HttpClientResponse::body)
+ .onSuccess(body -> System.out.println(
+ "Msg" + counter + " response body is: " + body))
+ .onComplete(event -> requests.incrementAndGet())
+ .onFailure(Throwable::printStackTrace)
+ ;
+ }
+*/
+
+ NetClient client = vertx.createNetClient(createNetClientOptions().setConnectTimeout(1000));
+
+ client.connect(SocketAddress.inetSocketAddress(8090, "localhost")).onSuccess(so -> {
+ NetSocketInternal soi = (NetSocketInternal) so;
+ StringBuilder part1 = new StringBuilder();
+ part1.append("1".repeat(1200));
+ part1.append("2".repeat(1200));
+ part1.append("3".repeat(1200));
+ part1.append("4".repeat(1200));
+
+ StringBuilder part2 = new StringBuilder();
+ part2.append("3".repeat(1200));
+ part2.append("4".repeat(1200));
+
+ soi.write(Buffer.buffer(part1.toString()));
+// soi.write(Buffer.buffer(part2.toString()));
+ // soi.messageHandler(msg -> fail("Unexpected"));
+ soi.messageHandler(msg -> {
+ ByteBuf byteBuf = (ByteBuf) msg;
+
+ byte[]arr = new byte[byteBuf.readableBytes()];
+ byteBuf.copy().readBytes(arr);
+ System.out.println("received ByteBuf is: " + new String(arr));
+
+
+ if(!byteBuf.isDirect()) throw new RuntimeException();
+ if(1 != byteBuf.refCnt()) throw new RuntimeException();
+// if(!"Hello World".equals(byteBuf.toString(StandardCharsets.UTF_8))) throw new RuntimeException();
+ if(!byteBuf.release()) throw new RuntimeException();
+ if(0 != byteBuf.refCnt()) throw new RuntimeException();
+ System.out.println("OK");
+ });
+ }).onFailure(Throwable::printStackTrace);
+
+
+
+
+
+
+ int n = 10000;
+ int i = 0;
+ while (i != n) {
+ i++;
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ vertx.close();
+
+ }
+
+ public static void main(String[] args) {
+ Vertx vertx =
+ Vertx.vertx(new VertxOptions().setBlockedThreadCheckInterval(1_000_000_000));
+ new HTTP2ClientExamplesVertxHandler().example02Local(vertx);
+ }
+}
diff --git a/vertx-core/src/main/java/examples/h3devexamples/HTTP2ServerExamplesVertxHandler.java b/vertx-core/src/main/java/examples/h3devexamples/HTTP2ServerExamplesVertxHandler.java
new file mode 100644
index 00000000000..983289e1644
--- /dev/null
+++ b/vertx-core/src/main/java/examples/h3devexamples/HTTP2ServerExamplesVertxHandler.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2011-2019 Contributors to the Eclipse Foundation
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+ * which is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+ */
+
+package examples.h3devexamples;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.handler.ssl.util.SelfSignedCertificate;
+import io.netty.incubator.codec.http3.Http3;
+import io.vertx.core.Vertx;
+import io.vertx.core.VertxOptions;
+import io.vertx.core.http.HttpServerOptions;
+import io.vertx.core.http.HttpVersion;
+import io.vertx.core.internal.net.NetSocketInternal;
+import io.vertx.core.net.JdkSSLEngineOptions;
+import io.vertx.core.net.NetServer;
+import io.vertx.core.net.NetServerOptions;
+import io.vertx.core.net.PemKeyCertOptions;
+
+import java.nio.charset.StandardCharsets;
+import java.security.cert.CertificateException;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author Iman Zolfaghari
+ */
+public class HTTP2ServerExamplesVertxHandler {
+
+ protected NetServerOptions createNetServerOptions() {
+ NetServerOptions options = new NetServerOptions();
+ options.setPort(8090);
+
+ options.setUseAlpn(true).setSsl(true);
+
+ SelfSignedCertificate ssc = null;
+ try {
+ ssc = new SelfSignedCertificate();
+ } catch (CertificateException e) {
+ throw new RuntimeException(e);
+ }
+ options.setKeyCertOptions(new PemKeyCertOptions()
+ .setCertPath(ssc.certificate().getAbsolutePath())
+ .setKeyPath(ssc.privateKey().getAbsolutePath())
+ );
+
+
+ return options;
+ }
+
+ public void example02Server(Vertx vertx) throws Exception {
+ NetServer server = vertx.createNetServer(createNetServerOptions());
+
+
+ server.connectHandler(so -> {
+ NetSocketInternal soi = (NetSocketInternal) so;
+ soi.messageHandler(msg -> {
+ ByteBuf byteBuf = (ByteBuf) msg;
+ byte[]arr = new byte[byteBuf.readableBytes()];
+ byteBuf.readBytes(arr);
+ System.out.println("new String(arr) = " + new String(arr));
+ if (!byteBuf.isDirect()) throw new RuntimeException();
+ if (1 != byteBuf.refCnt()) throw new RuntimeException();
+ ByteBuf buffer = Unpooled.buffer();
+ buffer.writeCharSequence("OK", StandardCharsets.UTF_8);
+ soi.writeMessage(buffer).onSuccess(v -> {
+// if (0 != byteBuf.refCnt()) throw new RuntimeException();
+ System.out.println("OK");
+ });
+ });
+ });
+ server.exceptionHandler(Throwable::printStackTrace);
+
+ server.listen();
+ }
+
+ public static void main(String[] args) throws Exception {
+ VertxOptions options = new VertxOptions()
+ .setBlockedThreadCheckInterval(1_000_000_000);
+
+ Vertx vertx = Vertx.vertx(options);
+ new HTTP2ServerExamplesVertxHandler().example02Server(vertx);
+ }
+}
diff --git a/vertx-core/src/main/java/examples/h3devexamples/HTTP3ClientExamples.java b/vertx-core/src/main/java/examples/h3devexamples/HTTP3ClientExamples.java
new file mode 100644
index 00000000000..55184d59836
--- /dev/null
+++ b/vertx-core/src/main/java/examples/h3devexamples/HTTP3ClientExamples.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2011-2019 Contributors to the Eclipse Foundation
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+ * which is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+ */
+
+package examples.h3devexamples;
+
+import io.vertx.core.Vertx;
+import io.vertx.core.VertxOptions;
+import io.vertx.core.http.HttpClient;
+import io.vertx.core.http.HttpClientOptions;
+import io.vertx.core.http.HttpClientResponse;
+import io.vertx.core.http.HttpMethod;
+import io.vertx.core.http.HttpVersion;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * @author Iman Zolfaghari
+ */
+public class HTTP3ClientExamples {
+ public void example02Local(Vertx vertx) {
+
+ HttpClientOptions options = new HttpClientOptions().
+ setSsl(true).
+ setIdleTimeout(1).
+ setReadIdleTimeout(1).
+ setWriteIdleTimeout(1).
+ setIdleTimeoutUnit(TimeUnit.HOURS).
+ setUseAlpn(true).
+ setForceSni(true).
+ setVerifyHost(false).
+ setTrustAll(true).
+ setProtocolVersion(HttpVersion.HTTP_3);
+
+ options
+ .getSslOptions()
+ .setSslHandshakeTimeout(1)
+ .setSslHandshakeTimeoutUnit(TimeUnit.HOURS);
+ HttpClient client = vertx.createHttpClient(options);
+
+ String path = "/";
+ int port = 8090;
+ String host = "localhost";
+
+ AtomicInteger requests = new AtomicInteger();
+
+ int n = 5;
+
+ for (int i = 0; i < n; i++) {
+ int counter = i + 1;
+ client.request(HttpMethod.GET, port, host, path)
+ .compose(req -> req.send("Msg " + counter))
+ .compose(HttpClientResponse::body)
+ .onSuccess(body -> System.out.println(
+ "Msg" + counter + " response body is: " + body))
+ .onComplete(event -> requests.incrementAndGet())
+ .onFailure(Throwable::printStackTrace)
+ ;
+ }
+
+ while (requests.get() != n) {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ vertx.close();
+
+ }
+
+ public static void main(String[] args) {
+ Vertx vertx =
+ Vertx.vertx(new VertxOptions().setBlockedThreadCheckInterval(1_000_000_000));
+ new HTTP3ClientExamples().example02Local(vertx);
+ }
+}
diff --git a/vertx-core/src/main/java/examples/h3devexamples/HTTP3ClientExamplesAsyncTestCase.java b/vertx-core/src/main/java/examples/h3devexamples/HTTP3ClientExamplesAsyncTestCase.java
new file mode 100644
index 00000000000..3ee09a39761
--- /dev/null
+++ b/vertx-core/src/main/java/examples/h3devexamples/HTTP3ClientExamplesAsyncTestCase.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2011-2019 Contributors to the Eclipse Foundation
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+ * which is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+ */
+
+package examples.h3devexamples;
+
+import io.vertx.core.Vertx;
+import io.vertx.core.VertxOptions;
+import io.vertx.core.http.HttpClient;
+import io.vertx.core.http.HttpClientOptions;
+import io.vertx.core.http.HttpMethod;
+import io.vertx.core.http.HttpVersion;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * @author Iman Zolfaghari
+ */
+public class HTTP3ClientExamplesAsyncTestCase {
+ public void example03Local(Vertx vertx) {
+
+ HttpClientOptions options = new HttpClientOptions().
+ setSsl(true).
+ setIdleTimeout(1).
+ setReadIdleTimeout(1).
+ setWriteIdleTimeout(1).
+ setIdleTimeoutUnit(TimeUnit.HOURS).
+ setUseAlpn(true).
+ setForceSni(true).
+ setVerifyHost(false).
+ setTrustAll(true).
+ setProtocolVersion(HttpVersion.HTTP_3);
+
+ options
+ .getSslOptions()
+ .setSslHandshakeTimeout(1)
+ .setSslHandshakeTimeoutUnit(TimeUnit.HOURS);
+ HttpClient client = vertx.createHttpClient(options);
+
+ String path = "/";
+ int port = 8090;
+ String host = "localhost";
+
+ AtomicInteger requests = new AtomicInteger();
+
+ int n = 1;
+
+ client.request(HttpMethod.GET, port, host, path)
+ .compose(req -> {
+ System.out.println("sending request ...");
+ return req.send();
+ })
+ .compose(resp -> {
+ System.out.println("receiving resp ...");
+ assert 200 == resp.statusCode();
+ return resp.end();
+ }
+ )
+ .onSuccess(event -> {
+ System.out.println("testComplete() called! ");
+ })
+ .onComplete(event -> requests.incrementAndGet())
+ .onFailure(Throwable::printStackTrace)
+ ;
+
+ while (requests.get() != n) {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ vertx.close();
+
+ }
+
+ public static void main(String[] args) {
+ Vertx vertx =
+ Vertx.vertx(new VertxOptions().setBlockedThreadCheckInterval(1_000_000_000));
+ new HTTP3ClientExamplesAsyncTestCase().example03Local(vertx);
+ }
+}
diff --git a/vertx-core/src/main/java/examples/h3devexamples/HTTP3ClientExamplesSni.java b/vertx-core/src/main/java/examples/h3devexamples/HTTP3ClientExamplesSni.java
new file mode 100644
index 00000000000..b7086852c37
--- /dev/null
+++ b/vertx-core/src/main/java/examples/h3devexamples/HTTP3ClientExamplesSni.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2011-2019 Contributors to the Eclipse Foundation
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+ * which is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+ */
+
+package examples.h3devexamples;
+
+import io.vertx.core.Vertx;
+import io.vertx.core.VertxOptions;
+import io.vertx.core.http.HttpClient;
+import io.vertx.core.http.HttpClientOptions;
+import io.vertx.core.http.HttpClientResponse;
+import io.vertx.core.http.HttpMethod;
+import io.vertx.core.http.HttpVersion;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * @author Iman Zolfaghari
+ */
+public class HTTP3ClientExamplesSni {
+ public void example02Local(Vertx vertx) {
+
+ HttpClientOptions options = new HttpClientOptions().
+ setSsl(true).
+ setIdleTimeout(1).
+ setReadIdleTimeout(1).
+ setWriteIdleTimeout(1).
+ setIdleTimeoutUnit(TimeUnit.HOURS).
+ setUseAlpn(true).
+ setForceSni(true).
+ setVerifyHost(false).
+ setTrustAll(true).
+ setProtocolVersion(HttpVersion.HTTP_3);
+
+ options
+ .getSslOptions()
+ .setSslHandshakeTimeout(1)
+ .setSslHandshakeTimeoutUnit(TimeUnit.HOURS);
+ HttpClient client = vertx.createHttpClient(options);
+
+ String path = "/";
+ int port = 8090;
+ String host = "localhost";
+
+ AtomicInteger requests = new AtomicInteger();
+
+ int n = 1;
+
+ for (int i = 0; i < n; i++) {
+ int counter = i + 1;
+ client.request(HttpMethod.GET, port, host, path)
+ .compose(req -> req.send("Msg " + counter))
+ .compose(HttpClientResponse::body)
+ .onSuccess(body -> System.out.println(
+ "Msg" + counter + " response body is: " + body))
+ .onComplete(event -> requests.incrementAndGet())
+ .onFailure(Throwable::printStackTrace)
+ ;
+ }
+
+ while (requests.get() != n) {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ vertx.close();
+
+ }
+
+ public static void main(String[] args) {
+ Vertx vertx =
+ Vertx.vertx(new VertxOptions().setBlockedThreadCheckInterval(1_000_000_000));
+ new HTTP3ClientExamplesSni().example02Local(vertx);
+ }
+}
diff --git a/vertx-core/src/main/java/examples/h3devexamples/HTTP3ClientExamplesVertxHandler.java b/vertx-core/src/main/java/examples/h3devexamples/HTTP3ClientExamplesVertxHandler.java
new file mode 100644
index 00000000000..f80c3e55337
--- /dev/null
+++ b/vertx-core/src/main/java/examples/h3devexamples/HTTP3ClientExamplesVertxHandler.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2011-2019 Contributors to the Eclipse Foundation
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+ * which is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+ */
+
+package examples.h3devexamples;
+
+import io.netty.buffer.ByteBuf;
+import io.vertx.core.Vertx;
+import io.vertx.core.VertxOptions;
+import io.vertx.core.buffer.Buffer;
+import io.vertx.core.http.HttpVersion;
+import io.vertx.core.internal.net.NetSocketInternal;
+import io.vertx.core.net.JdkSSLEngineOptions;
+import io.vertx.core.net.NetClient;
+import io.vertx.core.net.NetClientOptions;
+import io.vertx.core.net.SocketAddress;
+import io.vertx.core.net.impl.Http3Utils;
+
+/**
+ * @author Iman Zolfaghari
+ */
+public class HTTP3ClientExamplesVertxHandler {
+ protected NetClientOptions createNetClientOptions() {
+ NetClientOptions options = new NetClientOptions();
+ options
+ .setHttp3(true)
+ .getSslOptions()
+ .setApplicationLayerProtocols(Http3Utils.supportedApplicationProtocols());
+ options
+ .setSslEngineOptions(new JdkSSLEngineOptions())
+ .setUseAlpn(true)
+ .setSsl(true)
+ .setTrustAll(true)
+// .setHostnameVerificationAlgorithm("HTTPS")
+ .setHostnameVerificationAlgorithm("")
+// .setTrustOptions(Trust.SERVER_JKS.get())
+ .setProtocolVersion(HttpVersion.HTTP_3);
+
+
+ return options;
+ }
+
+ public void example02Local(Vertx vertx) {
+
+/*
+ HttpClientOptions options = new HttpClientOptions().
+ setSsl(true).
+ setIdleTimeout(1).
+ setReadIdleTimeout(1).
+ setWriteIdleTimeout(1).
+ setIdleTimeoutUnit(TimeUnit.HOURS).
+ setUseAlpn(true).
+ setForceSni(true).
+ setVerifyHost(false).
+ setTrustAll(true).
+ setProtocolVersion(HttpVersion.HTTP_3);
+
+ options
+ .getSslOptions()
+ .setSslHandshakeTimeout(1)
+ .setSslHandshakeTimeoutUnit(TimeUnit.HOURS);
+ HttpClient client = vertx.createHttpClient(options);
+*/
+
+ String path = "/";
+ int port = 8090;
+ String host = "localhost";
+
+/*
+ AtomicInteger requests = new AtomicInteger();
+
+ int n = 5;
+
+ for (int i = 0; i < n; i++) {
+ int counter = i + 1;
+ client.request(HttpMethod.GET, port, host, path)
+ .compose(req -> req.send("Msg " + counter))
+ .compose(HttpClientResponse::body)
+ .onSuccess(body -> System.out.println(
+ "Msg" + counter + " response body is: " + body))
+ .onComplete(event -> requests.incrementAndGet())
+ .onFailure(Throwable::printStackTrace)
+ ;
+ }
+*/
+
+ NetClient client = vertx.createNetClient(createNetClientOptions().setConnectTimeout(1000));
+
+
+ client.connect(SocketAddress.inetSocketAddress(8090, "localhost")).onSuccess(so -> {
+ NetSocketInternal soi = (NetSocketInternal) so;
+ StringBuilder part1 = new StringBuilder();
+ part1.append("1".repeat(1200));
+ part1.append("2".repeat(1200));
+ part1.append("3".repeat(1200));
+ part1.append("4".repeat(1200));
+
+ StringBuilder part2 = new StringBuilder();
+ part2.append("3".repeat(1200));
+ part2.append("4".repeat(1200));
+
+ soi.write(Buffer.buffer(part1.toString()));
+// soi.write(Buffer.buffer(part2.toString()));
+ // soi.messageHandler(msg -> fail("Unexpected"));
+ soi.messageHandler(msg -> {
+ ByteBuf byteBuf = (ByteBuf) msg;
+
+ byte[]arr = new byte[byteBuf.readableBytes()];
+ byteBuf.copy().readBytes(arr);
+ System.out.println("received ByteBuf is: " + new String(arr));
+
+
+ if(!byteBuf.isDirect()) throw new RuntimeException();
+ if(1 != byteBuf.refCnt()) throw new RuntimeException();
+// if(!"Hello World".equals(byteBuf.toString(StandardCharsets.UTF_8))) throw new RuntimeException();
+ if(!byteBuf.release()) throw new RuntimeException();
+ if(0 != byteBuf.refCnt()) throw new RuntimeException();
+ System.out.println("OK");
+ });
+ }).onFailure(Throwable::printStackTrace);
+
+
+
+
+
+
+ int n = 10000;
+ int i = 0;
+ while (i != n) {
+ i++;
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ vertx.close();
+
+ }
+
+ public static void main(String[] args) {
+ Vertx vertx =
+ Vertx.vertx(new VertxOptions().setBlockedThreadCheckInterval(1_000_000_000));
+ new HTTP3ClientExamplesVertxHandler().example02Local(vertx);
+ }
+}
diff --git a/vertx-core/src/main/java/examples/h3devexamples/HTTP3ClientGoogleExamples.java b/vertx-core/src/main/java/examples/h3devexamples/HTTP3ClientGoogleExamples.java
new file mode 100644
index 00000000000..79787c99f9e
--- /dev/null
+++ b/vertx-core/src/main/java/examples/h3devexamples/HTTP3ClientGoogleExamples.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2011-2019 Contributors to the Eclipse Foundation
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+ * which is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+ */
+
+package examples.h3devexamples;
+
+import io.vertx.core.Vertx;
+import io.vertx.core.VertxOptions;
+import io.vertx.core.http.HttpClient;
+import io.vertx.core.http.HttpClientOptions;
+import io.vertx.core.http.HttpClientResponse;
+import io.vertx.core.http.HttpMethod;
+import io.vertx.core.http.HttpVersion;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * @author Iman Zolfaghari
+ */
+public class HTTP3ClientGoogleExamples {
+ private final static String okText =
+ "\n ____ _ __ \n" +
+ " / __ \\ | |/ / \n" +
+ "| | | || < \n" +
+ "| | | || |\\ \\ \n" +
+ "| |__| || | \\ \\ \n" +
+ " \\____/ |_| \\_\\ \n";
+
+ public void example01(Vertx vertx) {
+
+ String path = "/";
+// String path = "/cdn-cgi/trace";
+ int port = 443;
+// int port = 9999;
+// int port = 8090;
+// String host = "http3.is";
+ String host = "www.google.com";
+// String host = "localhost";
+// String host = "quic.nginx.org";
+// String host = "www.cloudflare.com";
+// String host = NetUtil.LOCALHOST4.getHostAddress();
+// String host = "www.mozilla.org";
+// String host = "www.bing.com";
+// String host = "www.yahoo.com";
+
+ HttpClientOptions options = new HttpClientOptions().
+ setSsl(true).
+ setIdleTimeout(1).
+ setReadIdleTimeout(1).
+ setWriteIdleTimeout(1).
+ setIdleTimeoutUnit(TimeUnit.HOURS).
+ setUseAlpn(true).
+ setForceSni(true).
+ setDefaultHost(host).
+ setVerifyHost(false).
+ setTrustAll(true).
+ setProtocolVersion(HttpVersion.HTTP_3);
+
+ options
+ .getSslOptions()
+ .setSslHandshakeTimeout(1)
+ .setSslHandshakeTimeoutUnit(TimeUnit.HOURS);
+
+
+ HttpClient client = vertx.createHttpClient(options);
+
+ System.out.print(String.format("Trying to fetch %s:%s%s\n", host, port,
+ path));
+
+ AtomicBoolean finished = new AtomicBoolean(false);
+
+ client.request(HttpMethod.GET, port, host, path)
+ .compose(req -> {
+
+ req.connection().goAwayHandler(goAway -> {
+ System.out.println(" Received goAway from server! ");
+ });
+
+ req.connection().shutdownHandler(v -> {
+ System.out.println(" Received shutdown signal! ");
+ req.connection().close();
+ vertx.close();
+ });
+
+// try {
+// System.out.println("req = " + req.connection().peerCertificates());
+// } catch (SSLPeerUnverifiedException e) {
+// throw new RuntimeException(e);
+// }
+
+ return req
+ .end()
+ .compose(res -> req
+ .response()
+ .onSuccess(resp -> {
+// System.out.println("The returned headers are: " + resp
+// .headers());
+ System.out.println("The returned Alt-Svc is: " + resp.headers().get(
+ "Alt-Svc"));
+ }).compose(HttpClientResponse::body).onSuccess(body -> {
+ if (host.contains("google.com") && body.toString().endsWith(
+ "google.log(\"rcm\"," +
+ "\"&ei=\"+c+\"&tgtved=\"+f+\"&jsname=\"+(a||\"\"))}}else " +
+ "F=a,E=[c]}window.document.addEventListener" +
+ "(\"DOMContentLoaded\"," +
+ "function(){document.body.addEventListener(\"click\",G)})" +
+ ";" +
+ "}).call(this);