Skip to content

Http

Spice
import "std/net/http";

HttpHeader struct

A single header field

Fields

Name Type Description
name String Field name, in the casing it was given in
value String Field value

Constructors

ctor

Spice
public p HttpHeader.ctor(string name, string value)

Constructs a header field

Parameters

Name Type Description
name string Field name
value string Field value

ctor

Spice
public p HttpHeader.ctor(const HttpHeader& original)

Copy-constructs a header field, deep-copying both of its strings

Parameters

Name Type Description
original const HttpHeader&

HttpHeaders struct

Header field list of a request or a response.

Fields keep the order in which they were added and their names keep the case they were given in, while all lookups are case-insensitive, as required by RFC 9110 section 5.1. A name may appear more than once - use add for that and set when a field is meant to be unique.

Fields

Name Type Description
entries Vector<HttpHeader>

Methods

indexOf

Spice
public f<long> HttpHeaders.indexOf(string name)

Returns the index of the first field with the given name

Parameters

Name Type Description
name string Field name, compared case-insensitively

Returns: long — Index of the field, or -1 if there is no such field

contains

Spice
public f<bool> HttpHeaders.contains(string name)

Checks whether a field with the given name is present

Parameters

Name Type Description
name string Field name, compared case-insensitively

Returns: bool — true if the field is present

get

Spice
public f<String> HttpHeaders.get(string name)

Returns the value of the first field with the given name

Parameters

Name Type Description
name string Field name, compared case-insensitively

Returns: String — Field value, or an empty string if the field is not present

getOrDefault

Spice
public f<String> HttpHeaders.getOrDefault(string name, string fallback)

Returns the value of the first field with the given name, or the given fallback if the field is not present

Parameters

Name Type Description
name string Field name, compared case-insensitively
fallback string Value to return if the field is not present

Returns: String — Field value or fallback

set

Spice
public p HttpHeaders.set(string name, string value)

Sets a field, replacing the value of the first field with that name if it already exists

Parameters

Name Type Description
name string Field name
value string Field value

set

Spice
public p HttpHeaders.set(string name, const String& value)

Sets a field, replacing the value of the first field with that name if it already exists

Parameters

Name Type Description
name string Field name
value const String& Field value

add

Spice
public p HttpHeaders.add(string name, string value)

Appends a field, keeping any field with the same name that is already present. This is what repeatable fields such as Set-Cookie need.

Parameters

Name Type Description
name string Field name
value string Field value

remove

Spice
public p HttpHeaders.remove(string name)

Removes all fields with the given name

Parameters

Name Type Description
name string Field name, compared case-insensitively

getAt

Spice
public f<HttpHeader&> HttpHeaders.getAt(unsigned long index)

Returns the field at the given index, in insertion order

Parameters

Name Type Description
index unsigned long Index of the field

Returns: HttpHeader& — Name/value pair of the field

getSize

Spice
public f<unsigned long> HttpHeaders.getSize()

Returns the number of fields

Returns: unsigned long

isEmpty

Spice
public f<bool> HttpHeaders.isEmpty()

Checks if there is no field at all

Returns: bool

clear

Spice
public p HttpHeaders.clear()

Drops all fields

serialize

Spice
public f<String> HttpHeaders.serialize()

Serializes all fields into the wire format, including the terminating CRLF of the last field but without the empty line that ends the header block

Returns: String — Serialized header block

getContentLength

Spice
public f<long> HttpHeaders.getContentLength()

Returns the body length announced by the Content-Length field

Returns: long — Announced body length, or -1 if the field is absent or malformed

isChunked

Spice
public f<bool> HttpHeaders.isChunked()

Checks whether the message body is chunked, i.e. whether the Transfer-Encoding field ends in "chunked" (RFC 9112 section 6.1)

Returns: bool

Url struct

An absolute HTTP(S) URL, split into the parts a client needs to open a connection and to build a request line from

Fields

Name Type Description
scheme String "http" or "https", always lower case
host String Host name or IPv4 address, without the port
port unsigned short Port, defaulted from the scheme if the URL carries none
path String Path, always starting with a '/'
query String Query string, without the leading '?'
fragment String Fragment, without the leading '#'

Constructors

ctor

Spice
public p Url.ctor()

Constructs an empty http URL that points at the root path of no host yet

Methods

getRequestTarget

Spice
public f<String> Url.getRequestTarget()

Returns the request target of this URL, i.e. the path together with the query string. This is the middle part of the request line of an origin-form request.

Returns: String — Request target, e.g. "/a/b?x=1"

getAuthority

Spice
public f<String> Url.getAuthority()

Returns the authority of this URL, i.e. the host plus the port if it deviates from the default port of the scheme. This is what the Host header field carries.

Returns: String — Authority, e.g. "example.com:8080"

toString

Spice
public f<String> Url.toString()

Reassembles the URL into its textual form

Returns: String

HttpRequest struct

A request message: request line, header fields and body

Fields

Name Type Description
method HttpMethod
target String Request target in origin form, e.g. "/a/b?x=1"
version String
headers HttpHeaders
body String

Constructors

ctor

Spice
public p HttpRequest.ctor(HttpMethod method = HttpMethod::GET, string target = "/")

Constructs a request with an empty header block and an empty body

Parameters

Name Type Description
method HttpMethod Request method (default: HttpMethod::GET)
target string Request target in origin form, e.g. "/a/b?x=1" (default: "/")

Methods

getPath

Spice
public f<String> HttpRequest.getPath()

Returns the path of the request target, i.e. the target without the query string

Returns: String — Path, e.g. "/a/b"

getQuery

Spice
public f<String> HttpRequest.getQuery()

Returns the query string of the request target, without the leading '?'

Returns: String — Query string, e.g. "x=1&y=2"

getQueryParam

Spice
public f<String> HttpRequest.getQueryParam(string name)

Returns the value of a query parameter, percent-decoded

Parameters

Name Type Description
name string Parameter name

Returns: String — Parameter value, or an empty string if the parameter is not present

hasQueryParam

Spice
public f<bool> HttpRequest.hasQueryParam(string name)

Checks whether the request target carries the given query parameter

Parameters

Name Type Description
name string Parameter name

Returns: bool

setBody

Spice
public p HttpRequest.setBody(const String& body, string contentType = CONTENT_TYPE_TEXT)

Sets the body of the request and the header fields that describe it

Parameters

Name Type Description
body const String& Body payload
contentType string Media type of the payload (default: CONTENT_TYPE_TEXT)

serialize

Spice
public f<String> HttpRequest.serialize()

Serializes the request into the wire format

Returns: String — Serialized request, ready to be written to a socket

HttpResponse struct

A response message: status line, header fields and body

Fields

Name Type Description
version String
statusCode unsigned short
reason String
headers HttpHeaders
body String

Constructors

ctor

Spice
public p HttpResponse.ctor(unsigned short statusCode = STATUS_OK)

Constructs a response with the reason phrase that belongs to the given status code, an empty header block and an empty body

Parameters

Name Type Description
statusCode unsigned short Status code of the response (default: STATUS_OK)

Methods

setStatus

Spice
public p HttpResponse.setStatus(unsigned short statusCode)

Sets the status code together with its default reason phrase

Parameters

Name Type Description
statusCode unsigned short Status code of the response

setBody

Spice
public p HttpResponse.setBody(const String& body, string contentType = CONTENT_TYPE_TEXT)

Sets the body of the response and the header fields that describe it

Parameters

Name Type Description
body const String& Body payload
contentType string Media type of the payload (default: CONTENT_TYPE_TEXT)

setHtmlBody

Spice
public p HttpResponse.setHtmlBody(const String& html)

Sets an HTML body, a shorthand for setBody(html, CONTENT_TYPE_HTML)

Parameters

Name Type Description
html const String& HTML payload

setJsonBody

Spice
public p HttpResponse.setJsonBody(const String& json)

Sets a JSON body, a shorthand for setBody(json, CONTENT_TYPE_JSON)

Parameters

Name Type Description
json const String& JSON payload

redirectTo

Spice
public p HttpResponse.redirectTo(string location, unsigned short statusCode = STATUS_FOUND)

Turns the response into a redirect to the given location

Parameters

Name Type Description
location string Target of the redirect
statusCode unsigned short Redirect status code to use (default: STATUS_FOUND)

isSuccess

Spice
public f<bool> HttpResponse.isSuccess()

Checks whether the status code denotes success (2xx)

Returns: bool

isRedirect

Spice
public f<bool> HttpResponse.isRedirect()

Checks whether the status code denotes a redirect (3xx)

Returns: bool

isClientError

Spice
public f<bool> HttpResponse.isClientError()

Checks whether the status code denotes a client error (4xx)

Returns: bool

isServerError

Spice
public f<bool> HttpResponse.isServerError()

Checks whether the status code denotes a server error (5xx)

Returns: bool

serialize

Spice
public f<String> HttpResponse.serialize()

Serializes the response into the wire format

Returns: String — Serialized response, ready to be written to a socket

Functions

getMethodName

Spice
public f<string> getMethodName(HttpMethod method)

Returns the wire representation of the given request method

Parameters

Name Type Description
method HttpMethod Request method

Returns: string — Method name, e.g. "GET"

parseMethodName

Spice
public f<Result<HttpMethod>> parseMethodName(const String& name)

Parses a request method from its wire representation

Parameters

Name Type Description
name const String& Method name, e.g. "GET"

Returns: Result<HttpMethod> — The parsed method, or an error if the name denotes no known method

getReasonPhrase

Spice
public f<string> getReasonPhrase(unsigned short statusCode)

Returns the reason phrase that belongs to the given status code. Unknown codes fall back to the generic phrase of their status class, so every code yields a usable status line.

Parameters

Name Type Description
statusCode unsigned short Status code, e.g. 404

Returns: string — Reason phrase, e.g. "Not Found"

urlEncode

Spice
public f<String> urlEncode(const String& input)

Percent-encodes everything in the given text that is not an unreserved URI character (RFC 3986 section 2.3), so that the result can be used as a path segment, query key or query value.

Parameters

Name Type Description
input const String& Text to encode

Returns: String — Percent-encoded text

urlDecode

Spice
public f<String> urlDecode(const String& input)

Reverses urlEncode: turns percent escapes back into their bytes and, since query strings are form-encoded, also turns '+' back into a space. Malformed escapes at the end of the input are passed through verbatim.

Parameters

Name Type Description
input const String& Percent-encoded text

Returns: String — Decoded text

equalsIgnoreCase

Spice
public f<bool> equalsIgnoreCase(string lhs, string rhs)

Compares two raw strings while ignoring the case of ASCII letters. Header field names are case-insensitive, so every lookup goes through this.

Parameters

Name Type Description
lhs string First string
rhs string Second string

Returns: bool — true if both strings are equal, ignoring case

parseUrl

Spice
public f<Result<Url>> parseUrl(const String& raw)

Parses an absolute URL such as "http://example.com:8080/a/b?x=1#top". Relative URLs are rejected, since a client cannot connect anywhere without an authority.

Parameters

Name Type Description
raw const String& URL to parse

Returns: Result<Url> — The parsed URL, or an error describing why it could not be parsed

parseRequestHead

Spice
public f<Result<HttpRequest>> parseRequestHead(const String& head)

Parses the head of a request, i.e. its request line plus its header block. The body is not part of the head and stays empty.

Parameters

Name Type Description
head const String& Head block, with or without the terminating empty line

Returns: Result<HttpRequest> — The parsed request, or an error describing why it could not be parsed

parseResponseHead

Spice
public f<Result<HttpResponse>> parseResponseHead(const String& head)

Parses the head of a response, i.e. its status line plus its header block. The body is not part of the head and stays empty.

Parameters

Name Type Description
head const String& Head block, with or without the terminating empty line

Returns: Result<HttpResponse> — The parsed response, or an error describing why it could not be parsed

parseRequest

Spice
public f<Result<HttpRequest>> parseRequest(const String& raw)

Parses a complete request message, head and body.

The body is taken as everything behind the empty line that ends the head, which makes this the right entry point for messages that are already fully in memory. Reading a message off a socket goes through the client and the server instead, since those have to know when to stop reading.

Parameters

Name Type Description
raw const String& Complete request message

Returns: Result<HttpRequest> — The parsed request, or an error describing why it could not be parsed

parseResponse

Spice
public f<Result<HttpResponse>> parseResponse(const String& raw)

Parses a complete response message, head and body.

The body is taken as everything behind the empty line that ends the head, which makes this the right entry point for messages that are already fully in memory. Reading a message off a socket goes through the client and the server instead, since those have to know when to stop reading.

Parameters

Name Type Description
raw const String& Complete response message

Returns: Result<HttpResponse> — The parsed response, or an error describing why it could not be parsed

findHeadEnd

Spice
public f<long> findHeadEnd(const String& raw)

Returns the index of the empty line that separates head and body

Parameters

Name Type Description
raw const String& Message to scan

Returns: long — Index of the CRLFCRLF sequence, or -1 if the head is not terminated yet

getFormValue

Spice
public f<String> getFormValue(const String& formData, string name)

Returns the value that belongs to the given key in a form-encoded body or query string, i.e. in a "key=value&key2=value2" sequence. Both the key and the returned value are percent-decoded.

Parameters

Name Type Description
formData const String& Form-encoded data
name string Key to look up

Returns: String — Decoded value, or an empty string if the key is not present

containsFormKey

Spice
public f<bool> containsFormKey(const String& formData, string name)

Checks whether a form-encoded body or query string carries the given key

Parameters

Name Type Description
formData const String& Form-encoded data
name string Key to look up

Returns: bool

parseFormData

Spice
public f<Vector<Pair<String, String>>> parseFormData(const String& formData)

Splits a form-encoded body or query string into its decoded key/value pairs. Keys without a '=' yield an empty value, and empty segments are skipped.

Parameters

Name Type Description
formData const String& Form-encoded data

Returns: Vector<Pair<String, String>> — Decoded key/value pairs, in the order they appear

sendRequest

Spice
public f<bool> sendRequest(Socket& socket, const HttpRequest& request)

Writes a request to the socket

Parameters

Name Type Description
socket Socket& Socket to write to
request const HttpRequest& Request to write

Returns: bool — true if the whole request reached the peer

sendResponse

Spice
public f<bool> sendResponse(Socket& socket, const HttpResponse& response)

Writes a response to the socket

Parameters

Name Type Description
socket Socket& Socket to write to
response const HttpResponse& Response to write

Returns: bool — true if the whole response reached the peer

receiveRequest

Spice
public f<Result<HttpRequest>> receiveRequest(Socket& socket, unsigned long maxSize = DEFAULT_MAX_MESSAGE_SIZE)

Reads a complete request off the socket.

The body is framed by the Content-Length field, or by the chunked transfer coding. A request that announces neither carries no body, since a server may not wait for the connection to close to find the end of a request.

Parameters

Name Type Description
socket Socket& Socket to read from
maxSize unsigned long Maximum number of bytes to accept for head and body each (default: DEFAULT_MAX_MESSAGE_SIZE)

Returns: Result<HttpRequest> — The received request, or an error describing why it could not be received

receiveResponse

Spice
public f<Result<HttpResponse>> receiveResponse(Socket& socket, bool expectBody = true, unsigned long maxSize = DEFAULT_MAX_MESSAGE_SIZE)

Reads a complete response off the socket.

The body is framed by the Content-Length field or by the chunked transfer coding. A response that announces neither runs until the peer closes the connection, as HTTP/1.0 servers do.

Parameters

Name Type Description
socket Socket& Socket to read from
expectBody bool Whether the response carries a body at all - a response to HEAD never does (default: true)
maxSize unsigned long Maximum number of bytes to accept for head and body each (default: DEFAULT_MAX_MESSAGE_SIZE)

Returns: Result<HttpResponse> — The received response, or an error describing why it could not be received

Operators

operator=

Spice
public p operator=(HttpHeader& this, const HttpHeader& original)

Deep-copy assignment, so that header fields survive being shifted around inside a vector

Parameters

Name Type Description
original const HttpHeader&

HttpMethod enum

Request method, as defined in RFC 9110 section 9

Item Value Description
GET
HEAD
POST
PUT
DELETE
CONNECT
OPTIONS
TRACE
PATCH