http.bend fails
raw source on the hub · import bend-kit-http@0.14.0.1/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 0xb481bb64f1136053b0a6b2c6da6277ab/wire.bend as Wire import 0xd248560355ba8929ae030bc9c72f40be/url.bend as Url import 0xaec630f7a2f6b6ef96750f95d6e4195b/encoding.bend as Enc import 0xaaa10a97bf5ac6990143da2c863f8a3f/json.bend as Json import 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.bend as Bytes import 0xef7fb3464d57d2b70573cabf3289c442/dns.bend as Dns import 0xe01785b64266bf3ba0068183b9f9f5e3/zlib.bend as Zlib
Types
type Req source · line 19 · raw
Type
Req@method:String -> @path:String -> @headers:Map<&2, List<&2, String>> -> @body:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> Req
type Res source · line 22 · raw
Type
Res@status:U32 -> @headers:Map<&2, List<&2, String>> -> @body:0xbf22530d1ea11c951d1ecaa353ed1580/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 301 · 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 315 · 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 327 · 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 564 · raw
Type
A chunked body decoded from piece[i..]: a data run is sliced whole, and every other byte steps dc.
Cs@piece:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> @i:U32 -> @st:Dc -> @parts:List<&1, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes> -> Cs
type Ck source · line 568 · 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, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes> -> @rest:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> Ck
type Got source · line 689 · 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 820 · 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 913 · raw
Data
LeadCutLead
LeadFinalLead
LeadSkip@rest:String -> Lead
type Rb source · line 1012 · 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 1049 · 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, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes> -> @rest:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> Bf
type Hs source · line 1119 · 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:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> @from:U32 -> @k:U32 -> Hs
HsWait@buf:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> @k:U32 -> Hs
HsBadHs
HsRes@res:Res -> @rb:Rb -> @rest:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> Hs
type Rv source · line 1214 · raw
Type
A response read in pieces. Head: the head is not whole yet. Body: it is, and parts is the body so far.
RvHead@buf:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> @k:U32 -> Rv
RvBody@res:Res -> @rb:Rb -> @parts:List<&1, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes> -> Rv
type Rt source · line 1219 · 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, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes> -> Rt
type Reason source · line 1473 · 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 1569 · 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:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> Hop
type Out source · line 1666 · 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:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> Out
OutFail@e:Err -> @none:Bool -> Out
type Fl source · line 1707 · 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, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes> -> Fl
type Conn source · line 1786 · raw
Type
Connection pool: idle sockets by scheme, host, and port. fetch uses a fresh pool per call.
Conn@tls:Bool -> @s:Socket -> Conn
type Pool source · line 1789 · raw
Type
Pool@idle:Map<&1, Conn> -> Pool
type Next source · line 1995 · raw
Type
NDone@res:Result<&1, &1, Err, Res> -> Next
NStopNext
NGo@left:Nat -> @hop:Hop -> Next
type Mode source · line 2000 · raw
Data
ModeFollowMode
ModeManualMode
ModeErrorMode
type Dec source · line 2103 · 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 2232 · 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:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> Po
PoEndPo
PoBad@e:Err -> Po
type Stream source · line 2238 · raw
Type
Stream@tls:Bool -> @s:Socket -> @ms:U32 -> @res:Res -> @rb:Rb -> @out:Po -> Stream
type Pc source · line 2241 · raw
Type
Pc@rb:Rb -> @out:Po -> Pc
type Sh source · line 2344 · raw
Type
Head read state: still scanning, cut short or bad, or the head with the bytes after it.
ShMore@buf:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> @k:U32 -> Sh
ShBad@err:Maybe<&2, Err> -> Sh
ShRes@res:Res -> @rb:Rb -> @rest:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> Sh
type Sn source · line 2448 · 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 2517 · 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 2657 · raw
Type
The head is parsed once, when it is whole. Body pieces are kept as they come and joined once.
SvHead@buf:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> Sv
SvLen@req:Req -> @v11:Bool -> @left:U32 -> @parts:List<&1, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes> -> Sv
SvChunk@req:Req -> @v11:Bool -> @n:U32 -> @st:Dc -> @parts:List<&1, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes> -> Sv
type Turn source · line 2663 · raw
Type
More: read on, first answering 100 Continue when cont is set.
TurnCloseTurn
TurnFail@status:U32 -> Turn
TurnReq@req:Req -> @rest:0xbf22530d1ea11c951d1ecaa353ed1580/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 -> 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes
A byte string (one Char per octet) to a body, and back.
def to_string source · line 33 · raw
@b:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> String
def length source · line 36 · raw
@b:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> Pair(0xbf22530d1ea11c951d1ecaa353ed1580/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.if source · line 131 · raw
@+s:String -> @cr:Bool -> String
def drop_cr source · line 138 · raw
@+s:String -> String
def take.cut source · line 142 · 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 146 · 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 161 · raw
@s:String -> Pair(String, String)
def start_line.ver source · line 164 · raw
@m:String -> @pv:Pair(String, String) -> Pair(String, Pair(String, String))
def start_line.rest source · line 168 · raw
@mr:Pair(String, String) -> Pair(String, Pair(String, String))
def start_line source · line 172 · raw
@s:String -> Pair(String, Pair(String, String))
def split_at_blank.go source · line 175 · raw
@s:String -> @e:Bool -> @w:U32 -> @acc:String -> Pair(String, String)
def split_at_blank source · line 187 · raw
@s:String -> Pair(String, String)
def split_colon.go source · line 190 · raw
@s:String -> @acc:String -> @hit:Bool -> Pair(String, String)
def split_colon source · line 205 · raw
@s:String -> Pair(String, String)
def has_header.of source · line 208 · raw
@r:Pair(Map<&2, List<&2, String>>, Bool) -> Bool
def has_header source · line 212 · raw
@+h:Map<&2, List<&2, String>> -> @k:String -> Bool
def folded source · line 215 · raw
@+line:String -> Bool
def tracked source · line 218 · raw
@+k:String -> Bool
def fields_put.dup source · line 221 · raw
@m:Map<&2, List<&2, String>> -> @k:String -> @v:String -> @bad:Bool -> Fields
def fields_put.key source · line 228 · raw
@+m:Map<&2, List<&2, String>> -> @+k:String -> @v:String -> Fields
def fields_put.kv source · line 231 · raw
@m:Map<&2, List<&2, String>> -> @kv:Pair(String, String) -> Fields
def fields_put.fold source · line 235 · raw
@m:Map<&2, List<&2, String>> -> @line:String -> @fold:Bool -> Fields
def fields_put.empty source · line 242 · raw
@m:Map<&2, List<&2, String>> -> @+line:String -> @e:Bool -> Fields
def fields_put.ok source · line 249 · raw
@m:Map<&2, List<&2, String>> -> @+line:String -> Fields
def fields_put source · line 252 · raw
@acc:Fields -> @line:String -> Fields
def parse.headers.done source · line 259 · raw
@acc:Fields -> Maybe<&2, Map<&2, List<&2, String>>>
def parse.headers source · line 266 · raw
@xs:List<&2, String> -> @acc:Fields -> Maybe<&2, Map<&2, List<&2, String>>>
def parse_u32.digit source · line 273 · raw
@+c:U32 -> Bool
def parse_u32.add source · line 276 · raw
@acc:U32 -> @c:U32 -> U32
def parse_u32.done source · line 279 · raw
@acc:U32 -> @bad:Bool -> Maybe<&2, U32>
def parse_u32.go source · line 286 · raw
@s:String -> @acc:U32 -> @bad:Bool -> Maybe<&2, U32>
def parse_u32 source · line 293 · raw
@s:String -> Maybe<&2, U32>
def is_hex source · line 307 · raw
@+c:U32 -> Bool
def hexv source · line 310 · raw
@+c:U32 -> U32
def dc.start source · line 330 · raw
Dc
def dc.size.semi source · line 333 · raw
@+n:U32 -> @semi:Bool -> Dc
def dc.size.cr source · line 340 · raw
@+n:U32 -> @+c:U32 -> @cr:Bool -> Dc
def dc.size.end source · line 347 · raw
@+n:U32 -> @+c:U32 -> @seen:Bool -> Dc
def dc.size source · line 355 · 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 363 · 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 370 · raw
@+n:U32 -> @+c:U32 -> @cr:Bool -> Dc
def dc.sized source · line 377 · raw
@+n:U32 -> @zero:Bool -> Dc
def dc.size.lf source · line 384 · raw
@+n:U32 -> @lf:Bool -> Dc
def dc.data source · line 392 · raw
@+k:U32 -> @+m:U32 -> Dc
k data bytes are left and m of them were just read.
def dc.pick source · line 395 · raw
@ok:Bool -> @next:Dc -> Dc
def dc.tr.hit source · line 403 · raw
@+j:U32 -> Dc
ponytail: trailer fields are dropped unparsed (§7.1.2 allows discarding)
def dc.tr source · line 406 · raw
@+j:U32 -> @+c:U32 -> @hit:Bool -> Dc
def dc.tr.want source · line 413 · raw
@+j:U32 -> U32
def dc.byte source · line 416 · raw
@h:Char -> U32
def dc.step source · line 421 · 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 442 · raw
@st:Dc -> Bool
def dc.feed source · line 463 · raw
@s:String -> @st:Dc -> @racc:String -> Dco
def chunk.hold source · line 488 · raw
@o:Dco -> Hold
def chunk.live source · line 510 · raw
@s:String -> Hold
def chunk.rest source · line 513 · raw
@o:Dco -> Maybe<&2, String>
def chunk.suffix source · line 535 · raw
@s:String -> Maybe<&2, String>
def chunk.decode.hold source · line 538 · raw
@h:Hold -> Maybe<&2, String>
def chunk.decode source · line 549 · raw
@s:String -> Maybe<&2, String>
def bytes.snd source · line 552 · raw
@r:Pair(0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes) -> 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes
def found.at source · line 556 · raw
@+from:U32 -> @m:Maybe<&2, U32> -> Maybe<&2, U32>
def ck.next source · line 571 · raw
@+len:U32 -> @+i:U32 -> @+st:Dc -> @piece:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> @parts:List<&1, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes> -> Pair(Bool, Cs)
def ck.data source · line 574 · raw
@+len:U32 -> @+i:U32 -> @+k:U32 -> @+m:U32 -> @parts:List<&1, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes> -> @r:Pair(0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes) -> Pair(Bool, Cs)
def ck.byte source · line 578 · raw
@+len:U32 -> @+i:U32 -> @st:Dc -> @parts:List<&1, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes> -> @r:Pair(0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes, Maybe<&2, U32>) -> Pair(Bool, Cs)
def ck.step source · line 586 · raw
@+len:U32 -> @cs:Cs -> Pair(Bool, Cs)
def ck.rest source · line 609 · raw
@st:Dc -> @parts:List<&1, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes> -> @r:Pair(0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes) -> Ck
def ck.end source · line 613 · raw
@+len:U32 -> @cs:Cs -> Ck
def ck.feed source · line 618 · 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 631 · raw
@piece:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> @+st:Dc -> @parts:List<&1, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes> -> Ck
def parse.res.cl.have source · line 635 · raw
@+rest:String -> @+k:Nat -> @short:Bool -> Hold
def parse.res.cl.k source · line 642 · raw
@+rest:String -> @+k:Nat -> Hold
def parse.res.cl.n source · line 645 · raw
@rest:String -> @n:Maybe<&2, U32> -> Hold
def parse.body.cl source · line 652 · raw
@+h:Map<&2, List<&2, String>> -> @rest:String -> @hascl:Bool -> Hold
def parse.body.chunked.eq source · line 660 · 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 667 · raw
@te:String -> @rest:String -> Hold
def parse.body.chunked source · line 670 · raw
@+h:Map<&2, List<&2, String>> -> @rest:String -> @hascl:Bool -> Hold
def parse.body.te source · line 677 · raw
@+h:Map<&2, List<&2, String>> -> @rest:String -> @te:Bool -> Hold
def parse.body source · line 684 · raw
@+h:Map<&2, List<&2, String>> -> @rest:String -> Hold
def parse.finish source · line 695 · raw
@method:String -> @path:String -> @h:Map<&2, List<&2, String>> -> @body:Hold -> Got
def parse.host source · line 706 · raw
@method:String -> @path:String -> @+h:Map<&2, List<&2, String>> -> @rest:String -> @has:Bool -> Got
def parse.fields source · line 714 · 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 721 · raw
@+p:String -> Bool
def parse.target source · line 724 · raw
@method:String -> @+path:String -> @headers:List<&2, String> -> @rest:String -> @v11:Bool -> @ok:Bool -> Got
def parse.ver source · line 731 · raw
@method:String -> @+path:String -> @+v:String -> @headers:List<&2, String> -> @rest:String -> @ok:Bool -> Got
def parse.empty_method source · line 738 · raw
@method:String -> @path:String -> @+v:String -> @headers:List<&2, String> -> @rest:String -> @empty:Bool -> Got
def parse.start3 source · line 745 · raw
@mpv:Pair(String, Pair(String, String)) -> @headers:List<&2, String> -> @rest:String -> Got
def parse.lines source · line 749 · raw
@xs:List<&2, String> -> @rest:String -> Got
def parse.head source · line 756 · raw
@+head:String -> @rest:String -> @whole:Bool -> Got
def parse.of source · line 763 · raw
@hb:Pair(String, String) -> Got
def parse.got source · line 768 · raw
@raw:String -> Got
serve reads until this is not GotMore.
def parse.req source · line 771 · raw
@g:Got -> Maybe<&1, Req>
def parse source · line 782 · raw
@raw:String -> Maybe<&1, Req>
def parse.res.cl source · line 785 · raw
@+h:Map<&2, List<&2, String>> -> @rest:String -> @hascl:Bool -> Hold
def parse.res.chunked.eq source · line 792 · raw
@rest:String -> @ok:Bool -> Hold
def parse.res.chunked.val source · line 799 · raw
@te:String -> @rest:String -> Hold
def parse.res.chunked source · line 802 · raw
@+h:Map<&2, List<&2, String>> -> @rest:String -> @hascl:Bool -> Hold
def parse.res.te source · line 809 · raw
@+h:Map<&2, List<&2, String>> -> @rest:String -> @te:Bool -> Hold
def parse.res.body source · line 816 · raw
@+h:Map<&2, List<&2, String>> -> @rest:String -> Hold
def frame.cut source · line 826 · raw
@closed:Bool -> Frame
RFC 9112 §8: a message cut short by close is incomplete, not valid.
def frame.wait source · line 833 · raw
@res:Res -> @wait:Bool -> Frame
def frame.done source · line 840 · raw
@status:U32 -> @h:Map<&2, List<&2, String>> -> @body:Hold -> @+closed:Bool -> @open:Bool -> Frame
def frame.open source · line 852 · 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 856 · 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 860 · raw
@+status:U32 -> Bool
101 is the final response. Other 1xx are interim; a final response follows.
def frame.status source · line 863 · raw
@status:U32 -> @+h:Map<&2, List<&2, String>> -> @rest:String -> @closed:Bool -> @nobody:Bool -> Frame
def parse.res.fields source · line 870 · raw
@+status:U32 -> @rest:String -> @fs:Maybe<&2, Map<&2, List<&2, String>>> -> @closed:Bool -> @head:Bool -> Frame
def parse.res.num source · line 877 · raw
@code:Maybe<&2, U32> -> @headers:List<&2, String> -> @rest:String -> @closed:Bool -> @head:Bool -> Frame
def parse.res.ver source · line 884 · raw
@code:String -> @headers:List<&2, String> -> @rest:String -> @closed:Bool -> @head:Bool -> @ok:Bool -> Frame
def parse.res.start3 source · line 891 · raw
@mpv:Pair(String, Pair(String, String)) -> @headers:List<&2, String> -> @rest:String -> @closed:Bool -> @head:Bool -> Frame
def parse.res.lines source · line 895 · raw
@xs:List<&2, String> -> @rest:String -> @closed:Bool -> @head:Bool -> Frame
def parse.res.blank source · line 902 · raw
@hd:String -> @rest:String -> @+closed:Bool -> @head:Bool -> @ok:Bool -> Frame
def parse.res.of source · line 909 · raw
@hb:Pair(String, String) -> @closed:Bool -> @head:Bool -> Frame
def frame.lead.if source · line 918 · raw
@rest:String -> @interim:Bool -> Lead
def frame.lead.num source · line 925 · raw
@n:Maybe<&2, U32> -> @rest:String -> Lead
def frame.lead.code source · line 932 · raw
@mpv:Pair(String, Pair(String, String)) -> @rest:String -> Lead
def frame.lead.lines source · line 936 · raw
@xs:List<&2, String> -> @rest:String -> Lead
def frame.lead.blank source · line 943 · raw
@+hd:String -> @rest:String -> @ok:Bool -> Lead
def frame.lead source · line 950 · raw
@hb:Pair(String, String) -> Lead
def frame.at.zero.go source · line 954 · raw
@+raw:String -> @closed:Bool -> @head:Bool -> @lead:Lead -> Frame
def frame.at.zero source · line 963 · raw
@+raw:String -> @closed:Bool -> @head:Bool -> Frame
def frame.at.cont source · line 966 · raw
@+raw:String -> @lead:Lead -> String
def frame.at source · line 976 · 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 984 · raw
@raw:String -> @closed:Bool -> @head:Bool -> Frame
frame(bytes so far, server closed?, request was HEAD?)
def frame.res source · line 987 · raw
@f:Frame -> Maybe<&1, Res>
def parse_res source · line 996 · raw
@raw:String -> Maybe<&1, Res>
def res_fields.res source · line 999 · raw
@res:Res -> @k:String -> List<&2, String>
def res_fields source · line 1003 · raw
@m:Maybe<&1, Res> -> @k:String -> List<&2, String>
def rb.cl source · line 1019 · raw
@n:Maybe<&2, U32> -> Maybe<&2, Rb>
def rb.te source · line 1026 · raw
@+h:Map<&2, List<&2, String>> -> @cl:Bool -> Maybe<&2, Rb>
def rb.len source · line 1033 · raw
@+h:Map<&2, List<&2, String>> -> @te:Bool -> Maybe<&2, Rb>
def rb.of source · line 1041 · 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 1052 · raw
@parts:List<&1, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes> -> @+len:U32 -> @+left:U32 -> @r:Pair(0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes) -> Bf
def rb.len.have source · line 1056 · raw
@short:Bool -> @+left:U32 -> @parts:List<&1, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes> -> @+len:U32 -> @piece:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> Bf
def rb.chunk source · line 1063 · raw
@c:Ck -> Bf
def rb.feed source · line 1086 · raw
@rb:Rb -> @parts:List<&1, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes> -> @piece:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> Bf
The body bytes in piece, added to parts.
def rb.eof source · line 1101 · raw
@rb:Rb -> Bool
RFC 9112 §8: only a close-delimited body may end at close.
def rb.body source · line 1114 · raw
@parts:List<&1, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes> -> 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes
def hs.final source · line 1125 · raw
@+status:U32 -> @+h:Map<&2, List<&2, String>> -> @rest:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> @m:Maybe<&2, Rb> -> Hs
def hs.skip source · line 1132 · raw
@more:Bool -> @+k:U32 -> @rest:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> Hs
def hs.pick source · line 1139 · raw
@interim:Bool -> @+head:Bool -> @+k:U32 -> @+status:U32 -> @+h:Map<&2, List<&2, String>> -> @rest:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> Hs
def hs.res source · line 1146 · raw
@+head:Bool -> @+k:U32 -> @rest:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> @res:Res -> Hs
def hs.parsed source · line 1151 · raw
@+head:Bool -> @+k:U32 -> @rest:0xbf22530d1ea11c951d1ecaa353ed1580/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 1160 · raw
@+head:Bool -> @+k:U32 -> @+hlen:U32 -> @+len:U32 -> @r:Pair(0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes) -> Hs
def hs.hit source · line 1164 · raw
@+head:Bool -> @+k:U32 -> @+len:U32 -> @buf:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> @at:Maybe<&2, U32> -> Hs
def hs.seek.of source · line 1172 · raw
@+head:Bool -> @+k:U32 -> @+len:U32 -> @+from:U32 -> @buf:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> @r:Pair(0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes, Maybe<&2, U32>) -> Hs
def hs.seek source · line 1176 · raw
@+head:Bool -> @+k:U32 -> @+len:U32 -> @+from:U32 -> @r:Pair(0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes) -> Hs
def hs.step source · line 1180 · raw
@+head:Bool -> @st:Hs -> Hs
def hs.scan source · line 1193 · 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 1209 · raw
@+head:Bool -> @+k:U32 -> @buf:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> @piece:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> Hs
piece joins buf; only the new bytes, and the 3 before them, can finish the blank line.
def rv.start source · line 1224 · raw
Rv
def rv.done source · line 1227 · raw
@res:Res -> @parts:List<&1, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes> -> @rest:Maybe<&1, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes> -> Rt
def rv.fed source · line 1231 · raw
@res:Res -> @bf:Bf -> Rt
def rv.head source · line 1245 · raw
@hs:Hs -> Rt
def rv.eof source · line 1256 · raw
@res:Res -> @parts:List<&1, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes> -> @ok:Bool -> Rt
def rv.step source · line 1264 · raw
@closed:Bool -> @+head:Bool -> @rv:Rv -> @piece:0xbf22530d1ea11c951d1ecaa353ed1580/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 1279 · raw
@closed:Bool -> @+head:Bool -> @t:Rt -> Rt
def rv.go source · line 1292 · raw
@xs:List<&2, String> -> @closed:Bool -> @+head:Bool -> @t:Rt -> Rt
def rt.frame source · line 1305 · raw
@t:Rt -> Frame
def res.frame source · line 1315 · 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 1318 · raw
@t:Rt -> Maybe<&1, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes>
def after.of source · line 1327 · raw
@m:Maybe<&1, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes> -> Maybe<&2, String>
def after source · line 1335 · 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 1338 · raw
@mpv:Pair(String, Pair(String, String)) -> Bool
def req.v11.line source · line 1342 · raw
@+line:String -> Bool
def req.v11.lines source · line 1345 · raw
@xs:List<&2, String> -> Bool
def req.v11.pick source · line 1352 · raw
@+head:String -> @ok:Bool -> Bool
def req.v11.of source · line 1359 · raw
@hb:Pair(String, String) -> Bool
def req.v11 source · line 1363 · raw
@+raw:String -> Bool
def req.conn_close source · line 1366 · raw
@+headers:Map<&2, List<&2, String>> -> Bool
def res.conn_close source · line 1369 · raw
@+headers:Map<&2, List<&2, String>> -> Bool
def serve.fail_close source · line 1372 · raw
@+status:U32 -> Bool
def serve.keep.ok source · line 1375 · raw
@fail:Bool -> @res_close:Bool -> Bool
def serve.keep.v11 source · line 1382 · raw
@v11:Bool -> @+req_close:Bool -> @+status:U32 -> @res_close:Bool -> Bool
def serve.keep source · line 1393 · raw
@+headers:Map<&2, List<&2, String>> -> @v11:Bool -> @+status:U32 -> @+res:Map<&2, List<&2, String>> -> Bool
def again.keep source · line 1397 · raw
@close:Bool -> @x:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> Maybe<&1, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes>
def again.rest source · line 1404 · raw
@close:Bool -> @rest:Maybe<&1, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes> -> Maybe<&1, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes>
def again source · line 1413 · raw
@close:Bool -> @+h:Map<&2, List<&2, String>> -> @rest:Maybe<&1, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes> -> Maybe<&1, 0xbf22530d1ea11c951d1ecaa353ed1580/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 1420 · raw
@res:Res -> 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes
def res_body source · line 1424 · raw
@m:Maybe<&1, Res> -> 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes
def text source · line 1431 · raw
@res:Res -> String
def json source · line 1434 · raw
@res:Res -> Maybe<&2, 0xaaa10a97bf5ac6990143da2c863f8a3f/json.Val>
def got_body.req source · line 1437 · raw
@req:Req -> 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes
def got_body source · line 1441 · raw
@m:Maybe<&1, Req> -> 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes
def body.of source · line 1448 · raw
@hb:Pair(String, String) -> String
def body source · line 1452 · raw
@s:String -> String
def headers_lines source · line 1455 · raw
@+k:String -> @vs:List<&2, String> -> @acc:String -> String
def headers_block.go source · line 1462 · raw
@xs:List<&2, Sigma<&2, &2, String, _ => List<&2, String>>> -> @acc:String -> String
def headers_block source · line 1469 · raw
@h:Map<&2, List<&2, String>> -> String
def reasons source · line 1476 · raw
List<&2, Reason>
def reason.go source · line 1483 · raw
@xs:List<&2, Reason> -> @+status:U32 -> String
def reason source · line 1490 · raw
@+status:U32 -> String
def response source · line 1493 · raw
@+status:U32 -> @headers:Map<&2, List<&2, String>> -> @body:String -> String
def encode.body source · line 1496 · raw
@head:Bool -> @top:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> @body:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes
def encode.len source · line 1503 · raw
@+status:U32 -> @headers:Map<&2, List<&2, String>> -> @head:Bool -> @body:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes
def encode.pick source · line 1508 · raw
@+status:U32 -> @headers:Map<&2, List<&2, String>> -> @body:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> @head:Bool -> @nobody:Bool -> 0xbf22530d1ea11c951d1ecaa353ed1580/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 1515 · raw
@r:Res -> @head:Bool -> 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes
def encode source · line 1519 · raw
@r:Res -> 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes
def request source · line 1522 · raw
@method:String -> @path:String -> @headers:Map<&2, List<&2, String>> -> @body:String -> String
def req.reserved source · line 1525 · raw
@+k:String -> Bool
def req.put.one source · line 1528 · 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 1535 · 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 1544 · 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 1550 · 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 1557 · raw
@+method:String -> @target:String -> @host:String -> @headers:Map<&2, List<&2, String>> -> @body:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> @close:Bool -> 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes
def encode_req source · line 1562 · raw
@+method:String -> @target:String -> @host:String -> @headers:Map<&2, List<&2, String>> -> @body:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes
def redirect.code source · line 1572 · raw
@+s:U32 -> Bool
def redirect.origin source · line 1575 · raw
@a:0xd248560355ba8929ae030bc9c72f40be/url.Abs -> String
def redirect.del source · line 1579 · raw
@ks:List<&2, String> -> @m:Map<&2, List<&2, String>> -> Map<&2, List<&2, String>>
def redirect.hdrs source · line 1586 · raw
@+h:Map<&2, List<&2, String>> -> @drop:Bool -> @cross:Bool -> Map<&2, List<&2, String>>
def redirect.body source · line 1593 · raw
@drop:Bool -> @body:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> 0xbf22530d1ea11c951d1ecaa353ed1580/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 1600 · raw
@+status:U32 -> @+method:String -> @+from:0xd248560355ba8929ae030bc9c72f40be/url.Abs -> @headers:Map<&2, List<&2, String>> -> @body:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> @next:Maybe<&2, 0xd248560355ba8929ae030bc9c72f40be/url.Abs> -> Maybe<&1, Hop>
def redirect.hop source · line 1608 · raw
@status:U32 -> @h:Hop -> @loc:String -> Maybe<&1, Hop>
def redirect.if source · line 1612 · raw
@status:U32 -> @h:Hop -> @loc:String -> @ok:Bool -> Maybe<&1, Hop>
def redirect source · line 1620 · 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 1623 · 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 1630 · raw
@tls:Bool -> @s:Socket -> @data:String -> IO(Pair(Socket, Result<&1, &1, Pair(U32, String), Unit>))
def io.send.words source · line 1637 · 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 1644 · raw
@tls:Bool -> @s:Socket -> @b:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> IO(Pair(Socket, Result<&1, &1, Pair(U32, String), Unit>))
def io.close source · line 1648 · raw
@tls:Bool -> @s:Socket -> IO(Unit)
def fetch.close source · line 1655 · raw
@tls:Bool -> @s:Socket -> @r:Result<&1, &1, Err, Res> -> IO(Result<&1, &1, Err, Res>)
def fetch.max source · line 1661 · raw
Nat
Untrusted servers must not grow the buffer without bound.
def fetch.boxed source · line 1670 · raw
@r:Result<&1, &1, Err, Res> -> @none:Bool -> Out
def fetch.bad source · line 1677 · raw
@tls:Bool -> @s:Socket -> @e:Maybe<&2, Err> -> IO(Result<&1, &1, Err, Res>)
def fetch.shut source · line 1684 · raw
@tls:Bool -> @s:Socket -> @r:Result<&1, &1, Err, Res> -> @none:Bool -> IO(Out)
def fetch.hold.go source · line 1689 · raw
@tls:Bool -> @s:Socket -> @res:Res -> @left:Maybe<&1, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes> -> IO(Out)
def fetch.hold source · line 1696 · raw
@tls:Bool -> @close:Bool -> @s:Socket -> @res:Res -> @left:Maybe<&1, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes> -> IO(Out)
def fetch.failout source · line 1700 · raw
@tls:Bool -> @s:Socket -> @e:Maybe<&2, Err> -> @none:Bool -> IO(Out)
def fetch.rt source · line 1712 · raw
@+n:U32 -> @t:Rt -> Fl
def fetch.over source · line 1722 · raw
@+n:U32 -> Bool
64 KiB of head past the body cap, as serve allows.
def fetch.piece.cap source · line 1725 · raw
@over:Bool -> @+head:Bool -> @rv:Rv -> @+n2:U32 -> @+len:U32 -> @buf:Array<U32> -> Fl
def fetch.piece source · line 1732 · raw
@+head:Bool -> @rv:Rv -> @+n:U32 -> @p:Pair(U32, Array<U32>) -> Fl
def fetch.next source · line 1737 · 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 1759 · 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 1767 · raw
@+tls:Bool -> @+ms:U32 -> @+close:Bool -> @+head:Bool -> @s:Socket -> @wire:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> IO(Out)
def exchange.tup source · line 1772 · raw
@o:Out -> Pair(Maybe<&1, Socket>, Pair(Result<&1, &1, Err, Res>, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes))
def exchange source · line 1780 · raw
@+tls:Bool -> @+ms:U32 -> @+close:Bool -> @+head:Bool -> @s:Socket -> @wire:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> IO(Pair(Maybe<&1, Socket>, Pair(Result<&1, &1, Err, Res>, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes)))
One request on an open socket. Some{socket}: it can take another request.
def pool.new source · line 1792 · raw
Pool
def pool.key source · line 1795 · raw
@+scheme:String -> @+host:String -> @+port:U32 -> String
def pool.take.of source · line 1798 · raw
@r:Pair(Map<&1, Conn>, Maybe<&1, Conn>) -> Pair(Pool, Maybe<&1, Conn>)
def pool.take source · line 1802 · raw
@p:Pool -> @+key:String -> Pair(Pool, Maybe<&1, Conn>)
def conn.close source · line 1806 · raw
@c:Conn -> IO(Unit)
def conn.drop source · line 1810 · raw
@m:Maybe<&1, Conn> -> IO(Unit)
def pool.give.of source · line 1818 · raw
@+key:String -> @c:Conn -> @r:Pair(Map<&1, Conn>, Maybe<&1, Conn>) -> IO(Pool)
ponytail: one idle socket per origin; a second one replaces the first.
def pool.give source · line 1824 · raw
@p:Pool -> @+key:String -> @c:Conn -> IO(Pool)
def pool.close.go source · line 1828 · raw
@xs:List<&1, Conn> -> IO(Unit)
def pool.close source · line 1837 · raw
@p:Pool -> IO(Unit)
def pool.idempotent source · line 1842 · raw
@+method:String -> Bool
RFC 9110 §9.2.2
def conn.tls source · line 1845 · raw
@m:Pair(Socket, Result<&1, &1, Pair(U32, String), Unit>) -> IO(Result<&1, &1, Err, Conn>)
def conn.secure source · line 1856 · 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 1865 · 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 1872 · raw
@+tls:Bool -> @+ms:U32 -> @sni:String -> @ip:String -> @port:U32 -> IO(Result<&1, &1, Err, Conn>)
def conn.ex source · line 1877 · raw
@c:Conn -> @+ms:U32 -> @+head:Bool -> @wire:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> IO(Out)
def pool.keep.s source · line 1882 · 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 1893 · 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 1900 · raw
@p:Pool -> @+key:String -> @+tls:Bool -> @res:Res -> @sock:Maybe<&1, Socket> -> @rest:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> IO(Pair(Pool, Result<&1, &1, Err, Res>))
def pool.after source · line 1904 · raw
@p:Pool -> @+key:String -> @+tls:Bool -> @o:Out -> IO(Pair(Pool, Result<&1, &1, Err, Res>))
def pool.fresh.conn source · line 1911 · raw
@p:Pool -> @+key:String -> @+tls:Bool -> @+ms:U32 -> @+head:Bool -> @wire:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> @r:Result<&1, &1, Err, Conn> -> IO(Pair(Pool, Result<&1, &1, Err, Res>))
def pool.fresh.ip source · line 1920 · raw
@p:Pool -> @+key:String -> @+tls:Bool -> @+ms:U32 -> @+head:Bool -> @+host:String -> @+port:U32 -> @wire:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> @ip:Maybe<&2, String> -> IO(Pair(Pool, Result<&1, &1, Err, Res>))
def pool.fresh source · line 1929 · raw
@p:Pool -> @+key:String -> @+tls:Bool -> @+ms:U32 -> @+head:Bool -> @+host:String -> @+port:U32 -> @wire:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> IO(Pair(Pool, Result<&1, &1, Err, Res>))
def pool.retry source · line 1935 · raw
@+none:Bool -> @+idem:Bool -> Bool
A reused socket the server already closed fails before any response byte.
def pool.stale source · line 1938 · raw
@p:Pool -> @+key:String -> @+tls:Bool -> @+ms:U32 -> @+head:Bool -> @+host:String -> @+port:U32 -> @wire:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> @e:Err -> @again:Bool -> IO(Pair(Pool, Result<&1, &1, Err, Res>))
def pool.reused source · line 1945 · raw
@p:Pool -> @+key:String -> @+tls:Bool -> @+ms:U32 -> @+head:Bool -> @+idem:Bool -> @+host:String -> @+port:U32 -> @wire:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> @o:Out -> IO(Pair(Pool, Result<&1, &1, Err, Res>))
def pool.idle.reuse source · line 1953 · raw
@p:Pool -> @+key:String -> @+tls:Bool -> @+ms:U32 -> @+head:Bool -> @+idem:Bool -> @+host:String -> @+port:U32 -> @c:Conn -> @r:Pair(0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes, 0xbf22530d1ea11c951d1ecaa353ed1580/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 1959 · raw
@taken:Pair(Pool, Maybe<&1, Conn>) -> @+key:String -> @+tls:Bool -> @+ms:U32 -> @+head:Bool -> @+idem:Bool -> @+host:String -> @+port:U32 -> @wire:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> IO(Pair(Pool, Result<&1, &1, Err, Res>))
def pool.origin source · line 1967 · raw
@p:Pool -> @+method:String -> @+ms:U32 -> @headers:Map<&2, List<&2, String>> -> @body:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> @+hf:String -> @a:0xd248560355ba8929ae030bc9c72f40be/url.Abs -> @known:Bool -> IO(Pair(Pool, Result<&1, &1, Err, Res>))
def pool.scheme.ok source · line 1976 · raw
@a:0xd248560355ba8929ae030bc9c72f40be/url.Abs -> Bool
def pool.one.back source · line 1980 · 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 1984 · raw
@p:Pool -> @+method:String -> @+url:0xd248560355ba8929ae030bc9c72f40be/url.Abs -> @+headers:Map<&2, List<&2, String>> -> @+ms:U32 -> @r:Pair(0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes) -> IO(Pair(Pool, Pair(Result<&1, &1, Err, Res>, Hop)))
def pool.one source · line 1991 · 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 2006 · raw
@left:Nat -> @h:Hop -> Next
left: redirects still allowed after the request we just finished.
def fetch.decide.r source · line 2013 · raw
@left:Nat -> @r:Res -> @next:Maybe<&1, Hop> -> Next
def fetch.decide.res source · line 2020 · raw
@left:Nat -> @h:Hop -> @r:Res -> Next
def fetch.decide source · line 2024 · raw
@left:Nat -> @h:Hop -> @m:Result<&1, &1, Err, Res> -> Next
def fetch.error.res source · line 2031 · raw
@r:Res -> @bad:Bool -> Next
def fetch.error source · line 2038 · raw
@h:Hop -> @m:Result<&1, &1, Err, Res> -> Next
def fetch.policy source · line 2046 · raw
@mode:Mode -> @left:Nat -> @h:Hop -> @m:Result<&1, &1, Err, Res> -> Next
def accept.enc source · line 2056 · raw
@+h:Map<&2, List<&2, String>> -> Map<&2, List<&2, String>>
A caller's own Accept-Encoding wins.
def fetch.start source · line 2059 · raw
@method:String -> @headers:Map<&2, List<&2, String>> -> @body:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> @u:Maybe<&2, 0xd248560355ba8929ae030bc9c72f40be/url.Abs> -> Next
def pool.next source · line 2066 · raw
@+mode:Mode -> @left:Nat -> @x:Pair(Pool, Pair(Result<&1, &1, Err, Res>, Hop)) -> Pair(Pool, Next)
def ce.keep source · line 2085 · 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 2088 · raw
@xs:List<&2, String> -> List<&2, String>
def ce.split source · line 2095 · raw
@xs:List<&2, String> -> List<&2, String>
def ce.of source · line 2108 · raw
@m:Maybe<&2, String> -> Dec
def ce.deflate source · line 2116 · raw
@+b:String -> @m:Maybe<&2, String> -> Dec
Servers send deflate both with and without the zlib wrapper.
def ce.apply source · line 2123 · raw
@+c:String -> @+b:String -> Dec
def ce.go source · line 2128 · raw
@cs:List<&2, String> -> @d:Dec -> Dec
def decoded.pick source · line 2141 · raw
@d:Dec -> @+status:U32 -> @headers:Map<&2, List<&2, String>> -> @body:String -> Result<&1, &1, Err, Res>
def decoded.cs source · line 2151 · raw
@+status:U32 -> @+headers:Map<&2, List<&2, String>> -> @body:0xbf22530d1ea11c951d1ecaa353ed1580/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 2159 · raw
@empty:Bool -> @+status:U32 -> @+headers:Map<&2, List<&2, String>> -> @body:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> Result<&1, &1, Err, Res>
def decoded source · line 2167 · 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 2172 · raw
@r:Result<&1, &1, Err, Res> -> Maybe<&1, Res>
def decoded.some source · line 2179 · raw
@res:Res -> Maybe<&1, Res>
def fetch.final source · line 2183 · raw
@r:Result<&1, &1, Err, Res> -> Result<&1, &1, Err, Res>
The final response of a fetch, after redirects.
def pool.final source · line 2190 · raw
@pr:Pair(Pool, Result<&1, &1, Err, Res>) -> Pair(Pool, Result<&1, &1, Err, Res>)
def pool.how source · line 2197 · raw
@p:Pool -> @method:String -> @url:String -> @headers:Map<&2, List<&2, String>> -> @body:0xbf22530d1ea11c951d1ecaa353ed1580/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 2202 · raw
@p:Pool -> @method:String -> @url:String -> @headers:Map<&2, List<&2, String>> -> @body:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> @ms:U32 -> IO(Pair(Pool, Result<&1, &1, Err, Res>))
def pool.fetch source · line 2205 · raw
@p:Pool -> @method:String -> @url:String -> @headers:Map<&2, List<&2, String>> -> @body:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> IO(Pair(Pool, Result<&1, &1, Err, Res>))
def fetch.end source · line 2208 · raw
@pr:Pair(Pool, Result<&1, &1, Err, Res>) -> IO(Result<&1, &1, Err, Res>)
def fetch.how source · line 2215 · raw
@method:String -> @url:String -> @headers:Map<&2, List<&2, String>> -> @body:0xbf22530d1ea11c951d1ecaa353ed1580/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 2220 · raw
@method:String -> @url:String -> @headers:Map<&2, List<&2, String>> -> @body:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> @ms:U32 -> IO(Result<&1, &1, Err, Res>)
def fetch source · line 2224 · raw
@method:String -> @url:String -> @headers:Map<&2, List<&2, String>> -> @body:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> IO(Result<&1, &1, Err, Res>)
fetch.with and a 30 s step timeout.
def get source · line 2227 · raw
@url:String -> IO(Result<&1, &1, Err, Res>)
def pc.po source · line 2245 · raw
@more:Bool -> @empty:Bool -> @b:0xbf22530d1ea11c951d1ecaa353ed1580/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 2252 · raw
@more:Bool -> @+rb:Rb -> @b:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> Pc
def pc.fed.of source · line 2256 · raw
@b:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> @st:Rb -> Pc
def pc.fed source · line 2269 · raw
@bf:Bf -> Pc
def pc.of source · line 2274 · raw
@rb:Rb -> @piece:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> Pc
The body bytes that just arrived: what they add to the body, and how it ends.
def pc.end source · line 2278 · raw
@ok:Bool -> Pc
The server closed. Only a close-delimited body may end this way (RFC 9112 §8).
def pc.eof source · line 2285 · raw
@st:Rb -> Pc
def stream.mk source · line 2288 · raw
@+tls:Bool -> @s:Socket -> @+ms:U32 -> @res:Res -> @pc:Pc -> Stream
def stream.got.piece source · line 2292 · raw
@+tls:Bool -> @s:Socket -> @+ms:U32 -> @res:Res -> @+rb:Rb -> @p:Pair(U32, Array<U32>) -> Stream
def stream.got source · line 2296 · 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 2304 · raw
@+rb:Rb -> Po
def stream.res source · line 2334 · raw
@st:Stream -> Pair(Stream, Res)
Status and headers. Its body is empty: read the body with stream.read.
def stream.close source · line 2339 · raw
@st:Stream -> IO(Unit)
def sh.of source · line 2349 · raw
@hs:Hs -> Sh
def sh.piece source · line 2360 · raw
@+head:Bool -> @buf:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> @+k:U32 -> @p:Pair(U32, Array<U32>) -> Sh
def sh.next source · line 2364 · raw
@+head:Bool -> @buf:0xbf22530d1ea11c951d1ecaa353ed1580/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 2372 · raw
@r:Result<&1, &1, Err, Res> -> Result<&1, &1, Err, Stream>
def stream.sent source · line 2395 · 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 2405 · raw
@r:Result<&1, &1, Err, Conn> -> @+ms:U32 -> @+head:Bool -> @wire:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> IO(Result<&1, &1, Err, Stream>)
def stream.ip source · line 2415 · raw
@+tls:Bool -> @+ms:U32 -> @+head:Bool -> @+host:String -> @+port:U32 -> @wire:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> @ip:Maybe<&2, String> -> IO(Result<&1, &1, Err, Stream>)
def stream.origin source · line 2425 · raw
@+ms:U32 -> @+head:Bool -> @wire:0xbf22530d1ea11c951d1ecaa353ed1580/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 2435 · raw
@+method:String -> @+url:0xd248560355ba8929ae030bc9c72f40be/url.Abs -> @+headers:Map<&2, List<&2, String>> -> @+ms:U32 -> @r:Pair(0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes) -> IO(Pair(Hop, Result<&1, &1, Err, Stream>))
def stream.one source · line 2443 · 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 2453 · raw
@n:Next -> Sn
def stream.decide.n source · line 2466 · raw
@st:Stream -> @n:Next -> Sn
def stream.decide.of source · line 2475 · raw
@+left:Nat -> @hop:Hop -> @sr:Pair(Stream, Res) -> Sn
def stream.decide source · line 2479 · raw
@+left:Nat -> @x:Pair(Hop, Result<&1, &1, Err, Stream>) -> Sn
def stream.start source · line 2501 · raw
@method:String -> @headers:Map<&2, List<&2, String>> -> @body:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> @u:Maybe<&2, 0xd248560355ba8929ae030bc9c72f40be/url.Abs> -> Sn
def open.with source · line 2510 · raw
@method:String -> @url:String -> @headers:Map<&2, List<&2, String>> -> @body:0xbf22530d1ea11c951d1ecaa353ed1580/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 2513 · raw
@method:String -> @url:String -> @headers:Map<&2, List<&2, String>> -> @body:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> IO(Result<&1, &1, Err, Stream>)
def hex.digit source · line 2520 · raw
@+n:U32 -> Char
def hex.go source · line 2523 · raw
@k:Nat -> @+n:U32 -> @acc:String -> String
def hex.trim source · line 2530 · raw
@+s:String -> String
def hex source · line 2537 · raw
@+n:U32 -> String
def up.sent source · line 2540 · raw
@+tls:Bool -> @+ms:U32 -> @+head:Bool -> @m:Pair(Socket, Result<&1, &1, Pair(U32, String), Unit>) -> Up
def up.conn source · line 2548 · raw
@r:Result<&1, &1, Err, Conn> -> @+ms:U32 -> @+head:Bool -> @wire:String -> IO(Result<&1, &1, Err, Up>)
def up.ip source · line 2558 · 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 2567 · raw
@+method:String -> @+target:String -> @+hf:String -> @+headers:Map<&2, List<&2, String>> -> String
def up.origin source · line 2570 · 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 2580 · 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 2588 · 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 2591 · raw
@+method:String -> @url:String -> @headers:Map<&2, List<&2, String>> -> IO(Result<&1, &1, Err, Up>)
def up.wrote source · line 2594 · 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 2604 · raw
@+tls:Bool -> @s:Socket -> @+ms:U32 -> @+head:Bool -> @+len:U32 -> @piece:0xbf22530d1ea11c951d1ecaa353ed1580/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 2613 · raw
@+tls:Bool -> @s:Socket -> @+ms:U32 -> @+head:Bool -> @piece:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> IO(Pair(Up, Result<&2, &2, Err, Unit>))
def upload.write source · line 2618 · raw
@up:Up -> @piece:0xbf22530d1ea11c951d1ecaa353ed1580/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 2627 · raw
@up:Up -> IO(Result<&1, &1, Err, Stream>)
Ends the body and returns the response as a stream.
def reply.bytes source · line 2639 · raw
@res:Res -> @head:Bool -> @close:Bool -> 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes
def reply.fail.bytes source · line 2643 · raw
@+status:U32 -> Res
def reply.sent.close source · line 2646 · raw
@m:Pair(Socket, Result<&1, &1, Pair(U32, String), Unit>) -> IO(Unit)
def reply_fail source · line 2650 · raw
@s:Socket -> @+status:U32 -> IO(Unit)
def serve.max source · line 2669 · raw
Nat
def sv.none source · line 2672 · raw
Sv
def sv.body source · line 2675 · raw
@req:Req -> @+v11:Bool -> @parts:List<&1, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes> -> @rest:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> Turn
def sv.len.cut source · line 2679 · raw
@req:Req -> @+v11:Bool -> @parts:List<&1, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes> -> @+len:U32 -> @+left:U32 -> @r:Pair(0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes) -> Turn
def sv.len.have source · line 2683 · raw
@short:Bool -> @req:Req -> @+v11:Bool -> @+left:U32 -> @parts:List<&1, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes> -> @+len:U32 -> @piece:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> Turn
def sv.len source · line 2690 · raw
@req:Req -> @+v11:Bool -> @+left:U32 -> @parts:List<&1, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes> -> @piece:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> Turn
def sv.chunk.of source · line 2694 · raw
@req:Req -> @+v11:Bool -> @+n:U32 -> @c:Ck -> Turn
def sv.chunk.cap source · line 2716 · raw
@big:Bool -> @req:Req -> @+v11:Bool -> @+n:U32 -> @st:Dc -> @parts:List<&1, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes> -> @piece:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> Turn
def sv.chunk source · line 2723 · raw
@+max:Nat -> @req:Req -> @+v11:Bool -> @+n:U32 -> @st:Dc -> @parts:List<&1, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes> -> @piece:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> Turn
def sv.cont source · line 2729 · 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 2740 · raw
@big:Bool -> @req:Req -> @+v11:Bool -> @+k:U32 -> @rest:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> Turn
def sv.cl source · line 2747 · raw
@+max:Nat -> @req:Req -> @+v11:Bool -> @rest:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> @n:Maybe<&2, U32> -> Turn
def sv.frame source · line 2754 · raw
@+max:Nat -> @req:Req -> @+v11:Bool -> @rest:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> @te:Bool -> Turn
def sv.expects source · line 2762 · raw
@+v11:Bool -> @+headers:Map<&2, List<&2, String>> -> Bool
def sv.got.head source · line 2765 · raw
@+max:Nat -> @+v11:Bool -> @rest:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> @req:Req -> Turn
def sv.parsed source · line 2769 · raw
@+max:Nat -> @+v11:Bool -> @rest:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> @g:Got -> Turn
def sv.split source · line 2780 · raw
@+max:Nat -> @+hlen:U32 -> @+len:U32 -> @r:Pair(0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes) -> Turn
def sv.hit.none source · line 2785 · raw
@big:Bool -> @buf:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> Turn
def sv.hit.some source · line 2792 · raw
@big:Bool -> @+max:Nat -> @+hlen:U32 -> @+len:U32 -> @buf:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> Turn
def sv.hit source · line 2800 · raw
@+max:Nat -> @+len:U32 -> @buf:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> @at:Maybe<&2, U32> -> Turn
RFC 6585 §5: a head over 64 KiB is refused.
def sv.seek.of source · line 2808 · raw
@+max:Nat -> @+len:U32 -> @+from:U32 -> @buf:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> @r:Pair(0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes, Maybe<&2, U32>) -> Turn
def sv.seek source · line 2812 · raw
@+max:Nat -> @+len:U32 -> @+from:U32 -> @r:Pair(0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes) -> Turn
def sv.head.at source · line 2817 · raw
@+max:Nat -> @+from:U32 -> @buf:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> Turn
Only the new bytes, and the 3 before them, can finish the blank line.
def sv.head source · line 2821 · raw
@+max:Nat -> @buf:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> @piece:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> Turn
def sv.closed.pick source · line 2825 · raw
@empty:Bool -> Turn
def sv.closed.head source · line 2832 · raw
@buf:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> Turn
def sv.step source · line 2837 · raw
@closed:Bool -> @+max:Nat -> @sv:Sv -> @piece:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> Turn
A close mid-request is a request cut short (RFC 9112 §8).
def sv.frame.req source · line 2856 · raw
@t:Turn -> Maybe<&1, Pair(String, String)>
def sv.frame.go source · line 2868 · raw
@xs:List<&2, String> -> @t:Turn -> Maybe<&1, Pair(String, String)>
def serve.frame source · line 2884 · 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 2887 · raw
@+max:Nat -> @sv:Sv -> @p:Pair(U32, Array<U32>) -> Turn
def talk.next source · line 2891 · 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 2899 · raw
@empty:Bool -> @+max:Nat -> @rest:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> Turn
def talk.after.rest source · line 2906 · raw
@+max:Nat -> @rest:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> @s:Socket -> Pair(Socket, Turn)
def talk.after.keep source · line 2910 · raw
@keep:Bool -> @+max:Nat -> @rest:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> @s:Socket -> Pair(Socket, Turn)
def talk.after source · line 2917 · raw
@+max:Nat -> @keep:Bool -> @rest:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> @m:Pair(Socket, Result<&1, &1, Pair(U32, String), Unit>) -> Pair(Socket, Turn)
def talk.send source · line 2925 · raw
@+max:Nat -> @s:Socket -> @rest:0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes -> @+headers:Map<&2, List<&2, String>> -> @v11:Bool -> @+head:Bool -> @res:Res -> IO(Pair(Socket, Turn))
def talk.cont.sent source · line 2932 · raw
@m:Pair(Socket, Result<&1, &1, Pair(U32, String), Unit>) -> Socket
def talk.cont source · line 2936 · raw
@cont:Bool -> @s:Socket -> IO(Socket)
Templates
template conn source · line 2965 · raw
@-h:(@_:Req -> IO(Res)) -> @+max:Nat -> @m:Pair(Listener, Result<&1, &1, Pair(U32, String), Socket>) -> IO(Listener)
template serve.with source · line 2979 · raw
@-h:(@_:Req -> IO(Res)) -> @+port:U32 -> @+max:Nat -> IO(Unit)
template serve source · line 2985 · raw
@-h:(@_:Req -> IO(Res)) -> @+port:U32 -> IO(Unit)
Unsafe
unsafe fetch.loop source · line 1747 · 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 2072 · 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 2319 · raw
@st:Stream -> IO(Pair(Stream, Result<&1, &1, Err, Maybe<&1, 0xbf22530d1ea11c951d1ecaa353ed1580/bytes.Bytes>>))
The next piece of the body; None at the end. A piece is never empty.
unsafe stream.head source · line 2381 · 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 2488 · raw
@+ms:U32 -> @sn:Sn -> IO(Result<&1, &1, Err, Stream>)
unsafe talk source · line 2946 · raw
@-h:(@_:Req -> IO(Res)) -> @+max:Nat -> @st:Pair(Socket, Turn) -> IO(Unit)
unsafe loop source · line 2973 · raw
@-h:(@_:Req -> IO(Res)) -> @+max:Nat -> @l:Listener -> IO(Unit)