Skip to content

refactor(storage): use s2a-go v0.1.11 NextProtos and share S2A dialer - #5133

Open
anushka567 wants to merge 1 commit into
GoogleCloudPlatform:masterfrom
anushka567:s2a-alpn-next-protos
Open

anushka567 wants to merge 1 commit into
GoogleCloudPlatform:masterfrom
anushka567:s2a-alpn-next-protos

Conversation

@anushka567

@anushka567 anushka567 commented Oct 6, 2026 •

Copy link
Copy Markdown
Member

Description

s2a-go v0.1.11 (google/s2a-go#161) adds ClientOptions.NextProtos / TLSClientConfigOptions.NextProtos, so a client can choose the ALPN protocols offered during the S2A TLS handshake instead of always offering h2. This PR:

  • Bumps github.com/google/s2a-go from v0.1.10 to v0.1.11.
  • Sets s2aClientOptions.NextProtos = []string{"http/1.1"} when client-protocol is http1, replacing the post-Build tlsConfig.NextProtos overwrite from feat: add direct S2A authentication support for HTTP and gRPC transports #5112.
  • Renames newS2ADialTLSContextForHTTP1 to newS2ADialTLSContext and uses it for both http1 and http2.
    • Once http.Transport.DialTLSContext is set, DialContext is not used for HTTPS requests, and s2a.NewS2ADialTLSContextFunc always dials with a zero-value net.Dialer.
    • Previously http2 called s2a.NewS2ADialTLSContextFunc, which silently dropped --experimental-local-socket-address (dialer.LocalAddr) and --enable-http-dns-cache (dialer.Resolver, enabled by default) when S2A was enabled. Sharing newS2ADialTLSContext keeps both settings working across http1 and http2 and removes the http1/http2 dialer branch.

Link to the issue in case of a bug fix.

NA. Follow-up to #5112.

Testing details

  1. Manual: end-to-end run on a staging environment where gcsfuse runs on the host with S2A.
    • gcsfuse flags: --s2a-address, --s2a-spiffe-id, --token-url, and default client-protocol (http1) with enable-http-dns-cache at its default true.
    • Scenario: one VM writes a file through its gcsfuse mount; a second VM mounting the same bucket prefix reads it back; a third VM with a different prefix does not see it.
    • Positive run: passed (before and after the negative control). Every mount reported File system has been successfully mounted. and the gcsfuse logs had no HTTP errors.
    • Negative control: failed as expected. With the NextProtos = []string{http1ALPNProto} assignment removed so s2a-go falls back to offering h2, the write returned Input/output error and every JSON API request failed with:
      StatObject: error in fetching object attributes: Get "https://storage.mtls.googleapis.com/storage/v1/b/<bucket>/o/<object>?alt=json&prettyPrint=false&projection=full": net/http: HTTP/1.x transport connection broken: malformed HTTP response "\x00\x00\x12\x04\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00d\x00\x04\x00\x10\x00\x00\x00\x06\x00\x01\x00\x00..."
      
      (the server's HTTP/2 SETTINGS frame).
  2. Unit tests: go test -count=1 ./internal/storage/... passes, with TestCreateHttpClientWithS2A_DialVerification now parameterized over both http1 and http2.
  3. Integration tests: NA. Covered by the manual end-to-end run above.

Any backward incompatible change? If so, please explain.

No. The http1 S2A path still offers only http/1.1, and http2 with S2A now honors --experimental-local-socket-address and --enable-http-dns-cache just like http1.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the github.com/google/s2a-go dependency to v0.1.11 and refactors S2A dialer configuration by introducing helper functions newS2AClientOptions and newS2ADialTLSContextWithDialer to ensure HTTP/1.1 connections respect base dialer settings. Unit tests have also been added to verify these changes. The reviewer suggests unifying the dialer creation for both HTTP/1.1 and HTTP/2 to ensure base dialer settings (like local socket address and DNS cache) are consistently applied and to avoid recreating the TLS client config factory on every dial.

Comment thread internal/storage/storageutil/client.go Outdated
@anushka567 anushka567 changed the title refactor(storage): use s2a-go v0.1.11 NextProtos for S2A HTTP/1.1 ALPN refactor(storage): use s2a-go v0.1.11 NextProtos and share S2A dialer Oct 6, 2026
@anushka567
anushka567 force-pushed the s2a-alpn-next-protos branch from ed1ddf1 to 6bddd3b Compare October 6, 2026 12:45
s2a-go v0.1.11 (google/s2a-go#161) adds ClientOptions.NextProtos, so a
client can choose the ALPN protocols offered during the S2A TLS handshake
instead of always offering "h2". Upgrade to v0.1.11 and set
ClientOptions.NextProtos = []string{"http/1.1"} when clientProtocol is
http1, replacing the workaround that overwrote tlsConfig.NextProtos after
factory.Build.

With ALPN configured via ClientOptions, http1 and http2 can share a single
S2A dialer helper (newS2ADialTLSContext) that opens its TCP connection with
the base net.Dialer. Previously http2 called s2a.NewS2ADialTLSContextFunc,
which dials with a zero-value net.Dialer, and http.Transport ignores
DialContext for HTTPS once DialTLSContext is set; sharing the helper keeps
--experimental-local-socket-address and --enable-http-dns-cache working for
both http1 and http2 when S2A is enabled.
@anushka567
anushka567 force-pushed the s2a-alpn-next-protos branch from 6bddd3b to 75307d4 Compare October 6, 2026 13:01
@anushka567
anushka567 marked this pull request as ready for review October 6, 2026 13:03
@anushka567
anushka567 requested a review from a team as a code owner October 6, 2026 13:03
@anushka567

Copy link
Copy Markdown
Member Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request upgrades the github.com/google/s2a-go dependency to v0.1.11 and refactors the S2A dialer setup in client.go. It unifies the S2A TLS dialer creation for both HTTP/1.1 and HTTP/2 protocols under a single newS2ADialTLSContext function, ensuring that the underlying TCP connection is opened using the configured base dialer. This preserves features like local socket addresses and HTTP DNS caching when S2A is enabled. Additionally, the unit tests have been expanded to verify dial behavior for both protocols. There are no review comments, so we have no feedback to provide.

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.

1 participant