Send requests using the shared
roc-lang/httpRequest and Response
types. This module supplies effects and small JSON/UTF-8 conveniences while
leaving pure request and response construction to that package.
[Http.send!] and the functions built on it hold the whole response body in
memory. [Http.send_streaming!] returns as soon as the status and headers
have arrived and hands the body over as a Stream of chunks, for a
download larger than memory or one whose progress is shown.
See the host runtime behavior
for HTTP protocol, TLS trust-store, and timeout details.
The request URI must be an absolute HTTP or HTTPS URL accepted by Url.
Invalid URLs return InvalidUrl before any host effect occurs. Fragments
are removed because they are client-side identifiers and are not sent.
Validate and send an HTTP request, returning once the status and
headers have arrived. The body is read afterwards, through the
StreamingResponse.
The request is validated, built and sent exactly as [Http.send!] does
it. Any status is Ok, so check it before reading the body. Either
timeout expiring is Err(HttpErr(Timeout)).
Options for [Http.send_streaming!]. {} selects the defaults.
idle_timeout bounds each single wait: for the status and headers, and
then for each part of the body. A server that is silent for that long
has stalled, however much it has already sent. It defaults to 30
seconds; After(Duration.zero) expires at once, before anything is
sent, and NoTimeout waits for as long as the server takes.
The timeout of the Request keeps its meaning: it is the deadline for
the whole exchange, body included, and NoTimeout (its default) and
TimeoutMilliseconds(0) both mean no deadline. For a large download
leave the request at NoTimeout and rely on idle_timeout.
The status and headers of a response, and its body still to be read.
The body arrives over the response's own connection as it is read.
StreamingResponse.chunks and [read_to_end!] read from one shared
cursor, as do copies of the response, so each byte of the body is
returned once.
The connection is closed when the body ends, when a failure other than
an idle timeout ends it, or when the last reference to the response and
its streams is released; a body that is not wanted need not be read.
The length of the whole body in bytes, from the Content-Length
header. Unknown when the server did not send one, as with a
chunked body. For the response to a HEAD request this is the
length the header declares, although no body follows.
Lazily read the body as non-empty chunks of at most 64 KiB. Chunk
boundaries are chosen by the host and carry no meaning.
Building the stream reads nothing; each item is one read from the
shared cursor. The stream ends at the end of the body, and a
failure is the last item.
After an idle timeout, Err(HttpErr(Timeout)) with the response's
deadline not yet reached, the response stays usable and a new
chunks() continues where the last one stopped. Any other failure
is final: a new stream yields it again.
Read the rest of the body: everything StreamingResponse.chunks
and earlier reads have not returned. At the end of the body that is
Ok([]).
With MaxBytes(max) this fails with ReadLimitExceeded(max) as
soon as more than max unread bytes have arrived, without waiting
for the rest. NoLimit holds the whole remainder in memory.
A failed call consumes nothing it could keep: after
ReadLimitExceeded or an idle timeout the bytes that had arrived
are still unread, so StreamingResponse.chunks or another call
continues from the same place.
body = response.read_to_end!(MaxBytes(1_048_576))?