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.
Contents
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,
valueat keyhdr.Warning
If the header name given by
hdris 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,
valueat keyhdr.Note
If the header name given by
hdris 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;
NULLon 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
NULLon 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
NULLonce 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);
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,
wsis allocated and deallocated by yimmo automatically — i.e.wsis already usable at the time that any of the HTTP callbacks are invoked. Noymo_blalloc_create()orymo_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.
- invoking
- passing that proto object to
ymo_server_create(), along with the default
ymo_serfer_config_t.
- passing that proto object to
- 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_tpointers for HTTP upgrade requests.data – arbitrary pointer to associate with this server (available in callbacks as
data).
- Returns
a
ymo_server_tpointer on success;NULLwitherrnoset on failure.
Misc¶
-
YMO_HTTP_SWITCHING_PROTOCOLS¶
HTTP Status 101 (Switching protocols)
Definition¶#define YMO_HTTP_SWITCHING_PROTOCOLS 101
-
YMO_HTTP_NON_AUTHORITATIVE_INFORMATION¶
HTTP Status 203 (Non authoritative information)
Definition¶#define YMO_HTTP_NON_AUTHORITATIVE_INFORMATION 203
-
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_TEMPORARY_REDIRECT¶
HTTP Status 307 (Temporary redirect)
Definition¶#define YMO_HTTP_TEMPORARY_REDIRECT 307
-
YMO_HTTP_PAYMENT_REQUIRED¶
HTTP Status 402 (Payment required)
Definition¶#define YMO_HTTP_PAYMENT_REQUIRED 402
-
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_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_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
charfrom 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) \ )