silk.http.message.
HTTP/1.0 and HTTP/1.1 values: versions, methods, statuses, header fields, and message heads.
When to use#
Use these types to make or inspect an HTTP message head. silk.http.head parses and writes
them, and the client and server modules take them. Each make and parse function checks the
value. The values borrow their text. Call copy on a head to keep it after its input is gone.
Details#
A Method is any valid token, and keeps its spelling, so get and GET are different. A
Status is any code from 100 to 599. A Header keeps the exact bytes of its name and
value. RequestHead.make checks that the target form fits the method, and that an HTTP/1.1
request has one Host field. This module does not read or write bodies.
Errors#
ValueErrortells which rule failed inValueError.reason, in which part inValueError.component, and where, inValueError.fieldIndexandValueError.offset.
Gotchas#
Header.make takes the value without the spaces around it on the wire. It rejects CR, LF,
NUL, DEL, other control bytes, and leading or trailing spaces or tabs.
Examples#
Make a response head#
import silk.http.message { Header, ResponseHead, Status, StatusClass, ValueError, Version }
import silk.http.headers { Headers, Limits }
import silk.core.option { Option }
import silk.core.result { Result }
fn limits() -> Limits {
return Limits {
maxMethodBytes: 64,
maxTargetBytes: 8192,
maxNameBytes: 256,
maxValueBytes: 8192,
maxFields: 128,
maxFieldBytes: 65536,
maxOwnedBytes: 131072,
}
}
pub fn main() -> i32 {
let status = match Status.fromCode(404) {
Result<Status, ValueError>.Success { value } => value
Result<Status, ValueError>.Failure { error: _ } => {
return 1
}
}
if Status.class(&status) != StatusClass.ClientError {
return 1
}
let header = match Header.make("Content-Type", b"text/plain", limits()) {
Result<Header, ValueError>.Success { value } => value
Result<Header, ValueError>.Failure { error: _ } => {
return 1
}
}
let entries = [header]
let headers = match Headers.make(&entries, limits()) {
Result<Headers, ValueError>.Success { value } => value
Result<Headers, ValueError>.Failure { error: _ } => {
return 1
}
}
let reason = b"Not Found"
let head = match ResponseHead.make(
Version.Http11,
status,
Option<&[u8]>.some(&reason),
headers,
limits(),
) {
Result<ResponseHead, ValueError>.Success { value } => move value
Result<ResponseHead, ValueError>.Failure { error: _ } => {
return 1
}
}
if Status.code(&ResponseHead.status(&head)) != 404 {
return 1
}
// A value with a line break fails.
let bad = match Header.make("X-Note", b"a\r\nb", limits()) {
Result<Header, ValueError>.Success { value: _ } => false
Result<Header, ValueError>.Failure { error } => error.offset == 1
}
if !bad {
return 1
}
return 0
}Import as Version with import silk.http.message { Version }.
Public declarations: 13.
ValueComponent#
pub enum ValueComponentThe part of an HTTP value that failed a check. See ValueError.component.
Version#
VersionAn HTTP version token.
Method#
MethodA request method token.
Status#
StatusA numeric response status.
HeaderName#
HeaderNameA field name.
HeaderValue#
HeaderValueA field value.
ReasonPhrase#
ReasonPhraseAn optional response reason phrase.
Headers#
HeadersA list of header fields.
Target#
TargetA request target.
Authority#
AuthorityAn HTTP authority.
Host#
HostThe Host field of a request.
Metadata#
MetadataA list in a field such as Connection, Content-Encoding, or Transfer-Encoding.
Implementation Debug for ValueComponent#
impl Debug for ValueComponentOperation debug#
effect fn debug(self: &Self, formatter: &mut Formatter) -> () ! WriterError ? &mut WriterWrites the name of the variant, such as Version.
LimitKind#
pub enum LimitKindThe limit in Limits that a value exceeded. See ValueReason.LimitExceeded.
MethodBytes#
MethodBytesmaxMethodBytes: the length of a method.
TargetBytes#
TargetBytesmaxTargetBytes: the length of a request target.
NameBytes#
NameBytesmaxNameBytes: the length of a field name.
ValueBytes#
ValueBytesmaxValueBytes: the length of a field value or a reason phrase.
Fields#
FieldsmaxFields: the number of fields.
FieldBytes#
FieldBytesmaxFieldBytes: the total length of all names and values.
OwnedBytes#
OwnedBytesmaxOwnedBytes: the memory for a copy.
UniqueField#
UniqueFieldA field must occur at most one time, but it occurred more times.
Implementation Debug for LimitKind#
impl Debug for LimitKindOperation debug#
effect fn debug(self: &Self, formatter: &mut Formatter) -> () ! WriterError ? &mut WriterWrites the name of the variant, such as MethodBytes.
ValueReason#
pub union ValueReasonThe rule that failed. See ValueError.reason.
InvalidToken#
InvalidTokenA token, such as a method or a field name, is empty or has a byte that is not allowed in a token.
InvalidValueByte#
InvalidValueByteA value has a byte that is not allowed, such as CR, LF, or NUL.
UnsupportedVersion#
UnsupportedVersionA version is not HTTP/1.0 or HTTP/1.1.
InvalidStatus#
InvalidStatusA response code is outside 100 through 599.
InvalidTarget#
InvalidTargetA request target has invalid syntax.
InvalidAuthority#
InvalidAuthorityAn HTTP authority has invalid syntax.
InvalidPort#
InvalidPortA port is absent, empty, nonnumeric, or outside its accepted range.
MethodTargetMismatch#
MethodTargetMismatchThe target form does not fit the method. For example, CONNECT needs host:port, and only
OPTIONS can use *.
MissingHost#
MissingHostHTTP/1.1 has no Host field.
DuplicateHost#
DuplicateHostMore than one Host field is present.
LimitExceeded#
LimitExceededA value exceeded a limit in Limits.
Field limit#
pub limit: LimitKindThe limit that was exceeded.
Field allowed#
pub allowed: usizeThe value of the limit.
Field attempted#
pub attempted: usizeThe size that was found.
SizeOverflow#
SizeOverflowA size calculation overflowed usize.
OutputTooSmall#
OutputTooSmallThe output buffer is too small. Nothing was written.
Field required#
pub required: usizeThe number of bytes that the output needs.
Field available#
pub available: usizeThe length of the buffer that you gave.
Implementation Copy for ValueReason#
impl Copy for ValueReasonImplementation Debug for ValueReason#
impl Debug for ValueReasonOperation debug#
effect fn debug(self: &Self, formatter: &mut Formatter) -> () ! WriterError ? &mut WriterWrites the name of the variant and its fields, such as InvalidToken.
ValueError#
pub struct ValueErrorThe error from checking an HTTP value. It tells which rule failed, and where.
Details#
reason gives the rule, component the part of the value, and fieldIndex and offset the
position.
Field reason#
pub reason: ValueReasonThe rule that failed.
Field component#
pub component: ValueComponentThe part that failed.
Field fieldIndex#
pub fieldIndex: Option<usize>The position of the field in its list, from 0, when the error is in a field.
Field offset#
pub offset: usizeThe byte offset in the part where the rule failed.
Implementation Debug for ValueError#
impl Debug for ValueErrorOperation debug#
effect fn debug(self: &Self, formatter: &mut Formatter) -> () ! WriterError ? &mut WriterWrites the fields, as ValueError { reason: ..., component: ..., ... }.
Version#
pub enum VersionAn HTTP version that this module supports.
Http10#
Http10HTTP/1.0.
Http11#
Http11HTTP/1.1.
Implementation Debug for Version#
impl Debug for VersionOperation debug#
effect fn debug(self: &Self, formatter: &mut Formatter) -> () ! WriterError ? &mut WriterWrites the name of the variant, such as Http10.
Implementation Version#
impl VersionAssociated function parse#
pub fn parse(text: string) -> Result<Version, ValueError>Parses exactly HTTP/1.0 or HTTP/1.1.
Method format#
pub fn format(self: &Self) -> string<'static>Returns HTTP/1.0 or HTTP/1.1.
Method#
pub struct Method<'text>An HTTP method, such as GET. It keeps its exact spelling, and is compared with case.
Details#
Any valid token is a method, so get and GET are different methods. It borrows its text. The
make and parse functions check the token.
Implementation Copy for Method<'text>#
impl<'text> Copy for Method<'text>Implementation Method<'text>#
impl<'text> Method<'text>Associated function parse#
pub fn parse(text: string<'text>, maxBytes: usize) -> Result<Method<'text>, ValueError>Checks that text is a token of at most maxBytes bytes, and returns it as a method.
Method format#
pub fn format(self: &Self) -> string<'text>Returns the method text, spelled as given.
Method equals#
pub fn equals(self: &Self, other: &Method) -> boolReturns true if the two methods have the same spelling. Case matters.
Associated function get#
pub fn get() -> Method<'static>Returns the standard GET method value.
Associated function head#
pub fn head() -> Method<'static>Returns the standard HEAD method value.
Associated function post#
pub fn post() -> Method<'static>Returns the standard POST method value.
Associated function put#
pub fn put() -> Method<'static>Returns the standard PUT method value.
Associated function delete#
pub fn delete() -> Method<'static>Returns the standard DELETE method value.
Associated function connect#
pub fn connect() -> Method<'static>Returns the standard CONNECT method value.
Associated function options#
pub fn options() -> Method<'static>Returns the standard OPTIONS method value.
Associated function trace#
pub fn trace() -> Method<'static>Returns the standard TRACE method value.
Associated function patch#
pub fn patch() -> Method<'static>Returns the standard PATCH method value.
StatusClass#
pub enum StatusClassThe class of a status code, from its first digit.
Informational#
Informational1xx informational.
Successful#
Successful2xx successful.
Redirection#
Redirection3xx redirection.
ClientError#
ClientError4xx client error.
ServerError#
ServerError5xx server error.
Status#
pub struct StatusAn HTTP status code from 100 to 599. Codes without a name, such as 299, are kept.
Implementation Copy for Status#
impl Copy for StatusImplementation Debug for Status#
impl Debug for StatusOperation debug#
effect fn debug(self: &Self, formatter: &mut Formatter) -> () ! WriterError ? &mut WriterWrites the code, as Status { code: 404 }.
Implementation Status#
impl StatusAssociated function fromCode#
pub fn fromCode(code: u16) -> Result<Status, ValueError>Returns the status for code, or InvalidStatus if code is not from 100 to 599.
Method code#
pub fn code(self: &Self) -> u16Returns the code, such as 404.
Method class#
pub fn class(self: &Self) -> StatusClassReturns the class, from the first digit of the code.
Header#
pub struct Header<'value>An HTTP header field. It borrows its name and value, and keeps their exact bytes.
Gotchas#
Header.make takes the value without the spaces around it on the wire. It rejects CR, LF,
NUL, DEL, other control bytes, and leading or trailing spaces or tabs.
Implementation Copy for Header<'value>#
impl<'value> Copy for Header<'value>Implementation Header<'value>#
impl<'value> Header<'value>Associated function make#
pub fn make(
name: string<'value>,
value: &'value [u8],
limits: Limits,
) -> Result<Header<'value>, ValueError>Checks a field and returns it.
name must be a token. value is the value without the spaces around it on the wire.
Errors#
InvalidTokenifnameis not valid.InvalidValueByteifvaluehas a control byte, or starts or ends with a space or a tab.LimitExceededifnameorvalueis too long forlimits.
Method name#
pub fn name(self: &Self) -> string<'value>Returns the field name, spelled as given.
Method value#
pub fn value(self: &Self) -> &'value [u8]Returns the field value bytes.
RequestHead#
pub struct RequestHead<'value>A checked request line and header fields, without a body. It borrows its parts.
Implementation Copy for RequestHead<'value>#
impl<'value> Copy for RequestHead<'value>Implementation RequestHead<'value>#
impl<'value> RequestHead<'value>Associated function make#
pub fn make(
version: Version,
method: Method<'value>,
target: RequestTarget<'value>,
headers: Headers<'value>,
) -> Result<RequestHead<'value>, ValueError>Checks the parts of a request head and returns it.
Errors#
MethodTargetMismatchif the target form does not fit the method.MissingHostorDuplicateHostif an HTTP/1.1 request has noHostfield, or more than one.
Method version#
pub fn version(self: &Self) -> VersionReturns the request version.
Method method#
pub fn method(self: &Self) -> Method<'value>Returns the method.
Method target#
pub fn target(self: &Self) -> RequestTarget<'value>Returns the request target.
Method headers#
pub fn headers(self: &Self) -> Headers<'value>Returns the header fields, in order.
Method copy#
pub effect fn copy(
self: &Self,
limits: Limits,
) -> Result<OwnedRequestHead, ValueError> ! OutOfMemoryError ? &mut AllocatorCopies the head into new memory, so that it does not borrow its input.
Errors#
LimitExceededif the head exceedslimits. Nothing is allocated.OutOfMemoryErrorif theAllocatorfails.
OwnedRequestHead#
pub struct OwnedRequestHeadA request head that owns its memory. Get a RequestHead from it with
OwnedRequestHead.view.
Implementation OwnedRequestHead#
impl OwnedRequestHeadMethod view#
pub fn view<'value>(self: &'value Self) -> RequestHead<'value>Returns the head as a RequestHead that borrows this value.
ResponseHead#
pub struct ResponseHead<'value>A checked status line and header fields, without a body. It borrows its parts.
Implementation ResponseHead<'value>#
impl<'value> ResponseHead<'value>Associated function make#
pub fn make(
version: Version,
status: Status,
reason: Option<&'value [u8]>,
headers: Headers<'value>,
limits: Limits,
) -> Result<ResponseHead<'value>, ValueError>Checks the parts of a response head and returns it.
reason is the optional text after the status code, such as Not Found.
Errors#
InvalidValueByteifreasonhas a control byte.LimitExceededifreasonis longer thanmaxValueBytes.
Method version#
pub fn version(self: &Self) -> VersionReturns the response version.
Method status#
pub fn status(self: &Self) -> StatusReturns the status.
Method reason#
pub fn reason(self: &Self) -> Option<&'value [u8]>Returns the reason phrase, if there is one.
Method headers#
pub fn headers(self: &Self) -> Headers<'value>Returns the header fields, in order.
Method copy#
pub effect fn copy(
self: &Self,
limits: Limits,
) -> Result<OwnedResponseHead, ValueError> ! OutOfMemoryError ? &mut AllocatorCopies the head into new memory, so that it does not borrow its input.
Errors#
LimitExceededif the head exceedslimits. Nothing is allocated.OutOfMemoryErrorif theAllocatorfails.
Method copyMatchingHeaders#
pub effect fn copyMatchingHeaders(
self: &Self,
name: string<'value>,
limits: Limits,
) -> Result<OwnedResponseHead, ValueError> ! OutOfMemoryError ? &mut AllocatorCopies the status, the reason, and only the fields named name, into new memory.
Details#
Names are compared without case. Repeated fields stay separate, in their order. limits
applies to the copied parts only.
OwnedResponseHead#
pub struct OwnedResponseHeadA response head that owns its memory. Get a ResponseHead from it with
OwnedResponseHead.view.
Implementation Debug for OwnedResponseHead#
impl Debug for OwnedResponseHeadOperation debug#
effect fn debug(self: &Self, formatter: &mut Formatter) -> () ! WriterError ? &mut WriterWrites the version and the status, as OwnedResponseHead { version: Http11, status: Status { code: 407 } }. It leaves out the reason phrase and the headers.
Implementation OwnedResponseHead#
impl OwnedResponseHeadMethod view#
pub fn view<'value>(self: &'value Self) -> ResponseHead<'value>Returns the head as a ResponseHead that borrows this value.
Category: HTTP.
Profiles: aarch64-apple-darwin, aarch64-unknown-linux-gnu, aarch64-unknown-linux-gnu-no-libc, x86_64-unknown-linux-gnu, x86_64-unknown-linux-gnu-no-libc, wasm32-unknown-unknown, wasm32-wasip1, wasm32-wasip2.