Presenting 30 years of Internet through the lens of HTTP protocol versions
diff. HTTP/3 brings the most significant changes we've seen so far, so
let's review them alongside with reasoning and implications analysis.
Netty & Aleph • After upgrade, you get a Manifold stream • Deep HTTP Dive Through Aleph & Netty (require '[manifold.stream :as s]) (defn echo-handler [req] (let [s @(http/websocket-connection req)] (s/connect s s)))
hardest issues were about WS • Less common means less tested • HTTP/1.1 in Aleph has a "connectionless" API • This brings a few corner cases even for HTTP/1.1 • For WS the abstraction leaks heavily • Ring 2.0 spec in DRAFT
allows the application layer to negotiate which protocol should be performed • replaced NPN (Next Protocol Negotiation Extension) • emerged from SPDY development
(HPACK) • Framed transport (similar to WS) • Multiplexing over a single TCP connection • HTTP/2 Server Push • Settings management flow, priorities • ALPN, "Upgrade"
support in Aleph • Again, most features are not part of Ring spec • Some of the hardest issues I worked with were about WS • ^ because we don't support HTTP/2 • To my best knowledge, heavy usage of HTTP/2: • HTTTP/2 → HTTP/1.1 proxies, including LBs • gRPC
! ) • Streams are not independent • 3 different handshakes: TCP, TLS, HTTP • Better with TLS1.3, but still • TCP relies on IP address • TCP is "hardcoded" into infrastructure (links, routers, kernel)
• kachayev/quiche4j - QUIC & HTTP/3 in Java • utilizes cloudflare/quiche (Rust) • JNI layer using rust-jni (also in Rust) • Java API on top • Pluggable I/O scheduling • version with Netty Event Loop as an example
• netty/netty-incubator-codec-quic • netty/netty-incubator-codec-http3 • Also built on top of cloudflare/quiche • Contributions are always very welcome!
• OpenSSL does not (manually) • Framing is straightforward • Loss detection and congestion control are hard • cloudflare/quiche implements Reno & CUBIC • Connection migration between IPs is problematic
• Dynamic table is non-trivial • remember, no ordering guarantees • // TODO: implement dynamic table in quiche • QPACK to support dynamic table in Netty
You need more than request-reply (e.g. streaming) • You have high throughput requirements • TCP is too expensive for you • Too many things happens within the same connection