1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
7 // This file deals with lexical matters of HTTP
9 func isSeparator(c
byte) bool {
11 case '(', ')', '<', '>', '@', ',', ';', ':', '\\', '"', '/', '[', ']', '?', '=', '{', '}', ' ', '\t':
17 func isSpace(c
byte) bool {
19 case ' ', '\t', '\r', '\n':
25 func isCtl(c
byte) bool { return (0 <= c
&& c
<= 31) || c
== 127 }
27 func isChar(c
byte) bool { return 0 <= c
&& c
<= 127 }
29 func isAnyText(c
byte) bool { return !isCtl(c
) }
31 func isQdText(c
byte) bool { return isAnyText(c
) && c
!= '"' }
33 func isToken(c
byte) bool { return isChar(c
) && !isCtl(c
) && !isSeparator(c
) }
35 // Valid escaped sequences are not specified in RFC 2616, so for now, we assume
36 // that they coincide with the common sense ones used by GO. Malformed
37 // characters should probably not be treated as errors by a robust (forgiving)
38 // parser, so we replace them with the '?' character.
39 func httpUnquotePair(b
byte) byte {
40 // skip the first byte, which should always be '\'
66 // raw must begin with a valid quoted string. Only the first quoted string is
67 // parsed and is unquoted in result. eaten is the number of bytes parsed, or -1
69 func httpUnquote(raw
[]byte) (eaten
int, result
string) {
70 buf
:= make([]byte, len(raw
))
75 j
:= 0 // # of bytes written in buf
76 for i
:= 1; i
< len(raw
); i
++ {
77 switch b
:= raw
[i
]; b
{
81 return i
+ 1, string(buf
)
86 buf
[j
] = httpUnquotePair(raw
[i
+1])
103 // This is a best effort parse, so errors are not returned, instead not all of
104 // the input string might be parsed. result is always non-nil.
105 func httpSplitFieldValue(fv
string) (eaten
int, result
[]string) {
106 result
= make([]string, 0, len(fv
))
114 eaten
, unq
:= httpUnquote(raw
[i
:len(raw
)])
123 result
= result
[0 : len(result
)+1]
124 result
[len(result
)-1] = chunk
131 case b
== '\n' || b
== '\r':
139 result
= result
[0 : len(result
)+1]
140 result
[len(result
)-1] = chunk