net.http: pool HTTP/2 connections over the Windows SChannel backend#27712
Open
quaesitor-scientiam wants to merge 4 commits into
Open
net.http: pool HTTP/2 connections over the Windows SChannel backend#27712quaesitor-scientiam wants to merge 4 commits into
quaesitor-scientiam wants to merge 4 commits into
Conversation
…channel vschannel_read()/vschannel_write() call raw blocking recv()/send() with no timeout mechanism at all. A pooled H2Transport adapter needs a bounded read() -- close() takes the same lock a blocked reader would be holding, so a timeout-free reader would deadlock close() forever (exactly why h2_pooled_io_timeout exists for the mbedTLS/OpenSSL adapter). This adds two small, purely-additive functions needed to build that adapter on top of vschannel in a follow-up commit: - vschannel_set_io_timeouts: SO_RCVTIMEO/SO_SNDTIMEO on the connection's socket, set once at connect time. Unlike mbedTLS/OpenSSL's single shared duration field (reused for both directions' internal retry loop, needing widen-then-restore around every write), these are independent Winsock options. - vschannel_wait_writable: a pure socket-level select() on the write side, mirroring net.TcpConn.wait_for_write's role for the mbedTLS/OpenSSL adapter -- needed because vschannel's socket handle is otherwise opaque to V. No existing function's control flow changes; the one-shot request paths never call either function. Co-Authored-By: WOZCODE <contact@withwoz.com>
Extends Phase 3's default-on h2 pooling (mbedTLS/OpenSSL) to native Windows, which previously bypassed pooling entirely for every https request. Adds VSchannelPooledTransport, an H2Transport adapter around the SChannel one-shot client's TlsContext (safely embeddable by value, unlike mbedTLS's self-referential SSL context). Wires it into the dial path via a new h2_dial_probe/H2ProbeResult abstraction that extracts the mbedTLS/OpenSSL ALPN-probing dial behind the same interface, and narrows Transport.round_trip so only origins already proven http/1.1-only (or h2 disabled) keep the one-shot path; h2-enabled requests fall through to pooling like every other platform. h1-over-vschannel pooling stays out of scope (tracked separately); an h2-enabled request to an h1-only origin on Windows falls back to the proven one-shot req.ssl_do via h2_fallback_h1 rather than switching TLS backends. Un-skips 11 h2-pool tests that were previously platform-gated on this being unimplemented, adds VSchannelPooledTransport's own adapter tests, and adds end-to-end fallback coverage. vschannel_validation_windows_test.v's server now accepts up to 2 connections on this platform (the ALPN probe plus the h1 fallback's independent dial), bounded rather than looping so the existing certificate-rejection test's abort-mid-handshake case still returns promptly. Fixes vlang#27702. Co-Authored-By: WOZCODE <contact@withwoz.com>
6 tasks
CI builds tools with -N (notices promoted to errors), so the checker's 'interface field must be initialized' notice on H2ProbeResult's bare transport/closer interface fields -- unavoidable in the non-h2 probe outcome, which has nothing to initialize them with -- failed every job compiling anything that imports net.http, on all platforms. Option fields are the checker's sanctioned escape for exactly this (set-only-sometimes) shape; h2_dial_and_do unwraps them through h2_dial_failed so even a structurally-impossible miss still wakes singleflight waiters instead of stranding them. Repro: v -N -W -check cmd/tools/vdownload.v (errored before, clean now). Full net.http suite green in both default and -d no_vschannel configs. Co-Authored-By: WOZCODE <contact@withwoz.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Extends the existing HTTP/2 connection-pooling work (#27412/#27413/#27643, all
merged) to native Windows, which previously bypassed pooling entirely — every
httpsrequest on the SChannel backend (i.e. without-d no_vschannel) wentstraight to the old one-shot
req.ssl_dopath before any pooling logic ran.VSchannelPooledTransport, anH2Transportadapter around theSChannel backend's
TlsContext.TlsContextis safely embeddable by value(verified directly — unlike mbedTLS's SSL context, it wires no
self-referential pointer into its own address), so this needs no second
heap allocation the way
H2PooledTransportdoes for&ssl.SSLConn.thirdparty/vschannel/vschannel.c(
vschannel_set_io_timeouts,vschannel_wait_writable) — the one-shotclient had no timeout mechanism at all, and a pooled adapter's
read()must be bounded so
close()(which shares the same lock a blocked readerwould hold) can't deadlock.
h2_dial_probe/H2ProbeResultabstraction soh2_dial_and_do'ssingleflight/dial-id/eviction machinery stays backend-agnostic; the
Windows branch dials via
VSchannelPooledTransportinstead.Transport.round_tripso only origins already provenhttp/1.1-only (or with h2 disabled) keep the one-shot path — h2-enabled
requests now fall through to pooling like every other platform.
h1-over-vschannel pooling stays explicitly out of scope (tracked
separately): an h2-enabled request to an h1-only origin on Windows falls
back to the proven one-shot
req.ssl_dovia a newh2_fallback_h1helper,rather than silently switching TLS backends for that fallback.
Un-skips 11 h2-pool tests that were previously platform-gated on this being
unimplemented, adds
VSchannelPooledTransport's own adapter tests (stableaddress, concurrent read/write/close, read-timeout, write-survives-stall),
and adds one end-to-end fallback-path integration test. Also fixes
vschannel_validation_windows_test.v's server to accept up to 2 connectionson this platform (the ALPN probe plus the h1 fallback's independent dial) —
bounded rather than unbounded, so the certificate-rejection test's
abort-mid-handshake case still returns promptly (an unbounded accept loop
there previously stalled ~41s, since
SSLListener.shutdown()only frees thelistening socket, not a connection already stuck mid-handshake).
Fixes #27702.
Test plan
./vnew fmt -verifyon every touched file./vnew test vlib/net/http/— 25 passed, 2 skipped (by design; seeskip messages), default config (native SChannel pooling exercised)
./vnew -d no_vschannel test vlib/net/http/transport_h2_test.v— 1passed, confirming zero behavior change for the mbedTLS/OpenSSL path
/vreview(full A–G angles + mechanical detectors) — no findingshttps://www.google.com/)Co-Authored-By: WOZCODE contact@withwoz.com