Skip to content

Commit 48ce47f

Browse files
reverseproxy: Use correct cases for websocket related headers (#6621)
Co-authored-by: Francis Lavoie <[email protected]>
1 parent ef4e022 commit 48ce47f

File tree

2 files changed

+26
-0
lines changed

2 files changed

+26
-0
lines changed

modules/caddyhttp/reverseproxy/reverseproxy.go

+25
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,30 @@ func (h *Handler) proxyLoopIteration(r *http.Request, origReq *http.Request, w h
569569
return false, proxyErr
570570
}
571571

572+
// Mapping of the canonical form of the headers, to the RFC 6455 form,
573+
// i.e. `WebSocket` with uppercase 'S'.
574+
var websocketHeaderMapping = map[string]string{
575+
"Sec-Websocket-Accept": "Sec-WebSocket-Accept",
576+
"Sec-Websocket-Extensions": "Sec-WebSocket-Extensions",
577+
"Sec-Websocket-Key": "Sec-WebSocket-Key",
578+
"Sec-Websocket-Protocol": "Sec-WebSocket-Protocol",
579+
"Sec-Websocket-Version": "Sec-WebSocket-Version",
580+
}
581+
582+
// normalizeWebsocketHeaders ensures we use the standard casing as per
583+
// RFC 6455, i.e. `WebSocket` with uppercase 'S'. Most servers don't
584+
// care about this difference (read headers case insensitively), but
585+
// some do, so this maximizes compatibility with upstreams.
586+
// See https://github.com/caddyserver/caddy/pull/6621
587+
func normalizeWebsocketHeaders(header http.Header) {
588+
for k, rk := range websocketHeaderMapping {
589+
if v, ok := header[k]; ok {
590+
delete(header, k)
591+
header[rk] = v
592+
}
593+
}
594+
}
595+
572596
// prepareRequest clones req so that it can be safely modified without
573597
// changing the original request or introducing data races. It then
574598
// modifies it so that it is ready to be proxied, except for directing
@@ -655,6 +679,7 @@ func (h Handler) prepareRequest(req *http.Request, repl *caddy.Replacer) (*http.
655679
if reqUpType != "" {
656680
req.Header.Set("Connection", "Upgrade")
657681
req.Header.Set("Upgrade", reqUpType)
682+
normalizeWebsocketHeaders(req.Header)
658683
}
659684

660685
// Set up the PROXY protocol info

modules/caddyhttp/reverseproxy/streaming.go

+1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ func (h *Handler) handleUpgradeResponse(logger *zap.Logger, wg *sync.WaitGroup,
6666
// write header first, response headers should not be counted in size
6767
// like the rest of handler chain.
6868
copyHeader(rw.Header(), res.Header)
69+
normalizeWebsocketHeaders(rw.Header())
6970
rw.WriteHeader(res.StatusCode)
7071

7172
logger.Debug("upgrading connection")

0 commit comments

Comments
 (0)