11package qpack
22
33import (
4- "bytes"
54 "errors"
65 "fmt"
7- "sync "
6+ "io "
87
98 "golang.org/x/net/http2/hpack"
109)
1110
12- // A decodingError is something the spec defines as a decoding error.
11+ // A decodingError represents a QPACK decoding error as defined by the specification
1312type decodingError struct {
1413 err error
1514}
@@ -18,8 +17,8 @@ func (de decodingError) Error() string {
1817 return fmt .Sprintf ("decoding error: %v" , de .err )
1918}
2019
21- // An invalidIndexError is returned when an encoder references a table
22- // entry before the static table or after the end of the dynamic table.
20+ // An invalidIndexError is returned when decoding encounters an invalid index
21+ // (e.g., an index that is out of bounds for the static table) .
2322type invalidIndexError int
2423
2524func (e invalidIndexError ) Error () string {
@@ -28,221 +27,140 @@ func (e invalidIndexError) Error() string {
2827
2928var errNoDynamicTable = decodingError {errors .New ("no dynamic table" )}
3029
31- // errNeedMore is an internal sentinel error value that means the
32- // buffer is truncated and we need to read more data before we can
33- // continue parsing.
34- var errNeedMore = errors .New ("need more data" )
35-
36- // A Decoder is the decoding context for incremental processing of
37- // header blocks.
38- type Decoder struct {
39- mutex sync.Mutex
40-
41- emitFunc func (f HeaderField )
42-
43- readRequiredInsertCount bool
44- readDeltaBase bool
45-
46- // buf is the unparsed buffer. It's only written to
47- // saveBuf if it was truncated in the middle of a header
48- // block. Because it's usually not owned, we can only
49- // process it under Write.
50- buf []byte // not owned; only valid during Write
51-
52- // saveBuf is previous data passed to Write which we weren't able
53- // to fully parse before. Unlike buf, we own this data.
54- saveBuf bytes.Buffer
55- }
56-
57- // NewDecoder returns a new decoder
58- // The emitFunc will be called for each valid field parsed,
59- // in the same goroutine as calls to Write, before Write returns.
60- func NewDecoder (emitFunc func (f HeaderField )) * Decoder {
61- return & Decoder {emitFunc : emitFunc }
62- }
63-
64- func (d * Decoder ) Write (p []byte ) (int , error ) {
65- if len (p ) == 0 {
66- return 0 , nil
67- }
68-
69- d .mutex .Lock ()
70- n , err := d .writeLocked (p )
71- d .mutex .Unlock ()
72- return n , err
30+ // A Decoder decodes QPACK header blocks.
31+ // A Decoder can be reused to decode multiple header blocks on different streams
32+ // on the same connection (e.g., headers then trailers).
33+ // This will be useful when dynamic table support is added.
34+ type Decoder struct {}
35+
36+ // DecodeFunc is a function that decodes the next header field from a header block.
37+ // It should be called repeatedly until it returns io.EOF.
38+ // It returns io.EOF when all header fields have been decoded.
39+ // Any error other than io.EOF indicates a decoding error.
40+ type DecodeFunc func () (HeaderField , error )
41+
42+ // NewDecoder returns a new Decoder.
43+ func NewDecoder () * Decoder {
44+ return & Decoder {}
7345}
7446
75- func (d * Decoder ) writeLocked (p []byte ) (int , error ) {
76- // Only copy the data if we have to. Optimistically assume
77- // that p will contain a complete header block.
78- if d .saveBuf .Len () == 0 {
79- d .buf = p
80- } else {
81- d .saveBuf .Write (p )
82- d .buf = d .saveBuf .Bytes ()
83- d .saveBuf .Reset ()
84- }
85-
86- if err := d .decode (); err != nil {
87- if err != errNeedMore {
88- return 0 , err
47+ // Decode returns a function that decodes header fields from the given header block.
48+ // It does not copy the slice; the caller must ensure it remains valid during decoding.
49+ func (d * Decoder ) Decode (p []byte ) DecodeFunc {
50+ var readRequiredInsertCount bool
51+ var readDeltaBase bool
52+
53+ return func () (HeaderField , error ) {
54+ if ! readRequiredInsertCount {
55+ requiredInsertCount , rest , err := readVarInt (8 , p )
56+ if err != nil {
57+ return HeaderField {}, err
58+ }
59+ p = rest
60+ readRequiredInsertCount = true
61+ if requiredInsertCount != 0 {
62+ return HeaderField {}, decodingError {errors .New ("expected Required Insert Count to be zero" )}
63+ }
8964 }
90- // TODO: limit the size of the buffer
91- d .saveBuf .Write (d .buf )
92- }
93- return len (p ), nil
94- }
95-
96- // DecodeFull decodes an entire block.
97- func (d * Decoder ) DecodeFull (p []byte ) ([]HeaderField , error ) {
98- if len (p ) == 0 {
99- return []HeaderField {}, nil
100- }
10165
102- d .mutex .Lock ()
103- defer d .mutex .Unlock ()
104-
105- saveFunc := d .emitFunc
106- defer func () { d .emitFunc = saveFunc }()
107-
108- var hf []HeaderField
109- d .emitFunc = func (f HeaderField ) { hf = append (hf , f ) }
110- if _ , err := d .writeLocked (p ); err != nil {
111- return nil , err
112- }
113- if err := d .Close (); err != nil {
114- return nil , err
115- }
116- return hf , nil
117- }
118-
119- // Close declares that the decoding is complete and resets the Decoder
120- // to be reused again for a new header block. If there is any remaining
121- // data in the decoder's buffer, Close returns an error.
122- func (d * Decoder ) Close () error {
123- if d .saveBuf .Len () > 0 {
124- d .saveBuf .Reset ()
125- return decodingError {errors .New ("truncated headers" )}
126- }
127- d .readRequiredInsertCount = false
128- d .readDeltaBase = false
129- return nil
130- }
131-
132- func (d * Decoder ) decode () error {
133- if ! d .readRequiredInsertCount {
134- requiredInsertCount , rest , err := readVarInt (8 , d .buf )
135- if err != nil {
136- return err
137- }
138- d .readRequiredInsertCount = true
139- if requiredInsertCount != 0 {
140- return decodingError {errors .New ("expected Required Insert Count to be zero" )}
141- }
142- d .buf = rest
143- }
144- if ! d .readDeltaBase {
145- base , rest , err := readVarInt (7 , d .buf )
146- if err != nil {
147- return err
66+ if ! readDeltaBase {
67+ base , rest , err := readVarInt (7 , p )
68+ if err != nil {
69+ return HeaderField {}, err
70+ }
71+ p = rest
72+ readDeltaBase = true
73+ if base != 0 {
74+ return HeaderField {}, decodingError {errors .New ("expected Base to be zero" )}
75+ }
14876 }
149- d . readDeltaBase = true
150- if base ! = 0 {
151- return decodingError { errors . New ( "expected Base to be zero" )}
77+
78+ if len ( p ) = = 0 {
79+ return HeaderField {}, io . EOF
15280 }
153- d .buf = rest
154- }
155- if len (d .buf ) == 0 {
156- return errNeedMore
157- }
15881
159- for len (d .buf ) > 0 {
160- b := d .buf [0 ]
82+ b := p [0 ]
83+ var hf HeaderField
84+ var rest []byte
16185 var err error
16286 switch {
163- case b & 0x80 > 0 : // 1xxxxxxx
164- err = d .parseIndexedHeaderField ()
165- case b & 0xc0 == 0x40 : // 01xxxxxx
166- err = d .parseLiteralHeaderField ()
167- case b & 0xe0 == 0x20 : // 001xxxxx
168- err = d .parseLiteralHeaderFieldWithoutNameReference ()
87+ case ( b & 0x80 ) > 0 : // 1xxxxxxx
88+ hf , rest , err = d .parseIndexedHeaderField (p )
89+ case ( b & 0xc0 ) == 0x40 : // 01xxxxxx
90+ hf , rest , err = d .parseLiteralHeaderField (p )
91+ case ( b & 0xe0 ) == 0x20 : // 001xxxxx
92+ hf , rest , err = d .parseLiteralHeaderFieldWithoutNameReference (p )
16993 default :
17094 err = fmt .Errorf ("unexpected type byte: %#x" , b )
17195 }
96+ p = rest
17297 if err != nil {
173- return err
98+ return HeaderField {}, err
17499 }
100+ return hf , nil
175101 }
176- return nil
177102}
178103
179- func (d * Decoder ) parseIndexedHeaderField () error {
180- buf := d .buf
104+ func (d * Decoder ) parseIndexedHeaderField (buf []byte ) (_ HeaderField , rest []byte , _ error ) {
181105 if buf [0 ]& 0x40 == 0 {
182- return errNoDynamicTable
106+ return HeaderField {}, buf , errNoDynamicTable
183107 }
184- index , buf , err := readVarInt (6 , buf )
108+ index , rest , err := readVarInt (6 , buf )
185109 if err != nil {
186- return err
110+ return HeaderField {}, buf , err
187111 }
188112 hf , ok := d .at (index )
189113 if ! ok {
190- return decodingError {invalidIndexError (index )}
114+ return HeaderField {}, buf , decodingError {invalidIndexError (index )}
191115 }
192- d .emitFunc (hf )
193- d .buf = buf
194- return nil
116+ return hf , rest , nil
195117}
196118
197- func (d * Decoder ) parseLiteralHeaderField () error {
198- buf := d .buf
119+ func (d * Decoder ) parseLiteralHeaderField (buf []byte ) (_ HeaderField , rest []byte , _ error ) {
199120 if buf [0 ]& 0x10 == 0 {
200- return errNoDynamicTable
121+ return HeaderField {}, buf , errNoDynamicTable
201122 }
202123 // We don't need to check the value of the N-bit here.
203124 // It's only relevant when re-encoding header fields,
204125 // and determines whether the header field can be added to the dynamic table.
205126 // Since we don't support the dynamic table, we can ignore it.
206- index , buf , err := readVarInt (4 , buf )
127+ index , rest , err := readVarInt (4 , buf )
207128 if err != nil {
208- return err
129+ return HeaderField {}, buf , err
209130 }
210131 hf , ok := d .at (index )
211132 if ! ok {
212- return decodingError {invalidIndexError (index )}
133+ return HeaderField {}, buf , decodingError {invalidIndexError (index )}
213134 }
135+ buf = rest
214136 if len (buf ) == 0 {
215- return errNeedMore
137+ return HeaderField {}, buf , decodingError { errors . New ( "truncated literal header field" )}
216138 }
217139 usesHuffman := buf [0 ]& 0x80 > 0
218- val , buf , err := d .readString (buf , 7 , usesHuffman )
140+ val , rest , err := d .readString (rest , 7 , usesHuffman )
219141 if err != nil {
220- return err
142+ return HeaderField {}, rest , err
221143 }
222144 hf .Value = val
223- d .emitFunc (hf )
224- d .buf = buf
225- return nil
145+ return hf , rest , nil
226146}
227147
228- func (d * Decoder ) parseLiteralHeaderFieldWithoutNameReference () error {
229- buf := d .buf
148+ func (d * Decoder ) parseLiteralHeaderFieldWithoutNameReference (buf []byte ) (_ HeaderField , rest []byte , _ error ) {
230149 usesHuffmanForName := buf [0 ]& 0x8 > 0
231- name , buf , err := d .readString (buf , 3 , usesHuffmanForName )
150+ name , rest , err := d .readString (buf , 3 , usesHuffmanForName )
232151 if err != nil {
233- return err
152+ return HeaderField {}, rest , err
234153 }
154+ buf = rest
235155 if len (buf ) == 0 {
236- return errNeedMore
156+ return HeaderField {}, rest , decodingError { errors . New ( "truncated literal header field without name reference" )}
237157 }
238158 usesHuffmanForVal := buf [0 ]& 0x80 > 0
239- val , buf , err := d .readString (buf , 7 , usesHuffmanForVal )
159+ val , rest , err := d .readString (buf , 7 , usesHuffmanForVal )
240160 if err != nil {
241- return err
161+ return HeaderField {}, rest , err
242162 }
243- d .emitFunc (HeaderField {Name : name , Value : val })
244- d .buf = buf
245- return nil
163+ return HeaderField {Name : name , Value : val }, rest , nil
246164}
247165
248166func (d * Decoder ) readString (buf []byte , n uint8 , usesHuffman bool ) (string , []byte , error ) {
@@ -251,11 +169,10 @@ func (d *Decoder) readString(buf []byte, n uint8, usesHuffman bool) (string, []b
251169 return "" , nil , err
252170 }
253171 if uint64 (len (buf )) < l {
254- return "" , nil , errNeedMore
172+ return "" , nil , decodingError { errors . New ( "truncated string" )}
255173 }
256174 var val string
257175 if usesHuffman {
258- var err error
259176 val , err = hpack .HuffmanDecodeToString (buf [:l ])
260177 if err != nil {
261178 return "" , nil , err
0 commit comments