Skip to content

fix: return 400 instead of 502 for a Host header with a non-numeric port - #1708

Open
RajeshRajendiran wants to merge 2 commits into
cloudflare:masterfrom
RajeshRajendiran:fix-host-header-invalid-port
Open

fix: return 400 instead of 502 for a Host header with a non-numeric port#1708
RajeshRajendiran wants to merge 2 commits into
cloudflare:masterfrom
RajeshRajendiran:fix-host-header-invalid-port

Conversation

@RajeshRajendiran

Copy link
Copy Markdown

Summary

  • The QUIC data-path ConnectRequest.Dest can carry the eyeball's Host header verbatim, so a request with Host: app.example.com:aaaa produces a Dest like http://app.example.com:aaaa/....
  • buildHTTPRequest passes this straight into http.NewRequestWithContext, which fails Go's URL parser with invalid port ":aaaa" after host since the port isn't numeric.
  • That error propagated up through dispatchRequest/handleDataStream with no distinguishing metadata, so it was reported to the eyeball as a bare error with the default 502 status — indistinguishable from a genuine origin/proxy failure, and misleading for anyone debugging the client-side issue.

Fix

  • Wrap the http.NewRequestWithContext error in a new malformedRequestError type when it fails to build the request from Dest.
  • In handleDataStream, detect this error type (same pattern already used for cfdflow.ErrTooManyActiveFlows) and attach HttpStatus: 400 metadata so the eyeball gets a 400 instead of a 502.

Test plan

  • Added TestBuildHTTPRequestMalformedDest verifying a Dest with a non-numeric port returns malformedRequestError.
  • Added TestHTTPProxy_MalformedHostPort, an end-to-end QUIC test verifying the response metadata carries HttpStatus: 400.
  • go build ./...
  • go vet ./connection/...
  • go test -race -count=1 ./connection/...
  • golangci-lint run ./connection/... -> 0 issues

Fixes #1490

connectRequest.Dest can carry the eyeball's Host header verbatim, so a
port like ":aaaa" fails Go's URL parser inside http.NewRequestWithContext.
That error was surfacing to the eyeball as a 502, which looks like an
origin failure rather than a malformed client request. Wrap it in a
distinguishable error type so handleDataStream can report it as 400.
errors.Is against a sentinel matches the existing cfdflow.ErrTooManyActiveFlows
check right above it in handleDataStream, and needs less code than a custom
struct type with hand-written Error()/Unwrap() methods.
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.

🐛 Tunnel returns 502 for requests whose host header contains a non-numeric port

1 participant