#Http
Status: standard library specification draft.
This chapter defines std.http, which lib/std writes in ordinary hd
over the language tier:
- the capability trait
Http, and the free helpersget!andpost!; - the struct values
RequestandResponse, and the enumsMethodandHttpError; - status checking, retained error responses, and the JSON calls;
- which request URLs are valid;
ScriptedHttp, the deterministic provider ofHttp;- what the playground binds for
Http, and how ablock_oncall waits there.
Which provider a command binds, and which hosts its grant covers, is CLI tier (Host Capabilities).
#Read-Once Bodies
A Body is a value whose copies share private consumption state.
- std-http.body.declaration
std.httpdeclaresBodywith private shared state. - std-http.body.from-bytes
Body::from_bytes(bytes: List[u8]) -> Bodycreates a fresh unread body holding those bytes. - std-http.body.shared-stateCopying a
Bodyshares its bytes and read state with the original. - std-http.body.bytes
bytes(&self) -> Result[List[u8], BodyError]claims the body and returns its bytes. - std-http.body.usedAny later read through any copy returns
BodyError.Used. - std-http.body.claim-before-decodeEvery reader claims the body before decoding; a decoding failure leaves it used.
- std-http.body.empty-claimReading an empty body also claims it.
- std-http.body.text
text(&self) -> Result[string, BodyError]reads UTF-8, replacing malformed sequences with U+FFFD. - std-http.body.json
json[T < Deserialize](&self) -> Result[T, BodyError]decodes the body's text throughstd.json. - std-http.body.json-errorA JSON decoding failure returns
BodyError.Jsoncontaining the decoder's error. - std-http.body.form
form[T < Deserialize](&self) -> Result[T, BodyError]decodes a URL-encoded form using Typed Query And Form Values. - std-http.body.form-errorA form decoding failure returns
BodyError.Formcontaining itsFormError. - std-http.body.value-equality
BodyimplementsEqby comparing payload and read state, independently of allocation identity. - std-http.body.debug-private
BodyimplementsDebug, showing its length and read state without its bytes.
#Typed Query And Form Values
Query pairs and URL-encoded bodies share one serde codec.
- std-http.form-codec.query-reader
Url.query_as[T < Deserialize](&self) -> Result[T, FormError]decodes its query pairs intoT. - std-http.form-codec.parameter-recordThe root value is a struct whose fields are parameters named by their serde wire names.
- std-http.form-codec.scalarScalar values use the existing serde textual conversions.
- std-http.form-codec.deep-objectA struct-valued parameter uses one bracket level,
parameter[property], whose properties are scalars or optional scalars. - std-http.form-codec.repeated-scalarsA list or tuple of supported scalars uses repeated occurrences of its parameter name, in occurrence order.
- std-http.form-codec.tuple-countA tuple with the wrong number of values returns
Invalid(field, text). - std-http.form-codec.duplicate-scalarRepeated scalar parameters return
Invalid(field, text)with the first occurrence's text, even when the texts are equal. - std-http.form-codec.missing-listAn absent list parameter decodes to an empty list.
- std-http.form-codec.optionalAn absent optional value decodes to
None; an explicit empty string remains present. - std-http.form-codec.defaultsAn absent field with a declared serde default takes that default.
- std-http.form-codec.unknownUnknown keys are ignored after percent-encoding and UTF-8 validation.
- std-http.form-codec.missing-scalarA missing required scalar returns
Missing(field)with its declared wire path. - std-http.form-codec.invalid-scalarA failed scalar conversion returns
Invalid(field, text)with its declared wire path and original text. - std-http.form-codec.unit-enumA selected unit enum variant is a scalar whose text is its variant name.
- std-http.form-codec.payload-enumA visited enum variant with payload fields returns
Unsupported(field). - std-http.form-codec.unsupported-containersA visited dynamic map, deeper record or nested list returns
Unsupported(field). - std-http.form-codec.unsupported-visitsUnsupported values are rejected when visited, without schema preflight.
- std-http.form-codec.empty-unvisitedEmpty record lists and absent optional records encode and decode as empty or absent without error.
- std-http.form-codec.bracketed-renameA member wire name containing
[or]returnsUnsupported(field). - std-http.form-codec.body-pairsForm decoding splits nonempty parts at
&and each part's first=, retaining their order. - std-http.form-codec.body-empty-valueA form part without
=has an empty value. - std-http.form-codec.body-decodeForm names and values percent-decode UTF-8 and interpret
+as space. - std-http.form-codec.strict-inputInvalid percent-encoding or invalid UTF-8 returns
FormError, including in unknown pairs. - std-http.form-codec.query-writer
Url.set_query_as[T < Serialize](&mut self, value: T) -> voidreplaces the query using the same serde codec. - std-http.form-codec.query-write-orderWriting retains member declaration order and list or tuple item order as decoded query pairs.
- std-http.form-codec.query-write-absenceWriting an absent optional value emits no pair.
- std-http.form-codec.query-write-emptyEvery query write clears the explicit empty-query presence bit.
- std-http.form-codec.query-write-errorA failed query write retains a private
FormError, which laterquery_asreturns directly. - std-http.form-codec.query-replacementA successful
set_query_asreplaces the query and clears its pending preparation error. - std-http.form-codec.query-append-error
add_paramdoes not clear a pending query preparation error. - std-http.form-codec.query-resolve-inheritResolution retains a pending query error exactly when RFC 3986 inherits the base query, including empty and fragment-only references.
- std-http.form-codec.query-resolve-replaceA reference replacing the query clears its pending error, including an explicit query, new path, authority or scheme.
#Named Status Codes
- std-http.status.declaration
std.httpdeclaresHttpStatuswith the variants and numeric codes below, andOther(code: u16).
| Variant | Code |
|---|---|
Ok |
200 |
Created |
201 |
Accepted |
202 |
NoContent |
204 |
PartialContent |
206 |
MovedPermanently |
301 |
Found |
302 |
SeeOther |
303 |
NotModified |
304 |
TemporaryRedirect |
307 |
PermanentRedirect |
308 |
BadRequest |
400 |
Unauthorized |
401 |
Forbidden |
403 |
NotFound |
404 |
MethodNotAllowed |
405 |
RequestTimeout |
408 |
Conflict |
409 |
Gone |
410 |
PreconditionFailed |
412 |
ContentTooLarge |
413 |
UnsupportedMediaType |
415 |
UnprocessableContent |
422 |
TooManyRequests |
429 |
InternalServerError |
500 |
NotImplemented |
501 |
BadGateway |
502 |
ServiceUnavailable |
503 |
GatewayTimeout |
504 |
- std-http.status.code
HttpStatus.code(&self) -> u16returns the variant's numeric code. - std-http.status.from-code
HttpStatus::from_code(code: u16) -> HttpStatusreturns the named variant for a listed code, andOther(code)otherwise. - std-http.status.is-success
HttpStatus.is_success(&self) -> boolis true exactly for codes from 200 through 299. - std-http.status.numeric-equalityTwo
HttpStatusvalues are equal exactly when their numeric codes are equal, including named variants andOther. - std-http.status.numeric-hash
HttpStatusimplementsHashby hashing itsu16code. - std-http.status.debug
HttpStatusimplements structuralDebug.
#Header Names
- std-http.header-name.declaration
std.httpdeclaresHeaderNamewith the variants and wire names below, andOther(name: string).
| Variant | Wire name |
|---|---|
Accept |
accept |
AcceptEncoding |
accept-encoding |
AcceptLanguage |
accept-language |
ContentDisposition |
content-disposition |
ContentEncoding |
content-encoding |
ContentLength |
content-length |
ContentRange |
content-range |
ContentType |
content-type |
Range |
range |
CacheControl |
cache-control |
ETag |
etag |
Expires |
expires |
IfMatch |
if-match |
IfModifiedSince |
if-modified-since |
IfNoneMatch |
if-none-match |
LastModified |
last-modified |
Vary |
vary |
Authorization |
authorization |
Cookie |
cookie |
RetryAfter |
retry-after |
SetCookie |
set-cookie |
WwwAuthenticate |
www-authenticate |
AccessControlAllowCredentials |
access-control-allow-credentials |
AccessControlAllowHeaders |
access-control-allow-headers |
AccessControlAllowMethods |
access-control-allow-methods |
AccessControlAllowOrigin |
access-control-allow-origin |
AccessControlMaxAge |
access-control-max-age |
AccessControlRequestHeaders |
access-control-request-headers |
AccessControlRequestMethod |
access-control-request-method |
Origin |
origin |
ContentSecurityPolicy |
content-security-policy |
StrictTransportSecurity |
strict-transport-security |
XContentTypeOptions |
x-content-type-options |
XFrameOptions |
x-frame-options |
Allow |
allow |
Forwarded |
forwarded |
Host |
host |
Location |
location |
Referer |
referer |
XForwardedFor |
x-forwarded-for |
XForwardedHost |
x-forwarded-host |
XForwardedProto |
x-forwarded-proto |
Date |
date |
Server |
server |
UserAgent |
user-agent |
XRequestId |
x-request-id |
- std-http.header-name.wire
HeaderName.wire_name(&self) -> stringreturns the listed wire name, or theOthername with ASCII uppercase letters lowercased. - std-http.header-name.parse
HeaderNameimplementsParse[Error = HeaderError]. - std-http.header-name.parse-knownParsing a listed wire name, ignoring ASCII case, returns its named variant.
- std-http.header-name.parse-otherParsing another valid field name returns
Otherwith its ASCII letters lowercased. - std-http.header-name.parse-tokenA valid field name is a nonempty sequence of ASCII letters, digits, or a punctuation character from
!#$%&'*+-.^_`|~, as RFC 9110 §5.6.2 defines. - std-http.header-name.parse-invalidParsing any other text returns
HeaderError.InvalidNameholding the original text. - std-http.header-name.wire-equalityTwo
HeaderNamevalues are equal exactly when their wire names are equal. - std-http.header-name.wire-hash
HeaderNameimplementsHashby hashing its wire name as a string. - std-http.header-name.debug
HeaderNameimplements structuralDebug. - std-http.header-error.declaration
HeaderErroris an error enum withInvalidName(name: string)andInvalidValue(name: string). - std-http.header-error.displayThose variants display
invalid header name NAMEandinvalid value for header NAME, respectively. - std-http.header-error.traits
HeaderErrorimplementsEqandDebug.
#Header Collections
- std-http.header-collection.declaration
Headersis an ordered collection of(HeaderName, string)pairs with private storage. - std-http.header-collection.new
Headers::new() -> Headersreturns an empty collection. - std-http.header-collection.from-pairs
From[List[(string, string)]]retains every pair in input order, parsing valid names asHeaderNameand retaining invalid names asOtherfor wire validation. - std-http.header-collection.from-map
From[Map[string, string]]converts each map entry to one header pair. - std-http.header-collection.get
get(&self, name: HeaderName) -> string?returns matching values joined by", "in their stored order, orNonewhen absent, except forSetCookie. - std-http.header-collection.set-cookie-first
get(SetCookie)returns the first rawSet-Cookievalue without joining lines;response_cookies()reads every line. - std-http.header-collection.set
set(&mut self, name: HeaderName, value: string) -> voidreplaces every matching pair with one pair holdingvalue. - std-http.header-collection.remove
remove(&mut self, name: HeaderName) -> voidremoves every matching pair. - std-http.header-collection.entries
entries(&self) -> List[(HeaderName, string)]returns all stored pairs in order. - std-http.header-collection.traits
Headersimplements structuralEqandDebug. - std-http.request-cookies.read
request_cookies(&self) -> List[(string, string)]returns name/value pairs fromCookiefields in received order, retaining duplicate names. - std-http.request-cookies.first
request_cookie(&self, name: string) -> string?returns the first value for that case-sensitive cookie name, orNonewhen absent. - std-http.request-cookies.set
set_request_cookie(&mut self, name: string, value: string) -> voidreplaces that name's cookies while retaining other cookies in oneCookieheader.
#Response Cookies
- std-http.cookie.same-site
SameSitehas the variantsStrict,LaxandNone, and implementsEqandDebug. - std-http.cookie.declaration
Cookiehas public fieldsname: string,value: string,path: string?,domain: string?,max_age: Duration?,expires: Timestamp?,secure: bool,http_only: boolandsame_site: SameSite. - std-http.cookie.defaultsA constructed cookie defaults to
path = Some("/"), absent domain, max-age and expires,secure = true,http_only = trueandsame_site = Lax. - std-http.cookie.traits
Cookieimplements structuralEqandDebug. - std-http.cookie.expired
Cookie::expired(name: string) -> Cookiereturns that name with an empty value,max_age = Some(Duration::seconds(0))and the other outgoing defaults. - std-http.response-cookies.read
Headers.response_cookies(&self) -> List[Cookie]parses every separateSet-Cookieline in stored order. - std-http.response-cookies.incoming-defaultsAbsent Path, Domain, Max-Age and Expires parse as
None, absent Secure and HttpOnly asfalse, and absent or unknown SameSite asLax. - std-http.response-cookies.crlfA
Set-Cookieline containing CR or LF contributes no parsed cookie. - std-http.response-cookies.unknown-attributesParsing ignores unrecognized cookie attributes.
- std-http.response-cookies.attributesRecognized cookie attributes are parsed according to RFC 6265 §5.2, ignoring ASCII case in attribute names.
- std-http.response-cookies.expiresExpires uses the cookie-date algorithm in RFC 6265 §5.1.1, with invalid dates ignored.
- std-http.response-cookies.same-siteSameSite parses
Strict,LaxandNoneignoring ASCII case. - std-http.response-cookies.contextual-pathAn empty or non-slash Path parses as
None, clearing any earlier Path; CookieJar later applies the request's default path.
#Writing Response Cookies
- std-http.response-cookies.set
Headers.set_response_cookie(&mut self, cookie: Cookie) -> voidwrites oneSet-Cookieline, replacing earlier cookies with that case-sensitive name. - std-http.response-cookies.set-unrelatedSetting a response cookie retains unrelated headers and cookies in their order.
- std-http.response-cookies.wire-pairA written cookie begins with its name and value joined by
=, without encoding them. - std-http.response-cookies.wire-optionalPresent Path, Domain, Max-Age and Expires fields become corresponding attributes; absent ones are omitted.
- std-http.response-cookies.max-age-ceilingMax-Age is the duration's whole seconds rounded up; a positive fraction yields at least
1, and only zero yields0. - std-http.response-cookies.expires-textExpires uses an RFC 6265 HTTP date in UTC, with English weekday and month names and whole-second precision.
- std-http.response-cookies.wire-flagsSecure and HttpOnly attributes are included exactly when their corresponding flags are true.
- std-http.response-cookies.wire-same-siteEvery written cookie includes SameSite with its
Strict,LaxorNonespelling. - std-http.request-cookies.set-componentsRequest cookie setters retain the supplied name and value without interpreting delimiters inside either component.
#Message Conversion Errors
- std-http.body-error.declaration
BodyErroris an error enum withUsed,Json(error: JsonError)andForm(error: FormError). - std-http.body-error.display-used
BodyError.Useddisplaysthe body was already read. - std-http.body-error.display-json
BodyError.Json(error)displaysinvalid JSON body: ERROR, with the JSON error's Display text. - std-http.body-error.display-form
BodyError.Form(error)displaysinvalid form body: ERROR, with the form error's Display text. - std-http.body-error.traits
BodyErrorimplements structuralEqandDebug. - std-http.form-error.declaration
FormErroris an error enum withUnsupported(field: string),Missing(field: string)andInvalid(field: string, text: string). - std-http.form-error.display-unsupported
FormError.Unsupported(field)displaysfield FIELD has no form encoding. - std-http.form-error.display-missing
FormError.Missing(field)displaysmissing field FIELD. - std-http.form-error.display-invalid
FormError.Invalid(field, text)displaysfield FIELD: cannot read TEXT. - std-http.form-error.traits
FormErrorimplements structuralEqandDebug. - std-http.url-error.declaration
UrlErroris an error enum withInvalid(text: string)andRelativeWithoutBase(text: string). - std-http.url-error.display-invalid-text
UrlError.Invalid(text)normally displaysinvalid URL: TEXT. - std-http.url-error.display-relative
UrlError.RelativeWithoutBase(text)displaysrelative URL without a base: TEXT. - std-http.url-error.traits
UrlErrorimplements structuralEqandDebug. - std-http.url-error.into-http
From[UrlError] for HttpErrormaps either variant toHttpError.InvalidUrl, retaining its input text. - std-http.url-error.display-user-infoFor user-info input, the Invalid error omits credentials from Display and recommends using the Authorization header.
#Parsed URLs
- std-http.parsed-url.declaration
std.http.Urlis a value with these public fields and private encoding metadata.
| Field | Type | Meaning |
|---|---|---|
scheme |
string |
HTTP or HTTPS scheme |
host |
string |
ASCII authority host, including IP-literal brackets |
port |
u16? |
Explicit port when present |
path |
string |
Percent-decoded path |
query |
List[(string, string)] |
Decoded query pairs in order |
fragment |
string? |
Decoded fragment when present |
- std-http.parsed-url.parse
Url::parse(text: string) -> Result[Url, UrlError]parses an absolute HTTP or HTTPS URL satisfying the ASCII-host rule in URLs. - std-http.parsed-url.relativeInput without a scheme returns
UrlError.RelativeWithoutBasewith the original text. - std-http.parsed-url.invalidMalformed absolute input, unsupported schemes, non-ASCII hosts or invalid ports return
UrlError.Invalidwith the original text. - std-http.parsed-url.user-infoAn authority containing user-info is rejected as
UrlError.Invalid. - std-http.parsed-url.controlsA literal ASCII control character, space or DEL in the input makes the URL invalid.
- std-http.parsed-url.scheme-host-caseParsing lowercases ASCII letters in the scheme and host.
- std-http.parsed-url.portA nonempty explicit port must be decimal text within the
u16range; an absent or empty port becomesNone. - std-http.parsed-url.pathParsing percent-decodes the path as UTF-8 without interpreting encoded
/or?as component separators. - std-http.parsed-url.queryParsing splits nonempty query parts at
&and their first=, retaining pair order and repeated names. - std-http.parsed-url.query-empty-valueA query part without
=has an empty value. - std-http.parsed-url.query-decodeQuery names and values percent-decode UTF-8 and interpret
+as space. - std-http.parsed-url.fragmentParsing percent-decodes the fragment as UTF-8, retaining an explicit empty fragment as
Some(""). - std-http.parsed-url.invalid-escapeInvalid percent escapes or invalid decoded UTF-8 in the path, query or fragment make the input invalid.
- std-http.parsed-url.raw-pathDisplay retains the private escaped path while decoding it gives the current public path.
- std-http.parsed-url.changed-pathOtherwise Display percent-encodes the public path as UTF-8, preserving RFC 3986 path characters and escaping literal
%and?. - std-http.parsed-url.raw-path-unicodeLiteral non-ASCII path bytes are percent-encoded without changing existing valid escapes.
- std-http.parsed-url.display-queryDisplay writes nonempty query pairs as encoded
name=valueparts joined by&, encoding each component's UTF-8 bytes separately. - std-http.parsed-url.display-fragmentDisplay writes a present fragment after
#, percent-encoding its UTF-8 bytes while retaining permitted fragment characters. - std-http.parsed-url.empty-queryParsing an explicit empty query retains a private presence bit, so an empty public list can still display a trailing
?. - std-http.parsed-url.nonempty-queryA nonempty public query list overrides that presence bit in Display.
- std-http.parsed-url.param
param(&self, name: string) -> string?returns the first value whose name equalsname, orNonewhen absent. - std-http.parsed-url.add-param
add_param[T < Display](&mut self, name: string, value: T) -> voidappends the name and the value's Display text as decoded data. - std-http.parsed-url.add-param-empty-query
add_paramclears the earlier empty-query presence bit. - std-http.parsed-url.resolve
resolve(&self, reference: string) -> Result[Url, UrlError]resolves a reference by RFC 3986 section 5, preserving encoded path separators and query presence. - std-http.parsed-url.traits
UrlimplementsDisplay, structuralEqandDebug.
#Requests And Responses
Requests and responses use parsed fields and a shared read-once body:
pub enum Method:
Get
Head
Post
Put
Patch
Delete
Options
Other(name: string)
pub struct Request:
pub method: Method = .Get
pub url: Url
pub headers: Headers = Headers::new()
pub body: Body = Body::empty()
pub struct Response:
pub status: HttpStatus = .Ok
pub headers: Headers = Headers::new()
pub body: Body = Body::empty()
pub url: Url? = .None- std-http.types.parsed-messages
std.httpdeclaresMethod,Request, andResponseas above. - std-http.types.traits
Method,Request, andResponseimplementEqandDebug. - std-http.request.message-defaultsA request supplying only
urlhas methodGet, empty headers, and a fresh unread empty body. - std-http.request.default-timeoutA provider that sends requests to a host has a default timeout of 30 seconds.
- std-http.headers.typed-fieldsRequest and response headers are
Headersvalues. - std-http.headers.caseHeader names compare ignoring ASCII case, so a provider may change the case of a response header's name.
- std-http.headers.combinedA provider may combine repeated non-cookie response fields according to RFC 9110 §5.3.
- std-http.headers.cookies-separateA provider must deliver each
Set-Cookievalue as a separate pair, in received order. - std-http.headers.values-orderRepeated values of one response field retain their received order.
- std-http.headers.platform-orderResponse headers of different names may follow the platform's exposed order.
- std-http.response.header-typed
Response.header(&self, name: HeaderName) -> string?delegates toheaders.get(name). - std-http.response.text-read-once
Response.text(&self) -> Result[string, BodyError]delegates tobody.text(). - std-http.response.optional-urlA received response has
url = Some(final_url), while a response constructed without a URL hasNone. - std-http.method.eq.variant-payloadTwo
Methodvalues compare equal only when their variants and corresponding payloads are equal. - std-http.types.message-copyCopying a request or response copies its fields, sharing only the body's private consumption state.
- std-http.response.message-defaultsAn omitted response status is
Ok, with empty headers, a fresh unread empty body, and no URL. - std-http.request.read-bodyRequest
bytes,text,json[T], andform[T]borrow&selfand delegate to the corresponding body reader. - std-http.request.read-query
Request.query_as[T < Deserialize](&self) -> Result[T, FormError]delegates to its URL's query reader. - std-http.request.read-header
Request.header(&self, name: HeaderName) -> string?delegates toheaders.get(name). - std-http.request.read-cookie
Request.cookie(&self, name: string) -> string?delegates toheaders.request_cookie(name). - std-http.response.read-bytes
Response.bytes(&self) -> Result[List[u8], BodyError]delegates tobody.bytes(). - std-http.response.read-cookies
Response.cookies(&self) -> List[Cookie]delegates toheaders.response_cookies().
#Request Builder
Message writers return changed values for chaining; readers borrow locally.
- std-http.request.new-value
Request::new(method: Method, url: Url) -> Requestreturns a value with those fields and the other defaults. - std-http.request.get-value
Request::get(url: Url) -> RequestreturnsRequest::new(.Get, url). - std-http.request.post-value
Request::post(url: Url) -> RequestreturnsRequest::new(.Post, url). - std-http.message.writer-valueEvery
set_*message writer takesmut selfand returns the changed message value. - std-http.message.writer-detachReplacing a message's body creates a fresh unread body without changing copies of the earlier message.
- std-http.message.set-jsonRequest and response
set_json[T < Serialize]replace the body with UTF-8 bytes fromstd.json.encode(value). - std-http.message.json-once
set_jsonserializes its value once. - std-http.message.json-content-type
set_jsonreplacesContent-Typewithapplication/json. - std-http.message.set-textRequest and response
set_text(text: string)replace the body with the text's UTF-8 bytes. - std-http.message.text-content-type
set_textreplacesContent-Typewithtext/plain; charset=utf-8. - std-http.message.set-bytesRequest and response
set_bytes(bytes: List[u8])replace the body without changing headers. - std-http.message.set-headerRequest and response
set_header(name: HeaderName, value: string)delegate toheaders.set. - std-http.request.set-form
Request.set_form[T < Serialize]prepares the body using Typed Query And Form Values. - std-http.request.form-escapingForm names and values encode UTF-8 bytes, keeping only ASCII letters, digits,
*,-,., and_unchanged. - std-http.request.form-spaceForm encoding writes a space as
+and each remaining escaped byte as%followed by two uppercase hexadecimal digits. - std-http.request.form-pairsForm encoding joins each name and value with
=and each pair with&. - std-http.request.form-content-type-replace
set_formreplacesContent-Typewithapplication/x-www-form-urlencoded. - std-http.request.form-preparation-errorA failed
set_formretains itsFormErrorin the new body instead of panicking. - std-http.request.form-error-readReading or sending that body returns
BodyError.Form(error)through the corresponding result type. - std-http.request.set-query
Request.set_query_as[T < Serialize]delegates tourl.set_query_as. - std-http.request.set-cookie
Request.set_cookie(name: string, value: string)delegates toheaders.set_request_cookie. - std-http.response.status-constructor
Response::status(code: HttpStatus) -> Responsesupplies that status and the other defaults. - std-http.response.set-cookie
Response.set_cookie(cookie: Cookie)delegates toheaders.set_response_cookie. - std-http.request.send-borrowed
Request.send!(&self, redirects: usize = 10) -> Result[Response, HttpError] $ Httpvalidates the request, then calls its covering provider. - std-http.request.send-query-errorA pending query encoding failure returns
HttpError.Body(BodyError.Form(error))before calling the provider. - std-http.request.send-body-claimSending claims the body once, so another send or reader through any message copy returns
BodyError.Used. - std-http.request.send-validation-firstHeader and URL validation failures leave the body unread.
- std-http.send.zero-redirects-supportedWith
redirectszero, Node and Wasmtime providers return the first response without following or validating itsLocation.
Why. Local borrows permit reading messages without copying fields. Copies share consumption, while a value writer detaches its replacement body. Typed query and form values use one codec and one error vocabulary.
The provider's default timeout still applies; std.task.apply! with std.task.timeout can impose a shorter bound around a send.
#Client
A client owns a serializable cookie jar and follows redirects through its covering provider.
- std-http.client.jar-value
std.httpexports the value structClient. - std-http.client.jar-field
Clienthas the public fieldjar: CookieJar, defaulting toCookieJar::new(). - std-http.client.new-value
Client::new() -> Clientreturns a value with an empty jar. - std-http.client.with-jar
Client::with_jar(jar: CookieJar) -> Clientreturns a value containing that jar. - std-http.client.send-borrowed-clock
Client.send!(&mut self, request: &Request, redirects: usize = 10) -> Result[Response, HttpError] $ Http + Clocksends throughHttp. - std-http.client.clock-onceA send passing validation reads
Clock.now()once, using that timestamp for every cookie lookup and response store across redirects. - std-http.client.body-claimSending claims the supplied request's body once and prepares an independent body for each provider request.
- std-http.client.fields-retainedSending leaves request fields unchanged, while its shared body becomes used.
- std-http.client.unchecked-final-responseSending returns the final response without checking its status, or propagates a provider error unchanged.
- std-http.client.policy-timeout
Clienthas no timeout setter; a caller appliesstd.task.timeoutaround its Result-returning send throughstd.task.apply!. - std-http.client.jar-fillBefore each request, sending fills an absent
Cookieheader with eligible jar pairs joined by;in jar order. - std-http.client.jar-storeEvery response updates the jar before following another redirect, including responses returned without following.
- std-http.client.cookies.explicitAn explicit
Cookieheader takes precedence over the jar for that request without replacing stored cookies. - std-http.client.redirects.zero-providerThe client passes
redirects = 0to each provider call and follows redirects itself. - std-http.client.redirects.statusResponses with status 301, 302, 303, 307 or 308 and a
Locationheader are redirects. - std-http.client.redirects.zero-argumentA zero
redirectsargument returns the first response without following itsLocation. - std-http.client.redirects.methodA 303 changes the method to
Get; a 301 or 302 changesPosttoGetand preserves other methods. - std-http.client.redirects.bodyChanging a method to
Getremoves its body and itsContent-Type,Content-LengthandTransfer-Encodingheaders. - std-http.client.redirects.resolveA redirect's
Locationresolves against the current request URL as an RFC 3986 reference. - std-http.client.redirects.cross-hostA redirect to another hostname removes the previous request's
AuthorizationandCookieheaders before applying the target host's jar. - std-http.client.redirects.argument-limitExceeding a positive redirect argument returns
HttpError.TooManyRedirects(url), naming the next target without sending to it. - std-http.client.redirects.no-locationA response without
Locationis returned without following another request. - std-http.client.redirects.parsed-response-urlThe returned response's
urlisSome(final_request_url). - std-http.client.no-default-builders
Clienthas no base-URL, default-header, or cookie-lookup builder methods; callers useUrl, message headers, andjardirectly.
Why. Reading every response retains cookies set during redirects. Plain
Request.send!needs onlyHttp; a cookie-aware client also declares clock authority.
#Cookie Jar
CookieJar is plain data; each time-dependent operation takes its timestamp
explicitly, following RFC 6265 sections 5.1–5.4.
- std-http.jar.declaration
CookieJarhas private storage and implementsDebug,Eq,Serialize, andDeserialize. - std-http.jar.new
CookieJar::new() -> CookieJarreturns an empty jar. - std-http.jar.explicit-timeA jar retains no clock and reads no implicit time.
- std-http.jar.cookies-for
cookies_for(&self, url: &Url, now: Timestamp) -> List[(string, string)]returns the name/value pairs eligible at that time. - std-http.jar.store
store(&mut self, url: &Url, response: &Response, now: Timestamp) -> voidprocesses response cookies in header order. - std-http.jar.clear-expired
clear_expired(&mut self, now: Timestamp) -> voidremoves cookies whose expiry is at or beforenow. - std-http.jar.host-onlyWithout a Domain attribute, a cookie belongs only to the response request's ASCII-lowercase hostname, independently of its port.
- std-http.jar.domain-matchA Domain attribute must match the response hostname exactly or as a suffix preceded by a dot.
- std-http.jar.domain-ipAn IP address matches a Domain attribute only exactly.
- std-http.jar.domain-rejectA cookie whose Domain does not match the response request's hostname is ignored.
- std-http.jar.domain-sendA domain cookie is eligible for its domain and matching subdomains; a host-only cookie requires an exact hostname.
- std-http.jar.default-pathAn absent or invalid Path uses the escaped request URI's directory, or
/when no directory exists. - std-http.jar.path-matchA request path matches exactly, or extends a cookie path ending with
/or followed by/. - std-http.jar.escaped-pathPath matching uses escaped URI paths, so an encoded slash does not create a directory boundary.
- std-http.jar.secureA Secure cookie is eligible only for
httpsrequests. - std-http.jar.http-onlyHttpOnly does not exclude cookies from these HTTP request operations.
- std-http.jar.expiry-max-ageA valid Max-Age sets expiry relative to
now, taking precedence over Expires. - std-http.jar.expiry-expiresWithout Max-Age, a valid Expires sets absolute expiry; without either, the cookie has no expiry.
- std-http.jar.expired-ineligibleA cookie expiring at or before
nowis ineligible and removes an existing cookie with the same name, domain, and path. - std-http.jar.identityA cookie replaces the stored cookie with the same name, domain, and path, preserving its position among equally long paths.
- std-http.jar.orderEligible cookies are ordered by decreasing path length, then original creation order.
- std-http.jar.duplicate-namesDifferent scopes may supply repeated cookie names in the outgoing pairs.
- std-http.jar.serde-stateSerde retains cookie values, scopes, Secure and HttpOnly flags, and absolute expiry times without retaining a clock.
- std-http.jar.serde-expiry-millisecondsPrivate expiry storage serializes absolute Unix milliseconds as an optional
i64, without a calendar-year cap. - std-http.jar.expiry-beyond-rangeA positive Max-Age whose deadline exceeds every representable timestamp cannot expire at a representable timestamp.
- std-http.jar.empty-request-pathAn empty request URI path is treated as
/for cookie matching.
#URLs
A request URL is an RFC 3986 URL, so its host is plain ASCII:
use std.http.{Http, HttpError, Response, get}
fn shop!() -> Result[Response, HttpError] $ Http:
_ := get!("https://bücher.example/") # .Err(HttpError.InvalidUrl(url))
get!("https://xn--bcher-kva.example/") # the same host in punycode- std-http.url.validA request URL is valid when it is an absolute
httporhttpsURL by RFC 3986, with an ASCII host. - std-http.url.non-asciiA URL whose host holds a non-ASCII character is invalid, so
send!returns.Err(HttpError.InvalidUrl(url))for it. - std-http.url.grantA grant matches a request by its URL host, in lowercase ASCII.
- std-http.url.no-normalizeA provider maps the host no other way: no IDNA mapping and no lookalike normalization.
Why. An ASCII-only host leaves one spelling for each host, so a grant and the request it covers always compare the same text.
#Http Errors
Every failure of a request is one error enum:
pub enum HttpError:
NotGranted(host: string)
InvalidUrl(url: string)
Dns(host: string)
Connect(message: string)
Tls(message: string)
Timeout
TooManyRedirects(url: string)
Other(message: string)
Status(response: Response)
InvalidHeader(name: string)
Body(error: BodyError)- std-http.error.decl-message-errors
std.httpdeclaresHttpErroras above. Code imports it, as inuse std.http.HttpError. - std-http.error.traits
HttpErrorimplementsEq,Debug,Display, andstd.error.Error.
| Rule | Variant | Means |
|---|---|---|
| std-http.error.not-grantedNot granted | NotGranted(host) |
the program's capability grant does not cover the request's host, by Partial Deny |
| std-http.error.invalid-url-targetInvalid URL | InvalidUrl(url) |
Invalid HTTP target, including a URL rejected by Url::parse |
| std-http.error.dnsDNS | Dns(host) |
the host name did not resolve |
| std-http.error.connectConnect | Connect(message) |
no connection was made, or it failed before the whole response arrived |
| std-http.error.tlsTLS | Tls(message) |
the TLS handshake or a certificate check failed |
| std-http.error.timeoutTimeout | Timeout |
the request took longer than its timeout |
| std-http.error.redirect-argument-limitRedirects | TooManyRedirects(url) |
the response exceeded a positive send! redirect limit; url is the last target |
| std-http.error.otherOther | Other(message) |
any other failure, with the provider's message |
| std-http.error.status-response-valueStatus | Status(response) |
Response.ok found a status from 400 to 599, retaining the whole response |
- std-http.error.not-granted.plainThe
Displaytext ofNotGranted(host)ishttp access to HOST is not granted, with the host forHOST. - std-http.error.status.safe-response-text
Status(response)displaysHTTP status STATUS for URL, with the response status and its URL before any query or fragment. - std-http.error.status.no-response-secretsThe status error's
Displaytext contains no response body or header values. - std-http.error.transient-borrowed
HttpError.is_transient(&self) -> boolreturns true forTimeoutandConnecterrors. - std-http.error.transient-status-codesA
Statuserror is transient for 408, 429, 500, 502, 503, and 504. - std-http.error.permanent-kinds
is_transientreturns false for every other error. - std-http.error.invalid-url-display
InvalidUrl(url)displaysinvalid URL: URLunless the input contains user-info. - std-http.error.invalid-url-user-infoUser-info errors instead omit credentials from Display and recommend the Authorization header, including errors converted from
UrlError. - std-http.error.invalid-header-display
InvalidHeader(name)displaysinvalid header NAME, using its header name. - std-http.error.body-display
Body(error)displays the body error's Display text. - std-http.error.from-body
From[BodyError] for HttpErrorwraps its input inHttpError.Body.
#Sending
Http sends one request and completes with the whole response, with status and body available separately:
use std.http.{Http, HttpError, get}
fn latest_release!(repo: string) -> Result[string, HttpError] $ Http:
response := get!("https://api.github.com/repos/${repo}/releases/latest")?
if response.status != .Ok:
return .Err(.Other("status ${response.status.code()}"))
.Ok(response.text()?)-
std-http.trait.decl-borrowed-request
std.httpdeclaresHttpwithfn send!(&mut self, request: &Request, redirects: usize) -> Result[Response, HttpError]. Code imports it, as inuse std.http.Http. -
std-http.send.borrowed-request
send!(request, redirects)sends the borrowed request and completes with the whole response. -
std-http.send.statusEvery status, 404 and 500 included, is an
.Okresponse, and the caller reads it fromstatus. -
std-http.send.redirect-argument
send!follows at most itsredirectsargument redirects. -
std-http.send.provider-timeoutA host request exceeding the provider's default timeout completes with
.Err(HttpError.Timeout). -
std-http.send.timeout.wholeA timeout covers the whole request, every redirect included.
-
std-http.send.cancelCancelling the suspension of
send!aborts the request, byreq.cancel.external-abort. -
std-http.send.cancel.closeAborting a request closes its connection.
-
std-http.send.mut-ref.reference-values
send!takes&mut self, soHttpis a mutable requirement trait,$.use(Http)is a&mut dyn Httpbyreq.ref.use.reference-values, and a provider may record what it sends. -
std-http.bodies.read-once-bufferA body buffers a whole byte sequence behind read-once state;
std.httphas no streaming transport body. -
std-http.helper.get.parsed-response
get!(url: string) -> Result[Response, HttpError] $ Httpparses the URL, sends a GET, and checksok(). -
std-http.helper.get-postThe free request helpers are
get!andpost!; freesend!,get_text!, andpost_json!are not exported. -
std-http.helper.post-json-checked
post -> Result[Response, HttpError] $ Httpparses the URL, sends JSON, and checksok(). -
std-http.send.header-validationSending rejects invalid header names and CR or LF in header values as
HttpError.InvalidHeader(name)before transport. -
std-http.send.cookie-validationSending rejects invalid typed cookie components as
HttpError.InvalidHeader(name)before transport. -
std-http.send.mutated-urlSending revalidates a URL's public fields, rejecting invalid HTTP targets as
HttpError.InvalidUrl(url).
Why. A status is data about a request that worked, as with
fetchand Go, and as a non-zero exit status is forProcess. Header pairs keep a repeated header, which a map would lose.
#Status And JSON
Response.ok() checks 400–599 while preserving the whole response in the
error; the free get! calls it automatically:
use std.error.Error
use std.http.{Http, HttpError, Request, Url, get}
use std.serde.{Deserialize, Serialize}
@derive(Serialize)
struct NewUser:
name: string
@derive(Deserialize)
struct Created:
id: i64
fn notes!() -> Result[string, HttpError] $ Http:
.Ok(get!("https://example.com/notes.txt")?.text()?) # a 404 is .Err(HttpError.Status(response))
fn create!(name: string) -> Result[Created, *dyn Error] $ Http:
request := Request::post(Url::parse("https://example.com/users")?).set_json(NewUser { name: name })
.Ok(request.send!()?.ok()?.json::[Created]()?) # a bad body is a BodyError.Json- std-http.response.ok.borrowed-retained
Response.ok(&self) -> Result[Response, HttpError]copies the whole response intoErr(Status(response))for codes 400–599, orOk(response)otherwise. - std-http.response.json-read-once
Response.json[T < Deserialize](&self) -> Result[T, BodyError]delegates tobody.json[T]without checking status. - std-http.response.body-errors-propagateA function that sends and decodes propagates both errors with
?into an error type covering both, such as*dyn Error(expr.try.convert).
Why. Builder and provider
send!calls keep every status available (std-http.send.status).Response.ok()checks explicitly, as reqwest'serror_for_statusdoes; the freeget!checks by default. Retaining the response lets a caller decode an API's error body.
#Scripted Http
ScriptedHttp is the deterministic Http provider. It consumes replies queued
for each URL, and records every request:
use std.http.{Http, Response, ScriptedHttp, get}
fn status!(url: string) -> u16 $ Http:
match get!(url):
.Ok(response) => response.status.code()
.Err(_) => 0
tests:
use std.testing.assert_equal
it("reads the scripted status"):
http := ScriptedHttp::new()
http.reply("https://example.com/", .Ok(Response::status(.NoContent)))
$.with(Http=http):
assert_equal(status!("https://example.com/"), 204, reason="scripted")
assert_equal(http.received().len(), 1, reason="one request")- std-http.scripted.decl
std.httpdeclaresScriptedHttp, which implementsHttpandDebug, with private fields. Code imports it, as inuse std.http.ScriptedHttp. - std-http.scripted.new-empty
ScriptedHttp::new() -> *mut ScriptedHttpreturns a new provider with no replies and no received requests. - std-http.scripted.reply-captured
reply(&mut self, url: string, result: Result[Response, HttpError]) -> voidappends a result for that URL. - std-http.scripted.key-url-displayReplies match the complete request URL Display text exactly, whatever the request method.
- std-http.scripted.queue-orderSends consume queued results in insertion order, independently for each URL.
- std-http.scripted.repeat-lastAfter a URL's queued results have been consumed, further sends repeat its last result.
- std-http.scripted.error-valuesA queued error retains its value, except that
Status(response)gets a fresh response body for each delivery. - std-http.scripted.raw-statusEvery status of a queued successful response is returned as
.Ok, without a status check. - std-http.scripted.missing-replyA URL without a reply returns
.Err(HttpError.Connect("ScriptedHttp has no response for URL")), substituting its full URL. - std-http.scripted.received-bodies
received(&self) -> List[Request]returns validated requests in order with independent unread body snapshots, including unanswered requests. - std-http.scripted.no-hostA
ScriptedHttpopens no connection. - std-http.scripted.reply-body-snapshotRegistering a response copies its body payload into the reply queue without marking the caller's body used.
- std-http.scripted.delivery-body-freshEvery scripted response delivery, including a repeated last reply, receives a fresh unread
Body. - std-http.scripted.reply-used-panicRegistering a used body panics with
ScriptedHttp.reply: the response body was already read. Panic:explicit-panic. - std-http.scripted.status-body-snapshotThose registration and delivery rules also apply to the response held by a queued
HttpError.Status.
Why. An unknown URL is an error that names it, not a 404. So a route that a test forgot never hides behind a valid status.
#Playground
The playground runs a program in a browser. Its Http provider calls the
browser's HTTP facilities:
use std.http.{Http, HttpError, get}
fn ping!(url: string) -> string $ Http:
match get!(url):
.Ok(response) => "status ${response.status.code()}"
.Err(.NotGranted(host)) => "the playground grants no ${host}" # another origin
.Err(.Connect(_)) => "the browser refused the request" # a network failure or CORS
.Err(error) => "${error}"- std-http.playground.originThe playground binds
Httpwith a grant that covers only its own origin, as the browser's same-origin rule does. - std-http.playground.other-originA request to another origin returns
.Err(HttpError.NotGranted(host)). - std-http.playground.refusedA request that the browser refuses, for a network failure or by CORS, returns
.Err(HttpError.Connect(message)). - std-http.playground.unboundThe playground binds no
Process,Sys, orNetprovider. - std-http.playground.zero-redirects-errorA granted browser request with
redirects: 0returns.Err(HttpError.Other("the browser host cannot stop redirects"))before sending.
Why. A browser can't tell a CORS refusal from a network failure, so neither can the provider. The playground needs no grant table: the browser's own rule decides.
#Waiting In The Playground
A block_on
call in the playground may have to wait for the host, as for a response
to get!. How it waits depends on the browser:
| Browser | A block_on that waits on the host |
|---|---|
| has JavaScript Promise Integration | waits for the host operation, as on any other host |
| lacks it | completes an HTTP request as a synchronous same-origin request, and panics for any other host operation |
- std-http.playground.block-on.jspiIn a browser with JavaScript Promise Integration, a
block_oncall in the playground waits for each host operation it needs. - std-http.playground.block-on.syncIn a browser without it, an
Httprequest that ablock_oncall waits on is made as a synchronous same-origin request. - std-http.playground.block-on.otherIn such a browser, a
block_oncall that must wait on any other host operation panics, with a message that names the operation. Panic:host-contract.
use std.http.{Http, get}
use std.task.block_on
fn status_of(url: string) -> string $ Http:
match block_on(get(url)): # without Promise Integration: a synchronous request
.Completed(.Ok(response)) => "status ${response.status.code()}"
.Completed(.Err(error)) => "${error}"
.Cancelled => "cancelled"
.Abandoned => "cut short"Why. A browser thread cannot block, so only Promise Integration lets Wasm wait for a Promise. Without it, a synchronous request is the one wait a browser still offers, and only for HTTP.
See also: Capability Grants, Process, Time.
#Timeout Conversion
- std-http.error.from-timed-out
HttpErrorimplementsstd.convert.From[std.task.TimedOut], converting every deadline error to.Timeout.