The header keys are lowercase, which is what makes a Dictionary the right shape for them. HTTP header names do not differ by case, and header(named:) reads one under any spelling.
A name a host sent twice is one entry, with its values joined by , . That is what a host does to every other header name, and set-cookie is joined the same way here. Two cookies joined like that can not be read apart again, because a cookie's Expires holds a comma.
The body is text, decoded as UTF-8. Bytes that are not text are read as replacement characters, so an answer that is not text is a Response with a lossy body.
Answers work that asks the address for the headers alone.
The answer carries the headers a get would answer with, and an empty body.
NameTypeDescription
_Stringthe address to ask
headersDictionary<String, String> = [=]the headers to send; none when it is left out
Returns work answering the Response, or the reason there is none.
Reading the answer
isSuccessful
on Response
isSuccessful() -> Boolean
Answers whether the status is one of the successful ones.
The successful statuses are 200 through 299. A redirect, a refusal and a host error are each a Response that answers false here.
Returnstrue when the status is between 200 and 299.
Example
constant answered: Response = { status = 204, headers = [=], body = "",}expect answered::isSuccessful()
header
on Response
header(named name: String) -> Optional<String>
Answers the header of the given name, whatever case the name is written in.
The keys of a Response a host answered with are lowercase, so the name is lowercased before it is looked up. A header the answer does not carry answers nothing.
A Response a Program wrote down itself is found only where it wrote the key in lowercase. The lookup key is always the lowercased name, and a key written Content-Type is reached by no spelling at all.
NameTypeDescription
namedStringthe name of the header, in any case
Returns the header's value, or nothing where the answer carries none.
Example
constant answered: Response = { status = 200, headers = ["content-type" = "text/plain"], body = "hi",}expect answered::header(named "Content-Type")::is("text/plain")expect answered::header(named "accept")::isEmpty()
Reading a failure
toString
on HttpFailure
toString() -> String
Answers the failure as a String, written InvalidUrl(…), Unreachable(…) or InvalidBody(…).
The reason is quoted, as a String payload is quoted inside any structure. The # sigil is left out, as Result prints Failure and Ordering prints Less.
What a request does with a redirect a host answers with.
Under #Follow the request is made again at the new address, which is what a request that names no Case does. Under #Manual the redirect is the answer where the host hands it over. On Node and Bun it carries the status and the location header that says where it points. A browser answers an opaque redirect instead, with no status and no headers. Under #Refuse a redirect is a #Failure, and its reason is #Unreachable.
The Case #InvalidUrl is an address this library does not send to. It covers an address that can not be read at all, and one whose scheme is neither http nor https.
The Case #Unreachable is a host that was not reached. It covers a refused connection, a name that does not resolve and a certificate that was not accepted. It also covers a host with no way to send a request. A redirect a request refused to follow is one. So is a request this library refused to send. A #Get or a #Head carrying a body is one, and so is a header name HTTP does not allow.
The Case #InvalidBody is an answer whose body could not be read. The answer had been delivered, and reading its bytes failed part way.
A status is none of these. A host that answers 404 answered, and 404 is a Response.