hpack.go 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. // Copyright 2014 The Go Authors.
  2. // See https://code.google.com/p/go/source/browse/CONTRIBUTORS
  3. // Licensed under the same terms as Go itself:
  4. // https://code.google.com/p/go/source/browse/LICENSE
  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-08
  9. package hpack
  10. import "fmt"
  11. // A HeaderField is a name-value pair. Both the name and value are
  12. // treated as opaque sequences of octets.
  13. type HeaderField struct {
  14. Name, Value string
  15. }
  16. // A Decoder is the decoding context for incremental processing of
  17. // header blocks.
  18. type Decoder struct {
  19. dt dynamicTable
  20. refSet struct{} // TODO
  21. Emit func(f HeaderField, sensitive bool)
  22. // TODO: max table size http://http2.github.io/http2-spec/compression.html#maximum.table.size
  23. //
  24. }
  25. type dynamicTable []HeaderField
  26. // TODO: change dynamicTable to be a struct with a slice and a size int field,
  27. // per http://http2.github.io/http2-spec/compression.html#rfc.section.4.1:
  28. //
  29. // "The size of the dynamic table is the sum of the size of its
  30. // entries. The size of an entry is the sum of its name's length in
  31. // octets (as defined in Section 5.2), its value's length in octets
  32. // (see Section 5.2), plus 32. The size of an entry is calculated
  33. // using the length of the name and value without any Huffman encoding
  34. // applied. "
  35. //
  36. // Then make add increment the size. maybe the max size should move from Decoder to
  37. // dynamicTable and add should return an ok bool if there was enough space.
  38. //
  39. // Later we'll need a remove operation on dynamicTable.
  40. func (s *dynamicTable) add(f HeaderField) {
  41. *s = append(*s, f)
  42. }
  43. func (s *dynamicTable) at(i int) HeaderField {
  44. if i < 1 {
  45. panic(fmt.Sprintf("header table index %d too small", i))
  46. }
  47. dt := *s
  48. max := len(dt) + len(staticTable)
  49. if i > max {
  50. panic(fmt.Sprintf("header table index %d too large (max = %d)", i, max))
  51. }
  52. if i <= len(dt) {
  53. return dt[i-1]
  54. }
  55. return staticTable[i-len(dt)-1]
  56. }
  57. // TODO: new methods on dynamicTable for changing table max table size & eviction:
  58. // http://http2.github.io/http2-spec/compression.html#rfc.section.4.2