]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1] net/http: add missing hasToken function
authorAndrew Gerrand <adg@golang.org>
Fri, 21 Sep 2012 19:55:20 +0000 (05:55 +1000)
committerAndrew Gerrand <adg@golang.org>
Fri, 21 Sep 2012 19:55:20 +0000 (05:55 +1000)
src/pkg/net/http/header.go

index b107c312da782667fdfe8d627e88a3f44965fc34..6be94f98e7469798ca2f81fab09b2011065cb27c 100644 (file)
@@ -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'
+}