net.http: add ALPN negotiation to the Windows SChannel backend#27395
Merged
Conversation
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
First half of vlang#27383: give the SChannel (vschannel) TLS backend the ability to advertise ALPN protocols and read the protocol the server selected, reaching parity with the mbedtls/OpenSSL backends (vlang#27343) on the negotiation primitive. thirdparty/vschannel/vschannel.c: - TlsContext gains an ALPN protocol list to advertise and a slot for the negotiated protocol. - perform_client_handshake() passes a SECBUFFER_APPLICATION_PROTOCOLS input buffer (SEC_APPLICATION_PROTOCOLS / SecApplicationProtocolNegotiationExt_ALPN) into the ClientHello when a list is configured; the path is unchanged when it is not, so existing HTTP/1.1 requests are byte-identical. - After the handshake, SECPKG_ATTR_APPLICATION_PROTOCOL is queried and stored. - New C entry points: vschannel_set_alpn(), vschannel_get_alpn(), and vschannel_alpn_probe() (handshake-only, no application data). vlib/net/http (Windows only): - vschannel_alpn_windows.c.v exposes the C API, an alpn_wire() encoder, and schannel_alpn_probe(). - vschannel_alpn_windows_test.v: a wire-encoding unit test plus `-d network` tests that probe a public HTTP/2 server and assert `h2` is negotiated (and that offering only http/1.1 falls back). This deliberately does NOT change fetch(): the one-shot vschannel request() path still speaks HTTP/1.1, so advertising `h2` in real requests waits for the HTTP/2-driver wiring (the second half of vlang#27383). It satisfies the issue's first acceptance criterion (a negotiated_alpn()-equivalent on SChannel). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
tcc bundles Windows SDK headers that predate SChannel ALPN, so the ALPN structs, enums and constants were undeclared. Define them when the SDK headers do not, matching the official layout exactly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
e8d1c76 to
e078cd4
Compare
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.
What
First half of #27383: give the Windows SChannel (vschannel) TLS backend the ability to advertise ALPN protocols and read the protocol the server selected, bringing it to parity with the mbedtls/OpenSSL backends (ALPN landed for those in #27343; SChannel was explicitly deferred).
Why
On a default Windows build the HTTP client uses SChannel, which had no ALPN, so
http.fetch(enable_http2: true)could never negotiate HTTP/2 there. This is also why the server-side HTTP/2 test (#27382) and the default-on test had to be gated with$if windows && !no_vschannel ?. This PR adds the negotiation primitive those depend on.Changes
thirdparty/vschannel/vschannel.cTlsContextgains an ALPN list to advertise and a slot for the negotiated protocol.perform_client_handshake()passes aSECBUFFER_APPLICATION_PROTOCOLSinput buffer (SEC_APPLICATION_PROTOCOLS/SecApplicationProtocolNegotiationExt_ALPN) into the ClientHello when a list is configured. When it is not (the default),pInputstaysNULLand the handshake is byte-identical to before — existing HTTP/1.1 requests are unaffected.SECPKG_ATTR_APPLICATION_PROTOCOLis queried and stored.vschannel_set_alpn(),vschannel_get_alpn(),vschannel_alpn_probe()(handshake-only).vlib/net/http(Windows only)vschannel_alpn_windows.c.v— exposes the C API, analpn_wire()encoder, andschannel_alpn_probe().vschannel_alpn_windows_test.v— a wire-encoding unit test plus-d networktests that probe a public HTTP/2 server and asserth2is negotiated (and that offering onlyhttp/1.1falls back).Scope (deliberate)
This does not change
fetch(). The one-shot vschannelrequest()path still speaks HTTP/1.1, so advertisingh2in real requests would let a server pick a protocol we can't yet speak. Wiring the request path to an HTTP/2 driver is the second half of #27383. This PR satisfies the issue's first acceptance criterion: anegotiated_alpn()-equivalent that works on SChannel.Verification
Compiled and tested on real Windows (SChannel):
v test vlib\net\http\vschannel_alpn_windows_test.v— compilesvschannel.cwith the ALPN changes; wire-encoding test passes.v -d network -stats test vlib\net\http\vschannel_alpn_windows_test.v— all three tests pass, including liveh2negotiation against a real HTTP/2 server and thehttp/1.1fallback.v fmt -verifyclean on the V files.🤖 Generated with Claude Code