encode.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  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
  6. import (
  7. "errors"
  8. "io"
  9. )
  10. type Encoder struct {
  11. w io.Writer
  12. buf []byte
  13. }
  14. func NewEncoder(w io.Writer) *Encoder {
  15. return &Encoder{w: w}
  16. }
  17. // WriteField encodes f into a single Write to e's underlying Writer.
  18. func (e *Encoder) WriteField(f HeaderField) error {
  19. // TODO: write a decent Encoder. This is a quick hack job just to move on
  20. // to other pieces. With this encoder, we only write literals.
  21. // The form this writes is:
  22. // http://http2.github.io/http2-spec/compression.html#rfc.section.6.2.2
  23. // In particular, that second table. And no huffman
  24. // compression. Oh, and let's be even lazier for now and
  25. // reject keys or values with lengths greather than 126 so we
  26. // can save some time by not writing a varint encoder for
  27. // now. But I'm wasting time writing this comment.
  28. if len(f.Name) > 126 || len(f.Value) > 126 {
  29. return errors.New("TODO: finish hpack encoder. names/values too long for current laziness, procrastination, impatience.")
  30. }
  31. e.buf = e.buf[:0]
  32. e.buf = append(e.buf, 0)
  33. e.buf = append(e.buf, byte(len(f.Name)))
  34. e.buf = append(e.buf, f.Name...)
  35. e.buf = append(e.buf, byte(len(f.Value)))
  36. e.buf = append(e.buf, f.Value...)
  37. n, err := e.w.Write(e.buf)
  38. if err == nil && n != len(e.buf) {
  39. err = io.ErrShortWrite
  40. }
  41. return err
  42. }