Source file src/vendor/golang.org/x/net/internal/http3/qpack_decode.go

     1  // Copyright 2025 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package http3
     6  
     7  import (
     8  	"errors"
     9  	"math/bits"
    10  )
    11  
    12  type qpackDecoder struct {
    13  	// The decoder has no state for now,
    14  	// but that'll change once we add dynamic table support.
    15  	//
    16  	// TODO: dynamic table support.
    17  }
    18  
    19  func (qd *qpackDecoder) decode(st *stream, f func(itype indexType, name, value string) error) error {
    20  	// Encoded Field Section prefix.
    21  
    22  	// We set SETTINGS_QPACK_MAX_TABLE_CAPACITY to 0,
    23  	// so the Required Insert Count must be 0.
    24  	_, requiredInsertCount, err := st.readPrefixedInt(8)
    25  	if err != nil {
    26  		return err
    27  	}
    28  	if requiredInsertCount != 0 {
    29  		return errQPACKDecompressionFailed
    30  	}
    31  
    32  	// Delta Base. We don't use the dynamic table yet, so this may be ignored.
    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  			// Indexed Field Line
    49  			itype, name, value, err = st.decodeIndexedFieldLine(firstByte)
    50  		case 1:
    51  			// Literal Field Line With Name Reference
    52  			itype, name, value, err = st.decodeLiteralFieldLineWithNameReference(firstByte)
    53  		case 2:
    54  			// Literal Field Line with Literal Name
    55  			itype, name, value, err = st.decodeLiteralFieldLineWithLiteralName(firstByte)
    56  		case 3:
    57  			// Indexed Field Line With Post-Base Index
    58  			err = errors.New("dynamic table is not supported yet")
    59  		case 4:
    60  			// Indexed Field Line With Post-Base Name Reference
    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