Skip to content

Commit d3bc55c

Browse files
author
Egor Gorbunov
committed
Preserve client case for selected subprotocol
WebSocket implementation in chromium rejects ws connections in case server side responses with Sec-WebSocket-Protocol header which values does not match values sent in the same header by client In case you use protocols to send case-sensitive text (for example, auth tokens) you end up with inability to establish websocket connection from chromium. So lets make selected protocol completely match one send by the client. This patch does not break negotiation rules and server protocols are still matched against client protocols using EqualFold.
1 parent c9f314a commit d3bc55c

File tree

2 files changed

+14
-2
lines changed

2 files changed

+14
-2
lines changed

accept.go

+8-2
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ func match(pattern, s string) (bool, error) {
219219
}
220220

221221
func selectSubprotocol(r *http.Request, subprotocols []string) string {
222-
cps := headerTokens(r.Header, "Sec-WebSocket-Protocol")
222+
cps := headerTokensExt(r.Header, "Sec-WebSocket-Protocol", false)
223223
for _, sp := range subprotocols {
224224
for _, cp := range cps {
225225
if strings.EqualFold(sp, cp) {
@@ -349,12 +349,18 @@ func websocketExtensions(h http.Header) []websocketExtension {
349349
}
350350

351351
func headerTokens(h http.Header, key string) []string {
352+
return headerTokensExt(h, key, true)
353+
}
354+
355+
func headerTokensExt(h http.Header, key string, lower bool) []string {
352356
key = textproto.CanonicalMIMEHeaderKey(key)
353357
var tokens []string
354358
for _, v := range h[key] {
355359
v = strings.TrimSpace(v)
356360
for _, t := range strings.Split(v, ",") {
357-
t = strings.ToLower(t)
361+
if lower {
362+
t = strings.ToLower(t)
363+
}
358364
t = strings.TrimSpace(t)
359365
tokens = append(tokens, t)
360366
}

accept_test.go

+6
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,12 @@ func Test_selectSubprotocol(t *testing.T) {
224224
serverProtocols: []string{"echo2", "echo3"},
225225
negotiated: "echo3",
226226
},
227+
{
228+
name: "clientCasePresered",
229+
clientProtocols: []string{"Echo1"},
230+
serverProtocols: []string{"echo1"},
231+
negotiated: "Echo1",
232+
},
227233
}
228234

229235
for _, tc := range testCases {

0 commit comments

Comments
 (0)