HTTP API

This is the yimmo HTTP public API reference.

Info

To get a general sense for how the module is used, see The HTTP Protocol.

HTTP Headers

Note

Re: Set-Cookie:

All HTTP response headers have to conform to the rules outlined in RFC 7230 (section 3.2.2 — Field Order) with the exception of the Set-Cookie header which has its own grammar (outlined in RFC 6265, section 4.1.1 — Set-Cookie Syntax).

At this time, the library uses a crude trick to accommodate this: it checks to see if the header being set is Set-Cookie and, if so, it adds another node to the header table, rather than concatenating the values.

This works out okay for setting cookies, but it also means that once a cookie has been inserted into a header table as part of a single exchange, it cannot be unset using either insert or add operations.

This doesn’t mean you can’t unset cookies at all — it is possible to unset a cookie by merely not setting it again on subsequent requests. You just can’t set a cookie inside a request handler and then unset it in the same response.

TL;DR: The Set-Cookie header is essentially append-only.

Warning

Re: storage:

Generally, yimmo does not copy header field names or data (the only exception is concatenation — see ymo_http_hdr_table_add() for more info). The pointers you pass in are the locations in memory the header table will actually read from (but not write to — it does not modify any data passed in).

This means that you are responsible for ensuring that the data referenced by the header name/value parameters exists at least as long as the yimmo response object.

Don’t worry!: there are facilities in the ymo_http_request type to facilitate exactly this kind of memory pattern (i.e. allocation arenas associated with a particular HTTP exchange) via the ws (workspace) field.

For more info, see:

type ymo_http_hdr_table_t

HTTP header table type.

Definition
typedef struct ymo_http_hdr_table ymo_http_hdr_table_t;
type ymo_http_hdr_table_node_t

HTTP header table node type.

Definition
typedef struct ymo_http_hdr_table_node ymo_http_hdr_table_node_t;
type ymo_http_hdr_table_pool_t

HTTP header table node pool type (when enabled).

Definition
typedef struct ymo_http_hdr_table_pool ymo_http_hdr_table_pool_t;
type ymo_http_hdr_ptr_t

HTTP header table node pointer — used by ymo_http_hdr_table_next() as a cursor for iterating over tables.

Definition
typedef ymo_http_hdr_table_node_t* ymo_http_hdr_ptr_t;
ymo_http_hdr_table_t *ymo_http_hdr_table_create(void)

Create a new HTTP header table.

ymo_http_hdr_id_t ymo_http_hdr_table_insert(ymo_http_hdr_table_t *table, const char *hdr, const char *value)

Insert a new value, value at key hdr.

Warning

If the header name given by hdr is already present in the header table, it will be replaced.

Parameters
  • table – a pointer to the header table to modify.

  • hdr – the header field name.

  • value – the header field value.

Returns

the computed integer ID for the inserted header.

ymo_http_hdr_id_t ymo_http_hdr_table_add(ymo_http_hdr_table_t *table, const char *hdr, const char *value)

Add the value, value at key hdr.

Note

If the header name given by hdr is not present, it is created. If it’s already present, the header values are joined using ',' and combined into a single header table entry.

Parameters
  • table – a pointer to the header table to modify.

  • hdr – the header field name.

  • value – the header field value.

Returns

the computed integer ID for the added header.

const char *ymo_http_hdr_table_get(const ymo_http_hdr_table_t *table, const char *hdr)

Get the value of a header field by name.

Parameters
  • table – a pointer to the header table to query

  • hdr – the name of the header field whose value we’re fetching

Returns

a pointer to the internal header field value on success; NULL on failure.

ymo_http_hdr_ptr_t ymo_http_hdr_table_next(ymo_http_hdr_table_t *table, ymo_http_hdr_ptr_t cur, const char **hdr, size_t *hdr_len, const char **value)

Iterate over all of the headers in a header table.

Parameters
  • table – a pointer to the header table to query

  • cur – a cursor used to traverse the header table. (This is set to NULL on the first invocation).

  • hdr – the header field name is stored here

  • hdr_len – the length of the header field name is stored here

  • value – the header field value is stored here

Returns

the next cursor or NULL once the end of the table is reached.

Example: Print all of the entries in a header table
// These will be populated during iteration:
const char* hdr_name;
const char* hdr_value;
size_t name_len;

// On the first invocation, we just
// pass NULL for the cursor:
ymo_http_hdr_ptr_t iter = ymo_http_hdr_table_next(
        table, NULL, &hdr_name, &name_len, &hdr_value);

// As long as the returned cursor is not
// NULL, we've got data:
while( iter )
{
    printf("%.*s=%s\n", (int)name_len, hdr_name, hdr_value);

    // Get the next entry in the table:
    iter = ymo_http_hdr_table_next(
            table, iter, &hdr_name, &name_len, &hdr_value);
}
void ymo_http_hdr_table_clear(ymo_http_hdr_table_t *table)

Remove all the entries from the hash table.

void ymo_http_hdr_table_free(ymo_http_hdr_table_t *table)

Free the given hash table.

Exchanges

Type Definitions

type ymo_http_request_t

Opaque struct used to represent HTTP requests.

Definition
typedef struct ymo_http_request ymo_http_request_t;
type ymo_http_response_t

Opaque struct used to represent HTTP responses.

Definition
typedef struct ymo_http_response ymo_http_response_t;
type ymo_http_exchange_t

Opaque struct used to represent HTTP requests-response pairs.

Definition
typedef struct ymo_http_exchange ymo_http_exchange_t;
type ymo_http_session_t

Opaque struct used to represent HTTP sessions.

Definition
typedef struct ymo_http_session ymo_http_session_t;
type ymo_http_method

Enum type used to indicate parsed HTTP method.

Definition
YMO_ENUM8_TYPEDEF(ymo_http_method) {
    YMO_HTTP_METH_OPTIONS,
    YMO_HTTP_METH_GET,
    YMO_HTTP_METH_HEAD,
    YMO_HTTP_METH_POST,
    YMO_HTTP_METH_PUT,
    YMO_HTTP_METH_DELETE,
    YMO_HTTP_METH_TRACE,
    YMO_HTTP_METH_CONNECT,
    YMO_HTTP_METH_OTHER,
} YMO_ENUM8_AS(ymo_http_method_t);
type ymo_http_status_t

Convenience enums for HTTP status codes.

Definition
typedef uint16_t ymo_http_status_t;

Requests

struct ymo_http_request

HTTP request callback structure.

Note

Re: request “Workspaces”

Yimmo provides a Varnish-style, per-request, block-memory, workspace which can be used to acquire memory on demand which is automatically freed after the request has completed (or otherwise been disposed of), e.g.:

// Contrived example: set the HTTP header
// "hex-counter" to the value of some global
// counter, incremented with each request:
typedef ymo_status_t my_http_callback(
        ymo_http_session_t* session,
        ymo_http_request_t* request,
        ymo_http_response_t* response,
        void* user_data)
{
   // Allocate space enough for "0x" + 4 hex digits + '\0' terminal:
   char* value = ymo_blalloc(request->ws, alignof(char), 7);
   snprintf(value, "0x%x", ++my_global_counter, 7);

   ymo_http_hdr_table_insert(&request->headers, "hex-counter", value);

   // ... do other request handling stuff ...
   ymo_http_response_finish(response);
   return YMO_OKAY;
}

The workspace object, ws is allocated and deallocated by yimmo automatically — i.e. ws is already usable at the time that any of the HTTP callbacks are invoked. No ymo_blalloc_create() or ymo_blalloc_free() invocations are required!

Definition
struct ymo_http_request {
    const char*           method;           /* GET, POST, etc */
    const char*           uri;              /* Full URI, *as received* */
    const char*           version;          /* Protocol version *string* */
    const char*           query;            /* Query string, *as received* */
    const char*           fragment;         /* URI fragment, *as received* */
    ymo_http_hdr_table_t  headers;          /* Request headers */
    ymo_blalloc_t*        ws;               /* Request workspace */
    char*                 body;             /* Optionally buffered body data */
    size_t                body_received;    /* Body data received */
    size_t                content_length;   /* Content-length, per client */
    ymo_http_flags_t      flags;            /* Request flags */
    void*                 user;             /* Arbitrary, per-request, user-data */
};

Responses

ymo_http_hdr_table_t *ymo_http_response_get_headers(ymo_http_response_t *response)

Get the header table for a response object.

const char *ymo_http_response_get_header(const ymo_http_response_t *response, const char *hdr_name)

Get the value of the header given by hdr_name.

Parameters
  • response – the HTTP response object to modify

  • header – the HTTP header to get

ymo_status_t ymo_http_response_add_header(ymo_http_response_t *response, const char *header, const char *value)

Used to set HTTP header values for responses

Parameters
  • response – the HTTP response object to modify

  • header – the HTTP header to set

  • value – the value for the header

Returns

YMO_OKAY on success; appropriate errno on failure

ymo_status_t ymo_http_response_insert_header(ymo_http_response_t *response, const char *header, const char *value)

Used to set HTTP header values for responses

Parameters
  • response – the HTTP response object to modify

  • header – the HTTP header to set

  • value – the value for the header

Returns

YMO_OKAY on success; appropriate errno on failure

void ymo_http_response_body_append(ymo_http_response_t *response, ymo_bucket_t *body_data)

Add HTTP body data

Parameters
  • response – the HTTP response object to which we append body data

  • body_data – the body payload as a ymo_bucket_t (see Buckets for more info)

void ymo_http_response_set_status(ymo_http_response_t *response, ymo_http_status_t status)

Set the HTTP status code — the reason will be filled in from a table or else “NULL”.

Parameters
  • response – the HTTP response object to modify

  • status – the integer HTTP status code

int ymo_http_response_set_status_str(ymo_http_response_t *response, const char *status_str)

Set the HTTP status code and reason as a string.

Parameters
  • response – the HTTP response object to modify

  • status – the integer HTTP status code

void ymo_http_response_ready(ymo_http_response_t *response)

Mark the http response as ready for transmission.

int ymo_http_response_is_ready(const ymo_http_response_t *response)
Returns

true if this response has data ready to send; false otherwise.

void ymo_http_response_finish(ymo_http_response_t *response)

Mark the response data as complete (i.e. fully ready to transmit)

int ymo_http_response_finished(const ymo_http_response_t *response)
Returns

true if this response is finished; false otherwise.

Sessions

void ymo_http_session_set_userdata(ymo_http_session_t *session, void *data)

Set session-level user data.

void *ymo_http_session_get_userdata(const ymo_http_session_t *session)

Get session-level user data.

Callbacks

Note

See Callbacks for more info.

type ymo_http_session_init_cb_t

Session initialization callback.

Definition
typedef ymo_status_t (*ymo_http_session_init_cb_t)(
        void* server_data, ymo_http_session_t* session);
type ymo_http_session_cleanup_cb_t

Session cleanupialization callback.

Definition
typedef void (*ymo_http_session_cleanup_cb_t)(
        void* server_data, ymo_http_session_t* session, void* user_data);
type ymo_http_cb_t

HTTP exchange callback.

Param session

The client HTTP session

Param exchange

The originating exchange object

Param response

A blank response object

Param user_data

user data if set; else NULL

Returns

YMO_OKAY on success; errno.h value on failure.

Definition
typedef ymo_status_t (*ymo_http_cb_t)(
        ymo_http_session_t* session,
        ymo_http_request_t* request,
        ymo_http_response_t* response,
        void* user_data);
type ymo_http_header_cb_t

HTTP exchange callback.

Param session

The client HTTP session

Param exchange

The originating exchange object

Param response

A blank response object

Param user

user data if set; else NULL

Returns

YMO_OKAY on success; errno.h value on failure.

Definition
typedef ymo_http_cb_t ymo_http_header_cb_t;
type ymo_http_body_cb_t

HTTP exchange callback.

Param session

the client HTTP session

Param exchange

the originating exchange object

Param data

exchange body data

Param len

size of body data in bytes

Param user_data

user data if set; else NULL

Definition
typedef ymo_status_t (*ymo_http_body_cb_t)(
        ymo_http_session_t* session,
        ymo_http_request_t* request,
        ymo_http_response_t* response,
        const char* data,
        size_t len,
        void* user_data);

Protocol Management

type ymo_http_upgrade_status
Definition
YMO_ENUM8_TYPEDEF(ymo_http_upgrade_status) {
    YMO_HTTP_UPGRADE_HANDLED,
    YMO_HTTP_UPGRADE_IGNORE,
    YMO_HTTP_UPGRADE_ERROR,
    YMO_HTTP_UPGRADE_NOPROTO,
} YMO_ENUM8_AS(ymo_http_upgrade_status_t);
type ymo_http_upgrade_cb_t

HTTP upgrade handler callback.

Param hdr_upgrade

the value of the HTTP “Upgrade:” header

Param exchange

the originating http exchange object

Param response

a blank response object

Returns

ymo_http_status_t indicator + set errno on failure

Definition
typedef ymo_http_upgrade_status_t (*ymo_http_upgrade_cb_t)(
        const char* hdr_upgrade,
        ymo_http_request_t* request,
        ymo_http_response_t* response);
type ymo_http_upgrade_handler_t

Struct that encapsulates functions and data required to validate and perform and HTTP Upgrade exchange protocol switch.

Definition
typedef struct ymo_http_upgrade_handler {
    ymo_http_upgrade_cb_t  cb;
    ymo_proto_t*           proto_new;
} ymo_http_upgrade_handler_t;
ymo_http_upgrade_handler_t *ymo_http2_no_upgrade_handler(void)

Yimmo has no HTTP/2 support, at the moment. This callback can be used to reject an upgrade exchange for h2c over HTTP/1.0 or HTTP/1.1.

ymo_proto_t *ymo_proto_http_create(ymo_http_session_init_cb_t session_init, ymo_http_cb_t http_callback, ymo_http_header_cb_t header_callback, ymo_http_body_cb_t body_cb, ymo_http_session_cleanup_cb_t session_cleanup, void *data)

Used to create a new HTTP protocol endpoint.

ymo_status_t ymo_http_add_upgrade_handler(ymo_proto_t *proto, ymo_http_upgrade_handler_t *upgrade_handler)

Used to add an upgrade handler to the internal upgrade handler chain.

Quickstart

ymo_server_t *ymo_http_simple_init(struct ev_loop *loop, in_port_t port, ymo_http_cb_t http_callback, ymo_http_upgrade_handler_t **upgrade_handlers, void *data)

Create a server by

  • invoking ymo_proto_http_create() to create a new, buffered, HTTP

    protocol object with the given port and handler callback.

  • passing that proto object to ymo_server_create(), along with the

    default ymo_serfer_config_t.

Parameters
  • loop – pointer to a libev loop object, or NULL for default

  • port – port number to bind to

  • http_callback – buffered HTTP callback handler

  • upgrade_handlers – an array of ymo_http_upgrade_handler_t pointers for HTTP upgrade requests.

  • data – arbitrary pointer to associate with this server (available in callbacks as data).

Returns

a ymo_server_t pointer on success; NULL with errno set on failure.

Misc

YMO_HTTP_CONTINUE

HTTP Status 100 (Continue)

Definition
#define YMO_HTTP_CONTINUE                          100
YMO_HTTP_SWITCHING_PROTOCOLS

HTTP Status 101 (Switching protocols)

Definition
#define YMO_HTTP_SWITCHING_PROTOCOLS               101
YMO_HTTP_OK

HTTP Status 200 (Ok)

Definition
#define YMO_HTTP_OK                                200
YMO_HTTP_CREATED

HTTP Status 201 (Created)

Definition
#define YMO_HTTP_CREATED                           201
YMO_HTTP_ACCEPTED

HTTP Status 202 (Accepted)

Definition
#define YMO_HTTP_ACCEPTED                          202
YMO_HTTP_NON_AUTHORITATIVE_INFORMATION

HTTP Status 203 (Non authoritative information)

Definition
#define YMO_HTTP_NON_AUTHORITATIVE_INFORMATION     203
YMO_HTTP_NO_CONTENT

HTTP Status 204 (No content)

Definition
#define YMO_HTTP_NO_CONTENT                        204
YMO_HTTP_RESET_CONTENT

HTTP Status 205 (Reset content)

Definition
#define YMO_HTTP_RESET_CONTENT                     205
YMO_HTTP_PARTIAL_CONTENT

HTTP Status 206 (Partial content)

Definition
#define YMO_HTTP_PARTIAL_CONTENT                   206
YMO_HTTP_MULTIPLE_CHOICES

HTTP Status 300 (Multiple choices)

Definition
#define YMO_HTTP_MULTIPLE_CHOICES                  300
YMO_HTTP_MOVED_PERMANENTLY

HTTP Status 301 (Moved permanently)

Definition
#define YMO_HTTP_MOVED_PERMANENTLY                 301
YMO_HTTP_FOUND

HTTP Status 302 (Found)

Definition
#define YMO_HTTP_FOUND                             302
YMO_HTTP_SEE_OTHER

HTTP Status 303 (See other)

Definition
#define YMO_HTTP_SEE_OTHER                         303
YMO_HTTP_NOT_MODIFIED

HTTP Status 304 (Not modified)

Definition
#define YMO_HTTP_NOT_MODIFIED                      304
YMO_HTTP_USE_PROXY

HTTP Status 305 (Use proxy)

Definition
#define YMO_HTTP_USE_PROXY                         305
YMO_HTTP_TEMPORARY_REDIRECT

HTTP Status 307 (Temporary redirect)

Definition
#define YMO_HTTP_TEMPORARY_REDIRECT                307
YMO_HTTP_BAD_REQUEST

HTTP Status 400 (Bad request)

Definition
#define YMO_HTTP_BAD_REQUEST                       400
YMO_HTTP_UNAUTHORIZED

HTTP Status 401 (Unauthorized)

Definition
#define YMO_HTTP_UNAUTHORIZED                      401
YMO_HTTP_PAYMENT_REQUIRED

HTTP Status 402 (Payment required)

Definition
#define YMO_HTTP_PAYMENT_REQUIRED                  402
YMO_HTTP_FORBIDDEN

HTTP Status 403 (Forbidden)

Definition
#define YMO_HTTP_FORBIDDEN                         403
YMO_HTTP_NOT_FOUND

HTTP Status 404 (Not found)

Definition
#define YMO_HTTP_NOT_FOUND                         404
YMO_HTTP_METHOD_NOT_ALLOWED

HTTP Status 405 (Method not allowed)

Definition
#define YMO_HTTP_METHOD_NOT_ALLOWED                405
YMO_HTTP_NOT_ACCEPTABLE

HTTP Status 406 (Not acceptable)

Definition
#define YMO_HTTP_NOT_ACCEPTABLE                    406
YMO_HTTP_PROXY_AUTHENTICATION_REQUIRED

HTTP Status 407 (Proxy authentication required)

Definition
#define YMO_HTTP_PROXY_AUTHENTICATION_REQUIRED     407
YMO_HTTP_REQUEST_TIMEOUT

HTTP Status 408 (Request timeout)

Definition
#define YMO_HTTP_REQUEST_TIMEOUT                   408
YMO_HTTP_CONFLICT

HTTP Status 409 (Conflict)

Definition
#define YMO_HTTP_CONFLICT                          409
YMO_HTTP_GONE

HTTP Status 410 (Gone)

Definition
#define YMO_HTTP_GONE                              410
YMO_HTTP_LENGTH_REQUIRED

HTTP Status 411 (Length required)

Definition
#define YMO_HTTP_LENGTH_REQUIRED                   411
YMO_HTTP_PRECONDITION_FAILED

HTTP Status 412 (Precondition failed)

Definition
#define YMO_HTTP_PRECONDITION_FAILED               412
YMO_HTTP_REQUEST_ENTITY_TOO_LARGE

HTTP Status 413 (Request entity too large)

Definition
#define YMO_HTTP_REQUEST_ENTITY_TOO_LARGE          413
YMO_HTTP_REQUEST_URI_TOO_LONG

HTTP Status 414 (Request uri too long)

Definition
#define YMO_HTTP_REQUEST_URI_TOO_LONG              414
YMO_HTTP_UNSUPPORTED_MEDIA_TYPE

HTTP Status 415 (Unsupported media type)

Definition
#define YMO_HTTP_UNSUPPORTED_MEDIA_TYPE            415
YMO_HTTP_REQUESTED_RANGE_NOT_SATISFIABLE

HTTP Status 416 (Requested range not satisfiable)

Definition
#define YMO_HTTP_REQUESTED_RANGE_NOT_SATISFIABLE   416
YMO_HTTP_EXPECTATION_FAILED

HTTP Status 417 (Expectation failed)

Definition
#define YMO_HTTP_EXPECTATION_FAILED                417
YMO_HTTP_UPGRADE_REQUIRED

HTTP Status 426 (Upgrade required)

Definition
#define YMO_HTTP_UPGRADE_REQUIRED                  426
YMO_HTTP_PRECONDITION_REQUIRED

HTTP Status 428 (Precondition required)

Definition
#define YMO_HTTP_PRECONDITION_REQUIRED             428
YMO_HTTP_TOO_MANY_REQUESTES

HTTP Status 429 (Too many requestes)

Definition
#define YMO_HTTP_TOO_MANY_REQUESTES                429
YMO_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE

HTTP Status 431 (Request header fields too large)

Definition
#define YMO_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE   431
YMO_HTTP_INTERNAL_SERVER_ERROR

HTTP Status 500 (Internal server error)

Definition
#define YMO_HTTP_INTERNAL_SERVER_ERROR             500
YMO_HTTP_NOT_IMPLEMENTED

HTTP Status 501 (Not implemented)

Definition
#define YMO_HTTP_NOT_IMPLEMENTED                   501
YMO_HTTP_BAD_GATEWAY

HTTP Status 502 (Bad gateway)

Definition
#define YMO_HTTP_BAD_GATEWAY                       502
YMO_HTTP_SERVICE_UNAVAILABLE

HTTP Status 503 (Service unavailable)

Definition
#define YMO_HTTP_SERVICE_UNAVAILABLE               503
YMO_HTTP_GATEWAY_TIMEOUT

HTTP Status 504 (Gateway timeout)

Definition
#define YMO_HTTP_GATEWAY_TIMEOUT                   504
YMO_HTTP_HTTP_VERSION_NOT_SUPPORTED

HTTP Status 505 (Http version not supported)

Definition
#define YMO_HTTP_HTTP_VERSION_NOT_SUPPORTED        505
YMO_HTTP_STATUS_CHR3_TO_INT

Given an array of three or more char from a trusted source, convert the character string to an integer.

Warning

There is no:

  • bounds checking

  • range checking

  • validation

Definition
#define YMO_HTTP_STATUS_CHR3_TO_INT(s) \
        ( \
            ((s[0] & 0xf) * 100) + \
            ((s[1] & 0xf) * 10) + \
            (s[2] & 0xf) \
        )