qpack

package module
v0.6.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 8, 2026 License: MIT Imports: 6 Imported by: 1

README

QPACK

PkgGoDev Code Coverage Fuzzing Status

This is a minimal QPACK (RFC 9204) implementation in Go. It reuses the Huffman encoder / decoder code from the HPACK implementation in the Go standard library.

It is fully interoperable with other QPACK implementations (both encoders and decoders). However, it does not support the dynamic table and relies solely on the static table and string literals (including Huffman encoding), which limits compression efficiency. If you're interested in dynamic table support, please comment on issue #33.

Running the Interop Tests

Install the QPACK interop files by running

git submodule update --init --recursive

Then run the tests:

go test -v ./interop

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type DecodeFunc

type DecodeFunc func() (HeaderField, error)

DecodeFunc is a function that decodes the next header field from a header block. It should be called repeatedly until it returns io.EOF. It returns io.EOF when all header fields have been decoded. Any error other than io.EOF indicates a decoding error.

type Decoder

type Decoder struct {
	// contains filtered or unexported fields
}

A Decoder decodes QPACK header blocks. A Decoder can be reused to decode multiple header blocks on different streams on the same connection (e.g., headers then trailers).

func NewDecoder

func NewDecoder() *Decoder

NewDecoder returns a new Decoder with a dynamic table.

func NewDecoderWithCapacity

func NewDecoderWithCapacity(maxCapacity uint64) *Decoder

NewDecoderWithCapacity returns a new Decoder with the given max table capacity.

func (*Decoder) Decode

func (d *Decoder) Decode(p []byte) DecodeFunc

Decode returns a function that decodes header fields from the given header block. It does not copy the slice; the caller must ensure it remains valid during decoding.

func (*Decoder) Duplicate

func (d *Decoder) Duplicate(relIndex uint64) error

Duplicate processes a Duplicate instruction.

func (*Decoder) InsertCount

func (d *Decoder) InsertCount() uint64

InsertCount returns the current insert count of the dynamic table.

func (*Decoder) InsertWithNameReference

func (d *Decoder) InsertWithNameReference(isStatic bool, nameIndex uint64, value string) error

InsertWithNameReference processes an Insert With Name Reference instruction. The name comes from either the static or dynamic table.

func (*Decoder) InsertWithoutNameReference

func (d *Decoder) InsertWithoutNameReference(name, value string) error

InsertWithoutNameReference processes an Insert Without Name Reference instruction.

func (*Decoder) ProcessEncoderInstructions

func (d *Decoder) ProcessEncoderInstructions(data []byte) error

ProcessEncoderInstructions processes instructions from the encoder stream. This should be called with data received on the encoder stream. After processing, it broadcasts to wake any decoders waiting for entries.

func (*Decoder) SetDynamicTableCapacity

func (d *Decoder) SetDynamicTableCapacity(capacity uint64) error

SetDynamicTableCapacity processes a Set Dynamic Table Capacity instruction.

type DynamicTable

type DynamicTable struct {
	// contains filtered or unexported fields
}

DynamicTable represents the QPACK dynamic table. It's a FIFO queue where new entries are added at the front (index 0) and old entries are evicted from the back when capacity is exceeded.

func NewDynamicTable

func NewDynamicTable(capacity uint64) *DynamicTable

NewDynamicTable creates a new dynamic table with the given capacity.

func (*DynamicTable) AtAbsolute

func (dt *DynamicTable) AtAbsolute(absIndex uint64) (HeaderField, bool)

AtAbsolute returns the entry at an absolute index. Absolute index = insertCount at time of insertion.

func (*DynamicTable) AtPostBase

func (dt *DynamicTable) AtPostBase(base, postBaseIndex uint64) (HeaderField, bool)

AtPostBase returns the entry at a post-base index. Post-base indices are used for entries inserted after the base.

func (*DynamicTable) AtRelative

func (dt *DynamicTable) AtRelative(relIndex uint64) (HeaderField, bool)

AtRelative returns the entry at a relative index (0 = most recent).

func (*DynamicTable) Insert

func (dt *DynamicTable) Insert(hf HeaderField) uint64

Insert adds a new entry to the dynamic table. Returns the absolute index of the inserted entry.

func (*DynamicTable) InsertCount

func (dt *DynamicTable) InsertCount() uint64

InsertCount returns the total number of entries ever inserted.

func (*DynamicTable) Len

func (dt *DynamicTable) Len() int

Len returns the current number of entries in the table.

func (*DynamicTable) SetCapacity

func (dt *DynamicTable) SetCapacity(capacity uint64)

SetCapacity sets the maximum capacity of the dynamic table. If the new capacity is smaller, entries are evicted.

type Encoder

type Encoder struct {
	// contains filtered or unexported fields
}

An Encoder performs QPACK encoding.

func NewEncoder

func NewEncoder(w io.Writer) *Encoder

NewEncoder returns a new Encoder which performs QPACK encoding. An encoded data is written to w.

func (*Encoder) Close

func (e *Encoder) Close() error

Close declares that the encoding is complete and resets the Encoder to be reused again for a new header block.

func (*Encoder) WriteField

func (e *Encoder) WriteField(f HeaderField) error

WriteField encodes f into a single Write to e's underlying Writer. This function may also produce bytes for the Header Block Prefix if necessary. If produced, it is done before encoding f.

type HeaderField

type HeaderField struct {
	Name      string
	Value     string
	Sensitive bool // If true, encode with Never-Index (N=1) bit set
}

A HeaderField is a name-value pair. Both the name and value are treated as opaque sequences of octets.

func (HeaderField) IsPseudo

func (hf HeaderField) IsPseudo() bool

IsPseudo reports whether the header field is an HTTP3 pseudo header. That is, it reports whether it starts with a colon. It is not otherwise guaranteed to be a valid pseudo header field, though.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL