Skip to content

Payload

[Source]

This class represent a single HTTP message, which can be either a request or a response.

Transfer Modes

HTTP provides two ways to encode the transmission of a message 'body', of any size. This package supports both of them:

  1. StreamTransfer. This is used for payload bodies where the exact length is known in advance, including most transfers of files. It is selected by calling Payload.set_length with an integer bytecount. Appication buffer sizes determine how much data is fed to the TCP connection at once, but the total amount must match this size.

  2. ChunkedTransfer. This is used when the payload length can not be known in advance, but can be large. It is selected by calling Payload.set_length with a parameter of None. On the TCP link this mode can be detected because there is no Content-Length header at all, being replaced by the Transfer-Encoding: chunked header. In addition, the message body is separated into chunks, each with its own bytecount. As with StreamTransfer mode, transmission can be spread out over time with the difference that it is the original data source that determines the chunk size.

If Payload.set_length is never called at all, a variation on StreamTransfer called OneshotTransfer is used. In this case, all of the message body is placed into the message at once, using Payload.add_chunk calls. The size will be determined when the message is submitted for transmission. Care must be taken not to consume too much memory, especially on a server where there can be multiple messages in transit at once.

The type of transfer being used by an incoming message can be determined from its transfer_mode field, which will be one of the TransferMode types.

Sequence

For example, to send a message of possibly large size:

  1. Create the message with a call to Payload.request or Payload.response.
  2. Set the session field of the message.
  3. Call Payload.set_length to indicate the length of the body.
  4. Add any additional headers that may be required, such as Content-type.
  5. Submit the message for transmission by calling the either the HTTPSession.apply method (in servers) or the HTTPCLient.apply method in clients.
  6. Wait for the send_body notification.
  7. Make any number of calls to Payload.send_chunk.
  8. Call Payload.finish.

To send a message of small, reasonable size (say, under 20KB), this simplified method can be used instead:

  1. Create the message with a call to Payload.request or Payload.response.
  2. Set the session field of the message.
  3. Add any additional headers that may be required, such as Content-type.
  4. Call add_chunk one or more times to add body data.
  5. Submit the message for transmission by calling the either the HTTPSession.apply method (in servers) or the HTTPClient.apply method in clients.
class trn Payload

Constructors

request

[Source]

Create an HTTP request message.

new iso request(
  method': String val = "GET",
  url': URL val = reference)
: Payload iso^

Parameters

  • method': String val = "GET"
  • url': URL val = reference

Returns


response

[Source]

Create an HTTP response message.

new iso response(
  status': Status val = reference)
: Payload iso^

Parameters

  • status': Status val = reference

Returns


Public fields

var proto: String val

[Source]

The HTTP protocol string


var status: U16 val

[Source]

Internal representation of the response Status.

Will be 0 for HTTP requests.


var method: String val

[Source]

The HTTP Method.

GET, POST, DELETE, OPTIONS, ...

For HTTP responses this will be the status string, for a 200 status this will be 200 OK, for 404, 404 Not Found etc..


var url: URL val

[Source]

The HTTP request URL. It will be used for the HTTP path and the Host header. The user and password fields are ignored.

For HTTP responses this will be an empty URL.


var transfer_mode: (ChunkedTransfer val | StreamTransfer val | OneshotTransfer val)

[Source]

Determines the transfer mode of this message.

In case of outgoing requests or responses, use set_length to control the transfer mode.

In case of incoming requests, this field determines how the request is transferred.


var session: (HTTPSession tag | None val)

[Source]


var username: String val

[Source]

The username extracted from an Authentication header of an HTTP request received via HTTPServer.

This is not used and not sent using HTTPClient, use update to set an Authentication header instead.


var password: String val

[Source]

The password extracted from an Authentication header of an HTTP request received via HTTPServer.

This is not used and not sent using HTTPClient, use update to set an Authentication header instead.


Public Functions

apply

[Source]

Get a header.

fun box apply(
  key: String val)
: String val ?

Parameters

Returns


is_safe

[Source]

A request method is "safe" if it does not modify state in the resource. These methods can be guaranteed not to have any body data. Return true for a safe request method, false otherwise.

fun box is_safe()
: Bool val

Returns


body

[Source]

Get the body in OneshotTransfer mode. In the other modes it raises an error.

fun box body()
: this->Array[(String val | Array[U8 val] val)] ref ?

Returns


set_length

[Source]

Set the body length when known in advance. This determines the transfer mode that will be used. A parameter of 'None' will use Chunked Transfer Encoding. A numeric value will use Streamed transfer. Not calling this function at all will use Oneshot transfer.

fun ref set_length(
  bytecount: (USize val | None val))
: None val

Parameters

Returns


update

[Source]

Set any header. If we've already received the header, append the value as a comma separated list, as per RFC 2616 section 4.2.

fun ref update(
  key: String val,
  value: String val)
: Payload ref^

Parameters

Returns


headers

[Source]

Get all the headers.

fun box headers()
: this->HashMap[String val, String val, HashEq[String val] val] ref

Returns


body_size

[Source]

Get the total intended size of the body. ServerConnection accumulates actual size transferred for logging.

fun box body_size()
: (USize val | None val)

Returns


add_chunk

[Source]

This is how application code adds data to the body in OneshotTransfer mode. For large bodies, call set_length and use send_chunk instead.

fun ref add_chunk(
  data: (String val | Array[U8 val] val))
: Payload ref^

Parameters

Returns


send_chunk

[Source]

This is how application code sends body data in StreamTransfer and ChunkedTransfer modes. For smaller body lengths, add_chunk in Oneshot mode can be used instead.

fun box send_chunk(
  data: (String val | Array[U8 val] val))
: None val

Parameters

Returns


finish

[Source]

Mark the end of body transmission. This does not do anything, and is unnecessary, in Oneshot mode.

fun val finish()
: None val

Returns


respond

[Source]

Start sending a response from the server to the client.

fun val respond(
  response': Payload trn)
: None val

Parameters

Returns


has_body

[Source]

Determines whether a message has a body portion.

fun box has_body()
: Bool val

Returns