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‎

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

221221
funcselectSubprotocol(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:=rangesubprotocols{
224224
for_, cp:=rangecps{
225225
ifstrings.EqualFold(sp, cp){
@@ -349,12 +349,18 @@ func websocketExtensions(h http.Header) []websocketExtension{
349349
}
350350

351351
funcheaderTokens(h http.Header, keystring) []string{
352+
returnheaderTokensExt(h, key, true)
353+
}
354+
355+
funcheaderTokensExt(h http.Header, keystring, lowerbool) []string{
352356
key=textproto.CanonicalMIMEHeaderKey(key)
353357
vartokens []string
354358
for_, v:=rangeh[key]{
355359
v=strings.TrimSpace(v)
356360
for_, t:=rangestrings.Split(v, ","){
357-
t=strings.ToLower(t)
361+
iflower{
362+
t=strings.ToLower(t)
363+
}
358364
t=strings.TrimSpace(t)
359365
tokens=append(tokens, t)
360366
}

‎accept_test.go‎

Lines changed: 6 additions & 0 deletions
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:=rangetestCases{

0 commit comments

Comments
(0)