Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS
Mirrored from https://github.com/Slazee/caddy.git
Synced Nov 12, 07:00 UTC
reverseproxy: Use correct cases for websocket related headers (#6621)
Co-authored-by: Francis Lavoie <lavofr@gmail.com>
WeidiDeng committed
Oct 11, 2024 at 17:02 UTC
48ce47f1d44da485fbbf6be536a0e3822763f313
2 files changed
+26
modules/caddyhttp/reverseproxy/reverseproxy.go
+25
@@ -569,6 +569,30 @@ func (h *Handler) proxyLoopIteration(r *http.Request, origReq *http.Request, w h
569
return false, proxyErr
570
}
571
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
+
596
// prepareRequest clones req so that it can be safely modified without
597
// changing the original request or introducing data races. It then
598
// 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.
679
if reqUpType != "" {
680
req.Header.Set("Connection", "Upgrade")
681
req.Header.Set("Upgrade", reqUpType)
682
+ normalizeWebsocketHeaders(req.Header)
683
}
684
685
// Set up the PROXY protocol info
modules/caddyhttp/reverseproxy/streaming.go
+1
@@ -66,6 +66,7 @@ func (h *Handler) handleUpgradeResponse(logger *zap.Logger, wg *sync.WaitGroup,
66
// write header first, response headers should not be counted in size
67
// like the rest of handler chain.
68
copyHeader(rw.Header(), res.Header)
69
+ normalizeWebsocketHeaders(rw.Header())
70
rw.WriteHeader(res.StatusCode)
71
72
logger.Debug("upgrading connection")