~ubuntu-branches/ubuntu/saucy/golang/saucy

« back to all changes in this revision

Viewing changes to src/pkg/net/http/lex.go

  • Committer: Package Import Robot
  • Author(s): Adam Conrad
  • Date: 2013-07-08 05:52:37 UTC
  • mfrom: (29.1.1 sid)
  • Revision ID: package-import@ubuntu.com-20130708055237-at01839e0hp8z3ni
Tags: 2:1.1-1ubuntu1
016-armhf-elf-header.patch: Use correct ELF header for armhf binaries.

Show diffs side-by-side

added added

removed removed

Lines of Context:
6
6
 
7
7
// This file deals with lexical matters of HTTP
8
8
 
9
 
func isSeparator(c byte) bool {
10
 
        switch c {
11
 
        case '(', ')', '<', '>', '@', ',', ';', ':', '\\', '"', '/', '[', ']', '?', '=', '{', '}', ' ', '\t':
12
 
                return true
13
 
        }
14
 
        return false
15
 
}
16
 
 
17
 
func isCtl(c byte) bool { return (0 <= c && c <= 31) || c == 127 }
18
 
 
19
 
func isChar(c byte) bool { return 0 <= c && c <= 127 }
20
 
 
21
 
func isAnyText(c byte) bool { return !isCtl(c) }
22
 
 
23
 
func isQdText(c byte) bool { return isAnyText(c) && c != '"' }
24
 
 
25
 
func isToken(c byte) bool { return isChar(c) && !isCtl(c) && !isSeparator(c) }
26
 
 
27
 
// Valid escaped sequences are not specified in RFC 2616, so for now, we assume
28
 
// that they coincide with the common sense ones used by GO. Malformed
29
 
// characters should probably not be treated as errors by a robust (forgiving)
30
 
// parser, so we replace them with the '?' character.
31
 
func httpUnquotePair(b byte) byte {
32
 
        // skip the first byte, which should always be '\'
33
 
        switch b {
34
 
        case 'a':
35
 
                return '\a'
36
 
        case 'b':
37
 
                return '\b'
38
 
        case 'f':
39
 
                return '\f'
40
 
        case 'n':
41
 
                return '\n'
42
 
        case 'r':
43
 
                return '\r'
44
 
        case 't':
45
 
                return '\t'
46
 
        case 'v':
47
 
                return '\v'
48
 
        case '\\':
49
 
                return '\\'
50
 
        case '\'':
51
 
                return '\''
52
 
        case '"':
53
 
                return '"'
54
 
        }
55
 
        return '?'
56
 
}
57
 
 
58
 
// raw must begin with a valid quoted string. Only the first quoted string is
59
 
// parsed and is unquoted in result. eaten is the number of bytes parsed, or -1
60
 
// upon failure.
61
 
func httpUnquote(raw []byte) (eaten int, result string) {
62
 
        buf := make([]byte, len(raw))
63
 
        if raw[0] != '"' {
64
 
                return -1, ""
65
 
        }
66
 
        eaten = 1
67
 
        j := 0 // # of bytes written in buf
68
 
        for i := 1; i < len(raw); i++ {
69
 
                switch b := raw[i]; b {
70
 
                case '"':
71
 
                        eaten++
72
 
                        buf = buf[0:j]
73
 
                        return i + 1, string(buf)
74
 
                case '\\':
75
 
                        if len(raw) < i+2 {
76
 
                                return -1, ""
77
 
                        }
78
 
                        buf[j] = httpUnquotePair(raw[i+1])
79
 
                        eaten += 2
80
 
                        j++
81
 
                        i++
82
 
                default:
83
 
                        if isQdText(b) {
84
 
                                buf[j] = b
85
 
                        } else {
86
 
                                buf[j] = '?'
87
 
                        }
88
 
                        eaten++
89
 
                        j++
90
 
                }
91
 
        }
92
 
        return -1, ""
93
 
}
94
 
 
95
 
// This is a best effort parse, so errors are not returned, instead not all of
96
 
// the input string might be parsed. result is always non-nil.
97
 
func httpSplitFieldValue(fv string) (eaten int, result []string) {
98
 
        result = make([]string, 0, len(fv))
99
 
        raw := []byte(fv)
100
 
        i := 0
101
 
        chunk := ""
102
 
        for i < len(raw) {
103
 
                b := raw[i]
104
 
                switch {
105
 
                case b == '"':
106
 
                        eaten, unq := httpUnquote(raw[i:len(raw)])
107
 
                        if eaten < 0 {
108
 
                                return i, result
109
 
                        } else {
110
 
                                i += eaten
111
 
                                chunk += unq
112
 
                        }
113
 
                case isSeparator(b):
114
 
                        if chunk != "" {
115
 
                                result = result[0 : len(result)+1]
116
 
                                result[len(result)-1] = chunk
117
 
                                chunk = ""
118
 
                        }
119
 
                        i++
120
 
                case isToken(b):
121
 
                        chunk += string(b)
122
 
                        i++
123
 
                case b == '\n' || b == '\r':
124
 
                        i++
125
 
                default:
126
 
                        chunk += "?"
127
 
                        i++
128
 
                }
129
 
        }
130
 
        if chunk != "" {
131
 
                result = result[0 : len(result)+1]
132
 
                result[len(result)-1] = chunk
133
 
                chunk = ""
134
 
        }
135
 
        return i, result
 
9
var isTokenTable = [127]bool{
 
10
        '!':  true,
 
11
        '#':  true,
 
12
        '$':  true,
 
13
        '%':  true,
 
14
        '&':  true,
 
15
        '\'': true,
 
16
        '*':  true,
 
17
        '+':  true,
 
18
        '-':  true,
 
19
        '.':  true,
 
20
        '0':  true,
 
21
        '1':  true,
 
22
        '2':  true,
 
23
        '3':  true,
 
24
        '4':  true,
 
25
        '5':  true,
 
26
        '6':  true,
 
27
        '7':  true,
 
28
        '8':  true,
 
29
        '9':  true,
 
30
        'A':  true,
 
31
        'B':  true,
 
32
        'C':  true,
 
33
        'D':  true,
 
34
        'E':  true,
 
35
        'F':  true,
 
36
        'G':  true,
 
37
        'H':  true,
 
38
        'I':  true,
 
39
        'J':  true,
 
40
        'K':  true,
 
41
        'L':  true,
 
42
        'M':  true,
 
43
        'N':  true,
 
44
        'O':  true,
 
45
        'P':  true,
 
46
        'Q':  true,
 
47
        'R':  true,
 
48
        'S':  true,
 
49
        'T':  true,
 
50
        'U':  true,
 
51
        'W':  true,
 
52
        'V':  true,
 
53
        'X':  true,
 
54
        'Y':  true,
 
55
        'Z':  true,
 
56
        '^':  true,
 
57
        '_':  true,
 
58
        '`':  true,
 
59
        'a':  true,
 
60
        'b':  true,
 
61
        'c':  true,
 
62
        'd':  true,
 
63
        'e':  true,
 
64
        'f':  true,
 
65
        'g':  true,
 
66
        'h':  true,
 
67
        'i':  true,
 
68
        'j':  true,
 
69
        'k':  true,
 
70
        'l':  true,
 
71
        'm':  true,
 
72
        'n':  true,
 
73
        'o':  true,
 
74
        'p':  true,
 
75
        'q':  true,
 
76
        'r':  true,
 
77
        's':  true,
 
78
        't':  true,
 
79
        'u':  true,
 
80
        'v':  true,
 
81
        'w':  true,
 
82
        'x':  true,
 
83
        'y':  true,
 
84
        'z':  true,
 
85
        '|':  true,
 
86
        '~':  true,
 
87
}
 
88
 
 
89
func isToken(r rune) bool {
 
90
        i := int(r)
 
91
        return i < len(isTokenTable) && isTokenTable[i]
 
92
}
 
93
 
 
94
func isNotToken(r rune) bool {
 
95
        return !isToken(r)
136
96
}