Commit dbd323bb authored by Brad Fitzpatrick's avatar Brad Fitzpatrick

internal/x/net/http2/hpack: update from upstream

Updates to x/net git rev 891ebc4b82d6e74f468c533b06f983c7be918a96 for:

   http2/hpack: track the beginning of a header block
   https://go-review.googlesource.com/c/153978

Updates golang/go#29187

Change-Id: Ie2568b3f8d6aaa3f097a4ac25d3acdc794f5ff5c
Reviewed-on: https://go-review.googlesource.com/c/154118
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarMatt Layher <mdlayher@gmail.com>
parent 47fb1fbd
...@@ -92,6 +92,8 @@ type Decoder struct { ...@@ -92,6 +92,8 @@ type Decoder struct {
// saveBuf is previous data passed to Write which we weren't able // saveBuf is previous data passed to Write which we weren't able
// to fully parse before. Unlike buf, we own this data. // to fully parse before. Unlike buf, we own this data.
saveBuf bytes.Buffer saveBuf bytes.Buffer
firstField bool // processing the first field of the header block
} }
// NewDecoder returns a new decoder with the provided maximum dynamic // NewDecoder returns a new decoder with the provided maximum dynamic
...@@ -101,6 +103,7 @@ func NewDecoder(maxDynamicTableSize uint32, emitFunc func(f HeaderField)) *Decod ...@@ -101,6 +103,7 @@ func NewDecoder(maxDynamicTableSize uint32, emitFunc func(f HeaderField)) *Decod
d := &Decoder{ d := &Decoder{
emit: emitFunc, emit: emitFunc,
emitEnabled: true, emitEnabled: true,
firstField: true,
} }
d.dynTab.table.init() d.dynTab.table.init()
d.dynTab.allowedMaxSize = maxDynamicTableSize d.dynTab.allowedMaxSize = maxDynamicTableSize
...@@ -226,11 +229,15 @@ func (d *Decoder) DecodeFull(p []byte) ([]HeaderField, error) { ...@@ -226,11 +229,15 @@ func (d *Decoder) DecodeFull(p []byte) ([]HeaderField, error) {
return hf, nil return hf, nil
} }
// Close declares that the decoding is complete and resets the Decoder
// to be reused again for a new header block. If there is any remaining
// data in the decoder's buffer, Close returns an error.
func (d *Decoder) Close() error { func (d *Decoder) Close() error {
if d.saveBuf.Len() > 0 { if d.saveBuf.Len() > 0 {
d.saveBuf.Reset() d.saveBuf.Reset()
return DecodingError{errors.New("truncated headers")} return DecodingError{errors.New("truncated headers")}
} }
d.firstField = true
return nil return nil
} }
...@@ -266,6 +273,7 @@ func (d *Decoder) Write(p []byte) (n int, err error) { ...@@ -266,6 +273,7 @@ func (d *Decoder) Write(p []byte) (n int, err error) {
d.saveBuf.Write(d.buf) d.saveBuf.Write(d.buf)
return len(p), nil return len(p), nil
} }
d.firstField = false
if err != nil { if err != nil {
break break
} }
...@@ -391,7 +399,7 @@ func (d *Decoder) callEmit(hf HeaderField) error { ...@@ -391,7 +399,7 @@ func (d *Decoder) callEmit(hf HeaderField) error {
func (d *Decoder) parseDynamicTableSizeUpdate() error { func (d *Decoder) parseDynamicTableSizeUpdate() error {
// RFC 7541, sec 4.2: This dynamic table size update MUST occur at the // RFC 7541, sec 4.2: This dynamic table size update MUST occur at the
// beginning of the first header block following the change to the dynamic table size. // beginning of the first header block following the change to the dynamic table size.
if d.dynTab.size > 0 { if !d.firstField && d.dynTab.size > 0 {
return DecodingError{errors.New("dynamic table size update MUST occur at the beginning of a header block")} return DecodingError{errors.New("dynamic table size update MUST occur at the beginning of a header block")}
} }
......
...@@ -748,14 +748,22 @@ func TestDynamicSizeUpdate(t *testing.T) { ...@@ -748,14 +748,22 @@ func TestDynamicSizeUpdate(t *testing.T) {
enc.SetMaxDynamicTableSize(255) enc.SetMaxDynamicTableSize(255)
enc.WriteField(HeaderField{Name: "foo", Value: "bar"}) enc.WriteField(HeaderField{Name: "foo", Value: "bar"})
d := NewDecoder(4096, nil) d := NewDecoder(4096, func(_ HeaderField) {})
_, err := d.DecodeFull(buf.Bytes()) _, err := d.Write(buf.Bytes())
if err != nil {
t.Fatalf("unexpected error: got = %v", err)
}
d.Close()
// Start a new header
_, err = d.Write(buf.Bytes())
if err != nil { if err != nil {
t.Fatalf("unexpected error: got = %v", err) t.Fatalf("unexpected error: got = %v", err)
} }
// must fail since the dynamic table update must be at the beginning // must fail since the dynamic table update must be at the beginning
_, err = d.DecodeFull(buf.Bytes()) _, err = d.Write(buf.Bytes())
if err == nil { if err == nil {
t.Fatalf("dynamic table size update not at the beginning of a header block") t.Fatalf("dynamic table size update not at the beginning of a header block")
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment