github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/net/http2/hpack/hpack.go (about)

     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  func (hf *HeaderField) size() uint32 {
    45  	// http://http2.github.io/http2-spec/compression.html#rfc.section.4.1
    46  	// "The size of the dynamic table is the sum of the size of
    47  	// its entries.  The size of an entry is the sum of its name's
    48  	// length in octets (as defined in Section 5.2), its value's
    49  	// length in octets (see Section 5.2), plus 32.  The size of
    50  	// an entry is calculated using the length of the name and
    51  	// value without any Huffman encoding applied."
    52  
    53  	// This can overflow if somebody makes a large HeaderField
    54  	// Name and/or Value by hand, but we don't care, because that
    55  	// won't happen on the wire because the encoding doesn't allow
    56  	// it.
    57  	return uint32(len(hf.Name) + len(hf.Value) + 32)
    58  }
    59  
    60  // A Decoder is the decoding context for incremental processing of
    61  // header blocks.
    62  type Decoder struct {
    63  	dynTab dynamicTable
    64  	emit   func(f HeaderField)
    65  
    66  	emitEnabled bool // whether calls to emit are enabled
    67  	maxStrLen   int  // 0 means unlimited
    68  
    69  	// buf is the unparsed buffer. It's only written to
    70  	// saveBuf if it was truncated in the middle of a header
    71  	// block. Because it's usually not owned, we can only
    72  	// process it under Write.
    73  	buf []byte // not owned; only valid during Write
    74  
    75  	// saveBuf is previous data passed to Write which we weren't able
    76  	// to fully parse before. Unlike buf, we own this data.
    77  	saveBuf bytes.Buffer
    78  }
    79  
    80  // NewDecoder returns a new decoder with the provided maximum dynamic
    81  // table size. The emitFunc will be called for each valid field
    82  // parsed, in the same goroutine as calls to Write, before Write returns.
    83  func NewDecoder(maxDynamicTableSize uint32, emitFunc func(f HeaderField)) *Decoder {
    84  	d := &Decoder{
    85  		emit:        emitFunc,
    86  		emitEnabled: true,
    87  	}
    88  	d.dynTab.allowedMaxSize = maxDynamicTableSize
    89  	d.dynTab.setMaxSize(maxDynamicTableSize)
    90  	return d
    91  }
    92  
    93  // ErrStringLength is returned by Decoder.Write when the max string length
    94  // (as configured by Decoder.SetMaxStringLength) would be violated.
    95  var ErrStringLength = errors.New("hpack: string too long")
    96  
    97  // SetMaxStringLength sets the maximum size of a HeaderField name or
    98  // value string. If a string exceeds this length (even after any
    99  // decompression), Write will return ErrStringLength.
   100  // A value of 0 means unlimited and is the default from NewDecoder.
   101  func (d *Decoder) SetMaxStringLength(n int) {
   102  	d.maxStrLen = n
   103  }
   104  
   105  // SetEmitFunc changes the callback used when new header fields
   106  // are decoded.
   107  // It must be non-nil. It does not affect EmitEnabled.
   108  func (d *Decoder) SetEmitFunc(emitFunc func(f HeaderField)) {
   109  	d.emit = emitFunc
   110  }
   111  
   112  // SetEmitEnabled controls whether the emitFunc provided to NewDecoder
   113  // should be called. The default is true.
   114  //
   115  // This facility exists to let servers enforce MAX_HEADER_LIST_SIZE
   116  // while still decoding and keeping in-sync with decoder state, but
   117  // without doing unnecessary decompression or generating unnecessary
   118  // garbage for header fields past the limit.
   119  func (d *Decoder) SetEmitEnabled(v bool) { d.emitEnabled = v }
   120  
   121  // EmitEnabled reports whether calls to the emitFunc provided to NewDecoder
   122  // are currently enabled. The default is true.
   123  func (d *Decoder) EmitEnabled() bool { return d.emitEnabled }
   124  
   125  // TODO: add method *Decoder.Reset(maxSize, emitFunc) to let callers re-use Decoders and their
   126  // underlying buffers for garbage reasons.
   127  
   128  func (d *Decoder) SetMaxDynamicTableSize(v uint32) {
   129  	d.dynTab.setMaxSize(v)
   130  }
   131  
   132  // SetAllowedMaxDynamicTableSize sets the upper bound that the encoded
   133  // stream (via dynamic table size updates) may set the maximum size
   134  // to.
   135  func (d *Decoder) SetAllowedMaxDynamicTableSize(v uint32) {
   136  	d.dynTab.allowedMaxSize = v
   137  }
   138  
   139  type dynamicTable struct {
   140  	// ents is the FIFO described at
   141  	// http://http2.github.io/http2-spec/compression.html#rfc.section.2.3.2
   142  	// The newest (low index) is append at the end, and items are
   143  	// evicted from the front.
   144  	ents           []HeaderField
   145  	size           uint32
   146  	maxSize        uint32 // current maxSize
   147  	allowedMaxSize uint32 // maxSize may go up to this, inclusive
   148  }
   149  
   150  func (dt *dynamicTable) setMaxSize(v uint32) {
   151  	dt.maxSize = v
   152  	dt.evict()
   153  }
   154  
   155  // TODO: change dynamicTable to be a struct with a slice and a size int field,
   156  // per http://http2.github.io/http2-spec/compression.html#rfc.section.4.1:
   157  //
   158  //
   159  // Then make add increment the size. maybe the max size should move from Decoder to
   160  // dynamicTable and add should return an ok bool if there was enough space.
   161  //
   162  // Later we'll need a remove operation on dynamicTable.
   163  
   164  func (dt *dynamicTable) add(f HeaderField) {
   165  	dt.ents = append(dt.ents, f)
   166  	dt.size += f.size()
   167  	dt.evict()
   168  }
   169  
   170  // If we're too big, evict old stuff (front of the slice)
   171  func (dt *dynamicTable) evict() {
   172  	base := dt.ents // keep base pointer of slice
   173  	for dt.size > dt.maxSize {
   174  		dt.size -= dt.ents[0].size()
   175  		dt.ents = dt.ents[1:]
   176  	}
   177  
   178  	// Shift slice contents down if we evicted things.
   179  	if len(dt.ents) != len(base) {
   180  		copy(base, dt.ents)
   181  		dt.ents = base[:len(dt.ents)]
   182  	}
   183  }
   184  
   185  // constantTimeStringCompare compares string a and b in a constant
   186  // time manner.
   187  func constantTimeStringCompare(a, b string) bool {
   188  	if len(a) != len(b) {
   189  		return false
   190  	}
   191  
   192  	c := byte(0)
   193  
   194  	for i := 0; i < len(a); i++ {
   195  		c |= a[i] ^ b[i]
   196  	}
   197  
   198  	return c == 0
   199  }
   200  
   201  // Search searches f in the table. The return value i is 0 if there is
   202  // no name match. If there is name match or name/value match, i is the
   203  // index of that entry (1-based). If both name and value match,
   204  // nameValueMatch becomes true.
   205  func (dt *dynamicTable) search(f HeaderField) (i uint64, nameValueMatch bool) {
   206  	l := len(dt.ents)
   207  	for j := l - 1; j >= 0; j-- {
   208  		ent := dt.ents[j]
   209  		if !constantTimeStringCompare(ent.Name, f.Name) {
   210  			continue
   211  		}
   212  		if i == 0 {
   213  			i = uint64(l - j)
   214  		}
   215  		if f.Sensitive {
   216  			continue
   217  		}
   218  		if !constantTimeStringCompare(ent.Value, f.Value) {
   219  			continue
   220  		}
   221  		i = uint64(l - j)
   222  		nameValueMatch = true
   223  		return
   224  	}
   225  	return
   226  }
   227  
   228  func (d *Decoder) maxTableIndex() int {
   229  	return len(d.dynTab.ents) + len(staticTable)
   230  }
   231  
   232  func (d *Decoder) at(i uint64) (hf HeaderField, ok bool) {
   233  	if i < 1 {
   234  		return
   235  	}
   236  	if i > uint64(d.maxTableIndex()) {
   237  		return
   238  	}
   239  	if i <= uint64(len(staticTable)) {
   240  		return staticTable[i-1], true
   241  	}
   242  	dents := d.dynTab.ents
   243  	return dents[len(dents)-(int(i)-len(staticTable))], true
   244  }
   245  
   246  // Decode decodes an entire block.
   247  //
   248  // TODO: remove this method and make it incremental later? This is
   249  // easier for debugging now.
   250  func (d *Decoder) DecodeFull(p []byte) ([]HeaderField, error) {
   251  	var hf []HeaderField
   252  	saveFunc := d.emit
   253  	defer func() { d.emit = saveFunc }()
   254  	d.emit = func(f HeaderField) { hf = append(hf, f) }
   255  	if _, err := d.Write(p); err != nil {
   256  		return nil, err
   257  	}
   258  	if err := d.Close(); err != nil {
   259  		return nil, err
   260  	}
   261  	return hf, nil
   262  }
   263  
   264  func (d *Decoder) Close() error {
   265  	if d.saveBuf.Len() > 0 {
   266  		d.saveBuf.Reset()
   267  		return DecodingError{errors.New("truncated headers")}
   268  	}
   269  	return nil
   270  }
   271  
   272  func (d *Decoder) Write(p []byte) (n int, err error) {
   273  	if len(p) == 0 {
   274  		// Prevent state machine CPU attacks (making us redo
   275  		// work up to the point of finding out we don't have
   276  		// enough data)
   277  		return
   278  	}
   279  	// Only copy the data if we have to. Optimistically assume
   280  	// that p will contain a complete header block.
   281  	if d.saveBuf.Len() == 0 {
   282  		d.buf = p
   283  	} else {
   284  		d.saveBuf.Write(p)
   285  		d.buf = d.saveBuf.Bytes()
   286  		d.saveBuf.Reset()
   287  	}
   288  
   289  	for len(d.buf) > 0 {
   290  		err = d.parseHeaderFieldRepr()
   291  		if err == errNeedMore {
   292  			// Extra paranoia, making sure saveBuf won't
   293  			// get too large.  All the varint and string
   294  			// reading code earlier should already catch
   295  			// overlong things and return ErrStringLength,
   296  			// but keep this as a last resort.
   297  			const varIntOverhead = 8 // conservative
   298  			if d.maxStrLen != 0 && int64(len(d.buf)) > 2*(int64(d.maxStrLen)+varIntOverhead) {
   299  				return 0, ErrStringLength
   300  			}
   301  			d.saveBuf.Write(d.buf)
   302  			return len(p), nil
   303  		}
   304  		if err != nil {
   305  			break
   306  		}
   307  	}
   308  	return len(p), err
   309  }
   310  
   311  // errNeedMore is an internal sentinel error value that means the
   312  // buffer is truncated and we need to read more data before we can
   313  // continue parsing.
   314  var errNeedMore = errors.New("need more data")
   315  
   316  type indexType int
   317  
   318  const (
   319  	indexedTrue indexType = iota
   320  	indexedFalse
   321  	indexedNever
   322  )
   323  
   324  func (v indexType) indexed() bool   { return v == indexedTrue }
   325  func (v indexType) sensitive() bool { return v == indexedNever }
   326  
   327  // returns errNeedMore if there isn't enough data available.
   328  // any other error is fatal.
   329  // consumes d.buf iff it returns nil.
   330  // precondition: must be called with len(d.buf) > 0
   331  func (d *Decoder) parseHeaderFieldRepr() error {
   332  	b := d.buf[0]
   333  	switch {
   334  	case b&128 != 0:
   335  		// Indexed representation.
   336  		// High bit set?
   337  		// http://http2.github.io/http2-spec/compression.html#rfc.section.6.1
   338  		return d.parseFieldIndexed()
   339  	case b&192 == 64:
   340  		// 6.2.1 Literal Header Field with Incremental Indexing
   341  		// 0b10xxxxxx: top two bits are 10
   342  		// http://http2.github.io/http2-spec/compression.html#rfc.section.6.2.1
   343  		return d.parseFieldLiteral(6, indexedTrue)
   344  	case b&240 == 0:
   345  		// 6.2.2 Literal Header Field without Indexing
   346  		// 0b0000xxxx: top four bits are 0000
   347  		// http://http2.github.io/http2-spec/compression.html#rfc.section.6.2.2
   348  		return d.parseFieldLiteral(4, indexedFalse)
   349  	case b&240 == 16:
   350  		// 6.2.3 Literal Header Field never Indexed
   351  		// 0b0001xxxx: top four bits are 0001
   352  		// http://http2.github.io/http2-spec/compression.html#rfc.section.6.2.3
   353  		return d.parseFieldLiteral(4, indexedNever)
   354  	case b&224 == 32:
   355  		// 6.3 Dynamic Table Size Update
   356  		// Top three bits are '001'.
   357  		// http://http2.github.io/http2-spec/compression.html#rfc.section.6.3
   358  		return d.parseDynamicTableSizeUpdate()
   359  	}
   360  
   361  	return DecodingError{errors.New("invalid encoding")}
   362  }
   363  
   364  // (same invariants and behavior as parseHeaderFieldRepr)
   365  func (d *Decoder) parseFieldIndexed() error {
   366  	buf := d.buf
   367  	idx, buf, err := readVarInt(7, buf)
   368  	if err != nil {
   369  		return err
   370  	}
   371  	hf, ok := d.at(idx)
   372  	if !ok {
   373  		return DecodingError{InvalidIndexError(idx)}
   374  	}
   375  	d.buf = buf
   376  	return d.callEmit(HeaderField{Name: hf.Name, Value: hf.Value})
   377  }
   378  
   379  // (same invariants and behavior as parseHeaderFieldRepr)
   380  func (d *Decoder) parseFieldLiteral(n uint8, it indexType) error {
   381  	buf := d.buf
   382  	nameIdx, buf, err := readVarInt(n, buf)
   383  	if err != nil {
   384  		return err
   385  	}
   386  
   387  	var hf HeaderField
   388  	wantStr := d.emitEnabled || it.indexed()
   389  	if nameIdx > 0 {
   390  		ihf, ok := d.at(nameIdx)
   391  		if !ok {
   392  			return DecodingError{InvalidIndexError(nameIdx)}
   393  		}
   394  		hf.Name = ihf.Name
   395  	} else {
   396  		hf.Name, buf, err = d.readString(buf, wantStr)
   397  		if err != nil {
   398  			return err
   399  		}
   400  	}
   401  	hf.Value, buf, err = d.readString(buf, wantStr)
   402  	if err != nil {
   403  		return err
   404  	}
   405  	d.buf = buf
   406  	if it.indexed() {
   407  		d.dynTab.add(hf)
   408  	}
   409  	hf.Sensitive = it.sensitive()
   410  	return d.callEmit(hf)
   411  }
   412  
   413  func (d *Decoder) callEmit(hf HeaderField) error {
   414  	if d.maxStrLen != 0 {
   415  		if len(hf.Name) > d.maxStrLen || len(hf.Value) > d.maxStrLen {
   416  			return ErrStringLength
   417  		}
   418  	}
   419  	if d.emitEnabled {
   420  		d.emit(hf)
   421  	}
   422  	return nil
   423  }
   424  
   425  // (same invariants and behavior as parseHeaderFieldRepr)
   426  func (d *Decoder) parseDynamicTableSizeUpdate() error {
   427  	buf := d.buf
   428  	size, buf, err := readVarInt(5, buf)
   429  	if err != nil {
   430  		return err
   431  	}
   432  	if size > uint64(d.dynTab.allowedMaxSize) {
   433  		return DecodingError{errors.New("dynamic table size update too large")}
   434  	}
   435  	d.dynTab.setMaxSize(uint32(size))
   436  	d.buf = buf
   437  	return nil
   438  }
   439  
   440  var errVarintOverflow = DecodingError{errors.New("varint integer overflow")}
   441  
   442  // readVarInt reads an unsigned variable length integer off the
   443  // beginning of p. n is the parameter as described in
   444  // http://http2.github.io/http2-spec/compression.html#rfc.section.5.1.
   445  //
   446  // n must always be between 1 and 8.
   447  //
   448  // The returned remain buffer is either a smaller suffix of p, or err != nil.
   449  // The error is errNeedMore if p doesn't contain a complete integer.
   450  func readVarInt(n byte, p []byte) (i uint64, remain []byte, err error) {
   451  	if n < 1 || n > 8 {
   452  		panic("bad n")
   453  	}
   454  	if len(p) == 0 {
   455  		return 0, p, errNeedMore
   456  	}
   457  	i = uint64(p[0])
   458  	if n < 8 {
   459  		i &= (1 << uint64(n)) - 1
   460  	}
   461  	if i < (1<<uint64(n))-1 {
   462  		return i, p[1:], nil
   463  	}
   464  
   465  	origP := p
   466  	p = p[1:]
   467  	var m uint64
   468  	for len(p) > 0 {
   469  		b := p[0]
   470  		p = p[1:]
   471  		i += uint64(b&127) << m
   472  		if b&128 == 0 {
   473  			return i, p, nil
   474  		}
   475  		m += 7
   476  		if m >= 63 { // TODO: proper overflow check. making this up.
   477  			return 0, origP, errVarintOverflow
   478  		}
   479  	}
   480  	return 0, origP, errNeedMore
   481  }
   482  
   483  // readString decodes an hpack string from p.
   484  //
   485  // wantStr is whether s will be used. If false, decompression and
   486  // []byte->string garbage are skipped if s will be ignored
   487  // anyway. This does mean that huffman decoding errors for non-indexed
   488  // strings past the MAX_HEADER_LIST_SIZE are ignored, but the server
   489  // is returning an error anyway, and because they're not indexed, the error
   490  // won't affect the decoding state.
   491  func (d *Decoder) readString(p []byte, wantStr bool) (s string, remain []byte, err error) {
   492  	if len(p) == 0 {
   493  		return "", p, errNeedMore
   494  	}
   495  	isHuff := p[0]&128 != 0
   496  	strLen, p, err := readVarInt(7, p)
   497  	if err != nil {
   498  		return "", p, err
   499  	}
   500  	if d.maxStrLen != 0 && strLen > uint64(d.maxStrLen) {
   501  		return "", nil, ErrStringLength
   502  	}
   503  	if uint64(len(p)) < strLen {
   504  		return "", p, errNeedMore
   505  	}
   506  	if !isHuff {
   507  		if wantStr {
   508  			s = string(p[:strLen])
   509  		}
   510  		return s, p[strLen:], nil
   511  	}
   512  
   513  	if wantStr {
   514  		buf := bufPool.Get().(*bytes.Buffer)
   515  		buf.Reset() // don't trust others
   516  		defer bufPool.Put(buf)
   517  		if err := huffmanDecode(buf, d.maxStrLen, p[:strLen]); err != nil {
   518  			buf.Reset()
   519  			return "", nil, err
   520  		}
   521  		s = buf.String()
   522  		buf.Reset() // be nice to GC
   523  	}
   524  	return s, p[strLen:], nil
   525  }