~/bend-docscommunity

http.bend fails

raw source on the hub · import bend-kit-http@0.19.0.0/http.bend as Http

HTTP/1.1 client and server for http and https, with DNS and TLS. Source: https://github.com/paymog/bend-kit/tree/main/http

8 imports
import Base
import 0xa3dc0f6e3963608e4608a1017272cf4f/wire.bend as Wire
import 0x1f2d80f53f971b16c6de6a65cb1918ae/url.bend as Url
import 0xcfc8be7b076f41f95c8e118383892d55/encoding.bend as Enc
import 0x584fc27920487ceab242392391418d7f/json.bend as Json
import 0x49814d83de8f70993a43e1002be29ecd/bytes.bend as Bytes
import 0x296c14c91cb121bd2f42e9d9f730480d/dns.bend as Dns
import 0x58bd522479d133cfe1b2c4451fc1a28f/zlib.bend as Zlib

Types

type Req source · line 19 · raw

Type

type Res source · line 22 · raw

Type

type Err source · line 41 · raw

Data

Why fetch failed. Wire errors keep the errno and the text the effect already had. ponytail: 60 and 110 are ETIMEDOUT on macOS and Linux. Windows is out of scope.

type Fields source · line 65 · raw

Data

type Hold source · line 375 · raw

Data

More: a valid prefix. Bad: cannot become a body. Body: a whole chunked body.

type Dc source · line 389 · raw

Data

A chunked body decoder that reads each byte once, so a body fed in pieces costs O(bytes) in total. Tr{j}: j bytes of the closing CRLF CRLF matched.

type Dco source · line 401 · raw

Data

st: where the decoder is. racc: the body so far, reversed. rest: bytes after a Done body.

type Cs source · line 638 · raw

Type

A chunked body decoded from piece[i..]: a data run is sliced whole, and every other byte steps dc.

type Ck source · line 642 · raw

Type

st: where the decoder stopped. parts: the data so far, newest first. rest: the bytes after a Done body.

type Got source · line 763 · raw

Type

Bad: never a request. More: the head is not whole; read on. Head: the head is whole and valid, and the body is still coming (req.body is empty). Req: a whole request.

type Frame source · line 896 · raw

Type

Bad: never a message. More: a valid prefix; read on. Done: a whole response.

type Lead source · line 989 · raw

Data

type Rb source · line 1110 · raw

Data

The response body as it arrives. Len: bytes left. Chunk: the decoder. Close: until the server closes. Done: the body is whole. Bad: it cannot become a body.

type Bf source · line 1147 · raw

Type

rb: how the body goes on. parts: body bytes so far, newest first. rest: bytes past a Done body.

type Hs source · line 1217 · raw

Type

The head scan. Seek: look for the blank line from byte from; k interim heads are behind. Wait: no blank line yet. Res: the final head, how its body ends, and the bytes after it.

type Rv source · line 1317 · raw

Type

A response read in pieces. Head: the head is not whole yet. Body: it is, and parts is the body so far. Len: a Content-Length body in one buffer of that size, with left bytes still to come.

type Rt source · line 1323 · raw

Type

More: read on. Done: the response, and the bytes after it when the body is self-delimited.

type Reason source · line 1629 · raw

Data

RFC 9110 §15. An unknown code gets an empty reason, which RFC 9112 §4 allows.

type Hop source · line 1725 · raw

Type

One request to make: headers are already lowercased (see req.put).

type Out source · line 1818 · raw

Type

none: no response byte arrived, so an idempotent request may be retried (RFC 9112 §9.3.1). sock: the socket, when it can take another request.

type Fl source · line 1859 · raw

Type

Read state: the response so far and the bytes read, or how it ended. none: no byte arrived, so an idempotent request may be retried.

type Conn source · line 1939 · raw

Type

Connection pool: idle sockets by scheme, host, and port, newest first, at most cap per origin. fetch uses a fresh pool per call.

type Pool source · line 1942 · raw

Type

type Dial source · line 2053 · raw

Type

ponytail: addresses are tried in order, not raced; a broken first route can consume the step timeout.

type Next source · line 2230 · raw

Type

type Mode source · line 2235 · raw

Data

type Dec source · line 2338 · raw

Data

Ok: decoded so far. Bad: a coding failed. Skip: a coding we cannot decode, so the body stays as sent.

type Po source · line 2613 · raw

Type

Streaming (a body read or sent in pieces). A decoded stream owns its decoders. What the next read returns: read more, a raw piece, a decoded piece, the end, or an error.

type Stream source · line 2620 · raw

Type

type Pc source · line 2623 · raw

Type

type Fed source · line 2699 · raw

Type

type Sh source · line 2825 · raw

Type

Head read state: still scanning, cut short or bad, or the head with the bytes after it.

type Sn source · line 2921 · raw

Type

Go: the next request. Drop: close this stream, then go on. Done: the answer.

type Opened source · line 2974 · raw

Type

type Up source · line 3095 · raw

Type

Upload: the request body sent in chunks (RFC 9112 §7.1). err: the first failed write.

type Sv source · line 3227 · raw

Type

The head is parsed once, when it is whole. Body pieces are kept as they come and joined once.

type Turn source · line 3233 · raw

Type

More: read on, first answering 100 Continue when cont is set.

Definitions

def Body source · line 26 · raw

Type

The body type and its conversions, so a caller needs no bytes import.

def from_string source · line 30 · raw

@+s:String -> 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes

A byte string (one Char per octet) to a body, and back.

def to_string source · line 33 · raw

@b:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> String

def length source · line 36 · raw

@b:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Pair(0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes, U32)

def err.late source · line 52 · raw

@+code:U32 -> Bool

def err.pick source · line 55 · raw

@e:Err -> @late:Bool -> Err

def err.or_late source · line 62 · raw

@code:U32 -> @e:Err -> Err

def empty source · line 71 · raw

Map<&2, List<&2, String>>

One list per field name, in arrival order. header() is the first value. Set-Cookie is never joined. Encode writes one line per value.

def fields.of source · line 74 · raw

@r:Pair(Map<&2, List<&2, String>>, List<&2, String>) -> List<&2, String>

def fields source · line 78 · raw

@+h:Map<&2, List<&2, String>> -> @k:String -> List<&2, String>

def header.first source · line 81 · raw

@xs:List<&2, String> -> String

def field.last source · line 91 · raw

@xs:List<&2, String> -> String

def header.last source · line 101 · raw

@+h:Map<&2, List<&2, String>> -> @k:String -> String

Transfer-Encoding is a list; chunked, when present, is the last coding.

def snoc source · line 104 · raw

@xs:List<&2, String> -> @v:String -> List<&2, String>

def set source · line 111 · raw

@m:Map<&2, List<&2, String>> -> @k:String -> @v:String -> Map<&2, List<&2, String>>

def add source · line 114 · raw

@+m:Map<&2, List<&2, String>> -> @+k:String -> @v:String -> Map<&2, List<&2, String>>

def sanitize.cons source · line 117 · raw

@ch:Char -> @rest:String -> @drop:Bool -> String

def sanitize source · line 124 · raw

@s:String -> String

def drop_cr.last.if source · line 131 · raw

@cr:Bool -> @c:U32 -> String

def drop_cr.last source · line 138 · raw

@+c:U32 -> String

def drop_cr.go source · line 142 · raw

@s:String -> @prev:U32 -> String

prev is the char before s; it is kept unless it is a final CR.

def drop_cr source · line 149 · raw

@s:String -> String

def blank_end.go source · line 157 · raw

@s:String -> @w:U32 -> Bool

w holds the last four octets; a char past 255 clears it.

def blank_end source · line 165 · raw

@s:String -> Bool

String.ends_with(s, "\r\n\r\n") in one pass, with no reversed copy.

def trim_end.cons source · line 168 · raw

@h:Char -> @r:String -> @space:Bool -> String

def trim_end source · line 180 · raw

@s:String -> String

String.trim_end without the two reversed copies.

def trim source · line 187 · raw

@s:String -> String

def take.cut source · line 191 · raw

@acc:String -> @rest:String -> Pair(String, String)

Bool.pick evaluates both arms; a split that recursed inside it would reverse acc at every byte.

def take_sp.go source · line 195 · raw

@s:String -> @acc:String -> @hit:Bool -> Pair(String, String)

hit: the last char pushed onto acc was the stop char.

def take_sp source · line 210 · raw

@s:String -> Pair(String, String)

def start_line.ver source · line 213 · raw

@m:String -> @pv:Pair(String, String) -> Pair(String, Pair(String, String))

def start_line.rest source · line 217 · raw

@mr:Pair(String, String) -> Pair(String, Pair(String, String))

def start_line source · line 221 · raw

@s:String -> Pair(String, Pair(String, String))

def split_at_blank.go source · line 224 · raw

@s:String -> @e:Bool -> @w:U32 -> @acc:String -> Pair(String, String)

def split_at_blank.flag.go source · line 237 · raw

@+raw:String -> @s:String -> @off:Nat -> @w:U32 -> @e:Bool -> Pair(String, Pair(String, Bool))

split_at_blank, plus whether the head ends in the blank line.

def split_at_blank.pair source · line 250 · raw

@r:Pair(String, Pair(String, Bool)) -> Pair(String, String)

def split_at_blank source · line 254 · raw

@+s:String -> Pair(String, String)

def split_colon.go source · line 257 · raw

@s:String -> @acc:String -> @hit:Bool -> Pair(String, String)

def split_colon source · line 272 · raw

@+s:String -> Pair(String, String)

def has_header.of source · line 275 · raw

@r:Pair(Map<&2, List<&2, String>>, Bool) -> Bool

def has_header source · line 279 · raw

@+h:Map<&2, List<&2, String>> -> @k:String -> Bool

def folded source · line 282 · raw

@+line:String -> Bool

def tracked source · line 285 · raw

@+k:String -> Bool

def fields_put.dup source · line 288 · raw

@m:Map<&2, List<&2, String>> -> @k:String -> @v:String -> @bad:Bool -> Fields

def fields_put.tracked source · line 295 · raw

@+m:Map<&2, List<&2, String>> -> @+k:String -> @v:String -> @t:Bool -> Fields

def fields_put.key source · line 302 · raw

@+m:Map<&2, List<&2, String>> -> @+k:String -> @v:String -> Fields

def fields_put.kv source · line 305 · raw

@m:Map<&2, List<&2, String>> -> @kv:Pair(String, String) -> Fields

def fields_put.fold source · line 309 · raw

@m:Map<&2, List<&2, String>> -> @line:String -> @fold:Bool -> Fields

def fields_put.empty source · line 316 · raw

@m:Map<&2, List<&2, String>> -> @+line:String -> @e:Bool -> Fields

def fields_put.ok source · line 323 · raw

@m:Map<&2, List<&2, String>> -> @+line:String -> Fields

def fields_put source · line 326 · raw

@acc:Fields -> @line:String -> Fields

def parse.headers.done source · line 333 · raw

@acc:Fields -> Maybe<&2, Map<&2, List<&2, String>>>

def parse.headers source · line 340 · raw

@xs:List<&2, String> -> @acc:Fields -> Maybe<&2, Map<&2, List<&2, String>>>

def parse_u32.digit source · line 347 · raw

@+c:U32 -> Bool

def parse_u32.add source · line 350 · raw

@acc:U32 -> @c:U32 -> U32

def parse_u32.done source · line 353 · raw

@acc:U32 -> @bad:Bool -> Maybe<&2, U32>

def parse_u32.go source · line 360 · raw

@s:String -> @acc:U32 -> @bad:Bool -> Maybe<&2, U32>

def parse_u32 source · line 367 · raw

@s:String -> Maybe<&2, U32>

def is_hex source · line 381 · raw

@+c:U32 -> Bool

def hexv source · line 384 · raw

@+c:U32 -> U32

def dc.start source · line 404 · raw

Dc

def dc.size.semi source · line 407 · raw

@+n:U32 -> @semi:Bool -> Dc

def dc.size.cr source · line 414 · raw

@+n:U32 -> @+c:U32 -> @cr:Bool -> Dc

def dc.size.end source · line 421 · raw

@+n:U32 -> @+c:U32 -> @seen:Bool -> Dc

def dc.size source · line 429 · raw

@+acc:U32 -> @seen:Bool -> @+c:U32 -> @digit:Bool -> Dc

A size that would overflow 32 bits ends the digits, and size.end then refuses it.

def dc.ext.lf source · line 437 · raw

@+n:U32 -> @lf:Bool -> Dc

RFC 9112 §7.1.1: recipients ignore unknown chunk extensions; a bare LF is not CRLF.

def dc.ext source · line 444 · raw

@+n:U32 -> @+c:U32 -> @cr:Bool -> Dc

def dc.sized source · line 451 · raw

@+n:U32 -> @zero:Bool -> Dc

def dc.size.lf source · line 458 · raw

@+n:U32 -> @lf:Bool -> Dc

def dc.data source · line 466 · raw

@+k:U32 -> @+m:U32 -> Dc

k data bytes are left and m of them were just read.

def dc.pick source · line 469 · raw

@ok:Bool -> @next:Dc -> Dc

def dc.tr.hit source · line 477 · raw

@+j:U32 -> Dc

ponytail: trailer fields are dropped unparsed (§7.1.2 allows discarding)

def dc.tr source · line 480 · raw

@+j:U32 -> @+c:U32 -> @hit:Bool -> Dc

def dc.tr.want source · line 487 · raw

@+j:U32 -> U32

def dc.byte source · line 490 · raw

@h:Char -> U32

def dc.step source · line 495 · raw

@st:Dc -> @+c:U32 -> Dc

One byte c. Done and Bad never look at it, and a data byte is not inspected.

def dc.live source · line 516 · raw

@st:Dc -> Bool

def dc.feed source · line 537 · raw

@s:String -> @st:Dc -> @racc:String -> Dco

def chunk.hold source · line 562 · raw

@o:Dco -> Hold

def chunk.live source · line 584 · raw

@s:String -> Hold

def chunk.rest source · line 587 · raw

@o:Dco -> Maybe<&2, String>

def chunk.suffix source · line 609 · raw

@s:String -> Maybe<&2, String>

def chunk.decode.hold source · line 612 · raw

@h:Hold -> Maybe<&2, String>

def chunk.decode source · line 623 · raw

@s:String -> Maybe<&2, String>

def bytes.snd source · line 626 · raw

@r:Pair(0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes) -> 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes

def found.at source · line 630 · raw

@+from:U32 -> @m:Maybe<&2, U32> -> Maybe<&2, U32>

def ck.next source · line 645 · raw

@+len:U32 -> @+i:U32 -> @+st:Dc -> @piece:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @parts:List<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> Pair(Bool, Cs)

def ck.data source · line 648 · raw

@+len:U32 -> @+i:U32 -> @+k:U32 -> @+m:U32 -> @parts:List<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> @r:Pair(0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes) -> Pair(Bool, Cs)

def ck.byte source · line 652 · raw

@+len:U32 -> @+i:U32 -> @st:Dc -> @parts:List<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> @r:Pair(0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes, Maybe<&2, U32>) -> Pair(Bool, Cs)

def ck.step source · line 660 · raw

@+len:U32 -> @cs:Cs -> Pair(Bool, Cs)

def ck.rest source · line 683 · raw

@st:Dc -> @parts:List<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> @r:Pair(0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes) -> Ck

def ck.end source · line 687 · raw

@+len:U32 -> @cs:Cs -> Ck

def ck.feed source · line 692 · raw

@f:Nat -> @+len:U32 -> @r:Pair(Bool, Cs) -> Ck

Each step reads at least one byte, so len steps are enough.

def ck source · line 705 · raw

@piece:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @+st:Dc -> @parts:List<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> Ck

def parse.res.cl.have source · line 709 · raw

@+rest:String -> @+k:Nat -> @short:Bool -> Hold

def parse.res.cl.k source · line 716 · raw

@+rest:String -> @+k:Nat -> Hold

def parse.res.cl.n source · line 719 · raw

@rest:String -> @n:Maybe<&2, U32> -> Hold

def parse.body.cl source · line 726 · raw

@+h:Map<&2, List<&2, String>> -> @rest:String -> @hascl:Bool -> Hold

def parse.body.chunked.eq source · line 734 · raw

@rest:String -> @ok:Bool -> Hold

RFC 9112 §6.3 (4): a request coding other than chunked cannot be framed.

def parse.body.chunked.val source · line 741 · raw

@te:String -> @rest:String -> Hold

def parse.body.chunked source · line 744 · raw

@+h:Map<&2, List<&2, String>> -> @rest:String -> @hascl:Bool -> Hold

def parse.body.te source · line 751 · raw

@+h:Map<&2, List<&2, String>> -> @rest:String -> @te:Bool -> Hold

def parse.body source · line 758 · raw

@+h:Map<&2, List<&2, String>> -> @rest:String -> Hold

def parse.finish source · line 769 · raw

@method:String -> @path:String -> @h:Map<&2, List<&2, String>> -> @body:Hold -> Got

def parse.host source · line 780 · raw

@method:String -> @path:String -> @+h:Map<&2, List<&2, String>> -> @rest:String -> @has:Bool -> Got

def parse.fields source · line 788 · raw

@method:String -> @path:String -> @rest:String -> @v11:Bool -> @fs:Maybe<&2, Map<&2, List<&2, String>>> -> Got

RFC 9112 §3.2: only HTTP/1.1 requires Host.

def target_ok source · line 795 · raw

@+p:String -> Bool

def parse.target source · line 798 · raw

@method:String -> @+path:String -> @headers:List<&2, String> -> @rest:String -> @v11:Bool -> @ok:Bool -> Got

def parse.ver source · line 805 · raw

@method:String -> @+path:String -> @+v:String -> @headers:List<&2, String> -> @rest:String -> @ok:Bool -> Got

def parse.empty_method source · line 812 · raw

@method:String -> @path:String -> @+v:String -> @headers:List<&2, String> -> @rest:String -> @empty:Bool -> Got

def parse.start3 source · line 819 · raw

@mpv:Pair(String, Pair(String, String)) -> @headers:List<&2, String> -> @rest:String -> Got

def parse.lines source · line 823 · raw

@xs:List<&2, String> -> @rest:String -> Got

def parse.head source · line 831 · raw

@+head:String -> @rest:String -> @whole:Bool -> Got

def parse.of source · line 838 · raw

@hb:Pair(String, Pair(String, Bool)) -> Got

def parse.got source · line 843 · raw

@+raw:String -> Got

serve reads until this is not GotMore.

def parse.req source · line 847 · raw

@g:Got -> Maybe<&1, Req>

def parse source · line 858 · raw

@raw:String -> Maybe<&1, Req>

def parse.res.cl source · line 861 · raw

@+h:Map<&2, List<&2, String>> -> @rest:String -> @hascl:Bool -> Hold

def parse.res.chunked.eq source · line 868 · raw

@rest:String -> @ok:Bool -> Hold

def parse.res.chunked.val source · line 875 · raw

@te:String -> @rest:String -> Hold

def parse.res.chunked source · line 878 · raw

@+h:Map<&2, List<&2, String>> -> @rest:String -> @hascl:Bool -> Hold

def parse.res.te source · line 885 · raw

@+h:Map<&2, List<&2, String>> -> @rest:String -> @te:Bool -> Hold

def parse.res.body source · line 892 · raw

@+h:Map<&2, List<&2, String>> -> @rest:String -> Hold

def frame.cut source · line 902 · raw

@closed:Bool -> Frame

RFC 9112 §8: a message cut short by close is incomplete, not valid.

def frame.wait source · line 909 · raw

@res:Res -> @wait:Bool -> Frame

def frame.done source · line 916 · raw

@status:U32 -> @h:Map<&2, List<&2, String>> -> @body:Hold -> @+closed:Bool -> @open:Bool -> Frame

def frame.open source · line 928 · raw

@+h:Map<&2, List<&2, String>> -> Bool

RFC 9112 §6.3 (8): no TE and no CL ⇒ the body runs until the server closes.

def frame.nobody source · line 932 · raw

@+status:U32 -> @head:Bool -> Bool

RFC 9112 §6.3 (1): HEAD, 1xx, 204 and 304 responses end at the blank line.

def frame.interim source · line 936 · raw

@+status:U32 -> Bool

101 is the final response. Other 1xx are interim; a final response follows.

def frame.status source · line 939 · raw

@status:U32 -> @+h:Map<&2, List<&2, String>> -> @rest:String -> @closed:Bool -> @nobody:Bool -> Frame

def parse.res.fields source · line 946 · raw

@+status:U32 -> @rest:String -> @fs:Maybe<&2, Map<&2, List<&2, String>>> -> @closed:Bool -> @head:Bool -> Frame

def parse.res.num source · line 953 · raw

@code:Maybe<&2, U32> -> @headers:List<&2, String> -> @rest:String -> @closed:Bool -> @head:Bool -> Frame

def parse.res.ver source · line 960 · raw

@code:String -> @headers:List<&2, String> -> @rest:String -> @closed:Bool -> @head:Bool -> @ok:Bool -> Frame

def parse.res.start3 source · line 967 · raw

@mpv:Pair(String, Pair(String, String)) -> @headers:List<&2, String> -> @rest:String -> @closed:Bool -> @head:Bool -> Frame

def parse.res.lines source · line 971 · raw

@xs:List<&2, String> -> @rest:String -> @closed:Bool -> @head:Bool -> Frame

def parse.res.blank source · line 978 · raw

@hd:String -> @rest:String -> @+closed:Bool -> @head:Bool -> @ok:Bool -> Frame

def parse.res.of source · line 985 · raw

@hb:Pair(String, String) -> @closed:Bool -> @head:Bool -> Frame

def frame.lead.if source · line 994 · raw

@rest:String -> @interim:Bool -> Lead

def frame.lead.num source · line 1001 · raw

@n:Maybe<&2, U32> -> @rest:String -> Lead

def frame.lead.code source · line 1008 · raw

@mpv:Pair(String, Pair(String, String)) -> @rest:String -> Lead

def frame.lead.lines source · line 1012 · raw

@xs:List<&2, String> -> @rest:String -> Lead

def frame.lead.blank source · line 1019 · raw

@+hd:String -> @rest:String -> @ok:Bool -> Lead

def frame.lead source · line 1026 · raw

@hb:Pair(String, String) -> Lead

def frame.at.cont source · line 1030 · raw

@+raw:String -> @lead:Lead -> String

def frame.at.zero.go source · line 1039 · raw

@+raw:String -> @closed:Bool -> @head:Bool -> @lead:Lead -> Frame

def frame.at.zero.of source · line 1048 · raw

@+raw:String -> @closed:Bool -> @head:Bool -> Frame

def frame.at.pos.do source · line 1051 · raw

@f:Nat -> @+raw:String -> @closed:Bool -> @head:Bool -> @hb:Pair(String, String) -> @lead:Lead -> Frame

def frame.at.zero source · line 1070 · raw

@+raw:String -> @closed:Bool -> @head:Bool -> Frame

def frame.at source · line 1074 · raw

@fuel:Nat -> @+raw:String -> @closed:Bool -> @head:Bool -> Frame

ponytail: 8 interim responses; raise the fuel if a server sends more

def frame source · line 1082 · raw

@raw:String -> @closed:Bool -> @head:Bool -> Frame

frame(bytes so far, server closed?, request was HEAD?)

def frame.res source · line 1085 · raw

@f:Frame -> Maybe<&1, Res>

def parse_res source · line 1094 · raw

@raw:String -> Maybe<&1, Res>

def res_fields.res source · line 1097 · raw

@res:Res -> @k:String -> List<&2, String>

def res_fields source · line 1101 · raw

@m:Maybe<&1, Res> -> @k:String -> List<&2, String>

def rb.cl source · line 1117 · raw

@n:Maybe<&2, U32> -> Maybe<&2, Rb>

def rb.te source · line 1124 · raw

@+h:Map<&2, List<&2, String>> -> @cl:Bool -> Maybe<&2, Rb>

def rb.len source · line 1131 · raw

@+h:Map<&2, List<&2, String>> -> @te:Bool -> Maybe<&2, Rb>

def rb.of source · line 1139 · raw

@+h:Map<&2, List<&2, String>> -> @nobody:Bool -> Maybe<&2, Rb>

RFC 9112 §6.3: how the body of this response ends. None: it cannot be framed.

def rb.len.cut source · line 1150 · raw

@parts:List<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> @+len:U32 -> @+left:U32 -> @r:Pair(0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes) -> Bf

def rb.len.have source · line 1154 · raw

@short:Bool -> @+left:U32 -> @parts:List<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> @+len:U32 -> @piece:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Bf

def rb.chunk source · line 1161 · raw

@c:Ck -> Bf

def rb.feed source · line 1184 · raw

@rb:Rb -> @parts:List<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> @piece:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Bf

The body bytes in piece, added to parts.

def rb.eof source · line 1199 · raw

@rb:Rb -> Bool

RFC 9112 §8: only a close-delimited body may end at close.

def rb.body source · line 1212 · raw

@parts:List<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes

def hs.final source · line 1223 · raw

@+status:U32 -> @+h:Map<&2, List<&2, String>> -> @rest:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @m:Maybe<&2, Rb> -> Hs

def hs.skip source · line 1230 · raw

@more:Bool -> @+k:U32 -> @rest:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Hs

def hs.pick source · line 1237 · raw

@interim:Bool -> @+head:Bool -> @+k:U32 -> @+status:U32 -> @+h:Map<&2, List<&2, String>> -> @rest:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Hs

def hs.res source · line 1244 · raw

@+head:Bool -> @+k:U32 -> @rest:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @res:Res -> Hs

def hs.parsed source · line 1249 · raw

@+head:Bool -> @+k:U32 -> @rest:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @f:Frame -> Hs

The head alone, framed as a HEAD response so it stops at the blank line.

def hs.split source · line 1258 · raw

@+head:Bool -> @+k:U32 -> @+hlen:U32 -> @+len:U32 -> @r:Pair(0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes) -> Hs

def hs.hit source · line 1262 · raw

@+head:Bool -> @+k:U32 -> @+len:U32 -> @buf:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @at:Maybe<&2, U32> -> Hs

def hs.seek.of source · line 1270 · raw

@+head:Bool -> @+k:U32 -> @+len:U32 -> @+from:U32 -> @buf:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @r:Pair(0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes, Maybe<&2, U32>) -> Hs

def hs.seek source · line 1274 · raw

@+head:Bool -> @+k:U32 -> @+len:U32 -> @+from:U32 -> @r:Pair(0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes) -> Hs

def hs.step source · line 1278 · raw

@+head:Bool -> @st:Hs -> Hs

def hs.scan source · line 1291 · raw

@fuel:Nat -> @+head:Bool -> @st:Hs -> Hs

Each step ends the scan or passes one interim head, and at most 8 interim heads pass.

def hs.more source · line 1307 · raw

@+head:Bool -> @+k:U32 -> @buf:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @piece:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Hs

piece joins buf; only the new bytes, and the 3 before them, can finish the blank line.

def fetch.max source · line 1312 · raw

Nat

Untrusted servers must not grow the buffer without bound.

def rv.start source · line 1328 · raw

Rv

def rv.whole source · line 1331 · raw

@res:Res -> @b:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @rest:Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> Rt

def rv.done source · line 1335 · raw

@res:Res -> @parts:List<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> @rest:Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> Rt

def rl.put.of source · line 1338 · raw

@+total:U32 -> @+len:U32 -> @r:Pair(Array<U32>, Array<U32>) -> Pair(0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes)

def rl.put source · line 1343 · raw

@+m:U32 -> @+left:U32 -> @body:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @piece:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Pair(0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes)

The first m bytes of piece, written into body after the total - left bytes already there.

def rl.fed source · line 1348 · raw

@short:Bool -> @res:Res -> @+left:U32 -> @+len:U32 -> @r:Pair(0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes) -> Rt

def rl.feed source · line 1357 · raw

@res:Res -> @+left:U32 -> @body:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @piece:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Rt

def rv.fed source · line 1361 · raw

@res:Res -> @bf:Bf -> Rt

def rb.buf source · line 1376 · raw

@rb:Rb -> Maybe<&2, U32>

Some{left}: a Content-Length body small enough to allocate up front. Larger ones fail at the fetch cap.

def rv.body source · line 1389 · raw

@m:Maybe<&2, U32> -> @res:Res -> @rb:Rb -> @rest:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Rt

def rv.head source · line 1396 · raw

@hs:Hs -> Rt

def rv.eof source · line 1407 · raw

@res:Res -> @parts:List<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> @ok:Bool -> Rt

def rv.step source · line 1415 · raw

@closed:Bool -> @+head:Bool -> @rv:Rv -> @piece:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Rt

One read: piece, or the server closed (RFC 9112 §8: a message cut short is not a message).

def rv.end source · line 1434 · raw

@closed:Bool -> @+head:Bool -> @t:Rt -> Rt

def rv.go source · line 1447 · raw

@xs:List<&2, String> -> @closed:Bool -> @+head:Bool -> @t:Rt -> Rt

def rt.frame source · line 1460 · raw

@t:Rt -> Frame

def res.frame source · line 1470 · raw

@xs:List<&2, String> -> @closed:Bool -> @+head:Bool -> Frame

What the read loop makes of these pieces, then a close when closed is set.

def rt.rest source · line 1473 · raw

@t:Rt -> Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes>

def after.of source · line 1482 · raw

@m:Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> Maybe<&2, String>

def after source · line 1490 · raw

@+raw:String -> @+head:Bool -> Maybe<&2, String>

Bytes after a complete self-delimited message. None if it is not one yet.

def req.v11.ver source · line 1493 · raw

@mpv:Pair(String, Pair(String, String)) -> Bool

def req.v11.line source · line 1497 · raw

@+line:String -> Bool

def req.v11.lines source · line 1500 · raw

@xs:List<&2, String> -> Bool

def req.v11.pick source · line 1507 · raw

@+head:String -> @ok:Bool -> Bool

def req.v11.of source · line 1514 · raw

@hb:Pair(String, String) -> Bool

def req.v11 source · line 1518 · raw

@+raw:String -> Bool

def req.conn_close source · line 1521 · raw

@+headers:Map<&2, List<&2, String>> -> Bool

def res.conn_close source · line 1524 · raw

@+headers:Map<&2, List<&2, String>> -> Bool

def serve.fail_close source · line 1527 · raw

@+status:U32 -> Bool

def serve.keep.ok source · line 1530 · raw

@fail:Bool -> @res_close:Bool -> Bool

def serve.keep.v11 source · line 1537 · raw

@v11:Bool -> @+req_close:Bool -> @+status:U32 -> @res_close:Bool -> Bool

def serve.keep source · line 1548 · raw

@+headers:Map<&2, List<&2, String>> -> @v11:Bool -> @+status:U32 -> @+res:Map<&2, List<&2, String>> -> Bool

def again.keep source · line 1552 · raw

@close:Bool -> @x:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes>

def again.rest source · line 1559 · raw

@close:Bool -> @rest:Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes>

def again source · line 1568 · raw

@close:Bool -> @+h:Map<&2, List<&2, String>> -> @rest:Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes>

The bytes past the response when the socket can take another request: the request did not ask to close, the response is self-delimited, and the peer did not say close.

def res_body.res source · line 1575 · raw

@res:Res -> 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes

def res_body source · line 1579 · raw

@m:Maybe<&1, Res> -> 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes

def text source · line 1586 · raw

@res:Res -> String

def json source · line 1590 · raw

@res:Res -> Maybe<&1, 0x584fc27920487ceab242392391418d7f/json.Val>

UTF-8 is checked, not repaired: bad UTF-8 in a string gives None (RFC 8259 §8.1).

def got_body.req source · line 1593 · raw

@req:Req -> 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes

def got_body source · line 1597 · raw

@m:Maybe<&1, Req> -> 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes

def body.of source · line 1604 · raw

@hb:Pair(String, String) -> String

def body source · line 1608 · raw

@s:String -> String

def headers_lines source · line 1611 · raw

@+k:String -> @vs:List<&2, String> -> @acc:String -> String

def headers_block.go source · line 1618 · raw

@xs:List<&2, Sigma<&2, &2, String, _ => List<&2, String>>> -> @acc:String -> String

def headers_block source · line 1625 · raw

@h:Map<&2, List<&2, String>> -> String

def reasons source · line 1632 · raw

List<&2, Reason>

def reason.go source · line 1639 · raw

@xs:List<&2, Reason> -> @+status:U32 -> String

def reason source · line 1646 · raw

@+status:U32 -> String

def response source · line 1649 · raw

@+status:U32 -> @headers:Map<&2, List<&2, String>> -> @body:String -> String

def encode.body source · line 1652 · raw

@head:Bool -> @top:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @body:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes

def encode.len source · line 1659 · raw

@+status:U32 -> @headers:Map<&2, List<&2, String>> -> @head:Bool -> @body:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes

def encode.pick source · line 1664 · raw

@+status:U32 -> @headers:Map<&2, List<&2, String>> -> @body:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @head:Bool -> @nobody:Bool -> 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes

RFC 9110 §6.4.1, §8.6: 1xx, 204 and 304 have no body; HEAD gets the length but no body.

def encode.on source · line 1671 · raw

@r:Res -> @head:Bool -> 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes

def encode source · line 1675 · raw

@r:Res -> 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes

def request source · line 1678 · raw

@method:String -> @path:String -> @headers:Map<&2, List<&2, String>> -> @body:String -> String

def req.reserved source · line 1681 · raw

@+k:String -> Bool

def req.put.one source · line 1684 · raw

@m:Map<&2, List<&2, String>> -> @+k:String -> @vs:List<&2, String> -> @skip:Bool -> Map<&2, List<&2, String>>

def req.put source · line 1691 · raw

@xs:List<&2, Sigma<&2, &2, String, _ => List<&2, String>>> -> @m:Map<&2, List<&2, String>> -> Map<&2, List<&2, String>>

def req.cl source · line 1700 · raw

@+m:Map<&2, List<&2, String>> -> @+method:String -> @+len:U32 -> Map<&2, List<&2, String>>

RFC 9110 §8.6: no Content-Length on a bodiless request whose method gives a body no meaning.

def encode_req.word source · line 1706 · raw

@close:Bool -> String

Caller headers are lowercased so they cannot duplicate ours; host, connection, content-length and transfer-encoding are always ours (no smuggling through them).

def encode_req.on source · line 1713 · raw

@+method:String -> @target:String -> @host:String -> @headers:Map<&2, List<&2, String>> -> @body:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @close:Bool -> 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes

def encode_req source · line 1718 · raw

@+method:String -> @target:String -> @host:String -> @headers:Map<&2, List<&2, String>> -> @body:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes

def redirect.code source · line 1728 · raw

@+s:U32 -> Bool

def redirect.origin source · line 1731 · raw

@a:0x1f2d80f53f971b16c6de6a65cb1918ae/url.Abs -> String

def redirect.del source · line 1735 · raw

@ks:List<&2, String> -> @m:Map<&2, List<&2, String>> -> Map<&2, List<&2, String>>

def redirect.hdrs source · line 1742 · raw

@+h:Map<&2, List<&2, String>> -> @drop:Bool -> @cross:Bool -> Map<&2, List<&2, String>>

def redirect.body source · line 1749 · raw

@drop:Bool -> @body:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes

303 turns any method but HEAD into GET; 301 and 302 turn POST into GET; 307 and 308 keep method and body. A GET carries no body or body headers. Credentials do not follow a hop to another origin.

def redirect.to source · line 1756 · raw

@+status:U32 -> @+method:String -> @+from:0x1f2d80f53f971b16c6de6a65cb1918ae/url.Abs -> @headers:Map<&2, List<&2, String>> -> @body:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @next:Maybe<&2, 0x1f2d80f53f971b16c6de6a65cb1918ae/url.Abs> -> Maybe<&1, Hop>

def redirect.hop source · line 1764 · raw

@status:U32 -> @h:Hop -> @loc:String -> Maybe<&1, Hop>

def redirect.if source · line 1768 · raw

@status:U32 -> @h:Hop -> @loc:String -> @ok:Bool -> Maybe<&1, Hop>

def redirect source · line 1776 · raw

@+status:U32 -> @+headers:Map<&2, List<&2, String>> -> @h:Hop -> Maybe<&1, Hop>

The next request after a response, or None when it is not a redirect we follow.

def io.recv.words source · line 1779 · raw

@tls:Bool -> @s:Socket -> @max:U32 -> @ms:U32 -> IO(Pair(Socket, Result<&1, &1, Pair(U32, String), Pair(U32, Array<U32>)>))

def io.send source · line 1786 · raw

@tls:Bool -> @s:Socket -> @data:String -> IO(Pair(Socket, Result<&1, &1, Pair(U32, String), Unit>))

def io.send.words source · line 1793 · raw

@tls:Bool -> @s:Socket -> @+len:U32 -> @buf:Array<U32> -> IO(Pair(Socket, Result<&1, &1, Pair(U32, String), Unit>))

def io.send.bytes source · line 1800 · raw

@tls:Bool -> @s:Socket -> @b:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> IO(Pair(Socket, Result<&1, &1, Pair(U32, String), Unit>))

def io.close source · line 1804 · raw

@tls:Bool -> @s:Socket -> IO(Unit)

def fetch.close source · line 1811 · raw

@tls:Bool -> @s:Socket -> @r:Result<&1, &1, Err, Res> -> IO(Result<&1, &1, Err, Res>)

def fetch.boxed source · line 1822 · raw

@r:Result<&1, &1, Err, Res> -> @none:Bool -> Out

def fetch.bad source · line 1829 · raw

@tls:Bool -> @s:Socket -> @e:Maybe<&2, Err> -> IO(Result<&1, &1, Err, Res>)

def fetch.shut source · line 1836 · raw

@tls:Bool -> @s:Socket -> @r:Result<&1, &1, Err, Res> -> @none:Bool -> IO(Out)

def fetch.hold.go source · line 1841 · raw

@tls:Bool -> @s:Socket -> @res:Res -> @left:Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> IO(Out)

def fetch.hold source · line 1848 · raw

@tls:Bool -> @close:Bool -> @s:Socket -> @res:Res -> @left:Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> IO(Out)

def fetch.failout source · line 1852 · raw

@tls:Bool -> @s:Socket -> @e:Maybe<&2, Err> -> @none:Bool -> IO(Out)

def fetch.rt source · line 1864 · raw

@+n:U32 -> @t:Rt -> Fl

def fetch.over source · line 1874 · raw

@+n:U32 -> Bool

64 KiB of head past the body cap, as serve allows.

def fetch.piece.cap source · line 1877 · raw

@over:Bool -> @+head:Bool -> @rv:Rv -> @+n2:U32 -> @+len:U32 -> @buf:Array<U32> -> Fl

def fetch.piece source · line 1884 · raw

@+head:Bool -> @rv:Rv -> @+n:U32 -> @p:Pair(U32, Array<U32>) -> Fl

def fetch.next source · line 1889 · raw

@+head:Bool -> @rv:Rv -> @+n:U32 -> @m:Pair(Socket, Result<&1, &1, Pair(U32, String), Pair(U32, Array<U32>)>) -> Pair(Socket, Fl)

def exchange.sent source · line 1911 · raw

@+tls:Bool -> @+ms:U32 -> @+close:Bool -> @+head:Bool -> @m:Pair(Socket, Result<&1, &1, Pair(U32, String), Unit>) -> IO(Out)

def exchange.go source · line 1919 · raw

@+tls:Bool -> @+ms:U32 -> @+close:Bool -> @+head:Bool -> @s:Socket -> @wire:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> IO(Out)

def exchange.tup source · line 1924 · raw

@o:Out -> Pair(Maybe<&1, Socket>, Pair(Result<&1, &1, Err, Res>, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes))

def exchange source · line 1932 · raw

@+tls:Bool -> @+ms:U32 -> @+close:Bool -> @+head:Bool -> @s:Socket -> @wire:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> IO(Pair(Maybe<&1, Socket>, Pair(Result<&1, &1, Err, Res>, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes)))

One request on an open socket. Some{socket}: it can take another request.

def pool.new.with source · line 1945 · raw

@+cap:U32 -> Pool

def pool.new source · line 1949 · raw

Pool

Up to 8 idle sockets per origin.

def pool.key source · line 1952 · raw

@+scheme:String -> @+host:String -> @+port:U32 -> String

def pool.take.of source · line 1955 · raw

@+cap:U32 -> @+key:String -> @r:Pair(Map<&1, List<&1, Conn>>, Maybe<&1, List<&1, Conn>>) -> Pair(Pool, Maybe<&1, Conn>)

def pool.take source · line 1968 · raw

@p:Pool -> @+key:String -> Pair(Pool, Maybe<&1, Conn>)

The socket given back last.

def conn.close source · line 1972 · raw

@c:Conn -> IO(Unit)

def conns.cut source · line 1977 · raw

@xs:List<&1, Conn> -> @n:Nat -> IO(List<&1, Conn>)

The first n sockets; the rest are closed.

def pool.give.of source · line 1992 · raw

@+cap:U32 -> @+key:String -> @c:Conn -> @r:Pair(Map<&1, List<&1, Conn>>, Maybe<&1, List<&1, Conn>>) -> IO(Pool)

def pool.give source · line 1999 · raw

@p:Pool -> @+key:String -> @c:Conn -> IO(Pool)

Past cap, the oldest idle socket of the origin is closed.

def pool.close.go source · line 2003 · raw

@xs:List<&1, List<&1, Conn>> -> IO(Unit)

def pool.close source · line 2012 · raw

@p:Pool -> IO(Unit)

def pool.idempotent source · line 2017 · raw

@+method:String -> Bool

RFC 9110 §9.2.2

def conn.tls source · line 2020 · raw

@m:Pair(Socket, Result<&1, &1, Pair(U32, String), Unit>) -> IO(Result<&1, &1, Err, Conn>)

def conn.secure source · line 2031 · raw

@+ms:U32 -> @sni:String -> @s:Socket -> @tls:Bool -> IO(Result<&1, &1, Err, Conn>)

A failed handshake is an error, never plaintext.

def conn.made source · line 2040 · raw

@+ms:U32 -> @sni:String -> @tls:Bool -> @r:Result<&1, &1, Pair(U32, String), Socket> -> IO(Result<&1, &1, Err, Conn>)

def conn.open source · line 2047 · raw

@+tls:Bool -> @+ms:U32 -> @sni:String -> @ip:String -> @port:U32 -> IO(Result<&1, &1, Err, Conn>)

def conn.dial.time source · line 2056 · raw

@+ip:String -> @+port:U32 -> @+deadline:Nat -> @now:Nat -> @expired:Bool -> IO(Result<&1, &1, Pair(U32, String), Socket>)

def conn.dial.with source · line 2064 · raw

@+ip:String -> @+port:U32 -> @+ms:U32 -> @+deadline:Nat -> @+now:Nat -> @unlimited:Bool -> IO(Result<&1, &1, Pair(U32, String), Socket>)

def conn.dial.try source · line 2072 · raw

@+ip:String -> @+port:U32 -> @+ms:U32 -> @+deadline:Nat -> IO(Result<&1, &1, Pair(U32, String), Socket>)

def conn.dial.after source · line 2078 · raw

@r:Result<&1, &1, Pair(U32, String), Socket> -> @ip:String -> @+port:U32 -> @+ms:U32 -> @+deadline:Nat -> IO(Result<&1, &1, Pair(U32, String), Socket>)

def conn.dial.more source · line 2086 · raw

@prev:IO(Result<&1, &1, Pair(U32, String), Socket>) -> @ip:String -> @+port:U32 -> @+ms:U32 -> @+deadline:Nat -> IO(Result<&1, &1, Pair(U32, String), Socket>)

def conn.dial.fold source · line 2092 · raw

@d:Dial -> @ip:String -> Dial

def conn.dial.run source · line 2096 · raw

@d:Dial -> IO(Result<&1, &1, Pair(U32, String), Socket>)

def conn.dial.all source · line 2100 · raw

@+port:U32 -> @+ms:U32 -> @+start:Nat -> @first:String -> @rest:List<&2, String> -> IO(Result<&1, &1, Pair(U32, String), Socket>)

def conn.open.all source · line 2110 · raw

@+tls:Bool -> @+ms:U32 -> @+host:String -> @+port:U32 -> @ips:List<&2, String> -> IO(Result<&1, &1, Err, Conn>)

def conn.ex source · line 2120 · raw

@c:Conn -> @+ms:U32 -> @+head:Bool -> @wire:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> IO(Out)

def pool.keep.s source · line 2125 · raw

@p:Pool -> @+key:String -> @+tls:Bool -> @res:Res -> @s:Socket -> @clean:Bool -> IO(Pair(Pool, Result<&1, &1, Err, Res>))

A socket with bytes past the response is out of step with the server, so it is closed.

def pool.keep.m source · line 2136 · raw

@p:Pool -> @+key:String -> @+tls:Bool -> @res:Res -> @+clean:Bool -> @sock:Maybe<&1, Socket> -> IO(Pair(Pool, Result<&1, &1, Err, Res>))

def pool.keep source · line 2143 · raw

@p:Pool -> @+key:String -> @+tls:Bool -> @res:Res -> @sock:Maybe<&1, Socket> -> @rest:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> IO(Pair(Pool, Result<&1, &1, Err, Res>))

def pool.after source · line 2147 · raw

@p:Pool -> @+key:String -> @+tls:Bool -> @o:Out -> IO(Pair(Pool, Result<&1, &1, Err, Res>))

def pool.fresh.conn source · line 2154 · raw

@p:Pool -> @+key:String -> @+tls:Bool -> @+ms:U32 -> @+head:Bool -> @wire:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @r:Result<&1, &1, Err, Conn> -> IO(Pair(Pool, Result<&1, &1, Err, Res>))

def pool.fresh source · line 2163 · raw

@p:Pool -> @+key:String -> @+tls:Bool -> @+ms:U32 -> @+head:Bool -> @+host:String -> @+port:U32 -> @wire:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> IO(Pair(Pool, Result<&1, &1, Err, Res>))

def pool.retry source · line 2170 · raw

@+none:Bool -> @+idem:Bool -> Bool

A reused socket the server already closed fails before any response byte.

def pool.stale source · line 2173 · raw

@p:Pool -> @+key:String -> @+tls:Bool -> @+ms:U32 -> @+head:Bool -> @+host:String -> @+port:U32 -> @wire:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @e:Err -> @again:Bool -> IO(Pair(Pool, Result<&1, &1, Err, Res>))

def pool.reused source · line 2180 · raw

@p:Pool -> @+key:String -> @+tls:Bool -> @+ms:U32 -> @+head:Bool -> @+idem:Bool -> @+host:String -> @+port:U32 -> @wire:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @o:Out -> IO(Pair(Pool, Result<&1, &1, Err, Res>))

def pool.idle.reuse source · line 2188 · raw

@p:Pool -> @+key:String -> @+tls:Bool -> @+ms:U32 -> @+head:Bool -> @+idem:Bool -> @+host:String -> @+port:U32 -> @c:Conn -> @r:Pair(0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes) -> IO(Pair(Pool, Result<&1, &1, Err, Res>))

A spare copy of the request, for the retry after a stale socket.

def pool.idle source · line 2194 · raw

@taken:Pair(Pool, Maybe<&1, Conn>) -> @+key:String -> @+tls:Bool -> @+ms:U32 -> @+head:Bool -> @+idem:Bool -> @+host:String -> @+port:U32 -> @wire:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> IO(Pair(Pool, Result<&1, &1, Err, Res>))

def pool.origin source · line 2202 · raw

@p:Pool -> @+method:String -> @+ms:U32 -> @headers:Map<&2, List<&2, String>> -> @body:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @+hf:String -> @a:0x1f2d80f53f971b16c6de6a65cb1918ae/url.Abs -> @known:Bool -> IO(Pair(Pool, Result<&1, &1, Err, Res>))

def pool.scheme.ok source · line 2211 · raw

@a:0x1f2d80f53f971b16c6de6a65cb1918ae/url.Abs -> Bool

def pool.one.back source · line 2215 · raw

@h:Hop -> @pr:Pair(Pool, Result<&1, &1, Err, Res>) -> Pair(Pool, Pair(Result<&1, &1, Err, Res>, Hop))

def pool.one.of source · line 2219 · raw

@p:Pool -> @+method:String -> @+url:0x1f2d80f53f971b16c6de6a65cb1918ae/url.Abs -> @+headers:Map<&2, List<&2, String>> -> @+ms:U32 -> @r:Pair(0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes) -> IO(Pair(Pool, Pair(Result<&1, &1, Err, Res>, Hop)))

def pool.one source · line 2226 · raw

@p:Pool -> @h:Hop -> @+ms:U32 -> IO(Pair(Pool, Pair(Result<&1, &1, Err, Res>, Hop)))

One request, on an idle socket to its origin when the pool has one. The hop comes back for the redirect.

def fetch.hop source · line 2241 · raw

@left:Nat -> @h:Hop -> Next

left: redirects still allowed after the request we just finished.

def fetch.decide.r source · line 2248 · raw

@left:Nat -> @r:Res -> @next:Maybe<&1, Hop> -> Next

def fetch.decide.res source · line 2255 · raw

@left:Nat -> @h:Hop -> @r:Res -> Next

def fetch.decide source · line 2259 · raw

@left:Nat -> @h:Hop -> @m:Result<&1, &1, Err, Res> -> Next

def fetch.error.res source · line 2266 · raw

@r:Res -> @bad:Bool -> Next

def fetch.error source · line 2273 · raw

@h:Hop -> @m:Result<&1, &1, Err, Res> -> Next

def fetch.policy source · line 2281 · raw

@mode:Mode -> @left:Nat -> @h:Hop -> @m:Result<&1, &1, Err, Res> -> Next

def accept.enc source · line 2291 · raw

@+h:Map<&2, List<&2, String>> -> @+enc:String -> Map<&2, List<&2, String>>

A caller's own Accept-Encoding wins; enc is the codings fetch can undo.

def fetch.start source · line 2294 · raw

@method:String -> @headers:Map<&2, List<&2, String>> -> @body:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @u:Maybe<&2, 0x1f2d80f53f971b16c6de6a65cb1918ae/url.Abs> -> @+enc:String -> Next

def pool.next source · line 2301 · raw

@+mode:Mode -> @left:Nat -> @x:Pair(Pool, Pair(Result<&1, &1, Err, Res>, Hop)) -> Pair(Pool, Next)

def ce.keep source · line 2320 · raw

@+w:String -> @+rest:List<&2, String> -> List<&2, String>

Content-Encoding (RFC 9110 §8.4): each value, trimmed and lowercased, in the order applied.

def ce.norm source · line 2323 · raw

@xs:List<&2, String> -> List<&2, String>

def ce.split source · line 2330 · raw

@xs:List<&2, String> -> List<&2, String>

def ce.of source · line 2343 · raw

@m:Maybe<&2, String> -> Dec

def ce.deflate source · line 2351 · raw

@+b:String -> @m:Maybe<&2, String> -> Dec

Servers send deflate both with and without the zlib wrapper.

def ce.apply source · line 2358 · raw

@+c:String -> @+b:String -> Dec

def ce.go source · line 2363 · raw

@cs:List<&2, String> -> @d:Dec -> Dec

def decoded.pick source · line 2376 · raw

@d:Dec -> @+status:U32 -> @headers:Map<&2, List<&2, String>> -> @body:String -> Result<&1, &1, Err, Res>

def decoded.cs source · line 2386 · raw

@+status:U32 -> @+headers:Map<&2, List<&2, String>> -> @body:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @cs:List<&2, String> -> Result<&1, &1, Err, Res>

ponytail: the codings run on a String copy of the body; give zlib a Bytes input if gzip bodies get big.

def decoded.go source · line 2394 · raw

@empty:Bool -> @+status:U32 -> @+headers:Map<&2, List<&2, String>> -> @body:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Result<&1, &1, Err, Res>

def decoded source · line 2402 · raw

@res:Res -> Result<&1, &1, Err, Res>

The body decoded per Content-Encoding; the headers stay as sent. A corrupt body is ErrBad.

def decoded.m source · line 2407 · raw

@r:Result<&1, &1, Err, Res> -> Maybe<&1, Res>

def decoded.some source · line 2414 · raw

@res:Res -> Maybe<&1, Res>

def ce.words source · line 2417 · raw

@r:Result<&1, &1, Pair(U32, String), Pair(U32, Array<U32>)> -> Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes>

def ce.dec source · line 2431 · raw

@d:Dec -> Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes>

def ce.io.deflate source · line 2441 · raw

@on:Bool -> @b:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> IO(Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes>)

ponytail: deflate runs on the pure decoder, which also takes raw DEFLATE; servers rarely send it.

def ce.io.zstd source · line 2449 · raw

@on:Bool -> @+c:String -> @b:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> IO(Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes>)

def ce.io.br source · line 2456 · raw

@on:Bool -> @+c:String -> @b:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> IO(Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes>)

def ce.io.gz source · line 2464 · raw

@on:Bool -> @+c:String -> @b:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> IO(Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes>)

One known coding undone: gzip, x-gzip, br, zstd, deflate, or identity.

def ce.io.go source · line 2471 · raw

@cs:List<&2, String> -> @m:Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> IO(Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes>)

def ce.has source · line 2488 · raw

@xs:List<&2, String> -> @+c:String -> Bool

def ce.known source · line 2495 · raw

@cs:List<&2, String> -> @+ok:List<&2, String> -> Bool

def decoded.io.pick source · line 2502 · raw

@m:Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> @+status:U32 -> @headers:Map<&2, List<&2, String>> -> Result<&1, &1, Err, Res>

def decoded.io.run source · line 2509 · raw

@known:Bool -> @+status:U32 -> @+headers:Map<&2, List<&2, String>> -> @body:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @cs:List<&2, String> -> IO(Result<&1, &1, Err, Res>)

def decoded.io.go source · line 2518 · raw

@empty:Bool -> @+enc:String -> @+status:U32 -> @+headers:Map<&2, List<&2, String>> -> @body:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> IO(Result<&1, &1, Err, Res>)

def decoded.io source · line 2527 · raw

@+enc:String -> @res:Res -> IO(Result<&1, &1, Err, Res>)

decoded through the C libraries, for the codings in enc. A body with any other coding stays as sent.

def codings.ok source · line 2533 · raw

@r:Result<&1, &1, Pair(U32, String), Pair(U32, Array<U32>)> -> Bool

An effect on empty input fails with ENOENT only when its library does not load.

def codings.add source · line 2546 · raw

@has:Bool -> @+enc:String -> @+c:String -> String

def codings source · line 2550 · raw

IO(String)

gzip and deflate, then br and zstd when their C library loads.

def fetch.final source · line 2557 · raw

@+enc:String -> @r:Result<&1, &1, Err, Res> -> IO(Result<&1, &1, Err, Res>)

The final response of a fetch, after redirects.

def pool.final source · line 2564 · raw

@+enc:String -> @pr:Pair(Pool, Result<&1, &1, Err, Res>) -> IO(Pair(Pool, Result<&1, &1, Err, Res>))

def pool.how.enc source · line 2570 · raw

@+enc:String -> @p:Pool -> @method:String -> @url:String -> @headers:Map<&2, List<&2, String>> -> @body:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @ms:U32 -> @mode:Mode -> IO(Pair(Pool, Result<&1, &1, Err, Res>))

def pool.how source · line 2578 · raw

@p:Pool -> @method:String -> @url:String -> @headers:Map<&2, List<&2, String>> -> @body:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @ms:U32 -> @mode:Mode -> IO(Pair(Pool, Result<&1, &1, Err, Res>))

pool.how(p, "GET", "https://example.com/x?y=1", headers, body, ms, mode) follows redirects on p's idle sockets. Fail is a bad URL, a failed lookup, connect, handshake, send, read, a malformed response, more than 20 redirects, or a step past ms. Bodies are bytes.

def pool.fetch.with source · line 2583 · raw

@p:Pool -> @method:String -> @url:String -> @headers:Map<&2, List<&2, String>> -> @body:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @ms:U32 -> IO(Pair(Pool, Result<&1, &1, Err, Res>))

def pool.fetch source · line 2586 · raw

@p:Pool -> @method:String -> @url:String -> @headers:Map<&2, List<&2, String>> -> @body:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> IO(Pair(Pool, Result<&1, &1, Err, Res>))

def fetch.end source · line 2589 · raw

@pr:Pair(Pool, Result<&1, &1, Err, Res>) -> IO(Result<&1, &1, Err, Res>)

def fetch.how source · line 2596 · raw

@method:String -> @url:String -> @headers:Map<&2, List<&2, String>> -> @body:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @ms:U32 -> @mode:Mode -> IO(Result<&1, &1, Err, Res>)

fetch is pool.how on a fresh pool that closes afterwards.

def fetch.with source · line 2601 · raw

@method:String -> @url:String -> @headers:Map<&2, List<&2, String>> -> @body:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @ms:U32 -> IO(Result<&1, &1, Err, Res>)

def fetch source · line 2605 · raw

@method:String -> @url:String -> @headers:Map<&2, List<&2, String>> -> @body:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> IO(Result<&1, &1, Err, Res>)

fetch.with and a 30 s step timeout.

def get source · line 2608 · raw

@url:String -> IO(Result<&1, &1, Err, Res>)

def pc.po source · line 2627 · raw

@more:Bool -> @empty:Bool -> @b:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Po

A body piece, or none when empty: more reads the next piece, and not more is the end.

def pc.piece source · line 2634 · raw

@more:Bool -> @+rb:Rb -> @b:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Pc

def pc.fed.of source · line 2638 · raw

@b:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @st:Rb -> Pc

def pc.fed source · line 2651 · raw

@bf:Bf -> Pc

def pc.of source · line 2656 · raw

@rb:Rb -> @piece:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Pc

The body bytes that just arrived: what they add to the body, and how it ends.

def pc.end source · line 2660 · raw

@ok:Bool -> Pc

The server closed. Only a close-delimited body may end this way (RFC 9112 §8).

def pc.eof source · line 2667 · raw

@st:Rb -> Pc

def stream.mk source · line 2670 · raw

@+tls:Bool -> @s:Socket -> @+ms:U32 -> @res:Res -> @decs:List<&1, 0x58bd522479d133cfe1b2c4451fc1a28f/zlib.Decoder> -> @pc:Pc -> Stream

def stream.got.piece source · line 2674 · raw

@+tls:Bool -> @s:Socket -> @+ms:U32 -> @res:Res -> @decs:List<&1, 0x58bd522479d133cfe1b2c4451fc1a28f/zlib.Decoder> -> @+rb:Rb -> @p:Pair(U32, Array<U32>) -> Stream

def stream.got source · line 2678 · raw

@+tls:Bool -> @+ms:U32 -> @res:Res -> @decs:List<&1, 0x58bd522479d133cfe1b2c4451fc1a28f/zlib.Decoder> -> @+rb:Rb -> @m:Pair(Socket, Result<&1, &1, Pair(U32, String), Pair(U32, Array<U32>)>) -> Stream

def stream.after source · line 2686 · raw

@+rb:Rb -> Po

def stream.feed.received source · line 2702 · raw

@done:List<&1, 0x58bd522479d133cfe1b2c4451fc1a28f/zlib.Decoder> -> @m:Pair(0x58bd522479d133cfe1b2c4451fc1a28f/zlib.Decoder, Result<&1, &1, Pair(U32, String), Pair(U32, Array<U32>)>) -> Fed

def stream.feed.step source · line 2710 · raw

@st:Fed -> @d:0x58bd522479d133cfe1b2c4451fc1a28f/zlib.Decoder -> IO(Fed)

def stream.feed.one source · line 2722 · raw

@prev:IO(Fed) -> @d:0x58bd522479d133cfe1b2c4451fc1a28f/zlib.Decoder -> IO(Fed)

def stream.feed.reverse source · line 2727 · raw

@st:Fed -> Fed

def stream.feed.all source · line 2731 · raw

@decs:List<&1, 0x58bd522479d133cfe1b2c4451fc1a28f/zlib.Decoder> -> @b:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> IO(Fed)

def stream.ready source · line 2737 · raw

@empty:Bool -> @+rb:Rb -> @b:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Po

def stream.feed.got source · line 2744 · raw

@+tls:Bool -> @s:Socket -> @+ms:U32 -> @res:Res -> @+rb:Rb -> @st:Fed -> Stream

def stream.feed.st source · line 2753 · raw

@st:Stream -> @b:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> IO(Stream)

def stream.finish.ok source · line 2763 · raw

@r:Result<&1, &1, Pair(U32, String), Unit> -> Bool

def stream.finish source · line 2770 · raw

@decs:List<&1, 0x58bd522479d133cfe1b2c4451fc1a28f/zlib.Decoder> -> IO(Bool)

def stream.ended source · line 2780 · raw

@good:Bool -> @+tls:Bool -> @s:Socket -> @+ms:U32 -> @res:Res -> @+rb:Rb -> Pair(Stream, Result<&1, &1, Err, Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes>>)

def stream.res source · line 2813 · raw

@st:Stream -> Pair(Stream, Res)

Status and headers. Its body is empty: read the body with stream.read.

def stream.close source · line 2818 · raw

@st:Stream -> IO(Unit)

def sh.of source · line 2830 · raw

@hs:Hs -> Sh

def sh.piece source · line 2841 · raw

@+head:Bool -> @buf:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @+k:U32 -> @p:Pair(U32, Array<U32>) -> Sh

def sh.next source · line 2845 · raw

@+head:Bool -> @buf:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @+k:U32 -> @m:Pair(Socket, Result<&1, &1, Pair(U32, String), Pair(U32, Array<U32>)>) -> Pair(Socket, Sh)

def fetch.fail.of source · line 2853 · raw

@r:Result<&1, &1, Err, Res> -> Result<&1, &1, Err, Stream>

def stream.sent source · line 2876 · raw

@+tls:Bool -> @+ms:U32 -> @+head:Bool -> @m:Pair(Socket, Result<&1, &1, Pair(U32, String), Unit>) -> IO(Result<&1, &1, Err, Stream>)

def stream.conn source · line 2886 · raw

@r:Result<&1, &1, Err, Conn> -> @+ms:U32 -> @+head:Bool -> @wire:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> IO(Result<&1, &1, Err, Stream>)

def stream.origin source · line 2897 · raw

@+ms:U32 -> @+head:Bool -> @wire:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @a:0x1f2d80f53f971b16c6de6a65cb1918ae/url.Abs -> @known:Bool -> IO(Result<&1, &1, Err, Stream>)

One connection per stream; the request says close.

def stream.one.of source · line 2908 · raw

@+method:String -> @+url:0x1f2d80f53f971b16c6de6a65cb1918ae/url.Abs -> @+headers:Map<&2, List<&2, String>> -> @+ms:U32 -> @r:Pair(0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes) -> IO(Pair(Hop, Result<&1, &1, Err, Stream>))

def stream.one source · line 2916 · raw

@h:Hop -> @+ms:U32 -> IO(Pair(Hop, Result<&1, &1, Err, Stream>))

One request on its own connection. The hop comes back for the redirect.

def sn.of source · line 2926 · raw

@n:Next -> Sn

def stream.decide.n source · line 2939 · raw

@st:Stream -> @n:Next -> Sn

def stream.decide.of source · line 2948 · raw

@+left:Nat -> @hop:Hop -> @sr:Pair(Stream, Res) -> Sn

def stream.decide source · line 2952 · raw

@+left:Nat -> @x:Pair(Hop, Result<&1, &1, Err, Stream>) -> Sn

def stream.open.got source · line 2977 · raw

@st:Opened -> @r:Result<&1, &1, Pair(U32, String), 0x58bd522479d133cfe1b2c4451fc1a28f/zlib.Decoder> -> Opened

def stream.open.add source · line 2985 · raw

@st:Opened -> @m:IO(Result<&1, &1, Pair(U32, String), 0x58bd522479d133cfe1b2c4451fc1a28f/zlib.Decoder>) -> IO(Opened)

def stream.open.zstd source · line 2990 · raw

@zstd:Bool -> @st:Opened -> IO(Opened)

def stream.open.br source · line 2997 · raw

@br:Bool -> @+c:String -> @st:Opened -> IO(Opened)

def stream.open.gz source · line 3004 · raw

@gz:Bool -> @+c:String -> @st:Opened -> IO(Opened)

def stream.open.step source · line 3011 · raw

@+c:String -> @st:Opened -> IO(Opened)

def stream.open.one source · line 3020 · raw

@prev:IO(Opened) -> @c:String -> IO(Opened)

def stream.open.all source · line 3025 · raw

@cs:List<&2, String> -> IO(Opened)

def stream.put.decs source · line 3028 · raw

@st:Stream -> @decs:List<&1, 0x58bd522479d133cfe1b2c4451fc1a28f/zlib.Decoder> -> Stream

def stream.init.opened source · line 3032 · raw

@st:Stream -> @opened:Opened -> IO(Result<&1, &1, Err, Stream>)

def stream.init.known source · line 3042 · raw

@known:Bool -> @st:Stream -> @cs:List<&2, String> -> IO(Result<&1, &1, Err, Stream>)

def stream.init.st source · line 3051 · raw

@+enc:String -> @st:Stream -> IO(Result<&1, &1, Err, Stream>)

def stream.init source · line 3058 · raw

@+enc:String -> @r:Result<&1, &1, Err, Stream> -> IO(Result<&1, &1, Err, Stream>)

def stream.start source · line 3065 · raw

@method:String -> @headers:Map<&2, List<&2, String>> -> @body:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @u:Maybe<&2, 0x1f2d80f53f971b16c6de6a65cb1918ae/url.Abs> -> Sn

def open.raw.with source · line 3073 · raw

@method:String -> @url:String -> @headers:Map<&2, List<&2, String>> -> @body:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @+ms:U32 -> IO(Result<&1, &1, Err, Stream>)

Open a raw stream. Its body bytes and headers remain as sent.

def open.raw source · line 3076 · raw

@method:String -> @url:String -> @headers:Map<&2, List<&2, String>> -> @body:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> IO(Result<&1, &1, Err, Stream>)

def open.with.enc source · line 3079 · raw

@+enc:String -> @method:String -> @url:String -> @headers:Map<&2, List<&2, String>> -> @body:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @+ms:U32 -> IO(Result<&1, &1, Err, Stream>)

def open.with source · line 3086 · raw

@method:String -> @url:String -> @headers:Map<&2, List<&2, String>> -> @body:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @+ms:U32 -> IO(Result<&1, &1, Err, Stream>)

Follow redirects, then decode each body piece by Content-Encoding. Unknown codings stay raw.

def open source · line 3091 · raw

@method:String -> @url:String -> @headers:Map<&2, List<&2, String>> -> @body:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> IO(Result<&1, &1, Err, Stream>)

def hex.digit source · line 3098 · raw

@+n:U32 -> Char

def hex.go source · line 3101 · raw

@k:Nat -> @+n:U32 -> @acc:String -> String

def hex.trim source · line 3108 · raw

@+s:String -> String

def hex source · line 3115 · raw

@+n:U32 -> String

def up.sent source · line 3118 · raw

@+tls:Bool -> @+ms:U32 -> @+head:Bool -> @m:Pair(Socket, Result<&1, &1, Pair(U32, String), Unit>) -> Up

def up.conn source · line 3126 · raw

@r:Result<&1, &1, Err, Conn> -> @+ms:U32 -> @+head:Bool -> @wire:String -> IO(Result<&1, &1, Err, Up>)

def up.head source · line 3136 · raw

@+method:String -> @+target:String -> @+hf:String -> @+headers:Map<&2, List<&2, String>> -> String

def up.origin source · line 3139 · raw

@+method:String -> @+ms:U32 -> @headers:Map<&2, List<&2, String>> -> @a:0x1f2d80f53f971b16c6de6a65cb1918ae/url.Abs -> @known:Bool -> IO(Result<&1, &1, Err, Up>)

def up.url source · line 3150 · raw

@+method:String -> @+ms:U32 -> @headers:Map<&2, List<&2, String>> -> @u:Maybe<&2, 0x1f2d80f53f971b16c6de6a65cb1918ae/url.Abs> -> IO(Result<&1, &1, Err, Up>)

def upload.with source · line 3158 · raw

@+method:String -> @url:String -> @headers:Map<&2, List<&2, String>> -> @+ms:U32 -> IO(Result<&1, &1, Err, Up>)

Http.upload(method, url, headers) sends the head. A streamed body cannot be replayed, so redirects are not followed.

def upload source · line 3161 · raw

@+method:String -> @url:String -> @headers:Map<&2, List<&2, String>> -> IO(Result<&1, &1, Err, Up>)

def up.wrote source · line 3164 · raw

@+tls:Bool -> @+ms:U32 -> @+head:Bool -> @m:Pair(Socket, Result<&1, &1, Pair(U32, String), Unit>) -> Pair(Up, Result<&2, &2, Err, Unit>)

def up.put source · line 3174 · raw

@+tls:Bool -> @s:Socket -> @+ms:U32 -> @+head:Bool -> @+len:U32 -> @piece:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @skip:Bool -> IO(Pair(Up, Result<&2, &2, Err, Unit>))

One write per chunk, so the size line and the data do not wait on each other (Nagle).

def up.chunk source · line 3183 · raw

@+tls:Bool -> @s:Socket -> @+ms:U32 -> @+head:Bool -> @piece:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> IO(Pair(Up, Result<&2, &2, Err, Unit>))

def upload.write source · line 3188 · raw

@up:Up -> @piece:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> IO(Pair(Up, Result<&2, &2, Err, Unit>))

One chunk. An empty piece sends nothing, since an empty chunk would end the body.

def upload.finish source · line 3197 · raw

@up:Up -> IO(Result<&1, &1, Err, Stream>)

Ends the body and returns the response as a stream.

def reply.bytes source · line 3209 · raw

@res:Res -> @head:Bool -> @close:Bool -> 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes

def reply.fail.bytes source · line 3213 · raw

@+status:U32 -> Res

def reply.sent.close source · line 3216 · raw

@m:Pair(Socket, Result<&1, &1, Pair(U32, String), Unit>) -> IO(Unit)

def reply_fail source · line 3220 · raw

@s:Socket -> @+status:U32 -> IO(Unit)

def serve.max source · line 3239 · raw

Nat

def sv.none source · line 3242 · raw

Sv

def sv.body source · line 3245 · raw

@req:Req -> @+v11:Bool -> @parts:List<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> @rest:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Turn

def sv.len.cut source · line 3249 · raw

@req:Req -> @+v11:Bool -> @parts:List<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> @+len:U32 -> @+left:U32 -> @r:Pair(0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes) -> Turn

def sv.len.have source · line 3253 · raw

@short:Bool -> @req:Req -> @+v11:Bool -> @+left:U32 -> @parts:List<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> @+len:U32 -> @piece:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Turn

def sv.len source · line 3260 · raw

@req:Req -> @+v11:Bool -> @+left:U32 -> @parts:List<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> @piece:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Turn

def sv.chunk.of source · line 3264 · raw

@req:Req -> @+v11:Bool -> @+n:U32 -> @c:Ck -> Turn

def sv.chunk.cap source · line 3286 · raw

@big:Bool -> @req:Req -> @+v11:Bool -> @+n:U32 -> @st:Dc -> @parts:List<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> @piece:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Turn

def sv.chunk source · line 3293 · raw

@+max:Nat -> @req:Req -> @+v11:Bool -> @+n:U32 -> @st:Dc -> @parts:List<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> @piece:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Turn

def sv.cont source · line 3299 · raw

@want:Bool -> @t:Turn -> Turn

RFC 9110 §10.1.1: answer 100 Continue only when the body is still to come.

def sv.cl.k source · line 3310 · raw

@big:Bool -> @req:Req -> @+v11:Bool -> @+k:U32 -> @rest:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Turn

def sv.cl source · line 3317 · raw

@+max:Nat -> @req:Req -> @+v11:Bool -> @rest:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @n:Maybe<&2, U32> -> Turn

def sv.frame source · line 3324 · raw

@+max:Nat -> @req:Req -> @+v11:Bool -> @rest:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @te:Bool -> Turn

def sv.expects source · line 3332 · raw

@+v11:Bool -> @+headers:Map<&2, List<&2, String>> -> Bool

def sv.got.head source · line 3335 · raw

@+max:Nat -> @+v11:Bool -> @rest:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @req:Req -> Turn

def sv.parsed source · line 3339 · raw

@+max:Nat -> @+v11:Bool -> @rest:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @g:Got -> Turn

def sv.split source · line 3350 · raw

@+max:Nat -> @+hlen:U32 -> @+len:U32 -> @r:Pair(0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes) -> Turn

def sv.hit.none source · line 3355 · raw

@big:Bool -> @buf:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Turn

def sv.hit.some source · line 3362 · raw

@big:Bool -> @+max:Nat -> @+hlen:U32 -> @+len:U32 -> @buf:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Turn

def sv.hit source · line 3370 · raw

@+max:Nat -> @+len:U32 -> @buf:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @at:Maybe<&2, U32> -> Turn

RFC 6585 §5: a head over 64 KiB is refused.

def sv.seek.of source · line 3378 · raw

@+max:Nat -> @+len:U32 -> @+from:U32 -> @buf:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @r:Pair(0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes, Maybe<&2, U32>) -> Turn

def sv.seek source · line 3382 · raw

@+max:Nat -> @+len:U32 -> @+from:U32 -> @r:Pair(0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes) -> Turn

def sv.head.at source · line 3387 · raw

@+max:Nat -> @+from:U32 -> @buf:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Turn

Only the new bytes, and the 3 before them, can finish the blank line.

def sv.head source · line 3391 · raw

@+max:Nat -> @buf:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @piece:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Turn

def sv.closed.pick source · line 3395 · raw

@empty:Bool -> Turn

def sv.closed.head source · line 3402 · raw

@buf:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Turn

def sv.step source · line 3407 · raw

@closed:Bool -> @+max:Nat -> @sv:Sv -> @piece:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Turn

A close mid-request is a request cut short (RFC 9112 §8).

def sv.frame.req source · line 3426 · raw

@t:Turn -> Maybe<&1, Pair(String, String)>

def sv.frame.go source · line 3438 · raw

@xs:List<&2, String> -> @t:Turn -> Maybe<&1, Pair(String, String)>

def serve.frame source · line 3454 · raw

@xs:List<&2, String> -> Maybe<&1, Pair(String, String)>

The body and the bytes after it, once the pieces make a whole request; None otherwise.

def talk.piece source · line 3457 · raw

@+max:Nat -> @sv:Sv -> @p:Pair(U32, Array<U32>) -> Turn

def talk.next source · line 3461 · raw

@+max:Nat -> @sv:Sv -> @m:Pair(Socket, Result<&1, &1, Pair(U32, String), Pair(U32, Array<U32>)>) -> Pair(Socket, Turn)

def talk.after.pick source · line 3469 · raw

@empty:Bool -> @+max:Nat -> @rest:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Turn

def talk.after.rest source · line 3476 · raw

@+max:Nat -> @rest:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @s:Socket -> Pair(Socket, Turn)

def talk.after.keep source · line 3480 · raw

@keep:Bool -> @+max:Nat -> @rest:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @s:Socket -> Pair(Socket, Turn)

def talk.after source · line 3487 · raw

@+max:Nat -> @keep:Bool -> @rest:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @m:Pair(Socket, Result<&1, &1, Pair(U32, String), Unit>) -> Pair(Socket, Turn)

def talk.send source · line 3495 · raw

@+max:Nat -> @s:Socket -> @rest:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @+headers:Map<&2, List<&2, String>> -> @v11:Bool -> @+head:Bool -> @res:Res -> IO(Pair(Socket, Turn))

def talk.cont.sent source · line 3502 · raw

@m:Pair(Socket, Result<&1, &1, Pair(U32, String), Unit>) -> Socket

def talk.cont source · line 3506 · raw

@cont:Bool -> @s:Socket -> IO(Socket)

Templates

template ce.eff source · line 2425 · raw

@-eff:(@_:U32 -> @_:U32 -> @_:Array<U32> -> IO(Result<&1, &1, Pair(U32, String), Pair(U32, Array<U32>)>)) -> @b:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> IO(Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes>)

A decoded body stops at 16 MiB, like a received one.

template codings.has source · line 2540 · raw

@-eff:(@_:U32 -> @_:U32 -> @_:Array<U32> -> IO(Result<&1, &1, Pair(U32, String), Pair(U32, Array<U32>)>)) -> @b:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> IO(Bool)

template conn source · line 3535 · raw

@-h:(@_:Req -> IO(Res)) -> @+max:Nat -> @m:Pair(Listener, Result<&1, &1, Pair(U32, String), Socket>) -> IO(Listener)

template serve.with source · line 3549 · raw

@-h:(@_:Req -> IO(Res)) -> @+port:U32 -> @+max:Nat -> IO(Unit)

template serve source · line 3555 · raw

@-h:(@_:Req -> IO(Res)) -> @+port:U32 -> IO(Unit)

Unsafe

unsafe fetch.loop source · line 1899 · raw

@+close:Bool -> @+head:Bool -> @+tls:Bool -> @+ms:U32 -> @st:Pair(Socket, Fl) -> IO(Out)

Reads until the response is whole or cannot be; an empty read means the server closed.

unsafe pool.hops source · line 2307 · raw

@+mode:Mode -> @+ms:U32 -> @st:Pair(Pool, Next) -> IO(Pair(Pool, Result<&1, &1, Err, Res>))

NGo.left is how many redirects may follow this request. 20 is WHATWG's limit.

unsafe stream.read source · line 2790 · raw

@st:Stream -> IO(Pair(Stream, Result<&1, &1, Err, Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes>>))

The next piece of the body; None at the end. A piece is never empty.

unsafe stream.head source · line 2862 · raw

@+tls:Bool -> @+ms:U32 -> @+head:Bool -> @st:Pair(Socket, Sh) -> IO(Result<&1, &1, Err, Stream>)

Reads until the final head is in; the body bytes that came with it are the first piece.

unsafe stream.hops source · line 2961 · raw

@+ms:U32 -> @sn:Sn -> IO(Result<&1, &1, Err, Stream>)

unsafe talk source · line 3516 · raw

@-h:(@_:Req -> IO(Res)) -> @+max:Nat -> @st:Pair(Socket, Turn) -> IO(Unit)

unsafe loop source · line 3543 · raw

@-h:(@_:Req -> IO(Res)) -> @+max:Nat -> @l:Listener -> IO(Unit)