Skip to content

Commit

Permalink
Compare request header tokens with ASCII case folding
Browse files Browse the repository at this point in the history
Compare request header tokens with ASCII case folding per the WebSocket
RFC.
  • Loading branch information
garyburd committed Nov 23, 2017
1 parent aa5ed01 commit 447c2df
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 2 deletions.
28 changes: 26 additions & 2 deletions util.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"io"
"net/http"
"strings"
"unicode/utf8"
)

var keyGUID = []byte("258EAFA5-E914-47DA-95CA-C5AB0DC85B11")
Expand Down Expand Up @@ -127,8 +128,31 @@ func nextTokenOrQuoted(s string) (value string, rest string) {
return "", ""
}

// equalASCIIFold returns true if s is equal to t with ASCII case folding.
func equalASCIIFold(s, t string) bool {
for s != "" && t != "" {
sr, size := utf8.DecodeRuneInString(s)
s = s[size:]
tr, size := utf8.DecodeRuneInString(t)
t = t[size:]
if sr == tr {
continue
}
if 'A' <= sr && sr <= 'Z' {
sr = sr + 'a' - 'A'
}
if 'A' <= tr && tr <= 'Z' {
tr = tr + 'a' - 'A'
}
if sr != tr {
return false
}
}
return s == t
}

// tokenListContainsValue returns true if the 1#token header with the given
// name contains token.
// name contains a token equal to value with ASCII case folding.
func tokenListContainsValue(header http.Header, name string, value string) bool {
headers:
for _, s := range header[name] {
Expand All @@ -142,7 +166,7 @@ headers:
if s != "" && s[0] != ',' {
continue headers
}
if strings.EqualFold(t, value) {
if equalASCIIFold(t, value) {
return true
}
if s == "" {
Expand Down
18 changes: 18 additions & 0 deletions util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,24 @@ import (
"testing"
)

var equalASCIIFoldTests = []struct {
t, s string
eq bool
}{
{"WebSocket", "websocket", true},
{"websocket", "WebSocket", true},
{"Öyster", "öyster", false},
}

func TestEqualASCIIFold(t *testing.T) {
for _, tt := range equalASCIIFoldTests {
eq := equalASCIIFold(tt.s, tt.t)
if eq != tt.eq {
t.Errorf("equalASCIIFold(%q, %q) = %v, want %v", tt.s, tt.t, eq, tt.eq)
}
}
}

var tokenListContainsValueTests = []struct {
value string
ok bool
Expand Down

0 comments on commit 447c2df

Please sign in to comment.