http

Version:
sha256:5a568e6
wit

types interface

This interface defines all of the types and methods for implementing HTTP Requests and Responses, both incoming and outgoing, as well as their headers, trailers, and bodies.

Imported Types
wasi:clocks/monotonic-clock.{duration}
wasi:io/streams.{input-stream}
wasi:io/streams.{output-stream}
wasi:io/error.{error as io-error}
wasi:io/poll.{pollable}

This type corresponds to HTTP standard Methods.

method:variant {
get
head
post
put
delete
connect
options
trace
patch
other(string)
}

This type corresponds to HTTP standard Related Schemes.

scheme:variant {
HTTP
HTTPS
other(string)
}

Defines the case payload type for DNS-error above:

DNS-error-payload:record {
rcode: option<string>
info-code: option<u16>
}

Defines the case payload type for TLS-alert-received above:

TLS-alert-received-payload:record {
alert-id: option<u8>
alert-message: option<string>
}

Defines the case payload type for HTTP-response-{header,trailer}-size above:

field-size-payload:record {
field-name: option<string>
field-size: option<u32>
}
error-code:variant {
DNS-timeout
destination-not-found
destination-unavailable
destination-IP-prohibited
destination-IP-unroutable
connection-refused
connection-terminated
connection-timeout
connection-read-timeout
connection-write-timeout
connection-limit-reached
TLS-protocol-error
TLS-certificate-error
TLS-alert-received(TLS-alert-received-payload)
HTTP-request-denied
HTTP-request-length-required
HTTP-request-body-size(option<u64>)
HTTP-request-method-invalid
HTTP-request-URI-invalid
HTTP-request-URI-too-long
HTTP-request-header-section-size(option<u32>)
HTTP-request-header-size(option<field-size-payload>)
HTTP-request-trailer-section-size(option<u32>)
HTTP-request-trailer-size(field-size-payload)
HTTP-response-incomplete
HTTP-response-header-section-size(option<u32>)
HTTP-response-header-size(field-size-payload)
HTTP-response-body-size(option<u64>)
HTTP-response-trailer-section-size(option<u32>)
HTTP-response-trailer-size(field-size-payload)
HTTP-response-transfer-coding(option<string>)
HTTP-response-content-coding(option<string>)
HTTP-response-timeout
HTTP-upgrade-failed
HTTP-protocol-error
loop-detected
configuration-error
internal-error(option<string>)

This is a catch-all error for anything that doesn't fit cleanly into a more specific case. It also includes an optional string for an unstructured description of the error. Users should not depend on the string for diagnosing errors, as it's not required to be consistent between implementations.

}

This type enumerates the different kinds of errors that may occur when setting or appending to a fields resource.

header-error:variant {
invalid-syntax

This error indicates that a field-key or field-value was syntactically invalid when used with an operation that sets headers in a fields.

forbidden

This error indicates that a forbidden field-key was used when trying to set a header in a fields.

immutable

This error indicates that the operation on the fields was not permitted because the fields are immutable.

}

Field keys are always strings.

field-key:string

Field values should always be ASCII strings. However, in reality, HTTP implementations often have to interpret malformed values, so they are provided as a list of bytes.

field-value:list<u8>
fields:resource {

This following block defines the fields resource which corresponds to HTTP standard Fields. Fields are a common representation used for both Headers and Trailers.

A fields may be mutable or immutable. A fields created using the constructor, from-list, or clone will be mutable, but a fields resource given by other means (including, but not limited to, incoming-request.headers, outgoing-request.headers) might be be immutable. In an immutable fields, the set, append, and delete operations will fail with header-error.immutable.

constructor()fields

Construct an empty HTTP Fields.

The resulting fields is mutable.

staticfrom-list(entries:list<tuple<field-key, field-value>>)result<fields, header-error>

Construct an HTTP Fields.

The resulting fields is mutable.

The list represents each key-value pair in the Fields. Keys which have multiple values are represented by multiple entries in this list with the same key.

The tuple is a pair of the field key, represented as a string, and Value, represented as a list of bytes. In a valid Fields, all keys and values are valid UTF-8 strings. However, values are not always well-formed, so they are represented as a raw list of bytes.

An error result will be returned if any header or value was syntactically invalid, or if a header was forbidden.

get(name:field-key)list<field-value>

Get all of the values corresponding to a key. If the key is not present in this fields, an empty list is returned. However, if the key is present but empty, this is represented by a list with one or more empty field-values present.

has(name:field-key)bool

Returns true when the key is present in this fields. If the key is syntactically invalid, false is returned.

set(name:field-key, value:list<field-value>)result<_, header-error>

Set all of the values for a key. Clears any existing values for that key, if they have been set.

Fails with header-error.immutable if the fields are immutable.

delete(name:field-key)result<_, header-error>

Delete all values for a key. Does nothing if no values for the key exist.

Fails with header-error.immutable if the fields are immutable.

append(name:field-key, value:field-value)result<_, header-error>

Append a value for a key. Does not change or delete any existing values for that key.

Fails with header-error.immutable if the fields are immutable.

entries()list<tuple<field-key, field-value>>

Retrieve the full set of keys and values in the Fields. Like the constructor, the list represents each key-value pair.

The outer list represents each key-value pair in the Fields. Keys which have multiple values are represented by multiple entries in this list with the same key.

clone()fields

Make a deep copy of the Fields. Equivelant in behavior to calling the fields constructor on the return value of entries. The resulting fields is mutable.

}

Headers is an alias for Fields.

headers:fields

Trailers is an alias for Fields.

trailers:fields
incoming-request:resource {

Represents an incoming HTTP Request.

method()method

Returns the method of the incoming request.

path-with-query()option<string>

Returns the path with query parameters from the request, as a string.

scheme()option<scheme>

Returns the protocol scheme from the request.

authority()option<string>

Returns the authority from the request, if it was present.

headers()headers

Get the headers associated with the request.

The returned headers resource is immutable: set, append, and delete operations will fail with header-error.immutable.

The headers returned are a child resource: it must be dropped before the parent incoming-request is dropped. Dropping this incoming-request before all children are dropped will trap.

consume()result<incoming-body, _>

Gives the incoming-body associated with this request. Will only return success at most once, and subsequent calls will return error.

}
outgoing-request:resource {

Represents an outgoing HTTP Request.

constructor(headers:headers)outgoing-request

Construct a new outgoing-request with a default method of GET, and none values for path-with-query, scheme, and authority.

  • headers is the HTTP Headers for the Request.

It is possible to construct, or manipulate with the accessor functions below, an outgoing-request with an invalid combination of scheme and authority, or headers which are not permitted to be sent. It is the obligation of the outgoing-handler.handle implementation to reject invalid constructions of outgoing-request.

body()result<outgoing-body, _>

Returns the resource corresponding to the outgoing Body for this Request.

Returns success on the first call: the outgoing-body resource for this outgoing-request can be retrieved at most once. Subsequent calls will return error.

method()method

Get the Method for the Request.

set-method(method:method)result<_, _>

Set the Method for the Request. Fails if the string present in a method.other argument is not a syntactically valid method.

path-with-query()option<string>

Get the combination of the HTTP Path and Query for the Request. When none, this represents an empty Path and empty Query.

set-path-with-query(path-with-query:option<string>)result<_, _>

Set the combination of the HTTP Path and Query for the Request. When none, this represents an empty Path and empty Query. Fails is the string given is not a syntactically valid path and query uri component.

scheme()option<scheme>

Get the HTTP Related Scheme for the Request. When none, the implementation may choose an appropriate default scheme.

set-scheme(scheme:option<scheme>)result<_, _>

Set the HTTP Related Scheme for the Request. When none, the implementation may choose an appropriate default scheme. Fails if the string given is not a syntactically valid uri scheme.

authority()option<string>

Get the HTTP Authority for the Request. A value of none may be used with Related Schemes which do not require an Authority. The HTTP and HTTPS schemes always require an authority.

set-authority(authority:option<string>)result<_, _>

Set the HTTP Authority for the Request. A value of none may be used with Related Schemes which do not require an Authority. The HTTP and HTTPS schemes always require an authority. Fails if the string given is not a syntactically valid uri authority.

headers()headers

Get the headers associated with the Request.

The returned headers resource is immutable: set, append, and delete operations will fail with header-error.immutable.

This headers resource is a child: it must be dropped before the parent outgoing-request is dropped, or its ownership is transfered to another component by e.g. outgoing-handler.handle.

}
request-options:resource {

Parameters for making an HTTP Request. Each of these parameters is currently an optional timeout applicable to the transport layer of the HTTP protocol.

These timeouts are separate from any the user may use to bound a blocking call to wasi:io/poll.poll.

constructor()request-options

Construct a default request-options value.

connect-timeout()option<duration>

The timeout for the initial connect to the HTTP Server.

set-connect-timeout(duration:option<duration>)result<_, _>

Set the timeout for the initial connect to the HTTP Server. An error return value indicates that this timeout is not supported.

first-byte-timeout()option<duration>

The timeout for receiving the first byte of the Response body.

set-first-byte-timeout(duration:option<duration>)result<_, _>

Set the timeout for receiving the first byte of the Response body. An error return value indicates that this timeout is not supported.

between-bytes-timeout()option<duration>

The timeout for receiving subsequent chunks of bytes in the Response body stream.

set-between-bytes-timeout(duration:option<duration>)result<_, _>

Set the timeout for receiving subsequent chunks of bytes in the Response body stream. An error return value indicates that this timeout is not supported.

}
response-outparam:resource {

Represents the ability to send an HTTP Response.

This resource is used by the wasi:http/incoming-handler interface to allow a Response to be sent corresponding to the Request provided as the other argument to incoming-handler.handle.

staticset(param:response-outparam, response:result<outgoing-response, error-code>)

Set the value of the response-outparam to either send a response, or indicate an error.

This method consumes the response-outparam to ensure that it is called at most once. If it is never called, the implementation will respond with an error.

The user may provide an error to response to allow the implementation determine how to respond with an HTTP error response.

}

This type corresponds to the HTTP standard Status Code.

status-code:u16
incoming-response:resource {

Represents an incoming HTTP Response.

status()status-code

Returns the status code from the incoming response.

headers()headers

Returns the headers from the incoming response.

The returned headers resource is immutable: set, append, and delete operations will fail with header-error.immutable.

This headers resource is a child: it must be dropped before the parent incoming-response is dropped.

consume()result<incoming-body, _>

Returns the incoming body. May be called at most once. Returns error if called additional times.

}
incoming-body:resource {

Represents an incoming HTTP Request or Response's Body.

A body has both its contents - a stream of bytes - and a (possibly empty) set of trailers, indicating that the full contents of the body have been received. This resource represents the contents as an input-stream and the delivery of trailers as a future-trailers, and ensures that the user of this interface may only be consuming either the body contents or waiting on trailers at any given time.

stream()result<input-stream, _>

Returns the contents of the body, as a stream of bytes.

Returns success on first call: the stream representing the contents can be retrieved at most once. Subsequent calls will return error.

The returned input-stream resource is a child: it must be dropped before the parent incoming-body is dropped, or consumed by incoming-body.finish.

This invariant ensures that the implementation can determine whether the user is consuming the contents of the body, waiting on the future-trailers to be ready, or neither. This allows for network backpressure is to be applied when the user is consuming the body, and for that backpressure to not inhibit delivery of the trailers if the user does not read the entire body.

staticfinish(this:incoming-body)future-trailers

Takes ownership of incoming-body, and returns a future-trailers. This function will trap if the input-stream child is still alive.

}
future-trailers:resource {

Represents a future which may eventaully return trailers, or an error.

In the case that the incoming HTTP Request or Response did not have any trailers, this future will resolve to the empty set of trailers once the complete Request or Response body has been received.

subscribe()pollable

Returns a pollable which becomes ready when either the trailers have been received, or an error has occured. When this pollable is ready, the get method will return some.

get()option<result<result<option<trailers>, error-code>, _>>

Returns the contents of the trailers, or an error which occured, once the future is ready.

The outer option represents future readiness. Users can wait on this option to become some using the subscribe method.

The outer result is used to retrieve the trailers or error at most once. It will be success on the first call in which the outer option is some, and error on subsequent calls.

The inner result represents that either the HTTP Request or Response body, as well as any trailers, were received successfully, or that an error occured receiving them. The optional trailers indicates whether or not trailers were present in the body.

When some trailers are returned by this method, the trailers resource is immutable, and a child. Use of the set, append, or delete methods will return an error, and the resource must be dropped before the parent future-trailers is dropped.

}
outgoing-response:resource {

Represents an outgoing HTTP Response.

constructor(headers:headers)outgoing-response

Construct an outgoing-response, with a default status-code of 200. If a different status-code is needed, it must be set via the set-status-code method.

  • headers is the HTTP Headers for the Response.
status-code()status-code

Get the HTTP Status Code for the Response.

set-status-code(status-code:status-code)result<_, _>

Set the HTTP Status Code for the Response. Fails if the status-code given is not a valid http status code.

headers()headers

Get the headers associated with the Request.

The returned headers resource is immutable: set, append, and delete operations will fail with header-error.immutable.

This headers resource is a child: it must be dropped before the parent outgoing-request is dropped, or its ownership is transfered to another component by e.g. outgoing-handler.handle.

body()result<outgoing-body, _>

Returns the resource corresponding to the outgoing Body for this Response.

Returns success on the first call: the outgoing-body resource for this outgoing-response can be retrieved at most once. Subsequent calls will return error.

}
outgoing-body:resource {

Represents an outgoing HTTP Request or Response's Body.

A body has both its contents - a stream of bytes - and a (possibly empty) set of trailers, inducating the full contents of the body have been sent. This resource represents the contents as an output-stream child resource, and the completion of the body (with optional trailers) with a static function that consumes the outgoing-body resource, and ensures that the user of this interface may not write to the body contents after the body has been finished.

If the user code drops this resource, as opposed to calling the static method finish, the implementation should treat the body as incomplete, and that an error has occured. The implementation should propogate this error to the HTTP protocol by whatever means it has available, including: corrupting the body on the wire, aborting the associated Request, or sending a late status code for the Response.

write()result<output-stream, _>

Returns a stream for writing the body contents.

The returned output-stream is a child resource: it must be dropped before the parent outgoing-body resource is dropped (or finished), otherwise the outgoing-body drop or finish will trap.

Returns success on the first call: the output-stream resource for this outgoing-body may be retrieved at most once. Subsequent calls will return error.

staticfinish(this:outgoing-body, trailers:option<trailers>)result<_, error-code>

Finalize an outgoing body, optionally providing trailers. This must be called to signal that the response is complete. If the outgoing-body is dropped without calling outgoing-body.finalize, the implementation should treat the body as corrupted.

Fails if the body's outgoing-request or outgoing-response was constructed with a Content-Length header, and the contents written to the body (via write) does not match the value given in the Content-Length.

}
future-incoming-response:resource {

Represents a future which may eventaully return an incoming HTTP Response, or an error.

This resource is returned by the wasi:http/outgoing-handler interface to provide the HTTP Response corresponding to the sent Request.

subscribe()pollable

Returns a pollable which becomes ready when either the Response has been received, or an error has occured. When this pollable is ready, the get method will return some.

get()option<result<result<incoming-response, error-code>, _>>

Returns the incoming HTTP Response, or an error, once one is ready.

The outer option represents future readiness. Users can wait on this option to become some using the subscribe method.

The outer result is used to retrieve the response or error at most once. It will be success on the first call in which the outer option is some, and error on subsequent calls.

The inner result represents that either the incoming HTTP Response status and headers have recieved successfully, or that an error occured. Errors may also occur while consuming the response body, but those will be reported by the incoming-body and its output-stream child.

}
http-error-code(err:borrow<io-error>)option<error-code>

Attempts to extract a http-related error from the wasi:io error provided.

Stream operations which return wasi:io/stream/stream-error::last-operation-failed have a payload of type wasi:io/error/error with more information about the operation that failed. This payload can be passed through to this function to see if there's http-related information about the error to return.

Note that this function is fallible because not all io-errors are http-related errors.

incoming-handler interface

This interface defines a handler of incoming HTTP Requests. It should be exported by components which can respond to HTTP Requests.

Imported Types
wasi:http/types.{incoming-request}
wasi:http/types.{response-outparam}
handle(request:incoming-request, response-out:response-outparam)

This function is invoked with an incoming HTTP Request, and a resource response-outparam which provides the capability to reply with an HTTP Response. The response is sent by calling the response-outparam.set method, which allows execution to continue after the response has been sent. This enables both streaming to the response body, and performing other work.

The implementor of this function must write a response to the response-outparam before returning, or else the caller will respond with an error on its behalf.

outgoing-handler interface

This interface defines a handler of outgoing HTTP Requests. It should be imported by components which wish to make HTTP Requests.

Imported Types
wasi:http/types.{outgoing-request}
wasi:http/types.{request-options}
wasi:http/types.{future-incoming-response}
wasi:http/types.{error-code}
handle(request:outgoing-request, options:option<request-options>)result<future-incoming-response, error-code>

This function is invoked with an outgoing HTTP Request, and it returns a resource future-incoming-response which represents an HTTP Response which may arrive in the future.

The options argument accepts optional parameters for the HTTP protocol's transport layer.

This function may return an error if the outgoing-request is invalid or not allowed to be made. Otherwise, protocol errors are reported through the future-incoming-response.