http.bend fails
raw source on the hub · import bend-kit-http@0.18.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 0x096635686408886b7d907f16c4550317/wire.bend as Wire import 0xd248560355ba8929ae030bc9c72f40be/url.bend as Url import 0xcfc8be7b076f41f95c8e118383892d55/encoding.bend as Enc import 0x584fc27920487ceab242392391418d7f/json.bend as Json import 0x49814d83de8f70993a43e1002be29ecd/bytes.bend as Bytes import 0xc10a5eaaa9c896e1570e279945f4241e/dns.bend as Dns import 0x9d101c075b333e2b07242347f7c35b1c/zlib.bend as Zlib
Types
type Req source · line 19 · raw
Type
Req@method:String -> @path:String -> @headers:Map<&2, List<&2, String>> -> @body:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Req
type Res source · line 22 · raw
Type
Res@status:U32 -> @headers:Map<&2, List<&2, String>> -> @body:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Res
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.
ErrUrlErr
ErrDnsErr
ErrConnect@code:U32 -> @why:String -> Err
ErrTls@code:U32 -> @why:String -> Err
ErrRead@code:U32 -> @why:String -> Err
ErrWrite@code:U32 -> @why:String -> Err
ErrTimeoutErr
ErrRedirectErr
ErrBadErr
type Fields source · line 65 · raw
Data
FieldsBadFields
FieldsOk@m:Map<&2, List<&2, String>> -> Fields
type Hold source · line 375 · raw
Data
More: a valid prefix. Bad: cannot become a body. Body: a whole chunked body.
HoldMoreHold
HoldBadHold
HoldBody@b:String -> Hold
HoldUntil@b:String -> Hold
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.
DcSize@acc:U32 -> @seen:Bool -> Dc
DcExt@n:U32 -> Dc
DcSizeLf@n:U32 -> Dc
DcData@k:U32 -> Dc
DcDataCrDc
DcDataLfDc
DcTr@j:U32 -> Dc
DcDoneDc
DcBadDc
type Dco source · line 401 · raw
Data
st: where the decoder is. racc: the body so far, reversed. rest: bytes after a Done body.
Dco@st:Dc -> @racc:String -> @rest:String -> Dco
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.
Cs@piece:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @i:U32 -> @st:Dc -> @parts:List<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> Cs
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.
Ck@st:Dc -> @parts:List<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> @rest:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Ck
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.
GotBadGot
GotMoreGot
GotHead@req:Req -> Got
GotReq@req:Req -> Got
type Frame source · line 896 · raw
Type
Bad: never a message. More: a valid prefix; read on. Done: a whole response.
FrameBadFrame
FrameMoreFrame
FrameDone@res:Res -> Frame
type Lead source · line 989 · raw
Data
LeadCutLead
LeadFinalLead
LeadSkip@+rest:String -> Lead
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.
RbLen@left:U32 -> Rb
RbChunk@st:Dc -> Rb
RbCloseRb
RbDoneRb
RbBadRb
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.
Bf@rb:Rb -> @parts:List<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> @rest:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Bf
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.
HsSeek@buf:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @from:U32 -> @k:U32 -> Hs
HsWait@buf:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @k:U32 -> Hs
HsBadHs
HsRes@res:Res -> @rb:Rb -> @rest:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Hs
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.
RvHead@buf:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @k:U32 -> Rv
RvBody@res:Res -> @rb:Rb -> @parts:List<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> Rv
RvLen@res:Res -> @left:U32 -> @body:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Rv
type Rt source · line 1323 · raw
Type
More: read on. Done: the response, and the bytes after it when the body is self-delimited.
RtMore@rv:Rv -> Rt
RtBadRt
RtDone@res:Res -> @rest:Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> Rt
type Reason source · line 1629 · raw
Data
RFC 9110 §15. An unknown code gets an empty reason, which RFC 9112 §4 allows.
Reason@code:U32 -> @text:String -> Reason
type Hop source · line 1725 · raw
Type
One request to make: headers are already lowercased (see req.put).
Hop@method:String -> @url:0xd248560355ba8929ae030bc9c72f40be/url.Abs -> @headers:Map<&2, List<&2, String>> -> @body:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Hop
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.
OutDone@res:Res -> @sock:Maybe<&1, Socket> -> @rest:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Out
OutFail@e:Err -> @none:Bool -> Out
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.
FlMore@rv:Rv -> @n:U32 -> Fl
FlBad@err:Maybe<&2, Err> -> @none:Bool -> Fl
FlDone@res:Res -> @rest:Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> Fl
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.
Conn@tls:Bool -> @s:Socket -> Conn
type Pool source · line 1942 · raw
Type
Pool@cap:U32 -> @idle:Map<&1, List<&1, Conn>> -> Pool
type Next source · line 2170 · raw
Type
NDone@res:Result<&1, &1, Err, Res> -> Next
NStopNext
NGo@left:Nat -> @hop:Hop -> Next
type Mode source · line 2175 · raw
Data
ModeFollowMode
ModeManualMode
ModeErrorMode
type Dec source · line 2278 · raw
Data
Ok: decoded so far. Bad: a coding failed. Skip: a coding we cannot decode, so the body stays as sent.
DecOk@b:String -> Dec
DecBadDec
DecSkipDec
type Po source · line 2553 · raw
Type
Streaming (a body read or sent in pieces). Stream bodies are never content-decoded. What the next read returns: read more, a piece, the end, or an error.
PoNonePo
PoPiece@b:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Po
PoEndPo
PoBad@e:Err -> Po
type Stream source · line 2559 · raw
Type
Stream@tls:Bool -> @s:Socket -> @ms:U32 -> @res:Res -> @rb:Rb -> @out:Po -> Stream
type Pc source · line 2562 · raw
Type
Pc@rb:Rb -> @out:Po -> Pc
type Sh source · line 2665 · raw
Type
Head read state: still scanning, cut short or bad, or the head with the bytes after it.
ShMore@buf:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @k:U32 -> Sh
ShBad@err:Maybe<&2, Err> -> Sh
ShRes@res:Res -> @rb:Rb -> @rest:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Sh
type Sn source · line 2769 · raw
Type
Go: the next request. Drop: close this stream, then go on. Done: the answer.
SnGo@left:Nat -> @hop:Hop -> Sn
SnDrop@st:Stream -> @next:Next -> Sn
SnDone@r:Result<&1, &1, Err, Stream> -> Sn
type Up source · line 2838 · raw
Type
Upload: the request body sent in chunks (RFC 9112 §7.1). err: the first failed write.
Up@tls:Bool -> @s:Socket -> @ms:U32 -> @head:Bool -> @err:Maybe<&2, Err> -> Up
type Sv source · line 2978 · raw
Type
The head is parsed once, when it is whole. Body pieces are kept as they come and joined once.
SvHead@buf:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Sv
SvLen@req:Req -> @v11:Bool -> @left:U32 -> @parts:List<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> Sv
SvChunk@req:Req -> @v11:Bool -> @n:U32 -> @st:Dc -> @parts:List<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> Sv
type Turn source · line 2984 · raw
Type
More: read on, first answering 100 Continue when cont is set.
TurnCloseTurn
TurnFail@status:U32 -> Turn
TurnReq@req:Req -> @rest:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @v11:Bool -> Turn
TurnMore@sv:Sv -> @cont:Bool -> Turn
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 header source · line 88 · raw
@+h:Map<&2, List<&2, String>> -> @k: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:0xd248560355ba8929ae030bc9c72f40be/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:0xd248560355ba8929ae030bc9c72f40be/url.Abs -> @headers:Map<&2, List<&2, String>> -> @body:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @next:Maybe<&2, 0xd248560355ba8929ae030bc9c72f40be/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.ex source · line 2052 · raw
@c:Conn -> @+ms:U32 -> @+head:Bool -> @wire:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> IO(Out)
def pool.keep.s source · line 2057 · 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 2068 · 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 2075 · 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 2079 · raw
@p:Pool -> @+key:String -> @+tls:Bool -> @o:Out -> IO(Pair(Pool, Result<&1, &1, Err, Res>))
def pool.fresh.conn source · line 2086 · 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.ip source · line 2095 · raw
@p:Pool -> @+key:String -> @+tls:Bool -> @+ms:U32 -> @+head:Bool -> @+host:String -> @+port:U32 -> @wire:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @ip:Maybe<&2, String> -> IO(Pair(Pool, Result<&1, &1, Err, Res>))
def pool.fresh source · line 2104 · 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 2110 · raw
@+none:Bool -> @+idem:Bool -> Bool
A reused socket the server already closed fails before any response byte.
def pool.stale source · line 2113 · 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 2120 · 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 2128 · 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 2134 · 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 2142 · raw
@p:Pool -> @+method:String -> @+ms:U32 -> @headers:Map<&2, List<&2, String>> -> @body:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @+hf:String -> @a:0xd248560355ba8929ae030bc9c72f40be/url.Abs -> @known:Bool -> IO(Pair(Pool, Result<&1, &1, Err, Res>))
def pool.scheme.ok source · line 2151 · raw
@a:0xd248560355ba8929ae030bc9c72f40be/url.Abs -> Bool
def pool.one.back source · line 2155 · 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 2159 · raw
@p:Pool -> @+method:String -> @+url:0xd248560355ba8929ae030bc9c72f40be/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 2166 · 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 2181 · raw
@left:Nat -> @h:Hop -> Next
left: redirects still allowed after the request we just finished.
def fetch.decide.r source · line 2188 · raw
@left:Nat -> @r:Res -> @next:Maybe<&1, Hop> -> Next
def fetch.decide.res source · line 2195 · raw
@left:Nat -> @h:Hop -> @r:Res -> Next
def fetch.decide source · line 2199 · raw
@left:Nat -> @h:Hop -> @m:Result<&1, &1, Err, Res> -> Next
def fetch.error.res source · line 2206 · raw
@r:Res -> @bad:Bool -> Next
def fetch.error source · line 2213 · raw
@h:Hop -> @m:Result<&1, &1, Err, Res> -> Next
def fetch.policy source · line 2221 · raw
@mode:Mode -> @left:Nat -> @h:Hop -> @m:Result<&1, &1, Err, Res> -> Next
def accept.enc source · line 2231 · 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 2234 · raw
@method:String -> @headers:Map<&2, List<&2, String>> -> @body:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @u:Maybe<&2, 0xd248560355ba8929ae030bc9c72f40be/url.Abs> -> @+enc:String -> Next
def pool.next source · line 2241 · raw
@+mode:Mode -> @left:Nat -> @x:Pair(Pool, Pair(Result<&1, &1, Err, Res>, Hop)) -> Pair(Pool, Next)
def ce.keep source · line 2260 · 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 2263 · raw
@xs:List<&2, String> -> List<&2, String>
def ce.split source · line 2270 · raw
@xs:List<&2, String> -> List<&2, String>
def ce.of source · line 2283 · raw
@m:Maybe<&2, String> -> Dec
def ce.deflate source · line 2291 · raw
@+b:String -> @m:Maybe<&2, String> -> Dec
Servers send deflate both with and without the zlib wrapper.
def ce.apply source · line 2298 · raw
@+c:String -> @+b:String -> Dec
def ce.go source · line 2303 · raw
@cs:List<&2, String> -> @d:Dec -> Dec
def decoded.pick source · line 2316 · raw
@d:Dec -> @+status:U32 -> @headers:Map<&2, List<&2, String>> -> @body:String -> Result<&1, &1, Err, Res>
def decoded.cs source · line 2326 · 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 2334 · raw
@empty:Bool -> @+status:U32 -> @+headers:Map<&2, List<&2, String>> -> @body:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Result<&1, &1, Err, Res>
def decoded source · line 2342 · 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 2347 · raw
@r:Result<&1, &1, Err, Res> -> Maybe<&1, Res>
def decoded.some source · line 2354 · raw
@res:Res -> Maybe<&1, Res>
def ce.words source · line 2357 · raw
@r:Result<&1, &1, Pair(U32, String), Pair(U32, Array<U32>)> -> Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes>
def ce.dec source · line 2371 · raw
@d:Dec -> Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes>
def ce.io.deflate source · line 2381 · 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 2389 · raw
@on:Bool -> @+c:String -> @b:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> IO(Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes>)
def ce.io.br source · line 2396 · raw
@on:Bool -> @+c:String -> @b:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> IO(Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes>)
def ce.io.gz source · line 2404 · 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 2411 · raw
@cs:List<&2, String> -> @m:Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> IO(Maybe<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes>)
def ce.has source · line 2428 · raw
@xs:List<&2, String> -> @+c:String -> Bool
def ce.known source · line 2435 · raw
@cs:List<&2, String> -> @+ok:List<&2, String> -> Bool
def decoded.io.pick source · line 2442 · 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 2449 · 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 2458 · 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 2467 · 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 2473 · 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 2486 · raw
@has:Bool -> @+enc:String -> @+c:String -> String
def codings source · line 2490 · raw
IO(String)
gzip and deflate, then br and zstd when their C library loads.
def fetch.final source · line 2497 · 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 2504 · 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 2510 · 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 2518 · 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 2523 · 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 2526 · 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 2529 · raw
@pr:Pair(Pool, Result<&1, &1, Err, Res>) -> IO(Result<&1, &1, Err, Res>)
def fetch.how source · line 2536 · 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 2541 · 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 2545 · 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 2548 · raw
@url:String -> IO(Result<&1, &1, Err, Res>)
def pc.po source · line 2566 · 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 2573 · raw
@more:Bool -> @+rb:Rb -> @b:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Pc
def pc.fed.of source · line 2577 · raw
@b:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @st:Rb -> Pc
def pc.fed source · line 2590 · raw
@bf:Bf -> Pc
def pc.of source · line 2595 · 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 2599 · raw
@ok:Bool -> Pc
The server closed. Only a close-delimited body may end this way (RFC 9112 §8).
def pc.eof source · line 2606 · raw
@st:Rb -> Pc
def stream.mk source · line 2609 · raw
@+tls:Bool -> @s:Socket -> @+ms:U32 -> @res:Res -> @pc:Pc -> Stream
def stream.got.piece source · line 2613 · raw
@+tls:Bool -> @s:Socket -> @+ms:U32 -> @res:Res -> @+rb:Rb -> @p:Pair(U32, Array<U32>) -> Stream
def stream.got source · line 2617 · raw
@+tls:Bool -> @+ms:U32 -> @res:Res -> @+rb:Rb -> @m:Pair(Socket, Result<&1, &1, Pair(U32, String), Pair(U32, Array<U32>)>) -> Stream
def stream.after source · line 2625 · raw
@+rb:Rb -> Po
def stream.res source · line 2655 · raw
@st:Stream -> Pair(Stream, Res)
Status and headers. Its body is empty: read the body with stream.read.
def stream.close source · line 2660 · raw
@st:Stream -> IO(Unit)
def sh.of source · line 2670 · raw
@hs:Hs -> Sh
def sh.piece source · line 2681 · raw
@+head:Bool -> @buf:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @+k:U32 -> @p:Pair(U32, Array<U32>) -> Sh
def sh.next source · line 2685 · 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 2693 · raw
@r:Result<&1, &1, Err, Res> -> Result<&1, &1, Err, Stream>
def stream.sent source · line 2716 · 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 2726 · raw
@r:Result<&1, &1, Err, Conn> -> @+ms:U32 -> @+head:Bool -> @wire:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> IO(Result<&1, &1, Err, Stream>)
def stream.ip source · line 2736 · raw
@+tls:Bool -> @+ms:U32 -> @+head:Bool -> @+host:String -> @+port:U32 -> @wire:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @ip:Maybe<&2, String> -> IO(Result<&1, &1, Err, Stream>)
def stream.origin source · line 2746 · raw
@+ms:U32 -> @+head:Bool -> @wire:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @a:0xd248560355ba8929ae030bc9c72f40be/url.Abs -> @known:Bool -> IO(Result<&1, &1, Err, Stream>)
One connection per stream; the request says close.
def stream.one.of source · line 2756 · raw
@+method:String -> @+url:0xd248560355ba8929ae030bc9c72f40be/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 2764 · 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 2774 · raw
@n:Next -> Sn
def stream.decide.n source · line 2787 · raw
@st:Stream -> @n:Next -> Sn
def stream.decide.of source · line 2796 · raw
@+left:Nat -> @hop:Hop -> @sr:Pair(Stream, Res) -> Sn
def stream.decide source · line 2800 · raw
@+left:Nat -> @x:Pair(Hop, Result<&1, &1, Err, Stream>) -> Sn
def stream.start source · line 2822 · raw
@method:String -> @headers:Map<&2, List<&2, String>> -> @body:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @u:Maybe<&2, 0xd248560355ba8929ae030bc9c72f40be/url.Abs> -> Sn
def open.with source · line 2831 · raw
@method:String -> @url:String -> @headers:Map<&2, List<&2, String>> -> @body:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @+ms:U32 -> IO(Result<&1, &1, Err, Stream>)
Http.open(method, url, headers, body) follows redirects like fetch and returns once the head is in. Read the body with stream.read. Stream bodies are sent and returned as is: no Accept-Encoding, no decoding.
def open source · line 2834 · 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 2841 · raw
@+n:U32 -> Char
def hex.go source · line 2844 · raw
@k:Nat -> @+n:U32 -> @acc:String -> String
def hex.trim source · line 2851 · raw
@+s:String -> String
def hex source · line 2858 · raw
@+n:U32 -> String
def up.sent source · line 2861 · raw
@+tls:Bool -> @+ms:U32 -> @+head:Bool -> @m:Pair(Socket, Result<&1, &1, Pair(U32, String), Unit>) -> Up
def up.conn source · line 2869 · raw
@r:Result<&1, &1, Err, Conn> -> @+ms:U32 -> @+head:Bool -> @wire:String -> IO(Result<&1, &1, Err, Up>)
def up.ip source · line 2879 · raw
@+tls:Bool -> @+ms:U32 -> @+head:Bool -> @+host:String -> @+port:U32 -> @wire:String -> @ip:Maybe<&2, String> -> IO(Result<&1, &1, Err, Up>)
def up.head source · line 2888 · raw
@+method:String -> @+target:String -> @+hf:String -> @+headers:Map<&2, List<&2, String>> -> String
def up.origin source · line 2891 · raw
@+method:String -> @+ms:U32 -> @headers:Map<&2, List<&2, String>> -> @a:0xd248560355ba8929ae030bc9c72f40be/url.Abs -> @known:Bool -> IO(Result<&1, &1, Err, Up>)
def up.url source · line 2901 · raw
@+method:String -> @+ms:U32 -> @headers:Map<&2, List<&2, String>> -> @u:Maybe<&2, 0xd248560355ba8929ae030bc9c72f40be/url.Abs> -> IO(Result<&1, &1, Err, Up>)
def upload.with source · line 2909 · 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 2912 · raw
@+method:String -> @url:String -> @headers:Map<&2, List<&2, String>> -> IO(Result<&1, &1, Err, Up>)
def up.wrote source · line 2915 · 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 2925 · 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 2934 · 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 2939 · 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 2948 · raw
@up:Up -> IO(Result<&1, &1, Err, Stream>)
Ends the body and returns the response as a stream.
def reply.bytes source · line 2960 · raw
@res:Res -> @head:Bool -> @close:Bool -> 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes
def reply.fail.bytes source · line 2964 · raw
@+status:U32 -> Res
def reply.sent.close source · line 2967 · raw
@m:Pair(Socket, Result<&1, &1, Pair(U32, String), Unit>) -> IO(Unit)
def reply_fail source · line 2971 · raw
@s:Socket -> @+status:U32 -> IO(Unit)
def serve.max source · line 2990 · raw
Nat
def sv.none source · line 2993 · raw
Sv
def sv.body source · line 2996 · raw
@req:Req -> @+v11:Bool -> @parts:List<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> @rest:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Turn
def sv.len.cut source · line 3000 · 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 3004 · 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 3011 · raw
@req:Req -> @+v11:Bool -> @+left:U32 -> @parts:List<&1, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes> -> @piece:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Turn
def sv.chunk.of source · line 3015 · raw
@req:Req -> @+v11:Bool -> @+n:U32 -> @c:Ck -> Turn
def sv.chunk.cap source · line 3037 · 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 3044 · 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 3050 · 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 3061 · raw
@big:Bool -> @req:Req -> @+v11:Bool -> @+k:U32 -> @rest:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Turn
def sv.cl source · line 3068 · raw
@+max:Nat -> @req:Req -> @+v11:Bool -> @rest:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @n:Maybe<&2, U32> -> Turn
def sv.frame source · line 3075 · raw
@+max:Nat -> @req:Req -> @+v11:Bool -> @rest:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @te:Bool -> Turn
def sv.expects source · line 3083 · raw
@+v11:Bool -> @+headers:Map<&2, List<&2, String>> -> Bool
def sv.got.head source · line 3086 · raw
@+max:Nat -> @+v11:Bool -> @rest:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @req:Req -> Turn
def sv.parsed source · line 3090 · raw
@+max:Nat -> @+v11:Bool -> @rest:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @g:Got -> Turn
def sv.split source · line 3101 · raw
@+max:Nat -> @+hlen:U32 -> @+len:U32 -> @r:Pair(0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes) -> Turn
def sv.hit.none source · line 3106 · raw
@big:Bool -> @buf:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Turn
def sv.hit.some source · line 3113 · raw
@big:Bool -> @+max:Nat -> @+hlen:U32 -> @+len:U32 -> @buf:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Turn
def sv.hit source · line 3121 · 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 3129 · 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 3133 · raw
@+max:Nat -> @+len:U32 -> @+from:U32 -> @r:Pair(0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes) -> Turn
def sv.head.at source · line 3138 · 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 3142 · raw
@+max:Nat -> @buf:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @piece:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Turn
def sv.closed.pick source · line 3146 · raw
@empty:Bool -> Turn
def sv.closed.head source · line 3153 · raw
@buf:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Turn
def sv.step source · line 3158 · 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 3177 · raw
@t:Turn -> Maybe<&1, Pair(String, String)>
def sv.frame.go source · line 3189 · raw
@xs:List<&2, String> -> @t:Turn -> Maybe<&1, Pair(String, String)>
def serve.frame source · line 3205 · 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 3208 · raw
@+max:Nat -> @sv:Sv -> @p:Pair(U32, Array<U32>) -> Turn
def talk.next source · line 3212 · 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 3220 · raw
@empty:Bool -> @+max:Nat -> @rest:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Turn
def talk.after.rest source · line 3227 · raw
@+max:Nat -> @rest:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @s:Socket -> Pair(Socket, Turn)
def talk.after.keep source · line 3231 · raw
@keep:Bool -> @+max:Nat -> @rest:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @s:Socket -> Pair(Socket, Turn)
def talk.after source · line 3238 · 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 3246 · 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 3253 · raw
@m:Pair(Socket, Result<&1, &1, Pair(U32, String), Unit>) -> Socket
def talk.cont source · line 3257 · raw
@cont:Bool -> @s:Socket -> IO(Socket)
Templates
template ce.eff source · line 2365 · 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 2480 · 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 3286 · raw
@-h:(@_:Req -> IO(Res)) -> @+max:Nat -> @m:Pair(Listener, Result<&1, &1, Pair(U32, String), Socket>) -> IO(Listener)
template serve.with source · line 3300 · raw
@-h:(@_:Req -> IO(Res)) -> @+port:U32 -> @+max:Nat -> IO(Unit)
template serve source · line 3306 · 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 2247 · 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 2640 · 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 2702 · 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 2809 · raw
@+ms:U32 -> @sn:Sn -> IO(Result<&1, &1, Err, Stream>)
unsafe talk source · line 3267 · raw
@-h:(@_:Req -> IO(Res)) -> @+max:Nat -> @st:Pair(Socket, Turn) -> IO(Unit)
unsafe loop source · line 3294 · raw
@-h:(@_:Req -> IO(Res)) -> @+max:Nat -> @l:Listener -> IO(Unit)