Skip to content

node: cover h2c upgrade route and TLS protocol negotiation - #22862

Merged
lupin012 merged 3 commits into
mainfrom
lupin012/test_h2c_upgrade_and_tls
Jul 29, 2026
Merged

node: cover h2c upgrade route and TLS protocol negotiation#22862
lupin012 merged 3 commits into
mainfrom
lupin012/test_h2c_upgrade_and_tls

Conversation

@lupin012

Copy link
Copy Markdown
Contributor

StartHTTPEndpoint is the single entry point for every JSON-RPC listener
(http, https, separate ws, engine) and negotiates four protocol routes.
Only one of them had a test. This PR adds the missing coverage; no
production code changes.

h2c upgrade route

TestHTTP2H2CUpgrade pins the HTTP/1.1 Upgrade route into h2c (RFC 7540
Section 3.2) — the one curl --http2 uses over cleartext, as opposed to
--http2-prior-knowledge.

Worth pinning because the two h2c routes are not interchangeable. The
x/net/http2/h2c wrapper we use serves both, while the stdlib
http.Protocols route (SetUnencryptedHTTP2) only recognizes the
prior-knowledge preface and has no handling for Upgrade: h2c. Replacing
the wrapper with the stdlib API — as geth did in ethereum/go-ethereum#33812,
which is the upstream equivalent of our #19100 — would silently downgrade
these clients to HTTP/1.1. The test now catches that.

TLS endpoint

TestHTTPSEndpoint covers the ServeTLS path behind --https.enabled,
which had no test at all: HTTP/2 negotiated via ALPN, plus the HTTP/1.1
fallback on the same listener. The certificate is generated in-process, so
no fixture lands on disk and no git restore-mtime entry is needed.

Short-mode guard

Dropped the testing.Short() guard on TestHTTP2H2C: it is labelled
"slow test" but runs in well under a second, so it only hid the test from
the -short suite.

Testing

  • All three tests pass, -count=3 with no flakes.
  • Verified the new tests actually have teeth rather than passing
    vacuously: applying geth's exact protocol config (SetHTTP1 +
    SetUnencryptedHTTP2) to StartHTTPEndpoint makes TestHTTPSEndpoint
    fail, and dropping the h2c wrapper makes TestHTTP2H2CUpgrade fail.
  • go test ./node/... -short green, make lint clean.

Test-only change, so the Red → Green cycle does not apply: these pin
existing behavior that was untested.

StartHTTPEndpoint negotiates four protocol routes and only one of them was
tested. Add the missing coverage:

- TestHTTP2H2CUpgrade pins the HTTP/1.1 Upgrade route into h2c (RFC 7540
  Section 3.2), which is what "curl --http2" uses over cleartext. The
  x/net/http2/h2c wrapper serves both this and prior knowledge, while the
  stdlib http.Protocols route (SetUnencryptedHTTP2) only recognizes the
  prior-knowledge preface, so swapping the wrapper for it would silently
  downgrade these clients to HTTP/1.1.

- TestHTTPSEndpoint covers the ServeTLS path behind --https.enabled, which
  had no test at all: h2 negotiated via ALPN, plus the HTTP/1.1 fallback.
  The certificate is generated in-process, so no fixture lands on disk.

Also drop the testing.Short guard on TestHTTP2H2C: it is labelled "slow
test" but runs in well under a second, so it only hid the test from the
short suite.

Copilot AI 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.

Pull request overview

Adds missing test coverage around JSON-RPC listener protocol negotiation in StartHTTPEndpoint (the shared entry point for HTTP, HTTPS, WS, engine), without changing production behavior. This helps prevent regressions in HTTP/2 cleartext (h2c) upgrade handling and TLS ALPN negotiation.

Changes:

  • Remove the testing.Short() skip from the existing h2c (prior-knowledge) test so it runs in -short.
  • Add TestHTTP2H2CUpgrade to pin the HTTP/1.1 Upgrade: h2c route (curl --http2 cleartext behavior).
  • Add TestHTTPSEndpoint plus an in-test self-signed cert helper to cover ServeTLS, including HTTP/2 via ALPN and HTTP/1.1 fallback.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@yperbasis yperbasis left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Verified locally: -count=5 and -race green; replicating the geth-style protocol config (ethereum/go-ethereum#33812) makes both new tests fail as intended.

Two non-blocking nits:

  • In newSelfSignedCert, IsCA: true is silently dropped from the encoded cert because BasicConstraintsValid is not set, and KeyUsageCertSign is unused for a leaf served under InsecureSkipVerify. Either drop both, or go further and pin the cert via RootCAs — the 127.0.0.1 IP SAN is already there, and it would remove the //nolint:gosec. Pinning would also require BasicConstraintsValid: true.
  • TestHTTPSEndpoint sets no client timeout, so a server hang would only surface at the go-test deadline. Same shape as the existing TestHTTP2H2C, so fine to leave as is.

lupin012 added 2 commits July 29, 2026 16:26
Address review nits on the HTTPS endpoint test:

- Verify the server certificate against a pool holding just that cert,
  which drops InsecureSkipVerify and its gosec suppression. The 127.0.0.1
  IP SAN was already there, so no cert change is needed for the name
  check. IsCA and KeyUsageCertSign go away: they were dead on a leaf, and
  a self-signed cert in the root pool is accepted as a chain of length
  one without a basic-constraints check.

- Give the client a timeout so a server hang surfaces there rather than
  at the go-test deadline.
@lupin012

Copy link
Copy Markdown
Contributor Author

@yperbasis Updated sw to solve non blocking issue

@lupin012
lupin012 added this pull request to the merge queue Jul 29, 2026
Merged via the queue into main with commit d8dac9f Jul 29, 2026
106 checks passed
@lupin012
lupin012 deleted the lupin012/test_h2c_upgrade_and_tls branch July 29, 2026 20:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants