Source file src/vendor/golang.org/x/net/internal/http3/qpack_encode.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  	"golang.org/x/net/internal/httpcommon"
     9  )
    10  
    11  type qpackEncoder struct {
    12  	// The encoder has no state for now,
    13  	// but that'll change once we add dynamic table support.
    14  	//
    15  	// TODO: dynamic table support.
    16  }
    17  
    18  func (qe *qpackEncoder) init() {
    19  	staticTableOnce.Do(initStaticTableMaps)
    20  }
    21  
    22  // encode encodes a list of headers into a QPACK encoded field section.
    23  //
    24  // The headers func must produce the same headers on repeated calls,
    25  // although the order may vary.
    26  func (qe *qpackEncoder) encode(headers func(func(itype indexType, name, value string))) []byte {
    27  	// Encoded Field Section prefix.
    28  	//
    29  	// We don't yet use the dynamic table, so both values here are zero.
    30  	var b []byte
    31  	b = appendPrefixedInt(b, 0, 8, 0) // Required Insert Count
    32  	b = appendPrefixedInt(b, 0, 7, 0) // Delta Base
    33  
    34  	headers(func(itype indexType, name, value string) {
    35  		// Technically, it is the responsibility of the protocol using HTTP/3
    36  		// to ensure that all field names are already in lowercase. However,
    37  		// this QPACK implementation is solely used by and live in the http3
    38  		// package. So, we might as well do the lowercasing here to make sure
    39  		// we do not miss any callsites or need to create yet another struct
    40  		// wrapping the qpackEncoder.
    41  		name, ascii := httpcommon.LowerHeader(name)
    42  		// Skip writing invalid headers. Per RFC 9114 section 4.2: "Field
    43  		// names are strings containing a subset of ASCII characters."
    44  		if !ascii {
    45  			return
    46  		}
    47  		if itype == mayIndex {
    48  			if i, ok := staticTableByNameValue[tableEntry{name, value}]; ok {
    49  				b = appendIndexedFieldLine(b, staticTable, i)
    50  				return
    51  			}
    52  		}
    53  		if i, ok := staticTableByName[name]; ok {
    54  			b = appendLiteralFieldLineWithNameReference(b, staticTable, itype, i, value)
    55  		} else {
    56  			b = appendLiteralFieldLineWithLiteralName(b, itype, name, value)
    57  		}
    58  	})
    59  
    60  	return b
    61  }
    62  

View as plain text