Standard library · Network

net/http2

The HTTP/2 protocol from the ground up: frames, HPACK header compression and streams.

import net.http2

This package implements HTTP/2 at the protocol level: it builds and reads frames, compresses the headers with HPACK and carries several requests at once over one connection as "streams". For building an ordinary web server net/http is simpler; this package is for when you need the protocol itself.

How it goes: build a Transport over a TCP or TLS socket, take a connection with NewConn and do the handshake. Then the client sends a request with SendHeaders and reads the answer in StreamAt after AwaitStreamEnd. Over TLS, the client and the server must have agreed on h2 through ALPN.

Types

Stream

struct Stream
One stream: one request and its answer.
NameTypeDescription
idint = 0The id; odd for the streams a client opens.
stateint = 0The state, one of the stream state constants.
send_windowint = 65535The sending window.
recv_windowint = 65535The receiving window.
headersHeaderListThe headers received.
trailersHeaderListThe trailing headers received.
datacompress.ByteBufThe body received.
got_headersbool = falseThe headers have arrived.
got_trailersbool = falseThe trailing headers have arrived.
end_streambool = falseThe other side has ended the stream.
resetbool = falseThe stream was closed with a reset frame.
error_codeint = 0The reset's error code.
livebool = falseThis slot of the table is in use.
net-http2-Conn.salam
import net.http2
import net.tcp
import compress

mut server := tcp.Server {}

func answer():
    conn := tcp.Accept(server)
    mut c := http2.NewConn(http2.PlainTransport(conn.fd), true)
    if not http2.ServerHandshake(c):
        ret
    end
    id := http2.AwaitAnyHeaders(c, 20)
    stream := http2.StreamAt(c, id)
    mut headers := http2.HeaderList {}
    http2.HeadersAdd(headers, ":status", "200")
    http2.HeadersAdd(headers, "content-type", "text/plain")
    _ := http2.SendHeaders(c, id, headers, false)
    _ := http2.SendData(c, id, compress.BufFromStr("hello " + http2.HeadersGet(stream.headers, ":path")), false)
    mut trailers := http2.HeaderList {}
    http2.HeadersAdd(trailers, "x-done", "1")
    _ := http2.SendTrailers(c, id, trailers)
    _ := http2.AwaitStreamEnd(c, 0, 5)
    http2.CloseConn(c)
end

func main:
    server = tcp.Bind(0)
    t := spawn(answer)
    conn := tcp.Dial("127.0.0.1", tcp.Port(server))
    tx := http2.PlainTransport(conn.fd)
    println tx.ok, tx.kind == http2.H2_TRANSPORT_PLAIN
    mut c := http2.NewConn(tx, false)
    println http2.ClientHandshake(c), http2.ConnOk(c)
    id := http2.NextStreamId(c)
    mut headers := http2.HeaderList {}
    http2.HeadersAdd(headers, ":method", "GET")
    http2.HeadersAdd(headers, ":scheme", "http")
    http2.HeadersAdd(headers, ":path", "/books")
    http2.HeadersAdd(headers, ":authority", "127.0.0.1")
    println id, http2.SendHeaders(c, id, headers, true)
    println http2.AwaitStreamEnd(c, id, 20)
    stream := http2.StreamAt(c, id)
    println http2.HeadersGet(stream.headers, ":status"), compress.BufToStrUnsafe(stream.data), stream.got_trailers, http2.HeadersGet(stream.trailers, "x-done"), stream.end_stream
    println http2.StreamCount(c) >= 1, c.remote.max_frame_size
    _ := http2.SendPing(c, compress.BufFromStr("abcdefgh"))
    println http2.Poll(c) >= http2.H2_POLL_CONNECTION
    _ := http2.SendRstStream(c, http2.NextStreamId(c), http2.H2_CANCEL)
    println http2.SendGoAway(c, http2.H2_NO_ERROR, "")
    http2.CloseConn(c)
    join(t)
    tcp.CloseServer(server)
end
Outputtrue true true true 1 true true 200 hello /books true 1 true true 16384 true true

StreamTable

struct StreamTable
The table of a connection's streams.
NameTypeDescription
itemsVectorThe streams.

The example for this item is shown with the ones above: net-http2-Conn.salam

Conn

struct Conn
One HTTP/2 connection with its tables, settings and streams.
NameTypeDescription
txTransportThe transport underneath.
is_serverbool = falseThis side is the server.
encDynTableThe HPACK table for sending.
decDynTableThe HPACK table for receiving.
localSettingsThis side's settings.
remoteSettingsThe other side's settings, after the handshake.
next_idint = 1The next stream id.
streamsStreamTableThe streams.
send_windowint = 65535The connection's sending window.
recv_windowint = 65535The connection's receiving window.
goawaybool = falseA goaway frame arrived or was sent.
last_errorint = 0The last error code.
okbool = falseThe connection is healthy.
pending_streamint = 0The stream whose headers block is not finished yet by a continuation frame.
pending_blockcompress.ByteBufThe parts of that block that arrived.
pending_end_streambool = falseThose headers end the stream.
pending_trailersbool = falseThose headers are trailing ones.

The example for this item is shown with the ones above: net-http2-Conn.salam

Frame

struct Frame
One HTTP/2 frame.
NameTypeDescription
kindint = 0The frame type, one of the frame type constants.
flagsint = 0The flags.
stream_idint = 0The stream id; zero means the whole connection.
payloadcompress.ByteBufThe frame payload.
okbool = falseThe frame was read correctly.
net-http2-Frame.salam
import net.http2
import compress

func main:
    mut settings := http2.DefaultSettings()
    println settings.header_table_size, settings.initial_window_size, settings.max_frame_size, settings.enable_push
    frame := http2.MakeSettingsFrame(settings)
    println http2.FrameTypeName(frame.kind), frame.stream_id, frame.payload.len
    settings.max_frame_size = 32768
    println http2.ApplySettings(settings, http2.MakeSettingsFrame(http2.DefaultSettings())), settings.max_frame_size
    ack := http2.MakeSettingsAck()
    println http2.FrameHasFlag(ack, http2.H2_FLAG_ACK)
    win := http2.MakeWindowUpdate(3, 1024)
    println http2.FrameTypeName(win.kind), http2.WindowIncrementOf(win)
    rst := http2.MakeRstStream(5, http2.H2_CANCEL)
    println http2.ErrorCodeOf(rst), http2.ErrorName(http2.ErrorCodeOf(rst))
    away := http2.MakeGoAway(7, http2.H2_NO_ERROR, "bye")
    println http2.FrameTypeName(away.kind), http2.ErrorCodeOf(away)
    ping := http2.MakePing(compress.BufFromStr("12345678"), false)
    println http2.FrameTypeName(ping.kind), ping.payload.len
    mut data := http2.NewFrame(http2.H2_DATA, http2.H2_FLAG_END_STREAM, 1)
    compress.BufPushBytes(data.payload, "hello" as void*, 5)
    mut ok := true
    println compress.BufToStrUnsafe(http2.DataOf(data, ok)), ok
    bytes := http2.FrameEncode(data)
    println bytes.len, compress.BufGet(bytes, 3)
    mut head := http2.NewFrame(http2.H2_HEADERS, http2.H2_FLAG_END_HEADERS, 1)
    compress.BufPush(head.payload, 130)
    println http2.HeaderBlockOf(head, ok).len, ok
    mut one := compress.NewByteBuf()
    http2.PutSetting(one, http2.H2_SETTINGS_MAX_FRAME_SIZE, 16384)
    println one.len
    http2.FreeFrame(data)
    println http2.H2_DATA, http2.H2_PING, http2.H2_PROTOCOL_ERROR, http2.H2_DEFAULT_FRAME_SIZE, http2.H2_DEFAULT_WINDOW, http2.H2_MAX_FRAME_LIMIT
    println http2.FrameTypeName(http2.H2_PRIORITY), http2.FrameTypeName(http2.H2_RST_STREAM), http2.FrameTypeName(http2.H2_PUSH_PROMISE)
    println http2.FrameTypeName(http2.H2_GOAWAY), http2.FrameTypeName(http2.H2_WINDOW_UPDATE), http2.FrameTypeName(http2.H2_CONTINUATION)
    println http2.H2_SETTINGS_HEADER_TABLE_SIZE, http2.H2_SETTINGS_ENABLE_PUSH, http2.H2_SETTINGS_MAX_CONCURRENT_STREAMS, http2.H2_SETTINGS_INITIAL_WINDOW_SIZE, http2.H2_SETTINGS_MAX_HEADER_LIST_SIZE
    println http2.ErrorName(http2.H2_INTERNAL_ERROR), http2.ErrorName(http2.H2_FLOW_CONTROL_ERROR), http2.ErrorName(http2.H2_SETTINGS_TIMEOUT), http2.ErrorName(http2.H2_STREAM_CLOSED)
    println http2.ErrorName(http2.H2_FRAME_SIZE_ERROR), http2.ErrorName(http2.H2_REFUSED_STREAM), http2.ErrorName(http2.H2_COMPRESSION_ERROR), http2.ErrorName(http2.H2_CONNECT_ERROR)
    println http2.ErrorName(http2.H2_ENHANCE_YOUR_CALM), http2.ErrorName(http2.H2_INADEQUATE_SECURITY), http2.ErrorName(http2.H2_HTTP_1_1_REQUIRED)
    println http2.H2_STREAM_IDLE, http2.H2_STREAM_OPEN, http2.H2_STREAM_HALF_CLOSED_LOCAL, http2.H2_STREAM_HALF_CLOSED_REMOTE, http2.H2_STREAM_CLOSED_STATE
    println http2.H2_DEFAULT_TABLE_SIZE, http2.H2_POLL_ERROR
end
Output4096 65535 16384 1 SETTINGS 0 24 true 16384 true WINDOW_UPDATE 1024 8 CANCEL GOAWAY 0 PING 8 hello true 14 0 1 true 6 0 6 1 16384 65535 16777215 PRIORITY RST_STREAM PUSH_PROMISE GOAWAY WINDOW_UPDATE CONTINUATION 1 2 3 4 6 INTERNAL_ERROR FLOW_CONTROL_ERROR SETTINGS_TIMEOUT STREAM_CLOSED FRAME_SIZE_ERROR REFUSED_STREAM COMPRESSION_ERROR CONNECT_ERROR ENHANCE_YOUR_CALM INADEQUATE_SECURITY HTTP_1_1_REQUIRED 0 1 2 3 4 4096 -1
struct Header
One header.
NameTypeDescription
namestr = ""The name; in HTTP/2 always in lower case.
valuestr = ""The value.
sensitivebool = falseIt is sensitive and never goes into the HPACK table; for tokens and cookies.
net-http2-Hpack.salam
import net.http2
import compress

func main:
    mut list := http2.HeaderList {}
    http2.HeadersAdd(list, ":method", "GET")
    http2.HeadersAdd(list, ":path", "/")
    http2.HeadersAdd(list, "user-agent", "salam")
    http2.HeadersAddSensitive(list, "authorization", "Bearer x")
    println http2.HeadersCount(list), http2.HeadersGet(list, ":path"), http2.HeadersHas(list, "cookie")
    mut sender := http2.NewDynTable(4096)
    mut receiver := http2.NewDynTable(4096)
    block := http2.EncodeHeaderList(sender, list, true)
    println block.len, http2.DynCount(sender), http2.DynSize(sender)
    mut ok := true
    read := http2.DecodeHeaderList(receiver, block, ok)
    println ok, read.items.len(), read.items[2].name, read.items[2].value, read.items[3].sensitive
    block2 := http2.EncodeHeaderList(sender, list, true)
    println block2.len < block.len
    fixed := http2.StaticGet(2)
    println fixed.name, fixed.value, http2.HPACK_STATIC_COUNT, http2.HPACK_ENTRY_OVERHEAD
    dyn := http2.DynGet(receiver, 1)
    println dyn.name
    mut exact := false
    println http2.TableFind(receiver, ":method", "GET", exact), exact
    println http2.TableGet(receiver, 62, ok).name, ok
    mut b := compress.NewByteBuf()
    http2.EncodeTableSizeUpdate(b, sender, 256)
    http2.DynSetMaxSize(receiver, 256)
    println b.len, sender.max_size, receiver.max_size
    mut b2 := compress.NewByteBuf()
    http2.EncodeHeader(b2, sender, http2.NewHeader("x-id", "7"), false)
    http2.DynInsert(receiver, http2.NewSensitiveHeader("k", "v"))
    println b2.len, http2.DynCount(receiver)
end
Output4 / false 17 1 47 true 4 user-agent salam true true :method GET 61 32 user-agent 2 true user-agent true 3 256 256 8 2

HeaderList

struct HeaderList
A list of headers, in their order.
NameTypeDescription
itemsVector
The headers.

The example for this item is shown with the ones above: net-http2-Hpack.salam

DynTable

struct DynTable
The HPACK dynamic table, which keeps the headers sent or received so that next time only their number is sent. Each side has its own table and the two must stay in step.
NameTypeDescription
itemsVector
The entries.
headint = 0The position of the newest entry in the ring.
sizeint = 0The current size in bytes, with the overhead.
max_sizeint = 4096The largest size; older entries are pushed out.

The example for this item is shown with the ones above: net-http2-Hpack.salam

HufTables

struct HufTables
The internal tables of the Huffman decoder; they are built once and then used again.
NameTypeDescription
countsVectorThe number of codes of each length.
firstVectorThe first code of each length.
symsVectorThe symbols in code order.
readybool = falseThe tables are built.
net-http2-Huffman.salam
import net.http2
import encoding
import compress

func main:
    b := http2.HuffmanEncodeStr("www.example.com")
    println encoding.HexEncode(compress.BufToStrUnsafe(b))
    println http2.HuffmanEncodedLenStr("www.example.com"), "www.example.com".len()
    mut ok := true
    println compress.BufToStrUnsafe(http2.HuffmanDecodeBuf(b, ok)), ok
    text := compress.BufFromStr("no-cache")
    println http2.HuffmanEncodedLen(text.data, text.len)
    mut out := compress.NewByteBuf()
    compress.BufPush(out, 0)
    http2.HuffmanEncode(out, text.data, text.len)
    println compress.BufToStrUnsafe(http2.HuffmanDecode(out, 1, out.len - 1, ok)), ok
end
Outputf1e3c2e5f23a6ba0ab90f4ff 12 15 www.example.com true 6 no-cache true

TlsBox

struct TlsBox
The internal holder of the TLS connections that the secure transports point into.
NameTypeDescription
itemsVectorThe connections.
net-http2-TLS.salam
import net.http2
import net.tcp

func main:
    secure := tcp.DialTLS("example.com", 443)
    mut c := http2.NewConn(http2.TLSTransport(secure), false)
    println http2.ClientHandshake(c), c.tx.kind == http2.H2_TRANSPORT_TLS
    http2.CloseConn(c)
end

Settings

struct Settings
The settings of one side of the connection.
NameTypeDescription
header_table_sizeint = 4096The HPACK table size.
enable_pushint = 1Server push; 1 or 0.
max_concurrent_streamsint = -1The most streams at once; -1 means no limit.
initial_window_sizeint = 65535The starting window.
max_frame_sizeint = 16384The largest frame size.
max_header_list_sizeint = -1The largest header size; -1 means no limit.

The example for this item is shown with the ones above: net-http2-Frame.salam

Transport

struct Transport
The layer that sends the bytes over TCP or TLS.
NameTypeDescription
kindint = 0The transport type.
fdi64 = -1The socket descriptor.
sec_idint = -1The number of the TLS connection in the internal holder.
okbool = falseThe transport is healthy.

The example for this item is shown with the ones above: net-http2-Conn.salam

Constants and variables

H2_POLL_ERROR

const H2_POLL_ERROR: i32 = -1
A result of Poll: an error, or the connection closed.

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_POLL_CONNECTION

const H2_POLL_CONNECTION: i32 = 0
A result of Poll: a frame for the whole connection arrived. A positive number is the id of the stream whose frame arrived.

The example for this item is shown with the ones above: net-http2-Conn.salam

H2_PREFACE

const H2_PREFACE: str = "PRI * HTTP/2.0

SM

"
The string an HTTP/2 client sends before anything else; 24 bytes.
net-http2-Transport.salam
import net.http2
import net.tcp
import compress

mut server := tcp.Server {}

func answer():
    conn := tcp.Accept(server)
    mut tx := http2.PlainTransport(conn.fd)
    println "server preface:", http2.ReadPreface(tx)
    frame := http2.ReadFrame(tx, http2.H2_DEFAULT_FRAME_SIZE)
    println "server frame:", frame.ok, http2.FrameTypeName(frame.kind), frame.stream_id, compress.BufToStrUnsafe(frame.payload)
    http2.CloseTransport(tx)
end

func main:
    server = tcp.Bind(0)
    t := spawn(answer)
    conn := tcp.Dial("127.0.0.1", tcp.Port(server))
    mut tx := http2.PlainTransport(conn.fd)
    _ := http2.WritePreface(tx)
    mut data := http2.NewFrame(http2.H2_DATA, 0, 3)
    compress.BufPushBuf(data.payload, compress.BufFromStr("hi"))
    _ := http2.WriteFrame(tx, data)
    join(t)
    http2.CloseTransport(tx)
    tcp.CloseServer(server)
    println http2.H2_PREFACE.len()
end
Outputserver preface: true server frame: true DATA 3 hi 24

H2_DATA

const H2_DATA: i32 = 0
The body data frame.

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_HEADERS

const H2_HEADERS: i32 = 1
The headers frame.

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_PRIORITY

const H2_PRIORITY: i32 = 2
The priority frame; it is deprecated but still read.

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_RST_STREAM

const H2_RST_STREAM: i32 = 3
The frame that closes one stream with an error code.

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_SETTINGS

const H2_SETTINGS: i32 = 4
The settings frame.

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_PUSH_PROMISE

const H2_PUSH_PROMISE: i32 = 5
The frame for a server push promise.

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_PING

const H2_PING: i32 = 6
The ping frame, for checking that the connection is alive.

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_GOAWAY

const H2_GOAWAY: i32 = 7
The frame that ends the connection.

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_WINDOW_UPDATE

const H2_WINDOW_UPDATE: i32 = 8
The frame that grows the flow control window.

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_CONTINUATION

const H2_CONTINUATION: i32 = 9
The rest of a headers block that did not fit in one frame.

The example for this item is shown with the ones above: net-http2-Frame.salam

The frame flags H2_FLAG_…

The flags in the fifth byte of a frame. What each flag means depends on the frame type; that is why H2_FLAG_END_STREAM and H2_FLAG_ACK are both 1, one for a data or headers frame and the other for settings and ping. Check them with FrameHasFlag.
NameValue
H2_FLAG_END_STREAM1
H2_FLAG_ACK1
H2_FLAG_END_HEADERS4
H2_FLAG_PADDED8
H2_FLAG_PRIORITY32

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_SETTINGS_HEADER_TABLE_SIZE

const H2_SETTINGS_HEADER_TABLE_SIZE: i32 = 1
Setting id: the largest size of the HPACK dynamic table.

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_SETTINGS_ENABLE_PUSH

const H2_SETTINGS_ENABLE_PUSH: i32 = 2
Setting id: whether the server is allowed to push.

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_SETTINGS_MAX_CONCURRENT_STREAMS

const H2_SETTINGS_MAX_CONCURRENT_STREAMS: i32 = 3
Setting id: the most streams at once.

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_SETTINGS_INITIAL_WINDOW_SIZE

const H2_SETTINGS_INITIAL_WINDOW_SIZE: i32 = 4
Setting id: the starting window size of each stream.

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_SETTINGS_MAX_FRAME_SIZE

const H2_SETTINGS_MAX_FRAME_SIZE: i32 = 5
Setting id: the largest payload of a frame.

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_SETTINGS_MAX_HEADER_LIST_SIZE

const H2_SETTINGS_MAX_HEADER_LIST_SIZE: i32 = 6
Setting id: the largest header size of a request.

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_NO_ERROR

const H2_NO_ERROR: i32 = 0
Error code: no error, for a normal close.

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_PROTOCOL_ERROR

const H2_PROTOCOL_ERROR: i32 = 1
Error code: a protocol error.

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_INTERNAL_ERROR

const H2_INTERNAL_ERROR: i32 = 2
Error code: an internal error.

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_FLOW_CONTROL_ERROR

const H2_FLOW_CONTROL_ERROR: i32 = 3
Error code: flow control was broken.

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_SETTINGS_TIMEOUT

const H2_SETTINGS_TIMEOUT: i32 = 4
Error code: the settings acknowledgement did not arrive in time.

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_STREAM_CLOSED

const H2_STREAM_CLOSED: i32 = 5
Error code: a frame arrived on a closed stream.

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_FRAME_SIZE_ERROR

const H2_FRAME_SIZE_ERROR: i32 = 6
Error code: the frame size is wrong.

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_REFUSED_STREAM

const H2_REFUSED_STREAM: i32 = 7
Error code: the stream was refused before it was processed and can be sent again.

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_CANCEL

const H2_CANCEL: i32 = 8
Error code: the stream is no longer needed.

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_COMPRESSION_ERROR

const H2_COMPRESSION_ERROR: i32 = 9
Error code: an HPACK error; the connection cannot be used any more.

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_CONNECT_ERROR

const H2_CONNECT_ERROR: i32 = 10
Error code: the CONNECT tunnel's connection closed.

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_ENHANCE_YOUR_CALM

const H2_ENHANCE_YOUR_CALM: i32 = 11
Error code: the other side is sending too many requests.

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_INADEQUATE_SECURITY

const H2_INADEQUATE_SECURITY: i32 = 12
Error code: the TLS security is not enough.

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_HTTP_1_1_REQUIRED

const H2_HTTP_1_1_REQUIRED: i32 = 13
Error code: send the request with HTTP/1.1.

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_DEFAULT_FRAME_SIZE

const H2_DEFAULT_FRAME_SIZE: i32 = 16384
The default frame payload size: 16384 bytes.

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_DEFAULT_WINDOW

const H2_DEFAULT_WINDOW: i32 = 65535
The default window size: 65535 bytes.

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_DEFAULT_TABLE_SIZE

const H2_DEFAULT_TABLE_SIZE: i32 = 4096
The default HPACK table size: 4096 bytes.

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_MAX_FRAME_LIMIT

const H2_MAX_FRAME_LIMIT: i32 = 16777215
The largest frame size the protocol allows.

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_STREAM_IDLE

const H2_STREAM_IDLE: i32 = 0
Stream state: not opened yet.

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_STREAM_OPEN

const H2_STREAM_OPEN: i32 = 1
Stream state: open on both sides.

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_STREAM_HALF_CLOSED_LOCAL

const H2_STREAM_HALF_CLOSED_LOCAL: i32 = 2
Stream state: this side no longer sends.

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_STREAM_HALF_CLOSED_REMOTE

const H2_STREAM_HALF_CLOSED_REMOTE: i32 = 3
Stream state: the other side no longer sends.

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_STREAM_CLOSED_STATE

const H2_STREAM_CLOSED_STATE: i32 = 4
Stream state: closed.

The example for this item is shown with the ones above: net-http2-Frame.salam

H2_TRANSPORT_PLAIN

const H2_TRANSPORT_PLAIN: i32 = 0
A plain TCP transport, that is h2c.

The example for this item is shown with the ones above: net-http2-Conn.salam

H2_TRANSPORT_TLS

const H2_TRANSPORT_TLS: i32 = 1
A secure TLS transport.

The example for this item is shown with the ones above: net-http2-TLS.salam

HPACK_STATIC_COUNT

const HPACK_STATIC_COUNT: i32 = 61
The number of entries in the HPACK static table, that is 61. Larger numbers reach the dynamic table.

The example for this item is shown with the ones above: net-http2-Hpack.salam

HPACK_ENTRY_OVERHEAD

const HPACK_ENTRY_OVERHEAD: i32 = 32
The overhead of each entry in the dynamic table's size: 32 bytes plus the length of the name and the value.

The example for this item is shown with the ones above: net-http2-Hpack.salam

Functions

NewConn

func NewConn(t: Transport, is_server: bool): Conn
A new connection over a transport; the second parameter says whether this side is the server or the client.

The example for this item is shown with the ones above: net-http2-Conn.salam

ClientHandshake

func ClientHandshake(c &: Conn): bool
Sends the preface and the settings and reads the server's settings.

The example for this item is shown with the ones above: net-http2-Conn.salam

ServerHandshake

func ServerHandshake(c &: Conn): bool
Reads the client's preface and exchanges the settings.

The example for this item is shown with the ones above: net-http2-Conn.salam

NextStreamId

func NextStreamId(c &: Conn): int
Gives a new stream id and moves the counter forward.

The example for this item is shown with the ones above: net-http2-Conn.salam

StreamAt

func StreamAt(c: Conn, id: int): Stream
The stream with this id; if there is none, an empty stream.

The example for this item is shown with the ones above: net-http2-Conn.salam

StreamCount

func StreamCount(c: Conn): int
The number of the connection's streams.

The example for this item is shown with the ones above: net-http2-Conn.salam

ConnOk

func ConnOk(c: Conn): bool
The connection can still be used.

The example for this item is shown with the ones above: net-http2-Conn.salam

SendHeaders

func SendHeaders(c &: Conn, stream_id: int, hl: HeaderList, end_stream: bool): bool
Sends the headers on a stream; if the request has no body, pass true so the stream ends right here.

The example for this item is shown with the ones above: net-http2-Conn.salam

SendTrailers

func SendTrailers(c &: Conn, stream_id: int, hl: HeaderList): bool
Sends the trailing headers and ends the stream.

The example for this item is shown with the ones above: net-http2-Conn.salam

SendData

func SendData(c &: Conn, stream_id: int, body: compress.ByteBuf, end_stream: bool): bool
Sends the body and cuts it up to the frame size and the window.

The example for this item is shown with the ones above: net-http2-Conn.salam

SendRstStream

func SendRstStream(c &: Conn, stream_id: int, error_code: int): bool
Closes the stream with an error code.

The example for this item is shown with the ones above: net-http2-Conn.salam

SendGoAway

func SendGoAway(c &: Conn, error_code: int, debug: str): bool
Tells the other side the connection is closing.

The example for this item is shown with the ones above: net-http2-Conn.salam

SendPing

func SendPing(c &: Conn, payload: compress.ByteBuf): bool
Sends a ping with 8 bytes of data.

The example for this item is shown with the ones above: net-http2-Conn.salam

Poll

func Poll(c &: Conn): int
Reads and processes one frame; returns a stream id or one of the poll result constants.

The example for this item is shown with the ones above: net-http2-Conn.salam

AwaitStreamEnd

func AwaitStreamEnd(c &: Conn, stream_id: int, max_frames: int): bool
Reads frames until the stream ends, or at most this many frames; if the stream ended, true.

The example for this item is shown with the ones above: net-http2-Conn.salam

AwaitAnyHeaders

func AwaitAnyHeaders(c &: Conn, max_frames: int): int
Reads frames until the headers of a new stream arrive and returns its id; for a server.

The example for this item is shown with the ones above: net-http2-Conn.salam

CloseConn

func CloseConn(c &: Conn)
Closes the connection and the transport and frees the memory.

The example for this item is shown with the ones above: net-http2-Conn.salam

HuffmanEncodedLen

func HuffmanEncodedLen(p: void*, n: int): int
The length of the bytes that come out of the HPACK Huffman code, for deciding whether compressing is worth it.

The example for this item is shown with the ones above: net-http2-Huffman.salam

HuffmanEncodedLenStr

func HuffmanEncodedLenStr(s: str): int
Like the routine above, for a string.

The example for this item is shown with the ones above: net-http2-Huffman.salam

HuffmanEncode

func HuffmanEncode(out &: compress.ByteBuf, p: void*, n: int)
Adds the bytes to the end of the buffer with the HPACK Huffman code.

The example for this item is shown with the ones above: net-http2-Huffman.salam

HuffmanEncodeStr

func HuffmanEncodeStr(s: str): compress.ByteBuf
Encodes a string with the HPACK Huffman code and returns a new buffer.

The example for this item is shown with the ones above: net-http2-Huffman.salam

HuffmanDecode

func HuffmanDecode(src: compress.ByteBuf, from: int, len: int, ok &: bool): compress.ByteBuf
Decodes a part of the buffer, from the given position and with the given length; if the data is broken, ok becomes false.

The example for this item is shown with the ones above: net-http2-Huffman.salam

HuffmanDecodeBuf

func HuffmanDecodeBuf(src: compress.ByteBuf, ok &: bool): compress.ByteBuf
Decodes the whole buffer.

The example for this item is shown with the ones above: net-http2-Huffman.salam

FrameTypeName

func FrameTypeName(kind: int): str
The name of a frame type, like DATA.

The example for this item is shown with the ones above: net-http2-Frame.salam

ErrorName

func ErrorName(code: int): str
The name of an error code, like CANCEL.

The example for this item is shown with the ones above: net-http2-Frame.salam

NewHeader

func NewHeader(name: str, value: str): Header
A new header.

The example for this item is shown with the ones above: net-http2-Hpack.salam

NewSensitiveHeader

func NewSensitiveHeader(name: str, value: str): Header
A new sensitive header.

The example for this item is shown with the ones above: net-http2-Hpack.salam

HeadersAdd

func HeadersAdd(hl &: HeaderList, name: str, value: str)
Adds a header to a list.

The example for this item is shown with the ones above: net-http2-Hpack.salam

HeadersAddSensitive

func HeadersAddSensitive(hl &: HeaderList, name: str, value: str)
Adds a sensitive header to a list.

The example for this item is shown with the ones above: net-http2-Hpack.salam

HeadersGet

func HeadersGet(hl: HeaderList, name: str): str
The value of the first header with this name; if there is none, an empty string.

The example for this item is shown with the ones above: net-http2-Hpack.salam

HeadersHas

func HeadersHas(hl: HeaderList, name: str): bool
The list has this header.

The example for this item is shown with the ones above: net-http2-Hpack.salam

HeadersCount

func HeadersCount(hl: HeaderList): int
The number of headers.

The example for this item is shown with the ones above: net-http2-Hpack.salam

DefaultSettings

func DefaultSettings(): Settings
The protocol's default settings.

The example for this item is shown with the ones above: net-http2-Frame.salam

PlainTransport

func PlainTransport(fd: i64): Transport
A plain transport over an open TCP socket.

The example for this item is shown with the ones above: net-http2-Conn.salam

TLSTransport

func TLSTransport(c: tls.Conn): Transport
A secure transport over a TLS connection.

The example for this item is shown with the ones above: net-http2-TLS.salam

CloseTransport

func CloseTransport(t &: Transport)
Closes the transport.

The example for this item is shown with the ones above: net-http2-Transport.salam

NewFrame

func NewFrame(kind: int, flags: int, stream_id: int): Frame
An empty frame with a type, flags and a stream id.

The example for this item is shown with the ones above: net-http2-Frame.salam

FreeFrame

func FreeFrame(f &: Frame)
Frees the frame payload's memory.

The example for this item is shown with the ones above: net-http2-Frame.salam

FrameHasFlag

func FrameHasFlag(f: Frame, flag: int): bool
The frame has this flag.

The example for this item is shown with the ones above: net-http2-Frame.salam

FrameEncode

func FrameEncode(f: Frame): compress.ByteBuf
Turns the frame, with its 9 byte header, into bytes.

The example for this item is shown with the ones above: net-http2-Frame.salam

WriteFrame

func WriteFrame(t &: Transport, f: Frame): bool
Writes the frame over the transport.

The example for this item is shown with the ones above: net-http2-Transport.salam

ReadFrame

func ReadFrame(t &: Transport, max_frame_size: int): Frame
Reads one frame from the transport; a frame larger than the given size is refused.

The example for this item is shown with the ones above: net-http2-Transport.salam

WritePreface

func WritePreface(t &: Transport): bool
Sends the preface.

The example for this item is shown with the ones above: net-http2-Transport.salam

ReadPreface

func ReadPreface(t &: Transport): bool
Reads the preface and checks that it is right.

The example for this item is shown with the ones above: net-http2-Transport.salam

HeaderBlockOf

func HeaderBlockOf(f: Frame, ok &: bool): compress.ByteBuf
The HPACK block of a headers frame, without the padding and the priority.

The example for this item is shown with the ones above: net-http2-Frame.salam

DataOf

func DataOf(f: Frame, ok &: bool): compress.ByteBuf
The data of a data frame, without the padding.

The example for this item is shown with the ones above: net-http2-Frame.salam

MakeSettingsFrame

func MakeSettingsFrame(s: Settings): Frame
A settings frame out of a settings struct.

The example for this item is shown with the ones above: net-http2-Frame.salam

MakeSettingsAck

func MakeSettingsAck(): Frame
The settings acknowledgement frame.

The example for this item is shown with the ones above: net-http2-Frame.salam

ApplySettings

func ApplySettings(s &: Settings, f: Frame): bool
Applies a frame's settings to the struct; if a value is invalid, false.

The example for this item is shown with the ones above: net-http2-Frame.salam

MakeWindowUpdate

func MakeWindowUpdate(stream_id: int, increment: int): Frame
The window update frame.

The example for this item is shown with the ones above: net-http2-Frame.salam

WindowIncrementOf

func WindowIncrementOf(f: Frame): int
The increment in a window frame.

The example for this item is shown with the ones above: net-http2-Frame.salam

MakeRstStream

func MakeRstStream(stream_id: int, error_code: int): Frame
The stream reset frame.

The example for this item is shown with the ones above: net-http2-Frame.salam

ErrorCodeOf

func ErrorCodeOf(f: Frame): int
The error code of a reset or goaway frame.

The example for this item is shown with the ones above: net-http2-Frame.salam

MakeGoAway

func MakeGoAway(last_stream_id: int, error_code: int, debug: str): Frame
A goaway frame with the last stream id that was processed.

The example for this item is shown with the ones above: net-http2-Frame.salam

MakePing

func MakePing(payload: compress.ByteBuf, ack: bool): Frame
A ping frame, or its answer.

The example for this item is shown with the ones above: net-http2-Frame.salam

PutSetting

func PutSetting(out &: compress.ByteBuf, id: int, v: int)
Adds one six byte setting to the buffer.

The example for this item is shown with the ones above: net-http2-Frame.salam

NewDynTable

func NewDynTable(max_size: int): DynTable
An empty dynamic table with the given largest size; usually 4096.

The example for this item is shown with the ones above: net-http2-Hpack.salam

DynCount

func DynCount(t: DynTable): int
The number of entries in the dynamic table.

The example for this item is shown with the ones above: net-http2-Hpack.salam

DynSize

func DynSize(t: DynTable): int
The current size of the dynamic table in bytes.

The example for this item is shown with the ones above: net-http2-Hpack.salam

DynGet

func DynGet(t: DynTable, index: int): Header
The dynamic table entry with a number from 1; number 1 is the newest entry.

The example for this item is shown with the ones above: net-http2-Hpack.salam

DynInsert

func DynInsert(t &: DynTable, h: Header)
Puts an entry in the dynamic table and, if there is no room, pushes the oldest ones out.

The example for this item is shown with the ones above: net-http2-Hpack.salam

DynSetMaxSize

func DynSetMaxSize(t &: DynTable, max_size: int)
Changes the largest size of the dynamic table.

The example for this item is shown with the ones above: net-http2-Hpack.salam

StaticGet

func StaticGet(index: int): Header
The HPACK static table entry with a number from 1 to 61; 2, for instance, is :method GET.

The example for this item is shown with the ones above: net-http2-Hpack.salam

TableGet

func TableGet(t: DynTable, index: int, ok &: bool): Header
The entry with a global HPACK number: 1 to 61 from the static table, larger ones from the dynamic table.

The example for this item is shown with the ones above: net-http2-Hpack.salam

TableFind

func TableFind(t: DynTable, name: str, value: str, exact &: bool): int
Finds the number of the entry that matches a name and a value; if only the name matches, exact becomes false. If there is none, zero.

The example for this item is shown with the ones above: net-http2-Hpack.salam

EncodeHeader

func EncodeHeader(out &: compress.ByteBuf, t &: DynTable, h: Header, use_huffman: bool)
Encodes one header and puts it in the table if it should be. A sensitive header never goes into the table.

The example for this item is shown with the ones above: net-http2-Hpack.salam

EncodeHeaderList

func EncodeHeaderList(t &: DynTable, hl: HeaderList, use_huffman: bool): compress.ByteBuf
Turns a header list into one HPACK block.

The example for this item is shown with the ones above: net-http2-Hpack.salam

EncodeTableSizeUpdate

func EncodeTableSizeUpdate(out &: compress.ByteBuf, t &: DynTable, new_size: int)
Writes the table size change instruction for the other side and changes our own table's size too.

The example for this item is shown with the ones above: net-http2-Hpack.salam

DecodeHeaderList

func DecodeHeaderList(t &: DynTable, block: compress.ByteBuf, ok &: bool): HeaderList
Turns an HPACK block back into a header list and brings the receiving table up to date.

The example for this item is shown with the ones above: net-http2-Hpack.salam