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 "golang.org/x/net/http2"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:"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{}// 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 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)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 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 are options for Transport.RoundTripOpt
type RoundTripOpt struct {
OnlyCachedConn bool // Only use cached connections
// Has unexported fields
}// 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 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 manages a pool of HTTP/2 client connections
type ClientConnPool interface {
GetClientConn(req *http.Request, addr string) (*ClientConn, error)
MarkDead(*ClientConn)
}// 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 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) errortype DataFrame struct {
FrameHeader
// Has unexported fields
}
func (f *DataFrame) Data() []byte
func (f *DataFrame) StreamEnded() booltype 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.HeaderFieldtype 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() stringtype PingFrame struct {
FrameHeader
Data [8]byte
}
func (f *PingFrame) IsAck() booltype GoAwayFrame struct {
FrameHeader
LastStreamID uint32
ErrCode ErrCode
// Has unexported fields
}
func (f *GoAwayFrame) DebugData() []bytetype RSTStreamFrame struct {
FrameHeader
ErrCode ErrCode
}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() booltype 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
}type WindowUpdateFrame struct {
FrameHeader
Increment uint32
}type ContinuationFrame struct {
FrameHeader
// Has unexported fields
}
func (f *ContinuationFrame) HeaderBlockFragment() []byte
func (f *ContinuationFrame) HeadersEnded() booltype UnknownFrame struct {
FrameHeader
// Has unexported fields
}
func (f *UnknownFrame) Payload() []byte// 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// 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() stringimport (
"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)
}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
}