# Requests

> UCall for C

Request handles own immutable received bytes and can outlive their callback until a reply consumes them or the server is freed.
Each request can be replied to independently, including after the callback returns.
`ucall_server_request_path()` answers the request target without its query, still percent-encoded, beside the segment and parameter accessors, and `ucall_server_request_query()` answers the raw query after the first `?`.
`ucall_decode_percent()` decodes the `%XX` escapes of either, and `+` as a space in a query.
`ucall_server_request_fields_count()` and `ucall_server_request_field()` walk the header fields in arrival order, names lowercased and values trimmed, beside the by-name `ucall_server_request_header()`; responses offer the same pair.
`ucall_server_request_peer()` reports which configured interface a request arrived on, the peer's authenticated Noise static key, zero on plaintext interfaces, and its `ucall_peer_address_t`: IPv4, IPv6 with its scope, or AF_UNIX.
Multipart bodies are read part by part through `ucall_server_request_parts_count()` and `ucall_server_request_part()`.
A reply to a disconnected request reports connection closure and consumes the handle.
All byte views carry an explicit length, including empty and binary values.

`#include <ucall/types.h>`

`#include <ucall/server.h>`

## ucall_byte_t

One byte of raw storage shared by views and cryptographic keys.

```c
typedef uint8_t ucall_byte_t;
```

## ucall_bytes_view_t

A borrowed run of bytes; text is bytes that happen to decode.

```c
struct ucall_bytes_view_t
```

Empty is {NULL, 0}. Length never requests a null-terminator lookup.

- `data` `ucall_byte_t const *`: First byte of the run.
- `length` `size_t`: Bytes the run spans, with no terminator assumed or written.

## ucall_received_http_request_t

Opaque handle for a single Remote Procedure Call on the __server__ side.

```c
typedef struct ucall_received_http_request_handle_t * ucall_received_http_request_t;
```

## ucall_address_family_t

The family of a peer's socket address.

```c
enum ucall_address_family_t
```

- `ucall_address_family_unknown_k` = `0`: No address was read for this peer.
- `ucall_address_family_ipv4_k` = `1`: IPv4, in the first 4 bytes.
- `ucall_address_family_ipv6_k` = `2`: IPv6, in all 16 bytes, with its scope.
- `ucall_address_family_unix_k` = `3`: A local AF_UNIX peer, with no address bytes.

## ucall_peer_address_t

A peer's socket address: IPv4 in the first 4 `bytes`, IPv6 in all 16, both in network order, the port in host order and the IPv6 scope; AF_UNIX peers carry only the family.

```c
struct ucall_peer_address_t
```

- `bytes` `ucall_byte_t`: The address in network order: IPv4 in the first 4 bytes, IPv6 in all 16.
- `scope` `uint32_t`: The IPv6 scope, 0 otherwise.
- `port` `uint16_t`: The port in host order.
- `family` `uint8_t`: A `[ucall_address_family_t](#ucall_address_family_t)`, one byte wide.
- `reserved` `uint8_t`: Zero, keeping the record at 24 bytes.

## ucall_http_status_t

HTTP status codes for server responses and client results.

```c
typedef uint32_t ucall_http_status_t;
```

Numeric codes also represent responses absent from the named constants below. For library outcomes, use `[ucall_status_t](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_t)` instead.

- `ucall_http_status_ok_k` = `200`: Request succeeded.
- `ucall_http_status_created_k` = `201`: Resource created.
- `ucall_http_status_no_content_k` = `204`: Success with an empty body.
- `ucall_http_status_partial_content_k` = `206`: Success with the requested `Range` of the body.
- `ucall_http_status_moved_permanently_k` = `301`: Resource has a new permanent URL.
- `ucall_http_status_found_k` = `302`: Resource is temporarily at a different URL.
- `ucall_http_status_not_modified_k` = `304`: Cached copy is still fresh.
- `ucall_http_status_bad_request_k` = `400`: Malformed request syntax.
- `ucall_http_status_unauthorized_k` = `401`: Authentication required or failed.
- `ucall_http_status_forbidden_k` = `403`: Authenticated, but not permitted.
- `ucall_http_status_not_found_k` = `404`: No endpoint matches the request path.
- `ucall_http_status_method_not_allowed_k` = `405`: Endpoint exists, but not for this verb.
- `ucall_http_status_timeout_k` = `408`: Client took too long to send the request.
- `ucall_http_status_conflict_k` = `409`: Request conflicts with current resource state.
- `ucall_http_status_precondition_failed_k` = `412`: A request condition does not match the current resource.
- `ucall_http_status_payload_too_large_k` = `413`: Request body is too large.
- `ucall_http_status_range_not_satisfiable_k` = `416`: A requested byte range starts or ends past the end of the resource.
- `ucall_http_status_too_many_requests_k` = `429`: Rate limit exceeded.
- `ucall_http_status_internal_error_k` = `500`: Unhandled failure inside an endpoint.
- `ucall_http_status_not_implemented_k` = `501`: Verb or feature not supported.
- `ucall_http_status_bad_gateway_k` = `502`: An upstream answered with something no HTTP peer would send.
- `ucall_http_status_service_unavailable_k` = `503`: Server is overloaded or shutting down.
- `ucall_http_status_gateway_timeout_k` = `504`: Upstream dependency timed out.
- `ucall_http_status_version_not_supported_k` = `505`: Request names an HTTP version the server does not speak.

## ucall_percent_mode_t

Which part of a URL `ucall_decode_percent()` reads, as only a query spells a space '+'.

```c
enum ucall_percent_mode_t
```

- `ucall_percent_path_k` = `0`: A path, where '+' stays itself.
- `ucall_percent_query_k` = `1`: A query, where '+' is a space.

## ucall_received_http_request_callback_t

Callback type for handling incoming requests on the server side.

```c
typedef void(*) ucall_received_http_request_callback_t(ucall_received_http_request_t request, void *context);
```

## ucall_reply_part_kind_t

What one part of a reply body holds.

```c
enum ucall_reply_part_kind_t
```

- `ucall_reply_part_bytes_k` = `0`: `data.bytes`, copied before the call returns.
- `ucall_reply_part_file_k` = `1`: `data.file`, a range of a descriptor the event loop reads unbuffered and sends without copying where the kernel allows.
- `ucall_reply_part_path_k` = `2`: `data.path`, a range of a file the event loop opens beneath a registered directory.

## ucall_reply_part_t

One part of a reply body: bytes in memory, or a byte range of a file, which the event loop reads after the call returns.

```c
struct ucall_reply_part_t
```

- `kind` `ucall_reply_part_kind_t`: Which member of `data` the part uses.
- `data` `union ucall_reply_part_t::@263277132012061031073105306216242353260173061112`

## ucall_decode_percent

Decodes the XX escapes of `encoded`, and '+' as a space in query mode.

```c
ucall_status_t ucall_decode_percent(
    ucall_bytes_view_t encoded,
    ucall_byte_t *decoded,
    size_t *length,
    ucall_percent_mode_t mode);
```

- `encoded` (in): A path or a query value, as a request lends it.
- `decoded` (out): At least `encoded.length` bytes; may alias `encoded.data`.
- `length` (out): The decoded length.
- `mode` (in): Whether a '+' is itself or a space.

Notes: __Thread-safe__.

Statuses: - [`ucall_status_invalid_argument_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_invalid_argument_k) A '' without two hexadecimal digits, an unknown `mode`, or a missing `length`, `decoded` or `encoded.data` while `encoded.length` is not zero.

## ucall_server_request_verb

Returns the HTTP method of the received request.

```c
ucall_verb_t ucall_server_request_verb(
    ucall_server_t server,
    ucall_received_http_request_t request);
```

Never [`ucall_verb_any_k`](https://www.unum.cloud/docs/ucall/c/serving.md#ucall_verb_any_k).

Needed by endpoints registered with [`ucall_verb_any_k`](https://www.unum.cloud/docs/ucall/c/serving.md#ucall_verb_any_k), which match every method.

- `server` (in): Server handle from `ucall_server_init()`.
- `request` (in): The received request inside the `[ucall_received_http_request_callback_t](#ucall_received_http_request_callback_t)`.

Notes: __Thread-safe__ across requests. Two threads must not operate on the __same__ `request` concurrently.

## ucall_server_request_path

Extracts the path of the received request: its target without the query.

```c
void ucall_server_request_path(ucall_server_request_path_t *arguments);
```

The path stays as the peer sent it, percent-encoded. Routing and the segment accessors take it exactly: `/` holds no segments, every `/` after the first starts one, so `//a` holds an empty segment before `a` and a trailing slash adds an empty last one.

- `server`: The server this call operates on.
- `outcome`: Output for the outcome.
- `request`: The received request inside the `[ucall_received_http_request_callback_t](#ucall_received_http_request_callback_t)`.
- `path`: Output for a borrowed view of the path.

Notes: __Thread-safe__ across requests, though two threads must not use one `request` at once.

Statuses: - [`ucall_status_uninitialized_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_uninitialized_k) The `server` is `NULL`.
- [`ucall_status_invalid_argument_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_invalid_argument_k) The `request` or the `path` output is `NULL`.

## ucall_server_request_query

Extracts the query of the received request: its target after the first ``?

```c
void ucall_server_request_query(
    ucall_server_request_query_t *arguments);
```

, as sent and percent-encoded, or empty when it has none.

- `server`: The server this call operates on.
- `outcome`: The verb's status, listed on the verb.
- `request`: The received request inside the `[ucall_received_http_request_callback_t](#ucall_received_http_request_callback_t)`.
- `query`: Output for a borrowed view of the query.

Notes: __Thread-safe__ across requests, though two threads must not use one `request` at once.

Statuses: - [`ucall_status_uninitialized_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_uninitialized_k) The `server` is `NULL`.
- [`ucall_status_invalid_argument_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_invalid_argument_k) The `request` or the `query` output is `NULL`.

## ucall_server_request_path_segments_count

Returns the number of path components of the received request.

```c
size_t ucall_server_request_path_segments_count(
    ucall_server_t server,
    ucall_received_http_request_t request);
```

- `server` (in): Server handle from `ucall_server_init()`.
- `request` (in): The received request inside the `[ucall_received_http_request_callback_t](#ucall_received_http_request_callback_t)`.

Notes: __Thread-safe__ across requests. Two threads must not operate on the __same__ `request` concurrently.

## ucall_server_request_path_segment

Extracts an indexed path component from the received request.

```c
void ucall_server_request_path_segment(
    ucall_server_request_path_segment_t *arguments);
```

Useful for RESTful APIs with path parameters, e.g., "/users/{id}/posts/{postId}".

- `server`: The server this call operates on.
- `outcome`: The verb's status, listed on the verb.
- `request`: The received request inside the `[ucall_received_http_request_callback_t](#ucall_received_http_request_callback_t)`.
- `index`: The zero-based index of the path component to extract.
- `segment`: Output for a borrowed view of the path component.

Notes: __Thread-safe__ across requests, though two threads must not use one `request` at once.

Statuses: - [`ucall_status_uninitialized_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_uninitialized_k) The `server` is `NULL`.
- [`ucall_status_invalid_argument_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_invalid_argument_k) The `request` or the `segment` output is `NULL`.
- [`ucall_status_not_found_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_not_found_k) The `index` is past the last segment.

## ucall_server_request_path_parameter

Extracts a named path parameter captured by the endpoint's URI template.

```c
void ucall_server_request_path_parameter(
    ucall_server_request_path_parameter_t *arguments);
```

For an endpoint registered as `"/users/{id}/posts/{post_id}"` receiving `"/users/7/posts/3"`, a `name` of `"id"` yields `"7"`. A greedy wildcard `{*path}` captures the remaining segments including separators.

- `server`: The server this call operates on.
- `outcome`: The verb's status, listed on the verb.
- `request`: The received request inside the `[ucall_received_http_request_callback_t](#ucall_received_http_request_callback_t)`.
- `name`: The __case-sensitive__ placeholder name, without braces.
- `value`: Output for a borrowed view of the captured value.

Notes: __Thread-safe__ across requests, though two threads must not use one `request` at once.

Statuses: - [`ucall_status_uninitialized_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_uninitialized_k) The `server` is `NULL`.
- [`ucall_status_invalid_argument_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_invalid_argument_k) The `request` or the `value` output is `NULL`, or the placeholder name is not a valid view.
- [`ucall_status_not_found_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_not_found_k) The template has no such placeholder, or the path ends before it.

## ucall_server_request_query_parameter

Extracts the named string parameter from the received request.

```c
void ucall_server_request_query_parameter(
    ucall_server_request_query_parameter_t *arguments);
```

Unlike HTTP headers, query parameters are case-sensitive by specification, but server-dependent in practice. An example would be ASP.NET / IIS, which treats "?id" and "?ID" as same parameters.

- `server`: The server this call operates on.
- `outcome`: The verb's status, listed on the verb.
- `request`: The received request inside the `[ucall_received_http_request_callback_t](#ucall_received_http_request_callback_t)`.
- `name`: The __case-sensitive__ name of the parameter to extract.
- `value`: Output for a borrowed view of the parameter value.

Notes: __Thread-safe__ across requests, though two threads must not use one `request` at once.

Statuses: - [`ucall_status_uninitialized_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_uninitialized_k) The `server` is `NULL`.
- [`ucall_status_invalid_argument_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_invalid_argument_k) The `request` or the `value` output is `NULL`, or the parameter name is not a valid view.
- [`ucall_status_not_found_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_not_found_k) The query has no such parameter.

## ucall_server_request_header

Extracts the named string header from the received request.

```c
void ucall_server_request_header(
    ucall_server_request_header_t *arguments);
```

- `server`: The server this call operates on.
- `outcome`: The verb's status, listed on the verb.
- `request`: The received request inside the `[ucall_received_http_request_callback_t](#ucall_received_http_request_callback_t)`.
- `name`: The name of the HTTP header to extract (case-insensitive).
- `value`: Output for a borrowed view of the header value.

Notes: __Thread-safe__ across requests, though two threads must not use one `request` at once.

Statuses: - [`ucall_status_uninitialized_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_uninitialized_k) The `server` is `NULL`.
- [`ucall_status_invalid_argument_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_invalid_argument_k) The `request` or the `value` output is `NULL`, or the header name is not an HTTP token.
- [`ucall_status_not_found_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_not_found_k) The request has no such header.

## ucall_server_request_fields_count

Counts the header field lines of the received request, repeated names included.

```c
void ucall_server_request_fields_count(
    ucall_server_request_fields_count_t *arguments);
```

- `server`: The server this call operates on.
- `outcome`: The verb's status, listed on the verb.
- `request`: The received request inside the `[ucall_received_http_request_callback_t](#ucall_received_http_request_callback_t)`.
- `count`: Output for the number of header field lines, in arrival order.

Notes: __Thread-safe__ across requests, though two threads must not use one `request` at once.

Statuses: - [`ucall_status_uninitialized_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_uninitialized_k) The `server` is `NULL`.
- [`ucall_status_invalid_argument_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_invalid_argument_k) The `request` or the `count` output is `NULL`.

## ucall_server_request_field

Extracts one header field line of the received request by its arrival order, as a proxy forwards a head whole.

```c
void ucall_server_request_field(
    ucall_server_request_field_t *arguments);
```

- `server`: The server this call operates on.
- `outcome`: The verb's status, listed on the verb.
- `request`: The received request inside the `[ucall_received_http_request_callback_t](#ucall_received_http_request_callback_t)`.
- `index`: Which field line, below `ucall_server_request_fields_count()`.
- `name`: Output for a borrowed view of its name, lowercased as the parser keeps every field name.
- `value`: Output for a borrowed view of its value, without surrounding whitespace.

Notes: __Thread-safe__ across requests, though two threads must not use one `request` at once.

Statuses: - [`ucall_status_uninitialized_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_uninitialized_k) The `server` is `NULL`.
- [`ucall_status_invalid_argument_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_invalid_argument_k) The `request`, the `name` or the `value` output is `NULL`.
- [`ucall_status_not_found_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_not_found_k) The `index` is past the last field line.

## ucall_server_request_peer

Reports which interface a request arrived on, which authenticated key sent it, and from which socket address.

```c
void ucall_server_request_peer(ucall_server_request_peer_t *arguments);
```

All three are copied when the request is received, so they remain readable after its connection closes, as batched requests often outlive theirs.

- `server`: The server this call operates on.
- `outcome`: Output for the outcome.
- `request`: A request from any endpoint, plain or batch, until its reply.
- `network_interface_index`: Output for the position of its interface in `[ucall_server_options_t::interfaces](https://www.unum.cloud/docs/ucall/c/serving.md#ucall_server_options_t)`.
- `static_key`: Output for the peer's authenticated Noise static key; zeroed on plaintext interfaces.
- `address`: Output for the peer's socket address as accepted.

Notes: __Thread-safe__ across requests, though two threads must not use one `request` at once.

Statuses: - [`ucall_status_uninitialized_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_uninitialized_k) The `server` is `NULL`.
- [`ucall_status_invalid_argument_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_invalid_argument_k) The `request` or an output is `NULL`.

## ucall_server_request_body

Extracts the body content from the received request.

```c
void ucall_server_request_body(ucall_server_request_body_t *arguments);
```

A streamed endpoint's body is pulled through `ucall_server_request_body_chunk()` instead.

- `server`: The server this call operates on.
- `outcome`: The verb's status, listed on the verb.
- `request`: The received request inside the `[ucall_received_http_request_callback_t](#ucall_received_http_request_callback_t)`.
- `body`: Output for a borrowed view of the body.

Notes: __Thread-safe__ across requests, though two threads must not use one `request` at once.

Statuses: - [`ucall_status_uninitialized_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_uninitialized_k) The `server` is `NULL`.
- [`ucall_status_invalid_argument_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_invalid_argument_k) The `request` or the `body` output is `NULL`, or the endpoint is streamed.

## ucall_server_request_body_chunk

Pulls the next chunk of a request body that is still arriving.

```c
void ucall_server_request_body_chunk(
    ucall_server_request_body_chunk_t *arguments);
```

Endpoints registered with [`ucall_body_delivery_streamed_k`](https://www.unum.cloud/docs/ucall/c/batches.md#ucall_body_delivery_streamed_k) are invoked as soon as headers are parsed, before the body is complete. Without this, a multi-gigabyte upload must be buffered in full before the handler runs, which is both a memory hazard and a denial-of-service vector. Each pull takes every byte decoded since the last one; the connection reads on only once the previous bytes were pulled, and parses no pipelined request until the body ended. On a buffered endpoint the first pull answers the whole body and the next one empty.

- `server`: The server this call operates on.
- `outcome`: Final with the next bytes, or deferred until they arrive; a deferred pull finishes on the request's polling thread, so a pull from that thread with nothing decoded yet answers [`ucall_status_would_block_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_would_block_k) instead and keeps no outcome.
- `request`: The received request inside the `[ucall_received_http_request_callback_t](#ucall_received_http_request_callback_t)`.
- `data`: Output for a borrowed view of the bytes decoded since the last pull, valid until the next pull and written once the outcome is final; empty once the body ended.

Warnings: The returned `data` is valid only until the next call on this `request`.

See also: Use `ucall_server_request_body()` for endpoints that are not registered as streaming.

Notes: __Thread-safe__ across requests, though two threads must not use one `request` at once.

Statuses: - [`ucall_status_uninitialized_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_uninitialized_k) The `server` is `NULL`.
- [`ucall_status_invalid_argument_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_invalid_argument_k) The `request` or the `data` output is `NULL`.
- [`ucall_status_malformed_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_malformed_k) The streamed body's framing is malformed.
- [`ucall_status_connection_closed_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_connection_closed_k) The connection closed before the streamed body ended.
- [`ucall_status_would_block_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_would_block_k) Called on the request's polling thread with nothing decoded yet; the next pull takes what arrives by then.

## ucall_server_request_parts_count

Returns the number of parts in a `multipart/form-data` request body.

```c
size_t ucall_server_request_parts_count(
    ucall_server_t server,
    ucall_received_http_request_t request);
```

Zero if it is not multipart.

- `server` (in): Server handle from `ucall_server_init()`.
- `request` (in): The received request inside the `[ucall_received_http_request_callback_t](#ucall_received_http_request_callback_t)`.

Notes: __Thread-safe__ across requests. Two threads must not operate on the __same__ `request` concurrently.

## ucall_server_request_part

Extracts one part of a `multipart/form-data` request body by index.

```c
void ucall_server_request_part(ucall_server_request_part_t *arguments);
```

The payload is handed over without decoding. Media formats are the application's concern - pass `data` straight to an image or video decoder to keep the path copy-free.

- `server`: The server this call operates on.
- `outcome`: The verb's status, listed on the verb.
- `request`: The received request inside the `[ucall_received_http_request_callback_t](#ucall_received_http_request_callback_t)`.
- `index`: Zero-based index of the part, below `ucall_server_request_parts_count()`.
- `name`: Output for the part name from `Content-Disposition`.
- `content_type`: Output for the part's `Content-Type`.
- `data`: Output for the part payload.

Notes: __Thread-safe__ across requests, though two threads must not use one `request` at once.

Statuses: - [`ucall_status_uninitialized_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_uninitialized_k) The `server` is `NULL`.
- [`ucall_status_invalid_argument_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_invalid_argument_k) The `request` or an output is `NULL`, or the `index` is past the last part.
- [`ucall_status_malformed_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_malformed_k) The body is not a well-formed `multipart/form-data` body, or the part has no blank line closing its headers.

## ucall_server_reply_content

Sends an HTTP response with custom headers and body.

```c
void ucall_server_reply_content(
    ucall_server_reply_content_t *arguments);
```

Automatically sets standard headers: `Content-Length`, `Date`, `Server`, `Connection`.

- `server`: The server this call operates on.
- `outcome`: Output for the outcome, final once its status leaves ucall_status_deferred_k.
- `request`: The received request to reply to.
- `http_status`: Response status.
- `headers`: Every HTTP header line, each as a counted byte view.
- `headers_count`: Number of counted header lines.
- `body`: Response body content.

Notes: __Thread-safe__ across requests, though two threads must not use one `request` at once.

Statuses: - [`ucall_status_uninitialized_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_uninitialized_k) The `server` is `NULL`.
- [`ucall_status_invalid_argument_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_invalid_argument_k) The `request` is `NULL`, a view is invalid, a 204 or 304 carries a body, the `http_status` is outside 200 to 599, or a header line is malformed or sets a length, a transfer encoding, a date, a server name or a connection.
- [`ucall_status_already_exists_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_already_exists_k) The request was already answered.
- [`ucall_status_connection_closed_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_connection_closed_k) The peer left or the server stops.
- [`ucall_status_overflow_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_overflow_k) The reply's length overflows its counter.

## ucall_server_reply_error

Sends an error response with plain text message.

```c
void ucall_server_reply_error(ucall_server_reply_error_t *arguments);
```

Automatically sets `Content-Type`: `text/plain`. For errors requiring custom headers, use `ucall_server_reply_content()` instead.

- `server`: The server this call operates on.
- `outcome`: Output for the outcome, final once its status leaves ucall_status_deferred_k.
- `request`: The received request to reply to.
- `http_status`: HTTP error status code (400, 404, 500, etc.).
- `message`: Error message text.

Notes: __Thread-safe__ across requests, though two threads must not use one `request` at once.

Statuses: - [`ucall_status_uninitialized_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_uninitialized_k) The `server` is `NULL`.
- [`ucall_status_invalid_argument_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_invalid_argument_k) The `request` is `NULL`, the `message` is not a valid view, or the `http_status` is outside 400 to 599.
- [`ucall_status_already_exists_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_already_exists_k) The request was already answered.
- [`ucall_status_connection_closed_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_connection_closed_k) The peer left or the server stops.
- [`ucall_status_overflow_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_overflow_k) The reply's length overflows its counter.

## ucall_server_reply_vectored

Sends a response assembled from several non-contiguous buffers and file ranges.

```c
void ucall_server_reply_vectored(
    ucall_server_reply_vectored_t *arguments);
```

Lets a handler reply with a header, a tensor, and a file without concatenating them into a staging buffer first. Sets `Content-Length` to the sum of the parts, and sends no body to a `HEAD` request.

Memory-only replies are final on return. With any file or path part, the outcome reads [`ucall_status_deferred_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_deferred_k) on return: the event loop opens and sizes every part before it sends the head, so `Content-Length` is measured, then publishes success once every part is sent, or the cause of a failure. A part failing before the head replaces the whole reply: `404` for a missing, unreadable or irregular file, `416` for a range past its end, `500` otherwise. A part failing after the head resets the connection.

[`ucall_status_invalid_argument_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_invalid_argument_k) answers a `NULL` `request`, an invalid part, view or range end, a descriptor that reads buffered, a path leaving its directories, a status outside 200 to 599, a 204 or 304 with a body, and a header line that is malformed or sets a length, a transfer encoding, a date or a server name.

- `server`: The server this call operates on.
- `outcome`: Output for the outcome, final once its status leaves ucall_status_deferred_k.
- `request`: The received request to reply to.
- `http_status`: Response status.
- `headers`: Every HTTP header line, each as a counted byte view.
- `headers_count`: Number of counted header lines.
- `parts`: Parts concatenated, in order, into the body.
- `parts_count`: Number of entries in `parts`.

Notes: __Thread-safe__ across requests, though two threads must not use one `request` at once.

Statuses: - [`ucall_status_uninitialized_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_uninitialized_k) The `server` is `NULL`.
- [`ucall_status_overflow_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_overflow_k) A range runs past the end of its file, published by the event loop once it measured the file.
- [`ucall_status_already_exists_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_already_exists_k) The request was already answered.
- [`ucall_status_connection_closed_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_connection_closed_k) The peer left or the server stops.
- [`ucall_status_not_found_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_not_found_k) A file is missing, unreadable or irregular.

## ucall_server_reply_begin

Begins a streamed response, emitting the status line and headers.

```c
void ucall_server_reply_begin(ucall_server_reply_begin_t *arguments);
```

Must be followed by zero or more `ucall_server_reply_append()` calls and exactly one `ucall_server_reply_end()` once this call reports success or [`ucall_status_connection_closed_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_connection_closed_k); any other failure leaves the request unanswered. The body is chunked for HTTP/1.1 peers. Supplying `Content-Length` switches to identity encoding, which is what `Range` responses need, and `ucall_server_reply_end()` checks the chunks summed to it. An HTTP/1.0 peer without it gets a body delimited by closing the connection. A `HEAD` request, `204` and `304` carry no body: chunks for a `HEAD` request are accepted and dropped.

- `server`: The server this call operates on.
- `outcome`: Output for the outcome, final once its status leaves ucall_status_deferred_k.
- `request`: The received request to reply to.
- `http_status`: Response status.
- `headers`: Every HTTP header line, each as a counted byte view.
- `headers_count`: Number of counted header lines.

Notes: __Thread-safe__ across requests, though two threads must not use one `request` at once.

Statuses: - [`ucall_status_uninitialized_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_uninitialized_k) The `server` is `NULL`.
- [`ucall_status_invalid_argument_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_invalid_argument_k) The `request` is `NULL`, the `http_status` is outside 200 to 599, a header line is malformed or sets `Transfer-Encoding`, `Date`, `Server` or `Connection`, the declared `Content-Length` is no decimal number, or a status of 204 or 304 declares one.
- [`ucall_status_already_exists_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_already_exists_k) The request was already answered.
- [`ucall_status_connection_closed_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_connection_closed_k) The peer left or the server stops.
- [`ucall_status_overflow_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_overflow_k) The head's length overflows its counter.

## ucall_server_reply_append

Appends parts to a response opened with `ucall_server_reply_begin()`.

```c
void ucall_server_reply_append(ucall_server_reply_append_t *arguments);
```

Can be called from any thread, long after the request callback returned. Empty bytes parts send nothing, and so do file ranges of zero bytes.

A file or path part that fails once the head left resets the connection.

[`ucall_status_invalid_argument_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_invalid_argument_k) answers a `NULL` `request`, a reply not begun or already ended, an invalid part, view or range end, a descriptor that reads buffered, a path leaving its directories, a zero-length file or path part on a stream with a declared length, as its size is unknown, a 204 or 304 that gets a body, and one call bringing more file and path parts than may wait.

- `server`: The server this call operates on.
- `outcome`: Output for the outcome, final once its status leaves ucall_status_deferred_k.
- `request`: The received request being replied to.
- `parts`: Parts appended, in order, to the body: queued together or not at all.
- `parts_count`: Number of entries in `parts`.

Notes: __Thread-safe__ across requests, though two threads must not use one `request` at once.

Statuses: - [`ucall_status_uninitialized_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_uninitialized_k) The `server` is `NULL`.
- [`ucall_status_overflow_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_overflow_k) The parts' length overflows its counter, or parts would run past a declared `Content-Length`.
- [`ucall_status_connection_closed_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_connection_closed_k) The peer left or the server stops.
- [`ucall_status_would_block_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_would_block_k) Nothing was queued, as the bytes parts already queued for this request and not yet taken by the socket exceed the bytes a reading peer takes per round trip, or too many file and path parts wait; retry once the peer catches up.

## ucall_server_reply_end

Completes a response opened with `ucall_server_reply_begin()`.

```c
void ucall_server_reply_end(ucall_server_reply_end_t *arguments);
```

Consumes the request handle on every outcome. A response whose chunks fell short of a declared `Content-Length` closes the connection after the bytes already sent, so the peer cannot mistake the truncated body for a whole one.

While file or path parts are still unsent, the outcome reads [`ucall_status_deferred_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_deferred_k) on return, and the event loop publishes success once they are sent, or the cause of a failure.

- `server`: The server this call operates on.
- `outcome`: Output for the outcome, final once its status leaves ucall_status_deferred_k.
- `request`: The received request being replied to.

Notes: __Thread-safe__ across requests, though two threads must not use one `request` at once.

Statuses: - [`ucall_status_uninitialized_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_uninitialized_k) The `server` is `NULL`.
- [`ucall_status_invalid_argument_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_invalid_argument_k) The `request` is `NULL`, or its reply was not begun or already ended.
- [`ucall_status_connection_closed_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_connection_closed_k) The peer left or the server stops.
- [`ucall_status_malformed_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_malformed_k) The chunks fell short of a declared `Content-Length`.
- [`ucall_status_overflow_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_overflow_k) The last chunk's length overflows its counter, or a range runs past the end of its file, published by the event loop once it measured the file.
- [`ucall_status_not_found_k`](https://www.unum.cloud/docs/ucall/c/errors.md#ucall_status_not_found_k) A file part's file is missing, unreadable or irregular.

