aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/golang.org/x/net/http2/hpack
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/golang.org/x/net/http2/hpack')
-rw-r--r--vendor/golang.org/x/net/http2/hpack/encode.go240
-rw-r--r--vendor/golang.org/x/net/http2/hpack/hpack.go490
-rw-r--r--vendor/golang.org/x/net/http2/hpack/huffman.go212
-rw-r--r--vendor/golang.org/x/net/http2/hpack/tables.go479
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
5package hpack
6
7import (
8 "io"
9)
10
11const (
12 uint32Max = ^uint32(0)
13 initialHeaderTableSize = 4096
14)
15
16type 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.
35func 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.
50func (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.
91func (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.
108func (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.
126func (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.
135func (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.
141func 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.
155func 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.
168func 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.
183func 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
195func 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.
213func 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.
232func 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
9package hpack
10
11import (
12 "bytes"
13 "errors"
14 "fmt"
15)
16
17// A DecodingError is something the spec defines as a decoding error.
18type DecodingError struct {
19 Err error
20}
21
22func (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.
28type InvalidIndexError int
29
30func (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.
36type 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.
48func (hf HeaderField) IsPseudo() bool {
49 return len(hf.Name) != 0 && hf.Name[0] == ':'
50}
51
52func (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.
61func (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.
79type 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.
100func 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.
113var 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.
119func (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.
126func (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.
137func (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.
141func (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
146func (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.
153func (d *Decoder) SetAllowedMaxDynamicTableSize(v uint32) {
154 d.dynTab.allowedMaxSize = v
155}
156
157type 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
165func (dt *dynamicTable) setMaxSize(v uint32) {
166 dt.maxSize = v
167 dt.evict()
168}
169
170func (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.
177func (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
186func (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
193func (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.
215func (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
229func (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
237func (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.
279var errNeedMore = errors.New("need more data")
280
281type indexType int
282
283const (
284 indexedTrue indexType = iota
285 indexedFalse
286 indexedNever
287)
288
289func (v indexType) indexed() bool { return v == indexedTrue }
290func (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
296func (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)
330func (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)
345func (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
378func (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)
391func (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
405var 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.
415func 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.
456func (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
5package hpack
6
7import (
8 "bytes"
9 "errors"
10 "io"
11 "sync"
12)
13
14var 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.
21func 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.
32func 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.
44var 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.
49func 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
107type 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
116func newInternalNode() *node {
117 return &node{children: make([]*node, 256)}
118}
119
120var rootHuffmanNode = newInternalNode()
121
122func 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
131func 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.
150func 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.
174func 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.
186func 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
5package hpack
6
7import (
8 "fmt"
9)
10
11// headerFieldTable implements a list of HeaderFields.
12// This is used to implement the static and dynamic tables.
13type 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
41type pairNameValue struct {
42 name, value string
43}
44
45func (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.
51func (t *headerFieldTable) len() int {
52 return len(t.ents)
53}
54
55// addEntry adds a new entry.
56func (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.
64func (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.
103func (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.
117func (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
129var staticTable = newStaticTable()
130var 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
194func newStaticTable() *headerFieldTable {
195 t := &headerFieldTable{}
196 t.init()
197 for _, e := range staticTableEntries[:] {
198 t.addEntry(e)
199 }
200 return t
201}
202
203var 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
462var 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}