Skip to content

Virtual thread http client#1038

Open
mtdowling wants to merge 60 commits intomainfrom
virtual-thread-http-client
Open

Virtual thread http client#1038
mtdowling wants to merge 60 commits intomainfrom
virtual-thread-http-client

Conversation

@mtdowling
Copy link
Member

Add a virtual thread friendly, blocking HTTP client (h1, h2) that supports bidirectional streaming.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

mtdowling and others added 30 commits February 18, 2026 14:50
The client support H1 and H2 using blocking I/O. The biggest
differentiator is that the client has a simple blocking-style API made
for virtual threads, but still supports full bidirectional h2 streaming.
That is, concurrent request/response streaming over H2 using
InputStream and OutputStream, allowing you to read response data while
still writing request data.

Other protocols
- ALPN negotiation with automatic protocol selection
- H2C prior knowledge (cleartext HTTP/2)

Connection Management
- Per-route connection pooling with LIFO reuse
- HTTP/2 stream multiplexing with load spreading across connections
- Idle connection cleanup and validation
- Configurable limits (per-route, global, host-specific)

Request/Response
- h1: Chunked transfer encoding/decoding with trailer support
- h1: Expect: 100-continue handling
- Content-Length validation
- Streaming and buffered exchange APIs to support full bidirectional
streaming

Proxy
- HTTP/HTTPS CONNECT tunneling
- Proxy authentication (Basic)
- Non-proxy host patterns (wildcards)
- Double-TLS (HTTPS proxy to HTTPS target)

TLS
- TLS hostname verification (certificate CN/SAN matching)
- Custom SSLContext support (mTLS, custom CAs)
- Separate TLS negotiation timeout

Flow Control (H2)
- Stream and connection-level window management
- Backpressure with configurable write timeout

Extensibility
- Interceptor chain (request modification, short-circuit, response
    handling, error recovery)
- Connection pool event listener for telemetry, leak detection, etc
- Pluggable DNS resolver
- Socket factory to customize sockets

Timeouts
- Connect, TLS, read, write, acquire, and 100-continue timeouts
- Fix H2Exchange to close H2DataOutputStream when request stream closes,
  ensuring DATA frame with END_STREAM is sent
- Refactor DelegatedClosingInputStream/OutputStream to pass delegate to
  CloseCallback, enabling callers to close delegate when needed
Connection pool changes:
- Track pending connection creations to prevent over-creation under load
- Preserve original exception when connection creation fails
- Always notify waiters after connection creation (success or failure)

Read timeout improvements:
- Move from per-stream timed waits to centralized timeout sweep (~100ms)
- Add readSeq activity counter to detect stale timeout decisions
- Use AtomicBoolean CAS for at-most-once timeout semantics
- Clear deadline on stream completion to prevent spurious timeouts

The timeout sweep approach scales better with high VT counts by avoiding
thousands of concurrent timed wait registrations. Timeouts are
approximate (±100ms) which is acceptable for network I/O.
Short spin before park. Only way when waiting.
mtdowling and others added 30 commits February 18, 2026 14:50
- Add a *bunch* of integration tests and integ test library-ish code
- Fix H1 connection pool race condition causing connections to be
  created instead of reused under high concurrency
- Add batched flow control acquisition for H2 to prevent connection
  window starvation
- Wait for server's initial WINDOW_UPDATE before starting writes to avoid
  exhausting the 65KB default connection window on large uploads
- Migrate H2ConnectionManager from synchronized to ReentrantLock
- Add configurable h2BufferSize (default 256KB) for stream buffering
- Use short polling in FlowControlWindow to avoid timed-wait contention
- Fix buffer leak in H2DataInputStream.transferTo()
- Simplify H2Exchange data signaling (signal endStream or buffer empty)
Avoids an intermediate InputStream in many cases.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments