diff options
Diffstat (limited to 'vendor/golang.org/x/net/http2/hpack')
-rw-r--r-- | vendor/golang.org/x/net/http2/hpack/encode.go | 240 | ||||
-rw-r--r-- | vendor/golang.org/x/net/http2/hpack/hpack.go | 490 | ||||
-rw-r--r-- | vendor/golang.org/x/net/http2/hpack/huffman.go | 212 | ||||
-rw-r--r-- | vendor/golang.org/x/net/http2/hpack/tables.go | 479 |
4 files changed, 1421 insertions, 0 deletions
diff --git a/vendor/golang.org/x/net/http2/hpack/encode.go b/vendor/golang.org/x/net/http2/hpack/encode.go new file mode 100644 index 0000000..54726c2 --- /dev/null +++ b/vendor/golang.org/x/net/http2/hpack/encode.go | |||
@@ -0,0 +1,240 @@ | |||
1 | // Copyright 2014 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. | ||
4 | |||
5 | package hpack | ||
6 | |||
7 | import ( | ||
8 | "io" | ||
9 | ) | ||
10 | |||
11 | const ( | ||
12 | uint32Max = ^uint32(0) | ||
13 | initialHeaderTableSize = 4096 | ||
14 | ) | ||
15 | |||
16 | type Encoder struct { | ||
17 | dynTab dynamicTable | ||
18 | // minSize is the minimum table size set by | ||
19 | // SetMaxDynamicTableSize after the previous Header Table Size | ||
20 | // Update. | ||
21 | minSize uint32 | ||
22 | // maxSizeLimit is the maximum table size this encoder | ||
23 | // supports. This will protect the encoder from too large | ||
24 | // size. | ||
25 | maxSizeLimit uint32 | ||
26 | // tableSizeUpdate indicates whether "Header Table Size | ||
27 | // Update" is required. | ||
28 | tableSizeUpdate bool | ||
29 | w io.Writer | ||
30 | buf []byte | ||
31 | } | ||
32 | |||
33 | // NewEncoder returns a new Encoder which performs HPACK encoding. An | ||
34 | // encoded data is written to w. | ||
35 | func NewEncoder(w io.Writer) *Encoder { | ||
36 | e := &Encoder{ | ||
37 | minSize: uint32Max, | ||
38 | maxSizeLimit: initialHeaderTableSize, | ||
39 | tableSizeUpdate: false, | ||
40 | w: w, | ||
41 | } | ||
42 | e.dynTab.table.init() | ||
43 | e.dynTab.setMaxSize(initialHeaderTableSize) | ||
44 | return e | ||
45 | } | ||
46 | |||
47 | // WriteField encodes f into a single Write to e's underlying Writer. | ||
48 | // This function may also produce bytes for "Header Table Size Update" | ||
49 | // if necessary. If produced, it is done before encoding f. | ||
50 | func (e *Encoder) WriteField(f HeaderField) error { | ||
51 | e.buf = e.buf[:0] | ||
52 | |||
53 | if e.tableSizeUpdate { | ||
54 | e.tableSizeUpdate = false | ||
55 | if e.minSize < e.dynTab.maxSize { | ||
56 | e.buf = appendTableSize(e.buf, e.minSize) | ||
57 | } | ||
58 | e.minSize = uint32Max | ||
59 | e.buf = appendTableSize(e.buf, e.dynTab.maxSize) | ||
60 | } | ||
61 | |||
62 | idx, nameValueMatch := e.searchTable(f) | ||
63 | if nameValueMatch { | ||
64 | e.buf = appendIndexed(e.buf, idx) | ||
65 | } else { | ||
66 | indexing := e.shouldIndex(f) | ||
67 | if indexing { | ||
68 | e.dynTab.add(f) | ||
69 | } | ||
70 | |||
71 | if idx == 0 { | ||
72 | e.buf = appendNewName(e.buf, f, indexing) | ||
73 | } else { | ||
74 | e.buf = appendIndexedName(e.buf, f, idx, indexing) | ||
75 | } | ||
76 | } | ||
77 | n, err := e.w.Write(e.buf) | ||
78 | if err == nil && n != len(e.buf) { | ||
79 | err = io.ErrShortWrite | ||
80 | } | ||
81 | return err | ||
82 | } | ||
83 | |||
84 | // searchTable searches f in both stable and dynamic header tables. | ||
85 | // The static header table is searched first. Only when there is no | ||
86 | // exact match for both name and value, the dynamic header table is | ||
87 | // then searched. If there is no match, i is 0. If both name and value | ||
88 | // match, i is the matched index and nameValueMatch becomes true. If | ||
89 | // only name matches, i points to that index and nameValueMatch | ||
90 | // becomes false. | ||
91 | func (e *Encoder) searchTable(f HeaderField) (i uint64, nameValueMatch bool) { | ||
92 | i, nameValueMatch = staticTable.search(f) | ||
93 | if nameValueMatch { | ||
94 | return i, true | ||
95 | } | ||
96 | |||
97 | j, nameValueMatch := e.dynTab.table.search(f) | ||
98 | if nameValueMatch || (i == 0 && j != 0) { | ||
99 | return j + uint64(staticTable.len()), nameValueMatch | ||
100 | } | ||
101 | |||
102 | return i, false | ||
103 | } | ||
104 | |||
105 | // SetMaxDynamicTableSize changes the dynamic header table size to v. | ||
106 | // The actual size is bounded by the value passed to | ||
107 | // SetMaxDynamicTableSizeLimit. | ||
108 | func (e *Encoder) SetMaxDynamicTableSize(v uint32) { | ||
109 | if v > e.maxSizeLimit { | ||
110 | v = e.maxSizeLimit | ||
111 | } | ||
112 | if v < e.minSize { | ||
113 | e.minSize = v | ||
114 | } | ||
115 | e.tableSizeUpdate = true | ||
116 | e.dynTab.setMaxSize(v) | ||
117 | } | ||
118 | |||
119 | // SetMaxDynamicTableSizeLimit changes the maximum value that can be | ||
120 | // specified in SetMaxDynamicTableSize to v. By default, it is set to | ||
121 | // 4096, which is the same size of the default dynamic header table | ||
122 | // size described in HPACK specification. If the current maximum | ||
123 | // dynamic header table size is strictly greater than v, "Header Table | ||
124 | // Size Update" will be done in the next WriteField call and the | ||
125 | // maximum dynamic header table size is truncated to v. | ||
126 | func (e *Encoder) SetMaxDynamicTableSizeLimit(v uint32) { | ||
127 | e.maxSizeLimit = v | ||
128 | if e.dynTab.maxSize > v { | ||
129 | e.tableSizeUpdate = true | ||
130 | e.dynTab.setMaxSize(v) | ||
131 | } | ||
132 | } | ||
133 | |||
134 | // shouldIndex reports whether f should be indexed. | ||
135 | func (e *Encoder) shouldIndex(f HeaderField) bool { | ||
136 | return !f.Sensitive && f.Size() <= e.dynTab.maxSize | ||
137 | } | ||
138 | |||
139 | // appendIndexed appends index i, as encoded in "Indexed Header Field" | ||
140 | // representation, to dst and returns the extended buffer. | ||
141 | func appendIndexed(dst []byte, i uint64) []byte { | ||
142 | first := len(dst) | ||
143 | dst = appendVarInt(dst, 7, i) | ||
144 | dst[first] |= 0x80 | ||
145 | return dst | ||
146 | } | ||
147 | |||
148 | // appendNewName appends f, as encoded in one of "Literal Header field | ||
149 | // - New Name" representation variants, to dst and returns the | ||
150 | // extended buffer. | ||
151 | // | ||
152 | // If f.Sensitive is true, "Never Indexed" representation is used. If | ||
153 | // f.Sensitive is false and indexing is true, "Inremental Indexing" | ||
154 | // representation is used. | ||
155 | func appendNewName(dst []byte, f HeaderField, indexing bool) []byte { | ||
156 | dst = append(dst, encodeTypeByte(indexing, f.Sensitive)) | ||
157 | dst = appendHpackString(dst, f.Name) | ||
158 | return appendHpackString(dst, f.Value) | ||
159 | } | ||
160 | |||
161 | // appendIndexedName appends f and index i referring indexed name | ||
162 | // entry, as encoded in one of "Literal Header field - Indexed Name" | ||
163 | // representation variants, to dst and returns the extended buffer. | ||
164 | // | ||
165 | // If f.Sensitive is true, "Never Indexed" representation is used. If | ||
166 | // f.Sensitive is false and indexing is true, "Incremental Indexing" | ||
167 | // representation is used. | ||
168 | func appendIndexedName(dst []byte, f HeaderField, i uint64, indexing bool) []byte { | ||
169 | first := len(dst) | ||
170 | var n byte | ||
171 | if indexing { | ||
172 | n = 6 | ||
173 | } else { | ||
174 | n = 4 | ||
175 | } | ||
176 | dst = appendVarInt(dst, n, i) | ||
177 | dst[first] |= encodeTypeByte(indexing, f.Sensitive) | ||
178 | return appendHpackString(dst, f.Value) | ||
179 | } | ||
180 | |||
181 | // appendTableSize appends v, as encoded in "Header Table Size Update" | ||
182 | // representation, to dst and returns the extended buffer. | ||
183 | func appendTableSize(dst []byte, v uint32) []byte { | ||
184 | first := len(dst) | ||
185 | dst = appendVarInt(dst, 5, uint64(v)) | ||
186 | dst[first] |= 0x20 | ||
187 | return dst | ||
188 | } | ||
189 | |||
190 | // appendVarInt appends i, as encoded in variable integer form using n | ||
191 | // bit prefix, to dst and returns the extended buffer. | ||
192 | // | ||
193 | // See | ||
194 | // http://http2.github.io/http2-spec/compression.html#integer.representation | ||
195 | func appendVarInt(dst []byte, n byte, i uint64) []byte { | ||
196 | k := uint64((1 << n) - 1) | ||
197 | if i < k { | ||
198 | return append(dst, byte(i)) | ||
199 | } | ||
200 | dst = append(dst, byte(k)) | ||
201 | i -= k | ||
202 | for ; i >= 128; i >>= 7 { | ||
203 | dst = append(dst, byte(0x80|(i&0x7f))) | ||
204 | } | ||
205 | return append(dst, byte(i)) | ||
206 | } | ||
207 | |||
208 | // appendHpackString appends s, as encoded in "String Literal" | ||
209 | // representation, to dst and returns the the extended buffer. | ||
210 | // | ||
211 | // s will be encoded in Huffman codes only when it produces strictly | ||
212 | // shorter byte string. | ||
213 | func appendHpackString(dst []byte, s string) []byte { | ||
214 | huffmanLength := HuffmanEncodeLength(s) | ||
215 | if huffmanLength < uint64(len(s)) { | ||
216 | first := len(dst) | ||
217 | dst = appendVarInt(dst, 7, huffmanLength) | ||
218 | dst = AppendHuffmanString(dst, s) | ||
219 | dst[first] |= 0x80 | ||
220 | } else { | ||
221 | dst = appendVarInt(dst, 7, uint64(len(s))) | ||
222 | dst = append(dst, s...) | ||
223 | } | ||
224 | return dst | ||
225 | } | ||
226 | |||
227 | // encodeTypeByte returns type byte. If sensitive is true, type byte | ||
228 | // for "Never Indexed" representation is returned. If sensitive is | ||
229 | // false and indexing is true, type byte for "Incremental Indexing" | ||
230 | // representation is returned. Otherwise, type byte for "Without | ||
231 | // Indexing" is returned. | ||
232 | func encodeTypeByte(indexing, sensitive bool) byte { | ||
233 | if sensitive { | ||
234 | return 0x10 | ||
235 | } | ||
236 | if indexing { | ||
237 | return 0x40 | ||
238 | } | ||
239 | return 0 | ||
240 | } | ||
diff --git a/vendor/golang.org/x/net/http2/hpack/hpack.go b/vendor/golang.org/x/net/http2/hpack/hpack.go new file mode 100644 index 0000000..176644a --- /dev/null +++ b/vendor/golang.org/x/net/http2/hpack/hpack.go | |||
@@ -0,0 +1,490 @@ | |||
1 | // Copyright 2014 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. | ||
4 | |||
5 | // Package hpack implements HPACK, a compression format for | ||
6 | // efficiently representing HTTP header fields in the context of HTTP/2. | ||
7 | // | ||
8 | // See http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-09 | ||
9 | package hpack | ||
10 | |||
11 | import ( | ||
12 | "bytes" | ||
13 | "errors" | ||
14 | "fmt" | ||
15 | ) | ||
16 | |||
17 | // A DecodingError is something the spec defines as a decoding error. | ||
18 | type DecodingError struct { | ||
19 | Err error | ||
20 | } | ||
21 | |||
22 | func (de DecodingError) Error() string { | ||
23 | return fmt.Sprintf("decoding error: %v", de.Err) | ||
24 | } | ||
25 | |||
26 | // An InvalidIndexError is returned when an encoder references a table | ||
27 | // entry before the static table or after the end of the dynamic table. | ||
28 | type InvalidIndexError int | ||
29 | |||
30 | func (e InvalidIndexError) Error() string { | ||
31 | return fmt.Sprintf("invalid indexed representation index %d", int(e)) | ||
32 | } | ||
33 | |||
34 | // A HeaderField is a name-value pair. Both the name and value are | ||
35 | // treated as opaque sequences of octets. | ||
36 | type HeaderField struct { | ||
37 | Name, Value string | ||
38 | |||
39 | // Sensitive means that this header field should never be | ||
40 | // indexed. | ||
41 | Sensitive bool | ||
42 | } | ||
43 | |||
44 | // IsPseudo reports whether the header field is an http2 pseudo header. | ||
45 | // That is, it reports whether it starts with a colon. | ||
46 | // It is not otherwise guaranteed to be a valid pseudo header field, | ||
47 | // though. | ||
48 | func (hf HeaderField) IsPseudo() bool { | ||
49 | return len(hf.Name) != 0 && hf.Name[0] == ':' | ||
50 | } | ||
51 | |||
52 | func (hf HeaderField) String() string { | ||
53 | var suffix string | ||
54 | if hf.Sensitive { | ||
55 | suffix = " (sensitive)" | ||
56 | } | ||
57 | return fmt.Sprintf("header field %q = %q%s", hf.Name, hf.Value, suffix) | ||
58 | } | ||
59 | |||
60 | // Size returns the size of an entry per RFC 7541 section 4.1. | ||
61 | func (hf HeaderField) Size() uint32 { | ||
62 | // http://http2.github.io/http2-spec/compression.html#rfc.section.4.1 | ||
63 | // "The size of the dynamic table is the sum of the size of | ||
64 | // its entries. The size of an entry is the sum of its name's | ||
65 | // length in octets (as defined in Section 5.2), its value's | ||
66 | // length in octets (see Section 5.2), plus 32. The size of | ||
67 | // an entry is calculated using the length of the name and | ||
68 | // value without any Huffman encoding applied." | ||
69 | |||
70 | // This can overflow if somebody makes a large HeaderField | ||
71 | // Name and/or Value by hand, but we don't care, because that | ||
72 | // won't happen on the wire because the encoding doesn't allow | ||
73 | // it. | ||
74 | return uint32(len(hf.Name) + len(hf.Value) + 32) | ||
75 | } | ||
76 | |||
77 | // A Decoder is the decoding context for incremental processing of | ||
78 | // header blocks. | ||
79 | type Decoder struct { | ||
80 | dynTab dynamicTable | ||
81 | emit func(f HeaderField) | ||
82 | |||
83 | emitEnabled bool // whether calls to emit are enabled | ||
84 | maxStrLen int // 0 means unlimited | ||
85 | |||
86 | // buf is the unparsed buffer. It's only written to | ||
87 | // saveBuf if it was truncated in the middle of a header | ||
88 | // block. Because it's usually not owned, we can only | ||
89 | // process it under Write. | ||
90 | buf []byte // not owned; only valid during Write | ||
91 | |||
92 | // saveBuf is previous data passed to Write which we weren't able | ||
93 | // to fully parse before. Unlike buf, we own this data. | ||
94 | saveBuf bytes.Buffer | ||
95 | } | ||
96 | |||
97 | // NewDecoder returns a new decoder with the provided maximum dynamic | ||
98 | // table size. The emitFunc will be called for each valid field | ||
99 | // parsed, in the same goroutine as calls to Write, before Write returns. | ||
100 | func NewDecoder(maxDynamicTableSize uint32, emitFunc func(f HeaderField)) *Decoder { | ||
101 | d := &Decoder{ | ||
102 | emit: emitFunc, | ||
103 | emitEnabled: true, | ||
104 | } | ||
105 | d.dynTab.table.init() | ||
106 | d.dynTab.allowedMaxSize = maxDynamicTableSize | ||
107 | d.dynTab.setMaxSize(maxDynamicTableSize) | ||
108 | return d | ||
109 | } | ||
110 | |||
111 | // ErrStringLength is returned by Decoder.Write when the max string length | ||
112 | // (as configured by Decoder.SetMaxStringLength) would be violated. | ||
113 | var ErrStringLength = errors.New("hpack: string too long") | ||
114 | |||
115 | // SetMaxStringLength sets the maximum size of a HeaderField name or | ||
116 | // value string. If a string exceeds this length (even after any | ||
117 | // decompression), Write will return ErrStringLength. | ||
118 | // A value of 0 means unlimited and is the default from NewDecoder. | ||
119 | func (d *Decoder) SetMaxStringLength(n int) { | ||
120 | d.maxStrLen = n | ||
121 | } | ||
122 | |||
123 | // SetEmitFunc changes the callback used when new header fields | ||
124 | // are decoded. | ||
125 | // It must be non-nil. It does not affect EmitEnabled. | ||
126 | func (d *Decoder) SetEmitFunc(emitFunc func(f HeaderField)) { | ||
127 | d.emit = emitFunc | ||
128 | } | ||
129 | |||
130 | // SetEmitEnabled controls whether the emitFunc provided to NewDecoder | ||
131 | // should be called. The default is true. | ||
132 | // | ||
133 | // This facility exists to let servers enforce MAX_HEADER_LIST_SIZE | ||
134 | // while still decoding and keeping in-sync with decoder state, but | ||
135 | // without doing unnecessary decompression or generating unnecessary | ||
136 | // garbage for header fields past the limit. | ||
137 | func (d *Decoder) SetEmitEnabled(v bool) { d.emitEnabled = v } | ||
138 | |||
139 | // EmitEnabled reports whether calls to the emitFunc provided to NewDecoder | ||
140 | // are currently enabled. The default is true. | ||
141 | func (d *Decoder) EmitEnabled() bool { return d.emitEnabled } | ||
142 | |||
143 | // TODO: add method *Decoder.Reset(maxSize, emitFunc) to let callers re-use Decoders and their | ||
144 | // underlying buffers for garbage reasons. | ||
145 | |||
146 | func (d *Decoder) SetMaxDynamicTableSize(v uint32) { | ||
147 | d.dynTab.setMaxSize(v) | ||
148 | } | ||
149 | |||
150 | // SetAllowedMaxDynamicTableSize sets the upper bound that the encoded | ||
151 | // stream (via dynamic table size updates) may set the maximum size | ||
152 | // to. | ||
153 | func (d *Decoder) SetAllowedMaxDynamicTableSize(v uint32) { | ||
154 | d.dynTab.allowedMaxSize = v | ||
155 | } | ||
156 | |||
157 | type dynamicTable struct { | ||
158 | // http://http2.github.io/http2-spec/compression.html#rfc.section.2.3.2 | ||
159 | table headerFieldTable | ||
160 | size uint32 // in bytes | ||
161 | maxSize uint32 // current maxSize | ||
162 | allowedMaxSize uint32 // maxSize may go up to this, inclusive | ||
163 | } | ||
164 | |||
165 | func (dt *dynamicTable) setMaxSize(v uint32) { | ||
166 | dt.maxSize = v | ||
167 | dt.evict() | ||
168 | } | ||
169 | |||
170 | func (dt *dynamicTable) add(f HeaderField) { | ||
171 | dt.table.addEntry(f) | ||
172 | dt.size += f.Size() | ||
173 | dt.evict() | ||
174 | } | ||
175 | |||
176 | // If we're too big, evict old stuff. | ||
177 | func (dt *dynamicTable) evict() { | ||
178 | var n int | ||
179 | for dt.size > dt.maxSize && n < dt.table.len() { | ||
180 | dt.size -= dt.table.ents[n].Size() | ||
181 | n++ | ||
182 | } | ||
183 | dt.table.evictOldest(n) | ||
184 | } | ||
185 | |||
186 | func (d *Decoder) maxTableIndex() int { | ||
187 | // This should never overflow. RFC 7540 Section 6.5.2 limits the size of | ||
188 | // the dynamic table to 2^32 bytes, where each entry will occupy more than | ||
189 | // one byte. Further, the staticTable has a fixed, small length. | ||
190 | return d.dynTab.table.len() + staticTable.len() | ||
191 | } | ||
192 | |||
193 | func (d *Decoder) at(i uint64) (hf HeaderField, ok bool) { | ||
194 | // See Section 2.3.3. | ||
195 | if i == 0 { | ||
196 | return | ||
197 | } | ||
198 | if i <= uint64(staticTable.len()) { | ||
199 | return staticTable.ents[i-1], true | ||
200 | } | ||
201 | if i > uint64(d.maxTableIndex()) { | ||
202 | return | ||
203 | } | ||
204 | // In the dynamic table, newer entries have lower indices. | ||
205 | // However, dt.ents[0] is the oldest entry. Hence, dt.ents is | ||
206 | // the reversed dynamic table. | ||
207 | dt := d.dynTab.table | ||
208 | return dt.ents[dt.len()-(int(i)-staticTable.len())], true | ||
209 | } | ||
210 | |||
211 | // Decode decodes an entire block. | ||
212 | // | ||
213 | // TODO: remove this method and make it incremental later? This is | ||
214 | // easier for debugging now. | ||
215 | func (d *Decoder) DecodeFull(p []byte) ([]HeaderField, error) { | ||
216 | var hf []HeaderField | ||
217 | saveFunc := d.emit | ||
218 | defer func() { d.emit = saveFunc }() | ||
219 | d.emit = func(f HeaderField) { hf = append(hf, f) } | ||
220 | if _, err := d.Write(p); err != nil { | ||
221 | return nil, err | ||
222 | } | ||
223 | if err := d.Close(); err != nil { | ||
224 | return nil, err | ||
225 | } | ||
226 | return hf, nil | ||
227 | } | ||
228 | |||
229 | func (d *Decoder) Close() error { | ||
230 | if d.saveBuf.Len() > 0 { | ||
231 | d.saveBuf.Reset() | ||
232 | return DecodingError{errors.New("truncated headers")} | ||
233 | } | ||
234 | return nil | ||
235 | } | ||
236 | |||
237 | func (d *Decoder) Write(p []byte) (n int, err error) { | ||
238 | if len(p) == 0 { | ||
239 | // Prevent state machine CPU attacks (making us redo | ||
240 | // work up to the point of finding out we don't have | ||
241 | // enough data) | ||
242 | return | ||
243 | } | ||
244 | // Only copy the data if we have to. Optimistically assume | ||
245 | // that p will contain a complete header block. | ||
246 | if d.saveBuf.Len() == 0 { | ||
247 | d.buf = p | ||
248 | } else { | ||
249 | d.saveBuf.Write(p) | ||
250 | d.buf = d.saveBuf.Bytes() | ||
251 | d.saveBuf.Reset() | ||
252 | } | ||
253 | |||
254 | for len(d.buf) > 0 { | ||
255 | err = d.parseHeaderFieldRepr() | ||
256 | if err == errNeedMore { | ||
257 | // Extra paranoia, making sure saveBuf won't | ||
258 | // get too large. All the varint and string | ||
259 | // reading code earlier should already catch | ||
260 | // overlong things and return ErrStringLength, | ||
261 | // but keep this as a last resort. | ||
262 | const varIntOverhead = 8 // conservative | ||
263 | if d.maxStrLen != 0 && int64(len(d.buf)) > 2*(int64(d.maxStrLen)+varIntOverhead) { | ||
264 | return 0, ErrStringLength | ||
265 | } | ||
266 | d.saveBuf.Write(d.buf) | ||
267 | return len(p), nil | ||
268 | } | ||
269 | if err != nil { | ||
270 | break | ||
271 | } | ||
272 | } | ||
273 | return len(p), err | ||
274 | } | ||
275 | |||
276 | // errNeedMore is an internal sentinel error value that means the | ||
277 | // buffer is truncated and we need to read more data before we can | ||
278 | // continue parsing. | ||
279 | var errNeedMore = errors.New("need more data") | ||
280 | |||
281 | type indexType int | ||
282 | |||
283 | const ( | ||
284 | indexedTrue indexType = iota | ||
285 | indexedFalse | ||
286 | indexedNever | ||
287 | ) | ||
288 | |||
289 | func (v indexType) indexed() bool { return v == indexedTrue } | ||
290 | func (v indexType) sensitive() bool { return v == indexedNever } | ||
291 | |||
292 | // returns errNeedMore if there isn't enough data available. | ||
293 | // any other error is fatal. | ||
294 | // consumes d.buf iff it returns nil. | ||
295 | // precondition: must be called with len(d.buf) > 0 | ||
296 | func (d *Decoder) parseHeaderFieldRepr() error { | ||
297 | b := d.buf[0] | ||
298 | switch { | ||
299 | case b&128 != 0: | ||
300 | // Indexed representation. | ||
301 | // High bit set? | ||
302 | // http://http2.github.io/http2-spec/compression.html#rfc.section.6.1 | ||
303 | return d.parseFieldIndexed() | ||
304 | case b&192 == 64: | ||
305 | // 6.2.1 Literal Header Field with Incremental Indexing | ||
306 | // 0b10xxxxxx: top two bits are 10 | ||
307 | // http://http2.github.io/http2-spec/compression.html#rfc.section.6.2.1 | ||
308 | return d.parseFieldLiteral(6, indexedTrue) | ||
309 | case b&240 == 0: | ||
310 | // 6.2.2 Literal Header Field without Indexing | ||
311 | // 0b0000xxxx: top four bits are 0000 | ||
312 | // http://http2.github.io/http2-spec/compression.html#rfc.section.6.2.2 | ||
313 | return d.parseFieldLiteral(4, indexedFalse) | ||
314 | case b&240 == 16: | ||
315 | // 6.2.3 Literal Header Field never Indexed | ||
316 | // 0b0001xxxx: top four bits are 0001 | ||
317 | // http://http2.github.io/http2-spec/compression.html#rfc.section.6.2.3 | ||
318 | return d.parseFieldLiteral(4, indexedNever) | ||
319 | case b&224 == 32: | ||
320 | // 6.3 Dynamic Table Size Update | ||
321 | // Top three bits are '001'. | ||
322 | // http://http2.github.io/http2-spec/compression.html#rfc.section.6.3 | ||
323 | return d.parseDynamicTableSizeUpdate() | ||
324 | } | ||
325 | |||
326 | return DecodingError{errors.New("invalid encoding")} | ||
327 | } | ||
328 | |||
329 | // (same invariants and behavior as parseHeaderFieldRepr) | ||
330 | func (d *Decoder) parseFieldIndexed() error { | ||
331 | buf := d.buf | ||
332 | idx, buf, err := readVarInt(7, buf) | ||
333 | if err != nil { | ||
334 | return err | ||
335 | } | ||
336 | hf, ok := d.at(idx) | ||
337 | if !ok { | ||
338 | return DecodingError{InvalidIndexError(idx)} | ||
339 | } | ||
340 | d.buf = buf | ||
341 | return d.callEmit(HeaderField{Name: hf.Name, Value: hf.Value}) | ||
342 | } | ||
343 | |||
344 | // (same invariants and behavior as parseHeaderFieldRepr) | ||
345 | func (d *Decoder) parseFieldLiteral(n uint8, it indexType) error { | ||
346 | buf := d.buf | ||
347 | nameIdx, buf, err := readVarInt(n, buf) | ||
348 | if err != nil { | ||
349 | return err | ||
350 | } | ||
351 | |||
352 | var hf HeaderField | ||
353 | wantStr := d.emitEnabled || it.indexed() | ||
354 | if nameIdx > 0 { | ||
355 | ihf, ok := d.at(nameIdx) | ||
356 | if !ok { | ||
357 | return DecodingError{InvalidIndexError(nameIdx)} | ||
358 | } | ||
359 | hf.Name = ihf.Name | ||
360 | } else { | ||
361 | hf.Name, buf, err = d.readString(buf, wantStr) | ||
362 | if err != nil { | ||
363 | return err | ||
364 | } | ||
365 | } | ||
366 | hf.Value, buf, err = d.readString(buf, wantStr) | ||
367 | if err != nil { | ||
368 | return err | ||
369 | } | ||
370 | d.buf = buf | ||
371 | if it.indexed() { | ||
372 | d.dynTab.add(hf) | ||
373 | } | ||
374 | hf.Sensitive = it.sensitive() | ||
375 | return d.callEmit(hf) | ||
376 | } | ||
377 | |||
378 | func (d *Decoder) callEmit(hf HeaderField) error { | ||
379 | if d.maxStrLen != 0 { | ||
380 | if len(hf.Name) > d.maxStrLen || len(hf.Value) > d.maxStrLen { | ||
381 | return ErrStringLength | ||
382 | } | ||
383 | } | ||
384 | if d.emitEnabled { | ||
385 | d.emit(hf) | ||
386 | } | ||
387 | return nil | ||
388 | } | ||
389 | |||
390 | // (same invariants and behavior as parseHeaderFieldRepr) | ||
391 | func (d *Decoder) parseDynamicTableSizeUpdate() error { | ||
392 | buf := d.buf | ||
393 | size, buf, err := readVarInt(5, buf) | ||
394 | if err != nil { | ||
395 | return err | ||
396 | } | ||
397 | if size > uint64(d.dynTab.allowedMaxSize) { | ||
398 | return DecodingError{errors.New("dynamic table size update too large")} | ||
399 | } | ||
400 | d.dynTab.setMaxSize(uint32(size)) | ||
401 | d.buf = buf | ||
402 | return nil | ||
403 | } | ||
404 | |||
405 | var errVarintOverflow = DecodingError{errors.New("varint integer overflow")} | ||
406 | |||
407 | // readVarInt reads an unsigned variable length integer off the | ||
408 | // beginning of p. n is the parameter as described in | ||
409 | // http://http2.github.io/http2-spec/compression.html#rfc.section.5.1. | ||
410 | // | ||
411 | // n must always be between 1 and 8. | ||
412 | // | ||
413 | // The returned remain buffer is either a smaller suffix of p, or err != nil. | ||
414 | // The error is errNeedMore if p doesn't contain a complete integer. | ||
415 | func readVarInt(n byte, p []byte) (i uint64, remain []byte, err error) { | ||
416 | if n < 1 || n > 8 { | ||
417 | panic("bad n") | ||
418 | } | ||
419 | if len(p) == 0 { | ||
420 | return 0, p, errNeedMore | ||
421 | } | ||
422 | i = uint64(p[0]) | ||
423 | if n < 8 { | ||
424 | i &= (1 << uint64(n)) - 1 | ||
425 | } | ||
426 | if i < (1<<uint64(n))-1 { | ||
427 | return i, p[1:], nil | ||
428 | } | ||
429 | |||
430 | origP := p | ||
431 | p = p[1:] | ||
432 | var m uint64 | ||
433 | for len(p) > 0 { | ||
434 | b := p[0] | ||
435 | p = p[1:] | ||
436 | i += uint64(b&127) << m | ||
437 | if b&128 == 0 { | ||
438 | return i, p, nil | ||
439 | } | ||
440 | m += 7 | ||
441 | if m >= 63 { // TODO: proper overflow check. making this up. | ||
442 | return 0, origP, errVarintOverflow | ||
443 | } | ||
444 | } | ||
445 | return 0, origP, errNeedMore | ||
446 | } | ||
447 | |||
448 | // readString decodes an hpack string from p. | ||
449 | // | ||
450 | // wantStr is whether s will be used. If false, decompression and | ||
451 | // []byte->string garbage are skipped if s will be ignored | ||
452 | // anyway. This does mean that huffman decoding errors for non-indexed | ||
453 | // strings past the MAX_HEADER_LIST_SIZE are ignored, but the server | ||
454 | // is returning an error anyway, and because they're not indexed, the error | ||
455 | // won't affect the decoding state. | ||
456 | func (d *Decoder) readString(p []byte, wantStr bool) (s string, remain []byte, err error) { | ||
457 | if len(p) == 0 { | ||
458 | return "", p, errNeedMore | ||
459 | } | ||
460 | isHuff := p[0]&128 != 0 | ||
461 | strLen, p, err := readVarInt(7, p) | ||
462 | if err != nil { | ||
463 | return "", p, err | ||
464 | } | ||
465 | if d.maxStrLen != 0 && strLen > uint64(d.maxStrLen) { | ||
466 | return "", nil, ErrStringLength | ||
467 | } | ||
468 | if uint64(len(p)) < strLen { | ||
469 | return "", p, errNeedMore | ||
470 | } | ||
471 | if !isHuff { | ||
472 | if wantStr { | ||
473 | s = string(p[:strLen]) | ||
474 | } | ||
475 | return s, p[strLen:], nil | ||
476 | } | ||
477 | |||
478 | if wantStr { | ||
479 | buf := bufPool.Get().(*bytes.Buffer) | ||
480 | buf.Reset() // don't trust others | ||
481 | defer bufPool.Put(buf) | ||
482 | if err := huffmanDecode(buf, d.maxStrLen, p[:strLen]); err != nil { | ||
483 | buf.Reset() | ||
484 | return "", nil, err | ||
485 | } | ||
486 | s = buf.String() | ||
487 | buf.Reset() // be nice to GC | ||
488 | } | ||
489 | return s, p[strLen:], nil | ||
490 | } | ||
diff --git a/vendor/golang.org/x/net/http2/hpack/huffman.go b/vendor/golang.org/x/net/http2/hpack/huffman.go new file mode 100644 index 0000000..8850e39 --- /dev/null +++ b/vendor/golang.org/x/net/http2/hpack/huffman.go | |||
@@ -0,0 +1,212 @@ | |||
1 | // Copyright 2014 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. | ||
4 | |||
5 | package hpack | ||
6 | |||
7 | import ( | ||
8 | "bytes" | ||
9 | "errors" | ||
10 | "io" | ||
11 | "sync" | ||
12 | ) | ||
13 | |||
14 | var bufPool = sync.Pool{ | ||
15 | New: func() interface{} { return new(bytes.Buffer) }, | ||
16 | } | ||
17 | |||
18 | // HuffmanDecode decodes the string in v and writes the expanded | ||
19 | // result to w, returning the number of bytes written to w and the | ||
20 | // Write call's return value. At most one Write call is made. | ||
21 | func HuffmanDecode(w io.Writer, v []byte) (int, error) { | ||
22 | buf := bufPool.Get().(*bytes.Buffer) | ||
23 | buf.Reset() | ||
24 | defer bufPool.Put(buf) | ||
25 | if err := huffmanDecode(buf, 0, v); err != nil { | ||
26 | return 0, err | ||
27 | } | ||
28 | return w.Write(buf.Bytes()) | ||
29 | } | ||
30 | |||
31 | // HuffmanDecodeToString decodes the string in v. | ||
32 | func HuffmanDecodeToString(v []byte) (string, error) { | ||
33 | buf := bufPool.Get().(*bytes.Buffer) | ||
34 | buf.Reset() | ||
35 | defer bufPool.Put(buf) | ||
36 | if err := huffmanDecode(buf, 0, v); err != nil { | ||
37 | return "", err | ||
38 | } | ||
39 | return buf.String(), nil | ||
40 | } | ||
41 | |||
42 | // ErrInvalidHuffman is returned for errors found decoding | ||
43 | // Huffman-encoded strings. | ||
44 | var ErrInvalidHuffman = errors.New("hpack: invalid Huffman-encoded data") | ||
45 | |||
46 | // huffmanDecode decodes v to buf. | ||
47 | // If maxLen is greater than 0, attempts to write more to buf than | ||
48 | // maxLen bytes will return ErrStringLength. | ||
49 | func huffmanDecode(buf *bytes.Buffer, maxLen int, v []byte) error { | ||
50 | n := rootHuffmanNode | ||
51 | // cur is the bit buffer that has not been fed into n. | ||
52 | // cbits is the number of low order bits in cur that are valid. | ||
53 | // sbits is the number of bits of the symbol prefix being decoded. | ||
54 | cur, cbits, sbits := uint(0), uint8(0), uint8(0) | ||
55 | for _, b := range v { | ||
56 | cur = cur<<8 | uint(b) | ||
57 | cbits += 8 | ||
58 | sbits += 8 | ||
59 | for cbits >= 8 { | ||
60 | idx := byte(cur >> (cbits - 8)) | ||
61 | n = n.children[idx] | ||
62 | if n == nil { | ||
63 | return ErrInvalidHuffman | ||
64 | } | ||
65 | if n.children == nil { | ||
66 | if maxLen != 0 && buf.Len() == maxLen { | ||
67 | return ErrStringLength | ||
68 | } | ||
69 | buf.WriteByte(n.sym) | ||
70 | cbits -= n.codeLen | ||
71 | n = rootHuffmanNode | ||
72 | sbits = cbits | ||
73 | } else { | ||
74 | cbits -= 8 | ||
75 | } | ||
76 | } | ||
77 | } | ||
78 | for cbits > 0 { | ||
79 | n = n.children[byte(cur<<(8-cbits))] | ||
80 | if n == nil { | ||
81 | return ErrInvalidHuffman | ||
82 | } | ||
83 | if n.children != nil || n.codeLen > cbits { | ||
84 | break | ||
85 | } | ||
86 | if maxLen != 0 && buf.Len() == maxLen { | ||
87 | return ErrStringLength | ||
88 | } | ||
89 | buf.WriteByte(n.sym) | ||
90 | cbits -= n.codeLen | ||
91 | n = rootHuffmanNode | ||
92 | sbits = cbits | ||
93 | } | ||
94 | if sbits > 7 { | ||
95 | // Either there was an incomplete symbol, or overlong padding. | ||
96 | // Both are decoding errors per RFC 7541 section 5.2. | ||
97 | return ErrInvalidHuffman | ||
98 | } | ||
99 | if mask := uint(1<<cbits - 1); cur&mask != mask { | ||
100 | // Trailing bits must be a prefix of EOS per RFC 7541 section 5.2. | ||
101 | return ErrInvalidHuffman | ||
102 | } | ||
103 | |||
104 | return nil | ||
105 | } | ||
106 | |||
107 | type node struct { | ||
108 | // children is non-nil for internal nodes | ||
109 | children []*node | ||
110 | |||
111 | // The following are only valid if children is nil: | ||
112 | codeLen uint8 // number of bits that led to the output of sym | ||
113 | sym byte // output symbol | ||
114 | } | ||
115 | |||
116 | func newInternalNode() *node { | ||
117 | return &node{children: make([]*node, 256)} | ||
118 | } | ||
119 | |||
120 | var rootHuffmanNode = newInternalNode() | ||
121 | |||
122 | func init() { | ||
123 | if len(huffmanCodes) != 256 { | ||
124 | panic("unexpected size") | ||
125 | } | ||
126 | for i, code := range huffmanCodes { | ||
127 | addDecoderNode(byte(i), code, huffmanCodeLen[i]) | ||
128 | } | ||
129 | } | ||
130 | |||
131 | func addDecoderNode(sym byte, code uint32, codeLen uint8) { | ||
132 | cur := rootHuffmanNode | ||
133 | for codeLen > 8 { | ||
134 | codeLen -= 8 | ||
135 | i := uint8(code >> codeLen) | ||
136 | if cur.children[i] == nil { | ||
137 | cur.children[i] = newInternalNode() | ||
138 | } | ||
139 | cur = cur.children[i] | ||
140 | } | ||
141 | shift := 8 - codeLen | ||
142 | start, end := int(uint8(code<<shift)), int(1<<shift) | ||
143 | for i := start; i < start+end; i++ { | ||
144 | cur.children[i] = &node{sym: sym, codeLen: codeLen} | ||
145 | } | ||
146 | } | ||
147 | |||
148 | // AppendHuffmanString appends s, as encoded in Huffman codes, to dst | ||
149 | // and returns the extended buffer. | ||
150 | func AppendHuffmanString(dst []byte, s string) []byte { | ||
151 | rembits := uint8(8) | ||
152 | |||
153 | for i := 0; i < len(s); i++ { | ||
154 | if rembits == 8 { | ||
155 | dst = append(dst, 0) | ||
156 | } | ||
157 | dst, rembits = appendByteToHuffmanCode(dst, rembits, s[i]) | ||
158 | } | ||
159 | |||
160 | if rembits < 8 { | ||
161 | // special EOS symbol | ||
162 | code := uint32(0x3fffffff) | ||
163 | nbits := uint8(30) | ||
164 | |||
165 | t := uint8(code >> (nbits - rembits)) | ||
166 | dst[len(dst)-1] |= t | ||
167 | } | ||
168 | |||
169 | return dst | ||
170 | } | ||
171 | |||
172 | // HuffmanEncodeLength returns the number of bytes required to encode | ||
173 | // s in Huffman codes. The result is round up to byte boundary. | ||
174 | func HuffmanEncodeLength(s string) uint64 { | ||
175 | n := uint64(0) | ||
176 | for i := 0; i < len(s); i++ { | ||
177 | n += uint64(huffmanCodeLen[s[i]]) | ||
178 | } | ||
179 | return (n + 7) / 8 | ||
180 | } | ||
181 | |||
182 | // appendByteToHuffmanCode appends Huffman code for c to dst and | ||
183 | // returns the extended buffer and the remaining bits in the last | ||
184 | // element. The appending is not byte aligned and the remaining bits | ||
185 | // in the last element of dst is given in rembits. | ||
186 | func appendByteToHuffmanCode(dst []byte, rembits uint8, c byte) ([]byte, uint8) { | ||
187 | code := huffmanCodes[c] | ||
188 | nbits := huffmanCodeLen[c] | ||
189 | |||
190 | for { | ||
191 | if rembits > nbits { | ||
192 | t := uint8(code << (rembits - nbits)) | ||
193 | dst[len(dst)-1] |= t | ||
194 | rembits -= nbits | ||
195 | break | ||
196 | } | ||
197 | |||
198 | t := uint8(code >> (nbits - rembits)) | ||
199 | dst[len(dst)-1] |= t | ||
200 | |||
201 | nbits -= rembits | ||
202 | rembits = 8 | ||
203 | |||
204 | if nbits == 0 { | ||
205 | break | ||
206 | } | ||
207 | |||
208 | dst = append(dst, 0) | ||
209 | } | ||
210 | |||
211 | return dst, rembits | ||
212 | } | ||
diff --git a/vendor/golang.org/x/net/http2/hpack/tables.go b/vendor/golang.org/x/net/http2/hpack/tables.go new file mode 100644 index 0000000..a66cfbe --- /dev/null +++ b/vendor/golang.org/x/net/http2/hpack/tables.go | |||
@@ -0,0 +1,479 @@ | |||
1 | // Copyright 2014 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. | ||
4 | |||
5 | package hpack | ||
6 | |||
7 | import ( | ||
8 | "fmt" | ||
9 | ) | ||
10 | |||
11 | // headerFieldTable implements a list of HeaderFields. | ||
12 | // This is used to implement the static and dynamic tables. | ||
13 | type headerFieldTable struct { | ||
14 | // For static tables, entries are never evicted. | ||
15 | // | ||
16 | // For dynamic tables, entries are evicted from ents[0] and added to the end. | ||
17 | // Each entry has a unique id that starts at one and increments for each | ||
18 | // entry that is added. This unique id is stable across evictions, meaning | ||
19 | // it can be used as a pointer to a specific entry. As in hpack, unique ids | ||
20 | // are 1-based. The unique id for ents[k] is k + evictCount + 1. | ||
21 | // | ||
22 | // Zero is not a valid unique id. | ||
23 | // | ||
24 | // evictCount should not overflow in any remotely practical situation. In | ||
25 | // practice, we will have one dynamic table per HTTP/2 connection. If we | ||
26 | // assume a very powerful server that handles 1M QPS per connection and each | ||
27 | // request adds (then evicts) 100 entries from the table, it would still take | ||
28 | // 2M years for evictCount to overflow. | ||
29 | ents []HeaderField | ||
30 | evictCount uint64 | ||
31 | |||
32 | // byName maps a HeaderField name to the unique id of the newest entry with | ||
33 | // the same name. See above for a definition of "unique id". | ||
34 | byName map[string]uint64 | ||
35 | |||
36 | // byNameValue maps a HeaderField name/value pair to the unique id of the newest | ||
37 | // entry with the same name and value. See above for a definition of "unique id". | ||
38 | byNameValue map[pairNameValue]uint64 | ||
39 | } | ||
40 | |||
41 | type pairNameValue struct { | ||
42 | name, value string | ||
43 | } | ||
44 | |||
45 | func (t *headerFieldTable) init() { | ||
46 | t.byName = make(map[string]uint64) | ||
47 | t.byNameValue = make(map[pairNameValue]uint64) | ||
48 | } | ||
49 | |||
50 | // len reports the number of entries in the table. | ||
51 | func (t *headerFieldTable) len() int { | ||
52 | return len(t.ents) | ||
53 | } | ||
54 | |||
55 | // addEntry adds a new entry. | ||
56 | func (t *headerFieldTable) addEntry(f HeaderField) { | ||
57 | id := uint64(t.len()) + t.evictCount + 1 | ||
58 | t.byName[f.Name] = id | ||
59 | t.byNameValue[pairNameValue{f.Name, f.Value}] = id | ||
60 | t.ents = append(t.ents, f) | ||
61 | } | ||
62 | |||
63 | // evictOldest evicts the n oldest entries in the table. | ||
64 | func (t *headerFieldTable) evictOldest(n int) { | ||
65 | if n > t.len() { | ||
66 | panic(fmt.Sprintf("evictOldest(%v) on table with %v entries", n, t.len())) | ||
67 | } | ||
68 | for k := 0; k < n; k++ { | ||
69 | f := t.ents[k] | ||
70 | id := t.evictCount + uint64(k) + 1 | ||
71 | if t.byName[f.Name] == id { | ||
72 | delete(t.byName, f.Name) | ||
73 | } | ||
74 | if p := (pairNameValue{f.Name, f.Value}); t.byNameValue[p] == id { | ||
75 | delete(t.byNameValue, p) | ||
76 | } | ||
77 | } | ||
78 | copy(t.ents, t.ents[n:]) | ||
79 | for k := t.len() - n; k < t.len(); k++ { | ||
80 | t.ents[k] = HeaderField{} // so strings can be garbage collected | ||
81 | } | ||
82 | t.ents = t.ents[:t.len()-n] | ||
83 | if t.evictCount+uint64(n) < t.evictCount { | ||
84 | panic("evictCount overflow") | ||
85 | } | ||
86 | t.evictCount += uint64(n) | ||
87 | } | ||
88 | |||
89 | // search finds f in the table. If there is no match, i is 0. | ||
90 | // If both name and value match, i is the matched index and nameValueMatch | ||
91 | // becomes true. If only name matches, i points to that index and | ||
92 | // nameValueMatch becomes false. | ||
93 | // | ||
94 | // The returned index is a 1-based HPACK index. For dynamic tables, HPACK says | ||
95 | // that index 1 should be the newest entry, but t.ents[0] is the oldest entry, | ||
96 | // meaning t.ents is reversed for dynamic tables. Hence, when t is a dynamic | ||
97 | // table, the return value i actually refers to the entry t.ents[t.len()-i]. | ||
98 | // | ||
99 | // All tables are assumed to be a dynamic tables except for the global | ||
100 | // staticTable pointer. | ||
101 | // | ||
102 | // See Section 2.3.3. | ||
103 | func (t *headerFieldTable) search(f HeaderField) (i uint64, nameValueMatch bool) { | ||
104 | if !f.Sensitive { | ||
105 | if id := t.byNameValue[pairNameValue{f.Name, f.Value}]; id != 0 { | ||
106 | return t.idToIndex(id), true | ||
107 | } | ||
108 | } | ||
109 | if id := t.byName[f.Name]; id != 0 { | ||
110 | return t.idToIndex(id), false | ||
111 | } | ||
112 | return 0, false | ||
113 | } | ||
114 | |||
115 | // idToIndex converts a unique id to an HPACK index. | ||
116 | // See Section 2.3.3. | ||
117 | func (t *headerFieldTable) idToIndex(id uint64) uint64 { | ||
118 | if id <= t.evictCount { | ||
119 | panic(fmt.Sprintf("id (%v) <= evictCount (%v)", id, t.evictCount)) | ||
120 | } | ||
121 | k := id - t.evictCount - 1 // convert id to an index t.ents[k] | ||
122 | if t != staticTable { | ||
123 | return uint64(t.len()) - k // dynamic table | ||
124 | } | ||
125 | return k + 1 | ||
126 | } | ||
127 | |||
128 | // http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-07#appendix-B | ||
129 | var staticTable = newStaticTable() | ||
130 | var staticTableEntries = [...]HeaderField{ | ||
131 | {Name: ":authority"}, | ||
132 | {Name: ":method", Value: "GET"}, | ||
133 | {Name: ":method", Value: "POST"}, | ||
134 | {Name: ":path", Value: "/"}, | ||
135 | {Name: ":path", Value: "/index.html"}, | ||
136 | {Name: ":scheme", Value: "http"}, | ||
137 | {Name: ":scheme", Value: "https"}, | ||
138 | {Name: ":status", Value: "200"}, | ||
139 | {Name: ":status", Value: "204"}, | ||
140 | {Name: ":status", Value: "206"}, | ||
141 | {Name: ":status", Value: "304"}, | ||
142 | {Name: ":status", Value: "400"}, | ||
143 | {Name: ":status", Value: "404"}, | ||
144 | {Name: ":status", Value: "500"}, | ||
145 | {Name: "accept-charset"}, | ||
146 | {Name: "accept-encoding", Value: "gzip, deflate"}, | ||
147 | {Name: "accept-language"}, | ||
148 | {Name: "accept-ranges"}, | ||
149 | {Name: "accept"}, | ||
150 | {Name: "access-control-allow-origin"}, | ||
151 | {Name: "age"}, | ||
152 | {Name: "allow"}, | ||
153 | {Name: "authorization"}, | ||
154 | {Name: "cache-control"}, | ||
155 | {Name: "content-disposition"}, | ||
156 | {Name: "content-encoding"}, | ||
157 | {Name: "content-language"}, | ||
158 | {Name: "content-length"}, | ||
159 | {Name: "content-location"}, | ||
160 | {Name: "content-range"}, | ||
161 | {Name: "content-type"}, | ||
162 | {Name: "cookie"}, | ||
163 | {Name: "date"}, | ||
164 | {Name: "etag"}, | ||
165 | {Name: "expect"}, | ||
166 | {Name: "expires"}, | ||
167 | {Name: "from"}, | ||
168 | {Name: "host"}, | ||
169 | {Name: "if-match"}, | ||
170 | {Name: "if-modified-since"}, | ||
171 | {Name: "if-none-match"}, | ||
172 | {Name: "if-range"}, | ||
173 | {Name: "if-unmodified-since"}, | ||
174 | {Name: "last-modified"}, | ||
175 | {Name: "link"}, | ||
176 | {Name: "location"}, | ||
177 | {Name: "max-forwards"}, | ||
178 | {Name: "proxy-authenticate"}, | ||
179 | {Name: "proxy-authorization"}, | ||
180 | {Name: "range"}, | ||
181 | {Name: "referer"}, | ||
182 | {Name: "refresh"}, | ||
183 | {Name: "retry-after"}, | ||
184 | {Name: "server"}, | ||
185 | {Name: "set-cookie"}, | ||
186 | {Name: "strict-transport-security"}, | ||
187 | {Name: "transfer-encoding"}, | ||
188 | {Name: "user-agent"}, | ||
189 | {Name: "vary"}, | ||
190 | {Name: "via"}, | ||
191 | {Name: "www-authenticate"}, | ||
192 | } | ||
193 | |||
194 | func newStaticTable() *headerFieldTable { | ||
195 | t := &headerFieldTable{} | ||
196 | t.init() | ||
197 | for _, e := range staticTableEntries[:] { | ||
198 | t.addEntry(e) | ||
199 | } | ||
200 | return t | ||
201 | } | ||
202 | |||
203 | var huffmanCodes = [256]uint32{ | ||
204 | 0x1ff8, | ||
205 | 0x7fffd8, | ||
206 | 0xfffffe2, | ||
207 | 0xfffffe3, | ||
208 | 0xfffffe4, | ||
209 | 0xfffffe5, | ||
210 | 0xfffffe6, | ||
211 | 0xfffffe7, | ||
212 | 0xfffffe8, | ||
213 | 0xffffea, | ||
214 | 0x3ffffffc, | ||
215 | 0xfffffe9, | ||
216 | 0xfffffea, | ||
217 | 0x3ffffffd, | ||
218 | 0xfffffeb, | ||
219 | 0xfffffec, | ||
220 | 0xfffffed, | ||
221 | 0xfffffee, | ||
222 | 0xfffffef, | ||
223 | 0xffffff0, | ||
224 | 0xffffff1, | ||
225 | 0xffffff2, | ||
226 | 0x3ffffffe, | ||
227 | 0xffffff3, | ||
228 | 0xffffff4, | ||
229 | 0xffffff5, | ||
230 | 0xffffff6, | ||
231 | 0xffffff7, | ||
232 | 0xffffff8, | ||
233 | 0xffffff9, | ||
234 | 0xffffffa, | ||
235 | 0xffffffb, | ||
236 | 0x14, | ||
237 | 0x3f8, | ||
238 | 0x3f9, | ||
239 | 0xffa, | ||
240 | 0x1ff9, | ||
241 | 0x15, | ||
242 | 0xf8, | ||
243 | 0x7fa, | ||
244 | 0x3fa, | ||
245 | 0x3fb, | ||
246 | 0xf9, | ||
247 | 0x7fb, | ||
248 | 0xfa, | ||
249 | 0x16, | ||
250 | 0x17, | ||
251 | 0x18, | ||
252 | 0x0, | ||
253 | 0x1, | ||
254 | 0x2, | ||
255 | 0x19, | ||
256 | 0x1a, | ||
257 | 0x1b, | ||
258 | 0x1c, | ||
259 | 0x1d, | ||
260 | 0x1e, | ||
261 | 0x1f, | ||
262 | 0x5c, | ||
263 | 0xfb, | ||
264 | 0x7ffc, | ||
265 | 0x20, | ||
266 | 0xffb, | ||
267 | 0x3fc, | ||
268 | 0x1ffa, | ||
269 | 0x21, | ||
270 | 0x5d, | ||
271 | 0x5e, | ||
272 | 0x5f, | ||
273 | 0x60, | ||
274 | 0x61, | ||
275 | 0x62, | ||
276 | 0x63, | ||
277 | 0x64, | ||
278 | 0x65, | ||
279 | 0x66, | ||
280 | 0x67, | ||
281 | 0x68, | ||
282 | 0x69, | ||
283 | 0x6a, | ||
284 | 0x6b, | ||
285 | 0x6c, | ||
286 | 0x6d, | ||
287 | 0x6e, | ||
288 | 0x6f, | ||
289 | 0x70, | ||
290 | 0x71, | ||
291 | 0x72, | ||
292 | 0xfc, | ||
293 | 0x73, | ||
294 | 0xfd, | ||
295 | 0x1ffb, | ||
296 | 0x7fff0, | ||
297 | 0x1ffc, | ||
298 | 0x3ffc, | ||
299 | 0x22, | ||
300 | 0x7ffd, | ||
301 | 0x3, | ||
302 | 0x23, | ||
303 | 0x4, | ||
304 | 0x24, | ||
305 | 0x5, | ||
306 | 0x25, | ||
307 | 0x26, | ||
308 | 0x27, | ||
309 | 0x6, | ||
310 | 0x74, | ||
311 | 0x75, | ||
312 | 0x28, | ||
313 | 0x29, | ||
314 | 0x2a, | ||
315 | 0x7, | ||
316 | 0x2b, | ||
317 | 0x76, | ||
318 | 0x2c, | ||
319 | 0x8, | ||
320 | 0x9, | ||
321 | 0x2d, | ||
322 | 0x77, | ||
323 | 0x78, | ||
324 | 0x79, | ||
325 | 0x7a, | ||
326 | 0x7b, | ||
327 | 0x7ffe, | ||
328 | 0x7fc, | ||
329 | 0x3ffd, | ||
330 | 0x1ffd, | ||
331 | 0xffffffc, | ||
332 | 0xfffe6, | ||
333 | 0x3fffd2, | ||
334 | 0xfffe7, | ||
335 | 0xfffe8, | ||
336 | 0x3fffd3, | ||
337 | 0x3fffd4, | ||
338 | 0x3fffd5, | ||
339 | 0x7fffd9, | ||
340 | 0x3fffd6, | ||
341 | 0x7fffda, | ||
342 | 0x7fffdb, | ||
343 | 0x7fffdc, | ||
344 | 0x7fffdd, | ||
345 | 0x7fffde, | ||
346 | 0xffffeb, | ||
347 | 0x7fffdf, | ||
348 | 0xffffec, | ||
349 | 0xffffed, | ||
350 | 0x3fffd7, | ||
351 | 0x7fffe0, | ||
352 | 0xffffee, | ||
353 | 0x7fffe1, | ||
354 | 0x7fffe2, | ||
355 | 0x7fffe3, | ||
356 | 0x7fffe4, | ||
357 | 0x1fffdc, | ||
358 | 0x3fffd8, | ||
359 | 0x7fffe5, | ||
360 | 0x3fffd9, | ||
361 | 0x7fffe6, | ||
362 | 0x7fffe7, | ||
363 | 0xffffef, | ||
364 | 0x3fffda, | ||
365 | 0x1fffdd, | ||
366 | 0xfffe9, | ||
367 | 0x3fffdb, | ||
368 | 0x3fffdc, | ||
369 | 0x7fffe8, | ||
370 | 0x7fffe9, | ||
371 | 0x1fffde, | ||
372 | 0x7fffea, | ||
373 | 0x3fffdd, | ||
374 | 0x3fffde, | ||
375 | 0xfffff0, | ||
376 | 0x1fffdf, | ||
377 | 0x3fffdf, | ||
378 | 0x7fffeb, | ||
379 | 0x7fffec, | ||
380 | 0x1fffe0, | ||
381 | 0x1fffe1, | ||
382 | 0x3fffe0, | ||
383 | 0x1fffe2, | ||
384 | 0x7fffed, | ||
385 | 0x3fffe1, | ||
386 | 0x7fffee, | ||
387 | 0x7fffef, | ||
388 | 0xfffea, | ||
389 | 0x3fffe2, | ||
390 | 0x3fffe3, | ||
391 | 0x3fffe4, | ||
392 | 0x7ffff0, | ||
393 | 0x3fffe5, | ||
394 | 0x3fffe6, | ||
395 | 0x7ffff1, | ||
396 | 0x3ffffe0, | ||
397 | 0x3ffffe1, | ||
398 | 0xfffeb, | ||
399 | 0x7fff1, | ||
400 | 0x3fffe7, | ||
401 | 0x7ffff2, | ||
402 | 0x3fffe8, | ||
403 | 0x1ffffec, | ||
404 | 0x3ffffe2, | ||
405 | 0x3ffffe3, | ||
406 | 0x3ffffe4, | ||
407 | 0x7ffffde, | ||
408 | 0x7ffffdf, | ||
409 | 0x3ffffe5, | ||
410 | 0xfffff1, | ||
411 | 0x1ffffed, | ||
412 | 0x7fff2, | ||
413 | 0x1fffe3, | ||
414 | 0x3ffffe6, | ||
415 | 0x7ffffe0, | ||
416 | 0x7ffffe1, | ||
417 | 0x3ffffe7, | ||
418 | 0x7ffffe2, | ||
419 | 0xfffff2, | ||
420 | 0x1fffe4, | ||
421 | 0x1fffe5, | ||
422 | 0x3ffffe8, | ||
423 | 0x3ffffe9, | ||
424 | 0xffffffd, | ||
425 | 0x7ffffe3, | ||
426 | 0x7ffffe4, | ||
427 | 0x7ffffe5, | ||
428 | 0xfffec, | ||
429 | 0xfffff3, | ||
430 | 0xfffed, | ||
431 | 0x1fffe6, | ||
432 | 0x3fffe9, | ||
433 | 0x1fffe7, | ||
434 | 0x1fffe8, | ||
435 | 0x7ffff3, | ||
436 | 0x3fffea, | ||
437 | 0x3fffeb, | ||
438 | 0x1ffffee, | ||
439 | 0x1ffffef, | ||
440 | 0xfffff4, | ||
441 | 0xfffff5, | ||
442 | 0x3ffffea, | ||
443 | 0x7ffff4, | ||
444 | 0x3ffffeb, | ||
445 | 0x7ffffe6, | ||
446 | 0x3ffffec, | ||
447 | 0x3ffffed, | ||
448 | 0x7ffffe7, | ||
449 | 0x7ffffe8, | ||
450 | 0x7ffffe9, | ||
451 | 0x7ffffea, | ||
452 | 0x7ffffeb, | ||
453 | 0xffffffe, | ||
454 | 0x7ffffec, | ||
455 | 0x7ffffed, | ||
456 | 0x7ffffee, | ||
457 | 0x7ffffef, | ||
458 | 0x7fffff0, | ||
459 | 0x3ffffee, | ||
460 | } | ||
461 | |||
462 | var huffmanCodeLen = [256]uint8{ | ||
463 | 13, 23, 28, 28, 28, 28, 28, 28, 28, 24, 30, 28, 28, 30, 28, 28, | ||
464 | 28, 28, 28, 28, 28, 28, 30, 28, 28, 28, 28, 28, 28, 28, 28, 28, | ||
465 | 6, 10, 10, 12, 13, 6, 8, 11, 10, 10, 8, 11, 8, 6, 6, 6, | ||
466 | 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 8, 15, 6, 12, 10, | ||
467 | 13, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, | ||
468 | 7, 7, 7, 7, 7, 7, 7, 7, 8, 7, 8, 13, 19, 13, 14, 6, | ||
469 | 15, 5, 6, 5, 6, 5, 6, 6, 6, 5, 7, 7, 6, 6, 6, 5, | ||
470 | 6, 7, 6, 5, 5, 6, 7, 7, 7, 7, 7, 15, 11, 14, 13, 28, | ||
471 | 20, 22, 20, 20, 22, 22, 22, 23, 22, 23, 23, 23, 23, 23, 24, 23, | ||
472 | 24, 24, 22, 23, 24, 23, 23, 23, 23, 21, 22, 23, 22, 23, 23, 24, | ||
473 | 22, 21, 20, 22, 22, 23, 23, 21, 23, 22, 22, 24, 21, 22, 23, 23, | ||
474 | 21, 21, 22, 21, 23, 22, 23, 23, 20, 22, 22, 22, 23, 22, 22, 23, | ||
475 | 26, 26, 20, 19, 22, 23, 22, 25, 26, 26, 26, 27, 27, 26, 24, 25, | ||
476 | 19, 21, 26, 27, 27, 26, 27, 24, 21, 21, 26, 26, 28, 27, 27, 27, | ||
477 | 20, 24, 20, 21, 22, 21, 21, 23, 22, 22, 25, 25, 24, 24, 26, 23, | ||
478 | 26, 27, 26, 26, 27, 27, 27, 27, 27, 28, 27, 27, 27, 27, 27, 26, | ||
479 | } | ||