aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Gerrand <adg@golang.org>2012-09-22 05:55:20 +1000
committerAndrew Gerrand <adg@golang.org>2012-09-22 05:55:20 +1000
commitc2de7b2cd6651f91f38b7df5566a796f45520da7 (patch)
tree81e107377a59d70febd1abca3c1784f8c0cac921
parent6ab2bfa952e8cbe3f50070b3303fa2abb170501c (diff)
downloadgo-c2de7b2cd6651f91f38b7df5566a796f45520da7.tar.gz
go-c2de7b2cd6651f91f38b7df5566a796f45520da7.zip
[release-branch.go1] net/http: add missing hasToken function
-rw-r--r--src/pkg/net/http/header.go40
1 files changed, 40 insertions, 0 deletions
diff --git a/src/pkg/net/http/header.go b/src/pkg/net/http/header.go
index b107c312da..6be94f98e7 100644
--- a/src/pkg/net/http/header.go
+++ b/src/pkg/net/http/header.go
@@ -76,3 +76,43 @@ func (h Header) WriteSubset(w io.Writer, exclude map[string]bool) error {
// the rest are converted to lowercase. For example, the
// canonical key for "accept-encoding" is "Accept-Encoding".
func CanonicalHeaderKey(s string) string { return textproto.CanonicalMIMEHeaderKey(s) }
+
+// hasToken returns whether token appears with v, ASCII
+// case-insensitive, with space or comma boundaries.
+// token must be all lowercase.
+// v may contain mixed cased.
+func hasToken(v, token string) bool {
+ if len(token) > len(v) || token == "" {
+ return false
+ }
+ if v == token {
+ return true
+ }
+ for sp := 0; sp <= len(v)-len(token); sp++ {
+ // Check that first character is good.
+ // The token is ASCII, so checking only a single byte
+ // is sufficient. We skip this potential starting
+ // position if both the first byte and its potential
+ // ASCII uppercase equivalent (b|0x20) don't match.
+ // False positives ('^' => '~') are caught by EqualFold.
+ if b := v[sp]; b != token[0] && b|0x20 != token[0] {
+ continue
+ }
+ // Check that start pos is on a valid token boundary.
+ if sp > 0 && !isTokenBoundary(v[sp-1]) {
+ continue
+ }
+ // Check that end pos is on a valid token boundary.
+ if endPos := sp + len(token); endPos != len(v) && !isTokenBoundary(v[endPos]) {
+ continue
+ }
+ if strings.EqualFold(v[sp:sp+len(token)], token) {
+ return true
+ }
+ }
+ return false
+}
+
+func isTokenBoundary(b byte) bool {
+ return b == ' ' || b == ',' || b == '\t'
+}