Support RFC 7239 Forwarded header proto in Scheme()#3061
Conversation
Parse the standardized Forwarded header for a valid proto= value when resolving the request scheme. Prefer Forwarded over the non-standard X-Forwarded-* headers while keeping TLS first and falling through on missing or invalid proto. Only http, https, ws, and wss are accepted. Multi-proxy and multi-header Forwarded values are handled with left-most valid proto; quoted-string values are unescaped per RFC 7230. Fixes labstack#2694
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #3061 +/- ##
==========================================
+ Coverage 93.34% 93.43% +0.08%
==========================================
Files 43 43
Lines 4735 4810 +75
==========================================
+ Hits 4420 4494 +74
Misses 192 192
- Partials 123 124 +1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Add firstForwardedProto cases for quoted garbage, missing '=', unclosed quotes, trailing OWS, and isTokenChar checks so codecov/patch covers the RFC 7239 parser branches.
|
I really do not like this parsing logic from maintenance perspective. This is on par with @sonnemusk why are you so persistent to make it happen? You are working on quite low value item here - these days most of the internet is on HTTPS anyway and browsers will complain even if your site is using HTTP. so if you already have proxy in front of your application you have probably configured HTTP -> HTTPS redirect anyway. May I suggest something more beneficial for society - alternative router implemtation that stores routes by method in separate trees - so less frequent methods could be accessed "possibly" faster as their trees are smaller. |
Summary
Fixes #2694 by teaching
Context.Scheme()to honor the standardizedForwardedheader (proto=parameter, RFC 7239).Previous attempts (#2702, #2744) either returned the raw header without parsing
proto=, or introduced API surface / RealIP changes that were hard to get right. This PR is intentionally narrow:RealIP/IPExtractorchanges (those belong in a dedicated extractor if needed later)http,https,ws,wss(case-insensitive match)Resolution order
httpsForwardedproto=(RFC 7239), left-most valid valueX-Forwarded-ProtoX-Forwarded-ProtocolX-Forwarded-Ssl == "on"→httpsX-Url-SchemehttpForwardedis preferred over the non-standardX-Forwarded-*headers when both are present and valid. IfForwardedis missing, has noproto, or has an invalidproto, resolution falls through unchanged — existingX-Forwarded-Protobehavior is preserved.Parsing notes
Forwardedheader fieldsProto=HTTPS)Test plan
go test . -run 'TestContext_Scheme|TestFirstForwardedProto' -count=1go test ./... -count=1proto=https, fullfor;proto;by, multi-proxy left-most, multi-header fields, quoted values, invalid/empty fallback toX-Forwarded-Proto, precedence vs TLS /X-Forwarded-Proto, malformed input