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,42 @@
|
||||
# http3 — HTTP/3 in the Java HTTP Client (JEP 517, final in Java 26)
|
||||
|
||||
Companion code for the ankurm.com article **HTTP/3 in the Java HTTP Client (JEP 517): Migrating from HttpClient 11**. All explanation lives in the
|
||||
article; this folder holds the runnable sources, a local HTTP/3 test server, and the transcripts they produced.
|
||||
|
||||
## What was tested against
|
||||
|
||||
| Thing | Version | Note |
|
||||
|---|---|---|
|
||||
| JDK 26 | Temurin 26.0.2.1+1 | JEP 517 is delivered in 26 (GA 2026-03-17); this is the only JDK that can run HTTP/3 here |
|
||||
| JDK 25 | Temurin 25.0.4.1+1 | the "before": `HttpClient.Version.HTTP_3` does not exist, plain Java 11 code behaves the same as on 26 |
|
||||
| Test server | Hypercorn 0.18.0 (HTTP/1.1 + HTTP/2 on TCP) + aioquic 1.3.0 (HTTP/3 on UDP) | one Python process, same port number for both, `Alt-Svc` advertised. Hypercorn's own QUIC listener was dropped: it died on a `KeyError` under packet loss and the port went silent |
|
||||
| Loss injection | `iptables -m statistic --mode random` on `lo` | **not** `tc netem` (unavailable in the sandbox: `Specified qdisc kind is unknown`): loss only, no added delay |
|
||||
|
||||
The JDK 26 lane in the other modules of this repo uses Amazon Corretto 26.0.2.1; this module used Temurin because that is what the sandbox had. The API is the same.
|
||||
|
||||
## Quickstart
|
||||
|
||||
```bash
|
||||
pip install hypercorn==0.18.0 aioquic==1.3.0
|
||||
JDK25=/path/to/jdk-25 JDK26=/path/to/jdk-26 ./run.sh # about 45 minutes: the `HTTP_3_URI_ONLY` failure demos wait a full minute each and the loss table is 600 trials; needs root for 05 and 07; ONLY=07 regenerates just the loss table
|
||||
# or by hand:
|
||||
./server/make-cert.sh && python3 server/serve.py h3 4433 & # h3 | h2 | h1
|
||||
java src/OptIn.java https://localhost:4433/hello request
|
||||
```
|
||||
|
||||
## Layout
|
||||
|
||||
| Path | What is in it |
|
||||
|---|---|
|
||||
| `src/Tls.java` | trusts only the self-signed test certificate |
|
||||
| `src/Basics.java` | plain Java 11 `HttpClient` code, no version set |
|
||||
| `src/OptIn.java` | the JEP 517 opt-in, client-wide or per request |
|
||||
| `src/Discovery.java` | the three `H3_DISCOVERY` modes |
|
||||
| `src/Fallback.java` | first-request latency and version for each way of asking, against servers that cannot do HTTP/3 |
|
||||
| `src/ViaProxy.java` | HTTP/3 and a proxy |
|
||||
| `src/Bench.java` | HTTP/1.1 vs HTTP/2 vs HTTP/3 download times under packet loss |
|
||||
| `server/` | `app.py` (shared responses + ASGI wrapper), `serve.py` (h3 / h2 / h1 modes), `h3server.py` (aioquic HTTP/3), `connect-proxy.py`, `make-cert.sh` |
|
||||
| `scripts/loss.sh` | adds and removes the iptables loss rules and the MTU change |
|
||||
| `output/` | every transcript quoted in the article (`01`-`08`) |
|
||||
|
||||
Timings are machine dependent and the loss is random: treat `07-packet-loss.txt` as shape, not a benchmark of HTTP/3 implementations. The server is Python, the client is the JDK.
|
||||
Reference in New Issue
Block a user