or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

bpf.mdcontext-ctxhttp.mdcontext.mddict.mddns-dnsmessage.mdhtml-atom.mdhtml-charset.mdhtml.mdhttp-httpguts.mdhttp-httpproxy.mdhttp2-h2c.mdhttp2-hpack.mdhttp2.mdicmp.mdidna.mdindex.mdipv4.mdipv6.mdnettest.mdnetutil.mdproxy.mdpublicsuffix.mdquic-qlog.mdquic.mdtrace.mdwebdav.mdwebsocket.mdxsrftoken.md
tile.json

http2.mddocs/

HTTP/2 Implementation

Package http2 implements the HTTP/2 protocol.

This package is low-level and intended to be used directly by very few people. Most users will use it indirectly through the automatic use by the net/http package (from Go 1.6 and later).

Import

import "golang.org/x/net/http2"

Constants

const (
    // ClientPreface is the string that must be sent by new connections from clients
    ClientPreface = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"

    // NextProtoTLS is the NPN/ALPN protocol negotiated during HTTP/2's TLS setup
    NextProtoTLS = "h2"
)

// TrailerPrefix is a magic prefix for ResponseWriter.Header map keys for trailers
const TrailerPrefix = "Trailer:"

Variables

var (
    VerboseLogs bool
)

var (
    ErrRecursivePush    = errors.New("http2: recursive push not allowed")
    ErrPushLimitReached = errors.New("http2: push would exceed peer's SETTINGS_MAX_CONCURRENT_STREAMS")
)

var DebugGoroutines = os.Getenv("DEBUG_HTTP2_GOROUTINES") == "1"
var ErrFrameTooLarge = errors.New("http2: frame too large")
var ErrNoCachedConn error = noCachedConnError{}

Configuration Functions

// ConfigureServer adds HTTP/2 support to a net/http Server
func ConfigureServer(s *http.Server, conf *Server) error

// ConfigureTransport configures a net/http HTTP/1 Transport to use HTTP/2
func ConfigureTransport(t1 *http.Transport) error

// ConfigureTransports configures HTTP/1 Transport and returns HTTP/2 Transport
func ConfigureTransports(t1 *http.Transport) (*Transport, error)

Server

// Server is an HTTP/2 server
type Server struct {
    MaxHandlers                  int           // Limit of http.Handler ServeHTTP goroutines
    MaxConcurrentStreams         uint32        // Max concurrent streams per client
    MaxDecoderHeaderTableSize    uint32        // SETTINGS_HEADER_TABLE_SIZE (default: 4096)
    MaxEncoderHeaderTableSize    uint32        // Upper limit for header compression table
    MaxReadFrameSize             uint32        // Largest frame to read (16k-16M)
    PermitProhibitedCipherSuites bool          // Allow prohibited cipher suites
    IdleTimeout                  time.Duration // Timeout for idle clients
    ReadIdleTimeout              time.Duration // Timeout before health check ping
    PingTimeout                  time.Duration // Timeout for ping response (default: 15s)
    WriteByteTimeout             time.Duration // Timeout for writing data
    MaxUploadBufferPerConnection int32         // Initial flow control window for connection
    MaxUploadBufferPerStream     int32         // Initial flow control window for stream
    NewWriteScheduler            func() WriteScheduler
    CountError                   func(errType string)
    // Has unexported fields
}

func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts)

ServeConnOpts

type ServeConnOpts struct {
    Context          context.Context // Base context (default: context.Background)
    BaseConfig       *http.Server    // Base configuration for values
    Handler          http.Handler    // Handler for processing requests
    UpgradeRequest   *http.Request   // Initial request for h2c upgrade
    Settings         []byte          // Decoded HTTP2-Settings header contents
    SawClientPreface bool            // Whether HTTP/2 connection preface was read
}

Transport

// Transport is an HTTP/2 Transport (safe for concurrent use)
type Transport struct {
    DialTLSContext            func(ctx context.Context, network, addr string, cfg *tls.Config) (net.Conn, error)
    DialTLS                   func(network, addr string, cfg *tls.Config) (net.Conn, error) // Deprecated
    TLSClientConfig           *tls.Config
    ConnPool                  ClientConnPool
    DisableCompression        bool
    AllowHTTP                 bool   // Allow insecure plain-text "http"
    MaxHeaderListSize         uint32 // SETTINGS_MAX_HEADER_LIST_SIZE
    MaxReadFrameSize          uint32 // SETTINGS_MAX_FRAME_SIZE
    MaxDecoderHeaderTableSize uint32 // SETTINGS_HEADER_TABLE_SIZE
    MaxEncoderHeaderTableSize uint32 // Upper limit for encoding table
    StrictMaxConcurrentStreams bool
    IdleConnTimeout           time.Duration
    ReadIdleTimeout           time.Duration
    PingTimeout               time.Duration
    WriteByteTimeout          time.Duration
    CountError                func(errType string)
    // Has unexported fields
}

func (t *Transport) CloseIdleConnections()
func (t *Transport) NewClientConn(c net.Conn) (*ClientConn, error)
func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error)
func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Response, error)

RoundTripOpt

// RoundTripOpt are options for Transport.RoundTripOpt
type RoundTripOpt struct {
    OnlyCachedConn bool // Only use cached connections
    // Has unexported fields
}

ClientConn

// ClientConn is the state of a single HTTP/2 client connection
type ClientConn struct {
    // Has unexported fields
}

func (cc *ClientConn) CanTakeNewRequest() bool
func (cc *ClientConn) Close() error
func (cc *ClientConn) Ping(ctx context.Context) error
func (cc *ClientConn) ReserveNewRequest() bool
func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error)
func (cc *ClientConn) SetDoNotReuse()
func (cc *ClientConn) Shutdown(ctx context.Context) error
func (cc *ClientConn) State() ClientConnState

ClientConnState

// ClientConnState describes the state of a ClientConn
type ClientConnState struct {
    Closed               bool          // Whether connection is closed
    Closing              bool          // Whether connection is closing
    StreamsActive        int           // Active streams
    StreamsReserved      int           // Reserved streams
    StreamsPending       int           // Pending streams
    MaxConcurrentStreams uint32        // Peer's advertised max
    LastIdle             time.Time     // Last idle transition time
}

ClientConnPool

// ClientConnPool manages a pool of HTTP/2 client connections
type ClientConnPool interface {
    GetClientConn(req *http.Request, addr string) (*ClientConn, error)
    MarkDead(*ClientConn)
}

Frame Types

// Frame is the base interface for all frame types
type Frame interface {
    Header() FrameHeader
    // Has unexported methods
}

// FrameHeader is the 9 byte header of all HTTP/2 frames
type FrameHeader struct {
    Type     FrameType // 1 byte frame type
    Flags    Flags     // 1 byte of 8 potential bit flags
    Length   uint32    // Length of frame (not including header)
    StreamID uint32    // Stream ID (0 for non-stream frames)
    // Has unexported fields
}

func (h FrameHeader) Header() FrameHeader
func (h FrameHeader) String() string

// FrameType is a registered frame type
type FrameType uint8

const (
    FrameData         FrameType = 0x0
    FrameHeaders      FrameType = 0x1
    FramePriority     FrameType = 0x2
    FrameRSTStream    FrameType = 0x3
    FrameSettings     FrameType = 0x4
    FramePushPromise  FrameType = 0x5
    FramePing         FrameType = 0x6
    FrameGoAway       FrameType = 0x7
    FrameWindowUpdate FrameType = 0x8
    FrameContinuation FrameType = 0x9
)

func (t FrameType) String() string

// Flags is a bitmask of HTTP/2 flags
type Flags uint8

const (
    FlagDataEndStream         Flags = 0x1
    FlagDataPadded            Flags = 0x8
    FlagHeadersEndStream      Flags = 0x1
    FlagHeadersEndHeaders     Flags = 0x4
    FlagHeadersPadded         Flags = 0x8
    FlagHeadersPriority       Flags = 0x20
    FlagSettingsAck           Flags = 0x1
    FlagPingAck               Flags = 0x1
    FlagContinuationEndHeaders Flags = 0x4
    FlagPushPromiseEndHeaders Flags = 0x4
    FlagPushPromisePadded     Flags = 0x8
)

func (f Flags) Has(v Flags) bool

Framer

// Framer reads and writes Frames
type Framer struct {
    AllowIllegalWrites  bool           // Permit non-compliant writes
    AllowIllegalReads   bool           // Permit non-compliant reads
    ReadMetaHeaders     *hpack.Decoder // Merge HEADERS+CONTINUATION
    MaxHeaderListSize   uint32         // MAX_HEADER_LIST_SIZE
    // Has unexported fields
}

func NewFramer(w io.Writer, r io.Reader) *Framer
func ReadFrameHeader(r io.Reader) (FrameHeader, error)

func (fr *Framer) ErrorDetail() error
func (fr *Framer) ReadFrame() (Frame, error)
func (fr *Framer) ReadFrameForHeader(fh FrameHeader) (Frame, error)
func (fr *Framer) ReadFrameHeader() (FrameHeader, error)
func (fr *Framer) SetMaxReadFrameSize(v uint32)
func (fr *Framer) SetReuseFrames()
func (f *Framer) WriteContinuation(streamID uint32, endHeaders bool, headerBlockFragment []byte) error
func (f *Framer) WriteData(streamID uint32, endStream bool, data []byte) error
func (f *Framer) WriteDataPadded(streamID uint32, endStream bool, data, pad []byte) error
func (f *Framer) WriteGoAway(maxStreamID uint32, code ErrCode, debugData []byte) error
func (f *Framer) WriteHeaders(p HeadersFrameParam) error
func (f *Framer) WritePing(ack bool, data [8]byte) error
func (f *Framer) WritePriority(streamID uint32, p PriorityParam) error
func (f *Framer) WritePushPromise(p PushPromiseParam) error
func (f *Framer) WriteRSTStream(streamID uint32, code ErrCode) error
func (f *Framer) WriteRawFrame(t FrameType, flags Flags, streamID uint32, payload []byte) error
func (f *Framer) WriteSettings(settings ...Setting) error
func (f *Framer) WriteSettingsAck() error
func (f *Framer) WriteWindowUpdate(streamID, incr uint32) error

Specific Frame Types

DataFrame

type DataFrame struct {
    FrameHeader
    // Has unexported fields
}

func (f *DataFrame) Data() []byte
func (f *DataFrame) StreamEnded() bool

HeadersFrame

type HeadersFrame struct {
    FrameHeader
    Priority PriorityParam
    // Has unexported fields
}

func (f *HeadersFrame) HasPriority() bool
func (f *HeadersFrame) HeaderBlockFragment() []byte
func (f *HeadersFrame) HeadersEnded() bool
func (f *HeadersFrame) StreamEnded() bool

type HeadersFrameParam struct {
    StreamID      uint32
    BlockFragment []byte
    EndStream     bool
    EndHeaders    bool
    PadLength     uint8
    Priority      PriorityParam
}

type MetaHeadersFrame struct {
    *HeadersFrame
    Fields    []hpack.HeaderField
    Truncated bool
}

func (mh *MetaHeadersFrame) PseudoFields() []hpack.HeaderField
func (mh *MetaHeadersFrame) PseudoValue(pseudo string) string
func (mh *MetaHeadersFrame) RegularFields() []hpack.HeaderField

SettingsFrame

type SettingsFrame struct {
    FrameHeader
    // Has unexported fields
}

func (f *SettingsFrame) ForeachSetting(fn func(Setting) error) error
func (f *SettingsFrame) HasDuplicates() bool
func (f *SettingsFrame) IsAck() bool
func (f *SettingsFrame) NumSettings() int
func (f *SettingsFrame) Setting(i int) Setting
func (f *SettingsFrame) Value(id SettingID) (v uint32, ok bool)

type Setting struct {
    ID  SettingID
    Val uint32
}

func (s Setting) String() string
func (s Setting) Valid() error

type SettingID uint16

const (
    SettingHeaderTableSize       SettingID = 0x1
    SettingEnablePush            SettingID = 0x2
    SettingMaxConcurrentStreams  SettingID = 0x3
    SettingInitialWindowSize     SettingID = 0x4
    SettingMaxFrameSize          SettingID = 0x5
    SettingMaxHeaderListSize     SettingID = 0x6
    SettingEnableConnectProtocol SettingID = 0x8
)

func (s SettingID) String() string

PingFrame

type PingFrame struct {
    FrameHeader
    Data [8]byte
}

func (f *PingFrame) IsAck() bool

GoAwayFrame

type GoAwayFrame struct {
    FrameHeader
    LastStreamID uint32
    ErrCode      ErrCode
    // Has unexported fields
}

func (f *GoAwayFrame) DebugData() []byte

RSTStreamFrame

type RSTStreamFrame struct {
    FrameHeader
    ErrCode ErrCode
}

PriorityFrame

type PriorityFrame struct {
    FrameHeader
    PriorityParam
}

type PriorityParam struct {
    StreamDep uint32 // Stream dependency
    Exclusive bool   // Exclusive dependency
    Weight    uint8  // Zero-indexed weight (add 1 for actual weight 1-256)
    // Has unexported fields
}

func (p PriorityParam) IsZero() bool

PushPromiseFrame

type PushPromiseFrame struct {
    FrameHeader
    PromiseID uint32
    // Has unexported fields
}

func (f *PushPromiseFrame) HeaderBlockFragment() []byte
func (f *PushPromiseFrame) HeadersEnded() bool

type PushPromiseParam struct {
    StreamID      uint32
    PromiseID     uint32
    BlockFragment []byte
    EndHeaders    bool
    PadLength     uint8
}

WindowUpdateFrame

type WindowUpdateFrame struct {
    FrameHeader
    Increment uint32
}

ContinuationFrame

type ContinuationFrame struct {
    FrameHeader
    // Has unexported fields
}

func (f *ContinuationFrame) HeaderBlockFragment() []byte
func (f *ContinuationFrame) HeadersEnded() bool

UnknownFrame

type UnknownFrame struct {
    FrameHeader
    // Has unexported fields
}

func (f *UnknownFrame) Payload() []byte

Error Types

// ErrCode is an unsigned 32-bit error code
type ErrCode uint32

const (
    ErrCodeNo                 ErrCode = 0x0
    ErrCodeProtocol           ErrCode = 0x1
    ErrCodeInternal           ErrCode = 0x2
    ErrCodeFlowControl        ErrCode = 0x3
    ErrCodeSettingsTimeout    ErrCode = 0x4
    ErrCodeStreamClosed       ErrCode = 0x5
    ErrCodeFrameSize          ErrCode = 0x6
    ErrCodeRefusedStream      ErrCode = 0x7
    ErrCodeCancel             ErrCode = 0x8
    ErrCodeCompression        ErrCode = 0x9
    ErrCodeConnect            ErrCode = 0xa
    ErrCodeEnhanceYourCalm    ErrCode = 0xb
    ErrCodeInadequateSecurity ErrCode = 0xc
    ErrCodeHTTP11Required     ErrCode = 0xd
)

func (e ErrCode) String() string

type ConnectionError ErrCode

func (e ConnectionError) Error() string

type StreamError struct {
    StreamID uint32
    Code     ErrCode
    Cause    error
}

func (e StreamError) Error() string

type GoAwayError struct {
    LastStreamID uint32
    ErrCode      ErrCode
    DebugData    string
}

func (e GoAwayError) Error() string

Write Scheduling

// WriteScheduler is the interface for HTTP/2 write schedulers
type WriteScheduler interface {
    OpenStream(streamID uint32, options OpenStreamOptions)
    CloseStream(streamID uint32)
    AdjustStream(streamID uint32, priority PriorityParam)
    Push(wr FrameWriteRequest)
    Pop() (wr FrameWriteRequest, ok bool)
}

func NewPriorityWriteScheduler(cfg *PriorityWriteSchedulerConfig) WriteScheduler
func NewRandomWriteScheduler() WriteScheduler

type PriorityWriteSchedulerConfig struct {
    MaxClosedNodesInTree     int
    MaxIdleNodesInTree       int
    ThrottleOutOfOrderWrites bool
}

type OpenStreamOptions struct {
    PusherID uint32
    // Has unexported fields
}

type FrameWriteRequest struct {
    // Has unexported fields
}

func (wr FrameWriteRequest) Consume(n int32) (FrameWriteRequest, FrameWriteRequest, int)
func (wr FrameWriteRequest) DataSize() int
func (wr FrameWriteRequest) StreamID() uint32
func (wr FrameWriteRequest) String() string

Usage Examples

Configuring HTTP/2 Server

import (
    "golang.org/x/net/http2"
    "net/http"
    "time"
)

func setupHTTP2Server() error {
    server := &http.Server{
        Addr: ":8080",
    }

    http2Server := &http2.Server{
        MaxConcurrentStreams:  250,
        MaxReadFrameSize:      1 << 20,
        IdleTimeout:           5 * time.Minute,
        MaxUploadBufferPerConnection: 1 << 20,
    }

    return http2.ConfigureServer(server, http2Server)
}

Configuring HTTP/2 Transport

func setupHTTP2Client() (*http.Client, error) {
    transport := &http.Transport{}

    http2Transport, err := http2.ConfigureTransports(transport)
    if err != nil {
        return nil, err
    }

    http2Transport.ReadIdleTimeout = 30 * time.Second
    http2Transport.PingTimeout = 15 * time.Second

    return &http.Client{Transport: transport}, nil
}