@@ -39,6 +39,23 @@ const (
39
39
redirectURIQueryParam = "redirect_uri"
40
40
)
41
41
42
+ // nonCanonicalHeaders is a map from "canonical" headers to the actual header we
43
+ // should send to the app in the workspace. Some headers (such as the websocket
44
+ // upgrade headers from RFC 6455) are not canonical according to the HTTP/1
45
+ // spec. Golang has said that they will not add custom cases for these headers,
46
+ // so we need to do it ourselves.
47
+ //
48
+ // Some apps our customers use are sensitive to the case of these headers.
49
+ //
50
+ // https://github.com/golang/go/issues/18495
51
+ var nonCanonicalHeaders = map [string ]string {
52
+ "Sec-Websocket-Accept" : "Sec-WebSocket-Accept" ,
53
+ "Sec-Websocket-Extensions" : "Sec-WebSocket-Extensions" ,
54
+ "Sec-Websocket-Key" : "Sec-WebSocket-Key" ,
55
+ "Sec-Websocket-Protocol" : "Sec-WebSocket-Protocol" ,
56
+ "Sec-Websocket-Version" : "Sec-WebSocket-Version" ,
57
+ }
58
+
42
59
func (api * API ) appHost (rw http.ResponseWriter , r * http.Request ) {
43
60
host := api .AppHostname
44
61
if api .AccessURL .Port () != "" {
@@ -708,14 +725,24 @@ func (api *API) proxyWorkspaceApplication(proxyApp proxyApplication, rw http.Res
708
725
return
709
726
}
710
727
defer release ()
728
+ proxy .Transport = conn .HTTPTransport ()
711
729
712
730
// This strips the session token from a workspace app request.
713
731
cookieHeaders := r .Header .Values ("Cookie" )[:]
714
732
r .Header .Del ("Cookie" )
715
733
for _ , cookieHeader := range cookieHeaders {
716
734
r .Header .Add ("Cookie" , httpapi .StripCoderCookies (cookieHeader ))
717
735
}
718
- proxy .Transport = conn .HTTPTransport ()
736
+
737
+ // Convert canonicalized headers to their non-canonicalized counterparts.
738
+ // See the comment on `nonCanonicalHeaders` for more information on why this
739
+ // is necessary.
740
+ for k , v := range r .Header {
741
+ if n , ok := nonCanonicalHeaders [k ]; ok {
742
+ r .Header .Del (k )
743
+ r .Header [n ] = v
744
+ }
745
+ }
719
746
720
747
// end span so we don't get long lived trace data
721
748
tracing .EndHTTPSpan (r , http .StatusOK , trace .SpanFromContext (ctx ))
0 commit comments