1
2
3
4
5 package http3
6
7 import (
8 "errors"
9 "math/bits"
10 )
11
12 type qpackDecoder struct {
13
14
15
16
17 }
18
19 func (qd *qpackDecoder) decode(st *stream, f func(itype indexType, name, value string) error) error {
20
21
22
23
24 _, requiredInsertCount, err := st.readPrefixedInt(8)
25 if err != nil {
26 return err
27 }
28 if requiredInsertCount != 0 {
29 return errQPACKDecompressionFailed
30 }
31
32
33 _, _, err = st.readPrefixedInt(7)
34 if err != nil {
35 return err
36 }
37
38 sawNonPseudo := false
39 for st.lim > 0 {
40 firstByte, err := st.ReadByte()
41 if err != nil {
42 return err
43 }
44 var name, value string
45 var itype indexType
46 switch bits.LeadingZeros8(firstByte) {
47 case 0:
48
49 itype, name, value, err = st.decodeIndexedFieldLine(firstByte)
50 case 1:
51
52 itype, name, value, err = st.decodeLiteralFieldLineWithNameReference(firstByte)
53 case 2:
54
55 itype, name, value, err = st.decodeLiteralFieldLineWithLiteralName(firstByte)
56 case 3:
57
58 err = errors.New("dynamic table is not supported yet")
59 case 4:
60
61 err = errors.New("dynamic table is not supported yet")
62 }
63 if err != nil {
64 return err
65 }
66 if len(name) == 0 {
67 return errH3MessageError
68 }
69 if name[0] == ':' {
70 if sawNonPseudo {
71 return errH3MessageError
72 }
73 } else {
74 sawNonPseudo = true
75 }
76 if err := f(itype, name, value); err != nil {
77 return err
78 }
79 }
80 return nil
81 }
82
View as plain text