// saveBuf is previous data passed to Write which we weren't able
// to fully parse before. Unlike buf, we own this data.
saveBuf bytes.Buffer
+
+ firstField bool // processing the first field of the header block
}
// NewDecoder returns a new decoder with the provided maximum dynamic
d := &Decoder{
emit: emitFunc,
emitEnabled: true,
+ firstField: true,
}
d.dynTab.table.init()
d.dynTab.allowedMaxSize = maxDynamicTableSize
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 {
if d.saveBuf.Len() > 0 {
d.saveBuf.Reset()
return DecodingError{errors.New("truncated headers")}
}
+ d.firstField = true
return nil
}
d.saveBuf.Write(d.buf)
return len(p), nil
}
+ d.firstField = false
if err != nil {
break
}
func (d *Decoder) parseDynamicTableSizeUpdate() error {
// 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.
- 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")}
}
enc.SetMaxDynamicTableSize(255)
enc.WriteField(HeaderField{Name: "foo", Value: "bar"})
- d := NewDecoder(4096, nil)
- _, err := d.DecodeFull(buf.Bytes())
+ d := NewDecoder(4096, func(_ HeaderField) {})
+ _, 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 {
t.Fatalf("unexpected error: got = %v", err)
}
// 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 {
t.Fatalf("dynamic table size update not at the beginning of a header block")
}