Add http3 module: HTTP/3 in the Java HTTP Client (JEP 517), opt-in, discovery modes, fallback timings, proxy downgrade and a packet-loss comparison
Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01KqJyCidz3ZgRyHABv2GVJh
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
$ java src/Basics.java https://localhost:4433/hello (OpenJDK Runtime Environment Temurin-25.0.4.1+1 (build 25.0.4.1+1-LTS))
|
||||
request 1: HTTP_2 200 alt-svc=h3=":4433"; ma=3600
|
||||
request 2: HTTP_2 200 alt-svc=h3=":4433"; ma=3600
|
||||
request 3: HTTP_2 200 alt-svc=h3=":4433"; ma=3600
|
||||
|
||||
$ java src/Basics.java https://localhost:4433/hello (OpenJDK Runtime Environment Temurin-26.0.2.1+1 (build 26.0.2.1+1))
|
||||
request 1: HTTP_2 200 alt-svc=h3=":4433"; ma=3600
|
||||
request 2: HTTP_2 200 alt-svc=h3=":4433"; ma=3600
|
||||
request 3: HTTP_2 200 alt-svc=h3=":4433"; ma=3600
|
||||
|
||||
# the alt-svc value above is the server advertising h3 on UDP 4433; nobody asked the client to use it.
|
||||
@@ -0,0 +1,29 @@
|
||||
$ java src/OptIn.java https://localhost:4433/hello client (OpenJDK Runtime Environment Temurin-26.0.2.1+1 (build 26.0.2.1+1))
|
||||
client-level HTTP_3, request 1: HTTP_2
|
||||
client-level HTTP_3, request 2: HTTP_3
|
||||
client-level HTTP_3, request 3: HTTP_3
|
||||
client-level HTTP_3, request 4: HTTP_3
|
||||
|
||||
$ java src/OptIn.java https://localhost:4433/hello request (OpenJDK Runtime Environment Temurin-26.0.2.1+1 (build 26.0.2.1+1))
|
||||
request-level HTTP_3, request 1: HTTP_3
|
||||
request-level HTTP_3, request 2: HTTP_3
|
||||
request-level HTTP_3, request 3: HTTP_3
|
||||
request-level HTTP_3, request 4: HTTP_3
|
||||
|
||||
$ java src/OptIn.java https://localhost:4433/hello client (OpenJDK Runtime Environment Temurin-25.0.4.1+1 (build 25.0.4.1+1-LTS))
|
||||
src/OptIn.java:12: error: cannot find symbol
|
||||
if (where.equals("client")) builder.version(HttpClient.Version.HTTP_3);
|
||||
^
|
||||
symbol: variable HTTP_3
|
||||
location: class Version
|
||||
src/OptIn.java:15: error: cannot find symbol
|
||||
|
||||
$ first request of a fresh client-level HTTP_3 client, 8 fresh JVMs (OpenJDK Runtime Environment Temurin-26.0.2.1+1 (build 26.0.2.1+1))
|
||||
client-level HTTP_3, request 1: HTTP_2
|
||||
client-level HTTP_3, request 1: HTTP_2
|
||||
client-level HTTP_3, request 1: HTTP_2
|
||||
client-level HTTP_3, request 1: HTTP_2
|
||||
client-level HTTP_3, request 1: HTTP_2
|
||||
client-level HTTP_3, request 1: HTTP_2
|
||||
client-level HTTP_3, request 1: HTTP_2
|
||||
client-level HTTP_3, request 1: HTTP_2
|
||||
@@ -0,0 +1,4 @@
|
||||
$ java src/Discovery.java https://localhost:4433/hello (server: h1.1 + h2 on TCP, h3 on UDP, Alt-Svc advertised)
|
||||
ANY -> HTTP_2 HTTP_3 HTTP_3 HTTP_3
|
||||
ALT_SVC -> HTTP_2 HTTP_3 HTTP_3 HTTP_3
|
||||
HTTP_3_URI_ONLY -> HTTP_3 HTTP_3 HTTP_3 HTTP_3
|
||||
@@ -0,0 +1,19 @@
|
||||
$ java src/Fallback.java https://localhost:4433/hello 120 (server: h2 + h1.1 on TCP only; nothing listens on UDP 4433)
|
||||
request HTTP_3 (ANY) -> HTTP_2 after 3340 ms
|
||||
client HTTP_3 (ANY) -> HTTP_2 after 31 ms
|
||||
request HTTP_3_URI_ONLY -> java.net.ConnectException: No response from peer for 30 seconds after 60016 ms
|
||||
|
||||
$ java -Djdk.httpclient.http3.maxDirectConnectionTimeout=1 src/Fallback.java https://localhost:4433/hello 120 (same server)
|
||||
request HTTP_3 (ANY) -> HTTP_2 after 501 ms
|
||||
client HTTP_3 (ANY) -> HTTP_2 after 45 ms
|
||||
request HTTP_3_URI_ONLY -> java.net.ConnectException: No response from peer for 30 seconds after 60016 ms
|
||||
|
||||
$ java -Djdk.httpclient.quic.maxInitialTimeout=3 src/Fallback.java https://localhost:4433/hello 120 (same server)
|
||||
request HTTP_3 (ANY) -> HTTP_2 after 3338 ms
|
||||
client HTTP_3 (ANY) -> HTTP_2 after 39 ms
|
||||
request HTTP_3_URI_ONLY -> java.net.ConnectException: No response from peer for 3 seconds after 6011 ms
|
||||
|
||||
$ java src/Discovery.java https://localhost:4433/hello (server: HTTP/1.1 only, TCP)
|
||||
ANY -> HTTP_1_1 HTTP_1_1 HTTP_1_1 HTTP_1_1
|
||||
ALT_SVC -> HTTP_1_1 HTTP_1_1 HTTP_1_1 HTTP_1_1
|
||||
HTTP_3_URI_ONLY -> ConnectException(No response from peer for 30 seconds) ConnectException(No response from peer for 30 seconds) ConnectException(No response from peer for 30 seconds) ConnectException(No response from peer for 30 seconds)
|
||||
@@ -0,0 +1,5 @@
|
||||
$ iptables: DROP 100% of UDP to/from port 4433 (TCP untouched); server is the h3 server
|
||||
$ java src/Fallback.java https://localhost:4433/hello 120
|
||||
request HTTP_3 (ANY) -> HTTP_2 after 3397 ms
|
||||
client HTTP_3 (ANY) -> HTTP_2 after 46 ms
|
||||
request HTTP_3_URI_ONLY -> java.net.ConnectException: No response from peer for 30 seconds after 60014 ms
|
||||
@@ -0,0 +1,6 @@
|
||||
$ java src/ViaProxy.java https://localhost:4433/hello 4480 (client.proxy(...) points at a CONNECT proxy on 4480)
|
||||
ANY via proxy -> HTTP_2
|
||||
HTTP_3_URI_ONLY via proxy -> java.net.http.UnsupportedProtocolVersionException: can't use HTTP/3 with proxied or unsecured connection
|
||||
|
||||
$ proxy log
|
||||
proxy saw: CONNECT localhost:4433
|
||||
@@ -0,0 +1,38 @@
|
||||
# loss = per-packet drop probability, applied in EACH direction, TCP and UDP port 4433, by iptables -m statistic on lo (MTU 1500).
|
||||
# no added latency (loopback RTT is microseconds). 20 trials per row after one discarded warm-up; OpenJDK Runtime Environment Temurin-26.0.2.1+1 (build 26.0.2.1+1)
|
||||
# one = fresh client, 1 download of 1 MiB. many = fresh client, 10 parallel downloads of 100 KiB.
|
||||
h1 one loss=0 ok=20 failed=0 median=59 p90=68 max=84 (ms)
|
||||
h2 one loss=0 ok=20 failed=0 median=61 p90=90 max=97 (ms)
|
||||
h3 one loss=0 ok=20 failed=0 median=129 p90=197 max=246 (ms)
|
||||
h1 many loss=0 ok=20 failed=0 median=97 p90=114 max=143 (ms)
|
||||
h2 many loss=0 ok=20 failed=0 median=118 p90=152 max=159 (ms)
|
||||
h3 many loss=0 ok=20 failed=0 median=135 p90=167 max=214 (ms)
|
||||
|
||||
h1 one loss=1 ok=20 failed=0 median=61 p90=74 max=1278 (ms)
|
||||
h2 one loss=1 ok=20 failed=0 median=57 p90=66 max=79 (ms)
|
||||
h3 one loss=1 ok=20 failed=0 median=202 p90=273 max=1207 (ms)
|
||||
h1 many loss=1 ok=20 failed=0 median=111 p90=1044 max=1054 (ms)
|
||||
h2 many loss=1 ok=20 failed=0 median=160 p90=1039 max=1057 (ms)
|
||||
h3 many loss=1 ok=20 failed=0 median=176 p90=232 max=454 (ms)
|
||||
|
||||
h1 one loss=2 ok=20 failed=0 median=87 p90=281 max=2082 (ms)
|
||||
h2 one loss=2 ok=20 failed=0 median=57 p90=294 max=1082 (ms)
|
||||
h3 one loss=2 ok=20 failed=0 median=216 p90=316 max=390 (ms)
|
||||
h1 many loss=2 ok=20 failed=0 median=249 p90=1058 max=2818 (ms)
|
||||
h2 many loss=2 ok=20 failed=0 median=282 p90=1056 max=1073 (ms)
|
||||
h3 many loss=2 ok=20 failed=0 median=238 p90=296 max=305 (ms)
|
||||
|
||||
h1 one loss=5 ok=20 failed=0 median=100 p90=1070 max=1689 (ms)
|
||||
h2 one loss=5 ok=20 failed=0 median=248 p90=1084 max=3057 (ms)
|
||||
h3 one loss=5 ok=20 failed=0 median=302 p90=500 max=1508 (ms)
|
||||
h1 many loss=5 ok=20 failed=0 median=1055 p90=2833 max=3496 (ms)
|
||||
h2 many loss=5 ok=20 failed=0 median=1047 p90=1257 max=1305 (ms)
|
||||
h3 many loss=5 ok=20 failed=0 median=322 p90=577 max=1330 (ms)
|
||||
|
||||
h1 one loss=10 ok=20 failed=0 median=322 p90=1578 max=3475 (ms)
|
||||
h2 one loss=10 ok=20 failed=0 median=678 p90=2177 max=2742 (ms)
|
||||
h3 one loss=10 ok=20 failed=0 median=968 p90=1169 max=1292 (ms)
|
||||
h1 many loss=10 ok=20 failed=0 median=1509 p90=3370 max=6458 (ms)
|
||||
h2 many loss=10 ok=20 failed=0 median=1478 p90=3370 max=13812 (ms)
|
||||
h3 many loss=10 ok=20 failed=0 median=885 p90=1088 max=1250 (ms)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
# what the Hypercorn/aioquic server wrote to stderr during 07 (the loss run), exception lines only, counted
|
||||
Reference in New Issue
Block a user