|
cwist
Modern C web framework with libttak runtime
|
HTTP Protocol Definitions and Helpers. More...
#include <cwist/core/sstring/sstring.h>#include <cwist/sys/err/cwist_err.h>#include <cwist/net/http/query.h>#include <cwist/core/db/sql.h>#include <cwist/sys/app/endpoint_opts.h>#include <cwist/sys/app/big_dumb_reply.h>#include <cwist/sys/io/reactor.h>#include <stdint.h>#include <cwist/sys/platform.h>#include <netinet/in.h>#include <sys/socket.h>#include <sys/types.h>#include <stdio.h>#include <stdlib.h>

Go to the source code of this file.
Classes | |
| struct | cwist_http_header_node |
| Linked list for headers to handle multiple headers easily. More... | |
| struct | cwist_http_request |
| struct | cwist_http_response |
| HTTP Response Object. Supports standard string body or Zero-Copy pointer body. More... | |
| struct | cwist_server_config |
| struct | cwist_http_async_conn |
Macros | |
| #define | CWIST_HTTP_MAX_HEADER_SIZE (8 * 1024) |
| #define | CWIST_HTTP_MAX_BODY_SIZE (10 * 1024 * 1024) |
| #define | CWIST_HTTP_READ_BUFFER_SIZE (16 * 1024) |
| #define | CWIST_HTTP_TIMEOUT_MS 30000 |
| #define | CWIST_HTTPS_HANDSHAKE_TIMEOUT_MS 45000 /* Total TLS handshake budget */ |
| #define | CWIST_HTTP_HEADERS_TIMEOUT_MS 120000 /* Total header read budget */ |
| #define | CWIST_HTTP_BODY_IDLE_TIMEOUT_MS 60000 /* Abort body read after this much silence */ |
| #define | CWIST_HTTP2_IDLE_TIMEOUT_MS 300000 /* Default h2 idle budget (env overridable) */ |
| #define | CWIST_HTTP_KEEP_ALIVE_TIMEOUT_SEC 15 /* Default keep-alive idle connection timeout in seconds */ |
| #define | CWIST_HTTP_COALESCE_MAX (256 * 1024) |
Typedefs | |
| typedef enum cwist_http_method_t | cwist_http_method_t |
| typedef enum cwist_http_status_t | cwist_http_status_t |
| typedef enum cwist_http_parse_error_t | cwist_http_parse_error_t |
| Failure reason reported by the request receive APIs. Distinguishes protocol errors (which deserve an error response before close) from an orderly client disconnect (close quietly). | |
| typedef struct cwist_http_header_node | cwist_http_header_node |
| Linked list node for request/response headers. | |
| typedef struct cwist_http_request | cwist_http_request |
| typedef void(* | cwist_http_body_cleanup_fn) (const void *ptr, size_t len, void *ctx) |
| typedef struct cwist_http_response | cwist_http_response |
| HTTP Response Object. Supports standard string body or Zero-Copy pointer body. | |
| typedef struct cwist_server_config | cwist_server_config |
| typedef cwist_async_action_t(* | cwist_async_handler_t) (int fd, struct cwist_http_async_conn *conn) |
| typedef struct cwist_http_async_conn | cwist_http_async_conn_t |
Functions | |
| long | get_cpu_cores (void) |
| Return the number of CPUs available to this process. | |
| long | get_optimal_thread_count (void) |
| Compute the HTTP worker/event-loop thread count. | |
| const char * | cwist_http_status_reason (int status) |
| Return the standard reason phrase for an HTTP status code (e.g. 404 -> "Not Found"). Unknown codes return NULL; applications may also assign any int to a response status_code for non-standard codes. | |
| cwist_http_request * | cwist_http_receive_request (int client_fd, char *read_buf, size_t buf_size, size_t *buf_len, cwist_http_parse_error_t *err_out) |
| Blocking read of one full request from a classic-pool connection. | |
| void | cwist_http_send_error_response (int fd, int status, const char *msg) |
| Send a minimal HTTP/1.x error response (Connection: close) on a socket, used to answer malformed requests before dropping them. | |
| cwist_error_t | cwist_http_server_loop (int server_fd, cwist_server_config *config, void(*handler)(int, void *), void *ctx) |
| Run the main HTTP accept loop using the configured concurrency strategy. | |
| int | headers_have_content_length (cwist_http_header_node *headers) |
| Detect whether a header list already defines Content-Length. | |
| int | cwist_http_pool_init (void) |
| Initialize the handler pool in the mode CWIST_C1M_MODE selects. | |
| int | cwist_http_pool_init_mode (bool use_c1m) |
Initialize the handler pool as reactor workers (use_c1m) or the classic thread pool, without reading CWIST_C1M_MODE. | |
| void | cwist_http_pool_limit_core (unsigned int limit) |
| Fix the HTTP pool worker count to a specific value. | |
| void | cwist_http_pool_submit (int client_fd, void(*handler)(int, void *), void *ctx) |
| Queue a connection for handling on the classic dynamic pool. | |
| bool | cwist_http_pool_rearm_current (int client_fd, void(*handler)(int, void *), void *ctx) |
| Requeue the current connection's next handler turn on the pool. | |
| void | cwist_http_pool_destroy (void) |
| Tear down both pool variants. | |
| bool | cwist_http_async_rearm (int client_fd, cwist_reactor_t *reactor, cwist_http_async_conn_t *conn) |
| Re-arm an async connection for its next event. | |
| long | cwist_http_continuation_shed_count (void) |
| long | cwist_http_inflight_count (void) |
| void | cwist_http_async_send_response (int client_fd, cwist_http_response *res, cwist_reactor_t *reactor, cwist_http_async_conn_t *conn, bool keep_alive, bool head_only) |
| Send a response on the async path, parking the unsent remainder on EAGAIN instead of blocking the reactor thread. | |
| cwist_async_send_status_t | cwist_http_send_response_async (int client_fd, cwist_http_response *res, cwist_http_async_conn_t *conn, bool keep_alive, bool head_only) |
| Async send variant that reports the outcome to the caller instead of re-arming or closing the connection itself (deferred-completion handoff). | |
| int | cwist_http_coalesce_append (cwist_http_async_conn_t *conn, const void *data, size_t len) |
| Append bytes to a connection's coalesced-output stash. | |
| cwist_coalesce_flush_status_t | cwist_http_coalesce_flush (int client_fd, cwist_http_async_conn_t *conn, bool keep_alive) |
| Flush the coalesced-output stash with one speculative write. | |
| int | cwist_http_coalesce_flush_blocking (int client_fd, cwist_http_async_conn_t *conn) |
| Flush the coalesced-output stash, blocking in poll() until drained. | |
| int | cwist_http_coalesce_error_response (cwist_http_async_conn_t *conn, int status) |
| Build a minimal text error response into the coalesce stash. | |
| cwist_async_send_status_t | cwist_http_send_response_coalesced (int client_fd, cwist_http_response *res, cwist_http_async_conn_t *conn, bool keep_alive, bool head_only) |
| Coalescing variant of the async send: serialize small responses directly into the connection's output stash so one reactor turn flushes many responses with a single write. | |
| bool | cwist_http_pool_submit_async (int client_fd, cwist_async_handler_t handler, void *ctx) |
| Submit a connection to the C1M async reactor pool. | |
| int | cwist_http_async_conn_fill (cwist_http_async_conn_t *conn) |
| Drain the socket into the connection stash. Stops at EAGAIN, and also after a short read: poll is level-triggered, so if bytes remain after a short recv the one-shot re-arm fires again immediately. This skips the guaranteed-EAGAIN second recv that otherwise costs one wasted syscall per request on non-pipelined keep-alive traffic. | |
| cwist_recv_status_t | cwist_http_receive_request_nb (cwist_http_async_conn_t *conn, cwist_http_request **out, cwist_http_parse_error_t *err_out) |
| Try to assemble one complete request from the stash without any blocking IO. On CWIST_RECV_OK the consumed bytes are removed from the stash and *out holds a fully parsed request. | |
Request Lifecycle | |
— API Functions — | |
| cwist_http_request * | cwist_http_request_create (void) |
| Allocate and initialize a default HTTP request object. | |
| void | cwist_http_request_destroy (cwist_http_request *req) |
| Destroy a parsed HTTP request and all nested allocations it owns. | |
| cwist_http_request * | cwist_http_parse_request (const char *raw_request) |
| Parse a NUL-terminated raw HTTP request buffer. | |
| cwist_http_request * | cwist_http_parse_request_len (const char *buf, size_t len) |
| Parse an HTTP/1.x request held in a memory buffer (length-based; the buffer may contain a binary body and need not be NUL-terminated). | |
| int | cwist_http_response_serialize (cwist_http_response *res, char **out, size_t *out_len) |
Serialize a response into a freshly allocated HTTP/1.x buffer (status line + headers + body). Caller frees out with cwist_free(). File-streaming bodies cannot be serialized; the call fails for them. | |
Streaming producer (chunked response bodies from handlers) | |
A handler switches the response to chunked mode, writes the body incrementally, and ends the stream. Under cwist_app_dispatch_stream() each write is pushed to the host sink immediately (head first, lazily on the first write), so SSE-style handlers deliver chunks while still running; under cwist_app_dispatch_memory() the framed bytes buffer and serialize like any other body. A body assigned before begin is discarded; writes after end fail. When the handler returns without end, dispatch finalizes the stream implicitly. | |
| int | cwist_http_response_stream_begin (cwist_http_response *res) |
| Switch a response to chunked streaming mode. | |
| int | cwist_http_response_stream_write (cwist_http_response *res, const char *data, size_t len) |
| Append one data chunk to a streaming response. | |
| int | cwist_http_response_stream_end (cwist_http_response *res) |
| Terminate a streaming response with the final zero-length chunk and flush. | |
Request Data Processing | |
| cwist_sstring * | cwist_get_client_ip_from_fd (int fd) |
| Resolve the peer IP address for a connected client socket. | |
| void | cwist_http_format_date (time_t t, char *buf, size_t len) |
| Format a time_t as an HTTP-date (RFC 7231). | |
| time_t | cwist_http_parse_date (const char *str) |
| Parse an HTTP-date string into a time_t. | |
Response Lifecycle | |
| cwist_http_response * | cwist_http_response_create (void) |
| Allocate a response backed by its own arena. | |
| cwist_http_response * | cwist_http_response_create_in_arena (void *arena) |
Create a response inside an existing (request) arena. The response is bump-allocated from arena and shares its lifetime: cwist_http_response_destroy releases body/header resources but leaves the arena itself to the owner. arena must outlive the response. | |
| void | cwist_http_response_destroy (cwist_http_response *res) |
| Destroy an HTTP response and release any attached body resources. | |
| void | cwist_http_response_set_body_ptr (cwist_http_response *res, const void *ptr, size_t len) |
| Sets a direct pointer for the response body (Zero Copy). Use this when serving large files from memory mapped regions. The pointer must remain valid until the response is sent. | |
| void | cwist_http_response_set_body_ptr_managed (cwist_http_response *res, const void *ptr, size_t len, cwist_http_body_cleanup_fn cleanup, void *ctx) |
| Attach a managed zero-copy body pointer and optional cleanup hook to a response. | |
| void | cwist_http_response_set_alt_svc (cwist_http_response *res, const char *alt_svc) |
| Set the Alt-Svc header value for HTTP/3 upgrade advertisement. | |
| cwist_sstring * | cwist_http_stringify_response (cwist_http_response *res) |
| Materialize an HTTP response into a contiguous string for debugging or TLS writes. | |
| cwist_error_t | cwist_http_send_response (int client_fd, cwist_http_response *res) |
| Serialize and send an HTTP response to a connected client socket. | |
| cwist_error_t | cwist_http_send_response_head (int client_fd, cwist_http_response *res) |
| Send only the status line and headers of a response (HEAD replies). Content-Length still reflects the would-be body; body resources are released without being transmitted. | |
| bool | cwist_tcp_cork_enabled (void) |
| Whether the TCP_CORK coalescing layer is active for cleartext HTTP/1.1 responses. Enabled at runtime with CWIST_USE_TCP_CORK=1 (burst size via CWIST_TCP_CORK_BURST, default 256 KiB); always false off-Linux. | |
| size_t | cwist_http_serialize_headers (cwist_http_response *res, char *buf, size_t buf_size) |
| Serialize only the status line and headers into a caller buffer. Used by the TLS send path to stream header block and body separately. | |
| cwist_error_t | cwist_http_response_send_file (cwist_http_response *res, const char *file_path, const char *content_type_hint, size_t *out_size) |
| Prepare a response to serve a file either by buffering or direct streaming. | |
Header Manipulation | |
| cwist_error_t | cwist_http_header_add (cwist_http_header_node **head, const char *key, const char *value) |
| Prepend a header to the list. | |
| char * | cwist_http_header_get (cwist_http_header_node *head, const char *key) |
| Finds a header value by key. | |
| size_t | cwist_http_header_remove (cwist_http_header_node **head, const char *key) |
| Remove all headers matching a name, honoring per-node ownership (heap vs arena vs borrowed buffers). | |
| void | cwist_http_header_free_all (cwist_http_header_node *head) |
| Destroy every node in a request or response header list. | |
| void | cwist_http_response_add_security_headers (cwist_http_response *res) |
| Add default security headers (CSP, X-Frame-Options, Permissions-Policy, etc.) if missing. | |
| void | cwist_http_response_add_hsts (cwist_http_response *res) |
| Add Strict-Transport-Security to a TLS response (HTTPS only). | |
Helpers | |
| const char * | cwist_http_method_to_string (cwist_http_method_t method) |
| Convert a HTTP method enum into its wire-format token. | |
| cwist_http_method_t | cwist_http_string_to_method (const char *method_str) |
| Parse a NUL-terminated method string into a method enum. | |
| cwist_http_method_t | cwist_http_string_to_method_len (const char *str, size_t len) |
| Parse a method token (with explicit length) into a method enum. | |
TCP Socket Helpers | |
| int | cwist_make_socket_ipv4 (struct sockaddr_in *sockv4, const char *address, uint16_t port, uint16_t backlog) |
| Create an IPv4 socket and perform bind/listen. | |
| cwist_error_t | cwist_accept_socket (int server_fd, struct sockaddr *sockv4, void(*handler_func)(int client_fd, void *ctx), void *ctx) |
| Accept sockets and invoke a handler callback. | |
Variables | |
| const int | CWIST_CREATE_SOCKET_FAILED |
| const int | CWIST_HTTP_UNAVAILABLE_ADDRESS |
| const int | CWIST_HTTP_BIND_FAILED |
| const int | CWIST_HTTP_SETSOCKOPT_FAILED |
| const int | CWIST_HTTP_LISTEN_FAILED |
HTTP Protocol Definitions and Helpers.
Definition in file http.h.
| #define CWIST_HTTP_MAX_HEADER_SIZE (8 * 1024) |
| typedef cwist_async_action_t(* cwist_async_handler_t) (int fd, struct cwist_http_async_conn *conn) |
Linked list node for request/response headers.
— Structures —
— Enums —
Failure reason reported by the request receive APIs. Distinguishes protocol errors (which deserve an error response before close) from an orderly client disconnect (close quietly).
HTTP Response Object. Supports standard string body or Zero-Copy pointer body.
Failure reason reported by the request receive APIs. Distinguishes protocol errors (which deserve an error response before close) from an orderly client disconnect (close quietly).
| cwist_error_t cwist_accept_socket | ( | int | server_fd, |
| struct sockaddr * | sockv4, | ||
| void(*)(int client_fd, void *ctx) | handler_func, | ||
| void * | ctx | ||
| ) |
Accept sockets and invoke a handler callback.
| cwist_sstring * cwist_get_client_ip_from_fd | ( | int | fd | ) |
Resolve the peer IP address for a connected client socket.
| fd | Connected client socket descriptor. |
Definition at line 2141 of file http.c.
References cap, cwist_sstring_assign(), and cwist_sstring_create().
| int cwist_http_async_conn_fill | ( | cwist_http_async_conn_t * | conn | ) |
Drain the socket into the connection stash. Stops at EAGAIN, and also after a short read: poll is level-triggered, so if bytes remain after a short recv the one-shot re-arm fires again immediately. This skips the guaranteed-EAGAIN second recv that otherwise costs one wasted syscall per request on non-pipelined keep-alive traffic.
Definition at line 4956 of file http.c.
References cwist_http_async_conn::cap, cap, cwist_http_async_conn::fd, cwist_http_async_conn::len, cwist_http_async_conn::peer_eof, cwist_http_async_conn::rbuf, cwist_http_async_conn::rx_data_ready, cwist_http_async_conn::rx_recv_inflight, and cwist_http_async_conn::virgin.
Referenced by cwist_app_http_handler_async().
| bool cwist_http_async_rearm | ( | int | client_fd, |
| cwist_reactor_t * | reactor, | ||
| cwist_http_async_conn_t * | conn | ||
| ) |
Re-arm an async connection for its next event.
Handles deferred-completion shutdown races, peer EOF, pipelined bytes (posted as a continuation so other connections run between batches), and RECV-first re-arm with a POLL fallback.
Definition at line 1357 of file http.c.
References cap, cwist_alloc(), cwist_fast_monotonic_sec(), cwist_free(), CWIST_METRIC_HTTP_CONTINUATION_SHED, cwist_metric_inc(), cwist_metrics_registry(), cwist_http_async_conn::handler, cwist_http_async_conn::last_active_sec, cwist_http_async_conn::len, cwist_http_async_conn::peer_eof, and cwist_http_async_conn::user_ctx.
Referenced by cwist_app_http_handler_async(), and cwist_http_async_send_response().
| void cwist_http_async_send_response | ( | int | client_fd, |
| cwist_http_response * | res, | ||
| cwist_reactor_t * | reactor, | ||
| cwist_http_async_conn_t * | conn, | ||
| bool | keep_alive, | ||
| bool | head_only | ||
| ) |
Send a response on the async path, parking the unsent remainder on EAGAIN instead of blocking the reactor thread.
Pointer bodies park by reference (ownership moves to the park state); other bodies deep-copy the unsent remainder. File streams use the non-blocking sendfile path. On completion the connection is re-armed for keep-alive or closed.
Definition at line 3413 of file http.c.
References cwist_http_response::body, cap, cwist_alloc(), CWIST_FILE_BEGIN_HANDLED, cwist_free(), cwist_http_async_rearm(), CWIST_HTTP_MAX_HEADER_SIZE, cwist_http_send_response(), cwist_http_sendmsg_speculative(), cwist_reactor_add_out(), CWIST_WRITE_DONE, CWIST_WRITE_PENDING, cwist_sstring::data, g_cwist_running, cwist_http_response::is_ptr_body, cwist_http_async_conn::len, MSG_DONTWAIT, cwist_http_response::ptr_body, cwist_http_response::ptr_body_len, cwist_sstring::size, and cwist_http_response::use_file_stream.
| int cwist_http_coalesce_append | ( | cwist_http_async_conn_t * | conn, |
| const void * | data, | ||
| size_t | len | ||
| ) |
Append bytes to a connection's coalesced-output stash.
Definition at line 3653 of file http.c.
References cap, cwist_alloc(), cwist_fast_monotonic_sec(), cwist_free(), CWIST_HTTP_COALESCE_MAX, cwist_http_async_conn::obuf, cwist_http_async_conn::ocap, cwist_http_async_conn::olen, and cwist_http_async_conn::stash_grown_sec.
Referenced by cwist_http_coalesce_error_response().
| int cwist_http_coalesce_error_response | ( | cwist_http_async_conn_t * | conn, |
| int | status | ||
| ) |
Build a minimal text error response into the coalesce stash.
Definition at line 3756 of file http.c.
References cap, cwist_http_coalesce_append(), and cwist_http_status_reason().
| cwist_coalesce_flush_status_t cwist_http_coalesce_flush | ( | int | client_fd, |
| cwist_http_async_conn_t * | conn, | ||
| bool | keep_alive | ||
| ) |
Flush the coalesced-output stash with one speculative write.
On a partial write the unsent remainder is deep-copied into the parked writer, which re-arms or closes the connection when it drains.
Definition at line 3682 of file http.c.
References cap, cwist_alloc(), CWIST_COALESCE_FLUSH_DONE, CWIST_COALESCE_FLUSH_ERROR, CWIST_COALESCE_FLUSH_PARKED, cwist_free(), cwist_http_sendmsg_speculative(), cwist_reactor_add_out(), CWIST_WRITE_DONE, CWIST_WRITE_PENDING, g_cwist_running, cwist_http_async_conn::len, MSG_DONTWAIT, cwist_http_async_conn::obuf, cwist_http_async_conn::olen, and cwist_http_async_conn::reactor.
Referenced by cwist_app_http_handler_async().
| int cwist_http_coalesce_flush_blocking | ( | int | client_fd, |
| cwist_http_async_conn_t * | conn | ||
| ) |
Flush the coalesced-output stash, blocking in poll() until drained.
Definition at line 3737 of file http.c.
References cap, MSG_DONTWAIT, cwist_http_async_conn::obuf, and cwist_http_async_conn::olen.
Referenced by cwist_http_receive_request_nb(), and cwist_http_send_response_coalesced().
Continuations dropped because the reactor post queue was full; each one closed its connection. Exported for metrics/observability.
Definition at line 293 of file http.c.
References cap.
Referenced by cwist_metric_load(), and cwist_metrics_render_prometheus().
Format a time_t as an HTTP-date (RFC 7231).
Format a time_t as an HTTP-date (RFC 7231).
| fd | Connected client socket descriptor. |
Format a time_t as an HTTP-date (RFC 7231).
| t | Unix timestamp. |
| buf | Output buffer. |
| len | Buffer capacity. |
Definition at line 2108 of file http.c.
References cap.
| cwist_error_t cwist_http_header_add | ( | cwist_http_header_node ** | head, |
| const char * | key, | ||
| const char * | value | ||
| ) |
Prepend a header to the list.
Prepend a header to the list.
Add a header to the list.
| head | Header-list head pointer to update. |
| key | Header name to store. |
| value | Header value to store. |
Definition at line 1861 of file http.c.
Referenced by cwist_http_response_send_file().
| void cwist_http_header_free_all | ( | cwist_http_header_node * | head | ) |
Destroy every node in a request or response header list.
Free all headers.
| head | Head of the header linked list. |
Definition at line 2006 of file http.c.
Referenced by cwist_http_request_destroy(), and cwist_http_response_destroy().
| char * cwist_http_header_get | ( | cwist_http_header_node * | head, |
| const char * | key | ||
| ) |
Finds a header value by key.
Finds a header value by key.
Find a header value by key.
| head | Head of the header linked list. |
| key | Header name to search for. |
Definition at line 1880 of file http.c.
Referenced by cwist_http_response_add_hsts(), cwist_http_response_add_security_headers(), and cwist_http_response_send_file().
| size_t cwist_http_header_remove | ( | cwist_http_header_node ** | head, |
| const char * | key | ||
| ) |
Remove all headers matching a name, honoring per-node ownership (heap vs arena vs borrowed buffers).
Remove all headers matching a name, honoring per-node ownership (heap vs arena vs borrowed buffers).
| head | Pointer to the header-list head; updated as nodes are removed. |
| key | Header name (case-insensitive) to remove; all duplicates go. |
Ownership is handled per node: heap-owned nodes are freed, arena-owned nodes are left for the arena to reclaim, and borrowed key/value buffers are never freed individually. Applications should call this instead of hand-rolling unlink loops, which have repeatedly gotten that bookkeeping wrong.
Definition at line 1907 of file http.c.
References cwist_http_header_node::arena_owned, cap, cwist_free(), cwist_sstring_destroy(), cwist_sstring::data, head, cwist_http_header_node::key, cwist_http_header_node::next, and cwist_http_header_node::value.
Referenced by cwist_http_response_html_redirect().
Live C1M connections (accepted, not yet closed). The shutdown drain in cwist_app_listen_ex polls this to exit early once nothing is left. Acquire pairs with the handlers' release decrement, so once the drain sees zero, everything those handlers did happens before cwist_app_destroy().
Definition at line 301 of file http.c.
References cap.
| const char * cwist_http_method_to_string | ( | cwist_http_method_t | method | ) |
| cwist_http_request * cwist_http_parse_request | ( | const char * | raw_request | ) |
| cwist_http_request * cwist_http_parse_request_len | ( | const char * | buf, |
| size_t | len | ||
| ) |
Parse an HTTP/1.x request held in a memory buffer (length-based; the buffer may contain a binary body and need not be NUL-terminated).
Parse an HTTP/1.x request held in a memory buffer (length-based; the buffer may contain a binary body and need not be NUL-terminated).
Definition at line 4424 of file http.c.
References cap.
Referenced by cwist_app_dispatch_memory(), and cwist_app_dispatch_stream().
Tear down both pool variants.
Stops new work, drains queued tasks, retires the reactor generation and waits for in-flight posters, then stops, joins, and frees the C1M reactors.
Definition at line 836 of file http.c.
References cap, cwist_free(), cwist_reactor_destroy(), and cwist_reactor_stop().
Referenced by cwist_async_server_loop(), and cwist_http_server_loop().
Initialize the handler pool in the mode CWIST_C1M_MODE selects.
Initialize the handler pool in the mode CWIST_C1M_MODE selects.
Definition at line 678 of file http.c.
References cap, and cwist_http_pool_init_mode().
Initialize the handler pool as reactor workers (use_c1m) or the classic thread pool, without reading CWIST_C1M_MODE.
Initialize the handler pool as reactor workers (use_c1m) or the classic thread pool, without reading CWIST_C1M_MODE.
| use_c1m | true for the event-driven reactor (C1M) pool, false for the classic dynamic thread pool. |
Definition at line 696 of file http.c.
References cap, cwist_alloc(), cwist_free(), cwist_reactor_create(), and get_optimal_thread_count().
Referenced by cwist_async_server_loop(), cwist_http_pool_init(), and cwist_http_server_loop().
Requeue the current connection's next handler turn on the pool.
Definition at line 824 of file http.c.
References cwist_http_pool_submit().
Queue a connection for handling on the classic dynamic pool.
Enforces the inflight limit (over-limit connections get a bare 503 and are closed) and spawns an extra worker when queued demand exceeds idle capacity.
Definition at line 772 of file http.c.
References cap, cwist_alloc(), and MSG_DONTWAIT.
Referenced by cwist_http_pool_rearm_current(), and cwist_http_server_loop().
| bool cwist_http_pool_submit_async | ( | int | client_fd, |
| cwist_async_handler_t | handler, | ||
| void * | ctx | ||
| ) |
Submit a connection to the C1M async reactor pool.
Enforces the inflight limit (503 + close on overflow), sets the socket non-blocking, allocates the connection shell, and load-balances with power-of-two-choices over the per-worker load counters.
Definition at line 1468 of file http.c.
References cap, cwist_alloc(), cwist_fast_monotonic_sec(), cwist_sched_p2c_select_worker(), cwist_http_async_conn::fd, cwist_http_async_conn::handler, cwist_http_async_conn::last_active_sec, MSG_DONTWAIT, cwist_http_async_conn::reactor, cwist_http_async_conn::stash_grown_sec, cwist_http_async_conn::user_ctx, cwist_http_async_conn::virgin, and cwist_http_async_conn::worker_id.
| cwist_http_request * cwist_http_receive_request | ( | int | client_fd, |
| char * | read_buf, | ||
| size_t | buf_size, | ||
| size_t * | buf_len, | ||
| cwist_http_parse_error_t * | err_out | ||
| ) |
Blocking read of one full request from a classic-pool connection.
Receive and parse an HTTP request from a socket.
Bounds the header read by CWIST_HTTP_HEADERS_TIMEOUT_MS, answers a validated Expect: 100-continue, then completes the body per Content-Length or chunked framing. Leftover pipelined bytes are compacted into read_buf and *buf_len is updated.
| cwist_recv_status_t cwist_http_receive_request_nb | ( | cwist_http_async_conn_t * | conn, |
| cwist_http_request ** | out, | ||
| cwist_http_parse_error_t * | err_out | ||
| ) |
Try to assemble one complete request from the stash without any blocking IO. On CWIST_RECV_OK the consumed bytes are removed from the stash and *out holds a fully parsed request.
Definition at line 5035 of file http.c.
References cwist_http_request::body, cwist_http_async_conn::cap, cap, cwist_http_request::client_fd, cwist_http_request::content_length, cwist_alloc(), cwist_fast_monotonic_sec(), CWIST_HTTP_BODY_ZC_MIN, cwist_http_coalesce_flush_blocking(), CWIST_HTTP_MAX_BODY_SIZE, CWIST_HTTP_PARSE_BODY_TOO_LARGE, CWIST_HTTP_PARSE_EOF, CWIST_HTTP_PARSE_HEADER_OVERFLOW, CWIST_HTTP_PARSE_MALFORMED, CWIST_HTTP_PARSE_OK, CWIST_HTTP_READ_BUFFER_SIZE, cwist_http_request_destroy(), CWIST_LOG_WARN, CWIST_METRIC_HTTP_HEADER_OVERFLOW, cwist_metric_inc(), cwist_metrics_registry(), CWIST_RECV_FATAL, CWIST_RECV_NEED_MORE, CWIST_RECV_OK, cwist_sstring_adopt_len(), cwist_sstring_adopt_region(), cwist_sstring_create(), cwist_sstring_destroy(), cwist_http_request::expect_100_seen, cwist_http_async_conn::expect_continue_sent, cwist_http_async_conn::fd, cwist_http_async_conn::len, cwist_http_async_conn::rbuf, cwist_http_async_conn::stash_grown_sec, and cwist_http_request::te_chunked_seen.
Referenced by cwist_app_http_handler_async().
| cwist_http_request * cwist_http_request_create | ( | void | ) |
| void cwist_http_request_destroy | ( | cwist_http_request * | req | ) |
Destroy a parsed HTTP request and all nested allocations it owns.
Destroy an HTTP request object.
| req | Request object to destroy. |
Definition at line 2180 of file http.c.
Referenced by cwist_http_receive_request(), and cwist_http_receive_request_nb().
| void cwist_http_response_add_hsts | ( | cwist_http_response * | res | ) |
Add Strict-Transport-Security to a TLS response (HTTPS only).
RFC 6797 section 7.2 prohibits HSTS over plain HTTP. Call this from HTTPS handlers after cwist_http_response_add_security_headers(). No-op when the header is already present.
RFC 6797 section 7.2 prohibits HSTS over plain HTTP. Call this only from an HTTPS handler, after cwist_http_response_add_security_headers(). No-op when the header is already present.
| res | Response object to populate. |
Definition at line 1993 of file http.c.
References cwist_http_response::arena, cwist_http_header_get(), and cwist_http_response::headers.
| void cwist_http_response_add_security_headers | ( | cwist_http_response * | res | ) |
Add default security headers (CSP, X-Frame-Options, Permissions-Policy, etc.) if missing.
Transport-agnostic: safe to call on HTTP and HTTPS responses. HSTS is intentionally excluded — use cwist_http_response_add_hsts() on TLS only.
Add default security headers (CSP, X-Frame-Options, Permissions-Policy, etc.) if missing.
Add default security headers (CSP, X-Frame-Options, etc.) if missing.
Safe to call for both HTTP and HTTPS responses. HSTS is intentionally omitted here because RFC 6797 section 7.2 forbids sending it over plain HTTP; browsers ignore it on non-TLS connections anyway. Use cwist_http_response_add_hsts() from your HTTPS handler to add it there.
| res | Response object to populate. |
| cwist_http_response * cwist_http_response_create | ( | void | ) |
Allocate a response backed by its own arena.
Create a new HTTP response object.
Definition at line 2291 of file http.c.
Referenced by cwist_http_response_create_in_arena().
| cwist_http_response * cwist_http_response_create_in_arena | ( | void * | arena | ) |
Create a response inside an existing (request) arena. The response is bump-allocated from arena and shares its lifetime: cwist_http_response_destroy releases body/header resources but leaves the arena itself to the owner. arena must outlive the response.
Create a response inside an existing (request) arena. The response is bump-allocated from arena and shares its lifetime: cwist_http_response_destroy releases body/header resources but leaves the arena itself to the owner. arena must outlive the response.
| arena | Arena to allocate from; NULL falls back to cwist_http_response_create(). |
Definition at line 2306 of file http.c.
References cwist_http_response_create().
Referenced by cwist_http2_push_resource(), and cwist_http2_serve_connection_ex().
| void cwist_http_response_destroy | ( | cwist_http_response * | res | ) |
| cwist_error_t cwist_http_response_send_file | ( | cwist_http_response * | res, |
| const char * | file_path, | ||
| const char * | content_type_hint, | ||
| size_t * | out_size | ||
| ) |
Prepare a response to serve a file either by buffering or direct streaming.
| res | Response object to populate. |
| file_path | Filesystem path to the file that should be served. |
| content_type_hint | Optional MIME type override. |
| out_size | Optional output pointer receiving the file size in bytes. |
Definition at line 5223 of file http.c.
References cwist_http_response::body, cap, cwist_alloc(), CWIST_ENDPOINT_FILE, CWIST_ERR_INT16, cwist_free(), cwist_http_header_add(), cwist_http_header_get(), CWIST_HTTP_MAX_BODY_SIZE, CWIST_HTTP_OK, cwist_sstring_adopt_len(), cwist_sstring_borrow(), cwist_http_response::endpoint_opts, cwist_http_response::file_stream_auto_close, cwist_http_response::file_stream_fd, cwist_http_response::file_stream_len, cwist_http_response::file_stream_offset, cwist_http_response::headers, make_error(), cwist_http_response::status_code, and cwist_http_response::use_file_stream.
| int cwist_http_response_serialize | ( | cwist_http_response * | res, |
| char ** | out, | ||
| size_t * | out_len | ||
| ) |
Serialize a response into a freshly allocated HTTP/1.x buffer (status line + headers + body). Caller frees out with cwist_free(). File-streaming bodies cannot be serialized; the call fails for them.
Serialize a response into a freshly allocated HTTP/1.x buffer (status line + headers + body). Caller frees out with cwist_free(). File-streaming bodies cannot be serialized; the call fails for them.
Streaming responses are auto-finalized so the chunked terminator is present even when the handler skipped cwist_http_response_stream_end().
out and out_len set, or -1 (invalid input, file-stream body, or allocation failure). Definition at line 4439 of file http.c.
References cwist_http_response::body, cap, cwist_alloc(), CWIST_HTTP_MAX_HEADER_SIZE, cwist_http_response_stream_end(), cwist_sstring::data, cwist_http_response::is_ptr_body, cwist_http_response::ptr_body, cwist_http_response::ptr_body_len, cwist_sstring::size, cwist_http_response::stream_buf, cwist_http_response::stream_ended, cwist_http_response::stream_mode, and cwist_http_response::use_file_stream.
Referenced by cwist_app_dispatch_memory().
| void cwist_http_response_set_alt_svc | ( | cwist_http_response * | res, |
| const char * | alt_svc | ||
| ) |
Set the Alt-Svc header value for HTTP/3 upgrade advertisement.
| res | Response object to modify. |
| alt_svc | Alt-Svc header value (e.g., h3=":443"; ma=86400). Pass NULL to clear any previously set value. |
Definition at line 2376 of file http.c.
References cwist_http_response::alt_svc, cap, cwist_free(), and cwist_strdup().
| void cwist_http_response_set_body_ptr | ( | cwist_http_response * | res, |
| const void * | ptr, | ||
| size_t | len | ||
| ) |
Sets a direct pointer for the response body (Zero Copy). Use this when serving large files from memory mapped regions. The pointer must remain valid until the response is sent.
Sets a direct pointer for the response body (Zero Copy). Use this when serving large files from memory mapped regions. The pointer must remain valid until the response is sent.
| res | Response object to modify. |
| ptr | External body pointer. |
| len | Length of the external body in bytes. |
Definition at line 2346 of file http.c.
References cap, and cwist_http_response_set_body_ptr_managed().
Referenced by cwist_assets_respond().
| void cwist_http_response_set_body_ptr_managed | ( | cwist_http_response * | res, |
| const void * | ptr, | ||
| size_t | len, | ||
| cwist_http_body_cleanup_fn | cleanup, | ||
| void * | ctx | ||
| ) |
Attach a managed zero-copy body pointer and optional cleanup hook to a response.
| res | Response object to modify. |
| ptr | External body pointer. |
| len | Length of the external body in bytes. |
| cleanup | Optional cleanup callback for the body pointer. |
| ctx | Opaque context forwarded to the cleanup callback. |
Definition at line 2358 of file http.c.
References cwist_http_response::is_ptr_body, cwist_http_response::ptr_body, cwist_http_response::ptr_body_cleanup, cwist_http_response::ptr_body_cleanup_ctx, and cwist_http_response::ptr_body_len.
Referenced by cwist_http_response_set_body_ptr().
| int cwist_http_response_stream_begin | ( | cwist_http_response * | res | ) |
Switch a response to chunked streaming mode.
Discards any body assigned before the switch. Incompatible with pointer or file-stream bodies.
Definition at line 4503 of file http.c.
References cwist_http_response::body, cwist_http_response::is_ptr_body, cwist_sstring::size, cwist_http_response::stream_mode, and cwist_http_response::use_file_stream.
| int cwist_http_response_stream_end | ( | cwist_http_response * | res | ) |
Terminate a streaming response with the final zero-length chunk and flush.
Definition at line 4549 of file http.c.
References cwist_http_response::arena, cap, cwist_sstring_append_len(), cwist_http_response::stream_buf, cwist_http_response::stream_ended, cwist_http_response::stream_failed, and cwist_http_response::stream_mode.
Referenced by cwist_app_dispatch_memory(), cwist_app_dispatch_stream(), and cwist_http_response_serialize().
| int cwist_http_response_stream_write | ( | cwist_http_response * | res, |
| const char * | data, | ||
| size_t | len | ||
| ) |
Append one data chunk to a streaming response.
Frames the chunk (hex length prefix / CRLF suffix) and flushes through the sink. A sink failure marks the stream failed.
Definition at line 4519 of file http.c.
References cwist_http_response::arena, cap, cwist_sstring_append_len(), cwist_http_response::stream_buf, cwist_http_response::stream_ended, cwist_http_response::stream_failed, and cwist_http_response::stream_mode.
Send a minimal HTTP/1.x error response (Connection: close) on a socket, used to answer malformed requests before dropping them.
| msg | Plain-text body; NULL uses the status reason phrase. |
Send a minimal HTTP/1.x error response (Connection: close) on a socket, used to answer malformed requests before dropping them.
Send a minimal error response (Connection: close) for a failed request.
| fd | Connected client socket descriptor. |
| status | HTTP status code (reason phrase is derived from it). |
| msg | Plain-text body; NULL falls back to the reason phrase. |
| cwist_error_t cwist_http_send_response | ( | int | client_fd, |
| cwist_http_response * | res | ||
| ) |
Serialize and send an HTTP response to a connected client socket.
Send a response over a socket.
| client_fd | Connected client socket descriptor. |
| res | Response object to send. |
Definition at line 2878 of file http.c.
Referenced by cwist_http_async_send_response(), cwist_http_send_response_async(), and cwist_http_send_response_coalesced().
| cwist_async_send_status_t cwist_http_send_response_async | ( | int | client_fd, |
| cwist_http_response * | res, | ||
| cwist_http_async_conn_t * | conn, | ||
| bool | keep_alive, | ||
| bool | head_only | ||
| ) |
Async send variant that reports the outcome to the caller instead of re-arming or closing the connection itself (deferred-completion handoff).
Definition at line 3534 of file http.c.
References cwist_http_response::body, cap, cwist_alloc(), CWIST_ASYNC_SEND_CLOSE, CWIST_ASYNC_SEND_DEFERRED, CWIST_ASYNC_SEND_KEEPALIVE, CWIST_FILE_BEGIN_HANDLED, cwist_free(), CWIST_HTTP_MAX_HEADER_SIZE, cwist_http_send_response(), cwist_http_sendmsg_speculative(), cwist_reactor_add_out(), CWIST_WRITE_DONE, CWIST_WRITE_PENDING, cwist_sstring::data, cwist_http_response::is_ptr_body, cwist_http_async_conn::len, MSG_DONTWAIT, cwist_http_response::ptr_body, cwist_http_response::ptr_body_len, cwist_http_async_conn::reactor, cwist_sstring::size, and cwist_http_response::use_file_stream.
| cwist_async_send_status_t cwist_http_send_response_coalesced | ( | int | client_fd, |
| cwist_http_response * | res, | ||
| cwist_http_async_conn_t * | conn, | ||
| bool | keep_alive, | ||
| bool | head_only | ||
| ) |
Coalescing variant of the async send: serialize small responses directly into the connection's output stash so one reactor turn flushes many responses with a single write.
Oversized responses, cap pressure, and file streams drain through the bounded-blocking or parked paths instead of unbounded buffering.
Definition at line 3779 of file http.c.
References cwist_http_response::body, cap, cwist_alloc(), CWIST_ASYNC_SEND_CLOSE, CWIST_ASYNC_SEND_DEFERRED, CWIST_ASYNC_SEND_KEEPALIVE, cwist_fast_monotonic_sec(), CWIST_FILE_BEGIN_HANDLED, cwist_free(), cwist_http_coalesce_flush_blocking(), CWIST_HTTP_COALESCE_MAX, CWIST_HTTP_MAX_HEADER_SIZE, cwist_http_send_response(), cwist_http_sendmsg_speculative(), cwist_reactor_add_out(), CWIST_WRITE_DONE, CWIST_WRITE_ERR, CWIST_WRITE_PENDING, cwist_sstring::data, cwist_http_response::is_ptr_body, cwist_http_async_conn::len, MSG_DONTWAIT, cwist_http_async_conn::obuf, cwist_http_async_conn::ocap, cwist_http_async_conn::olen, cwist_http_response::ptr_body, cwist_http_response::ptr_body_len, cwist_http_async_conn::reactor, cwist_sstring::size, cwist_http_async_conn::stash_grown_sec, and cwist_http_response::use_file_stream.
| cwist_error_t cwist_http_send_response_head | ( | int | client_fd, |
| cwist_http_response * | res | ||
| ) |
Send only the status line and headers of a response (HEAD replies). Content-Length still reflects the would-be body; body resources are released without being transmitted.
Send only the status line and headers of a response (HEAD replies). Content-Length still reflects the would-be body; body resources are released without being transmitted.
Send only the status line and headers (HEAD replies).
| size_t cwist_http_serialize_headers | ( | cwist_http_response * | res, |
| char * | buf, | ||
| size_t | buf_size | ||
| ) |
Serialize only the status line and headers into a caller buffer. Used by the TLS send path to stream header block and body separately.
Serialize only the status line and headers into a caller buffer. Used by the TLS send path to stream header block and body separately.
Serialize only the status line and headers into a caller buffer.
Non-static wrapper around serialize_headers() so the TLS send path can stream headers and body separately instead of materializing one blob.
| res | Response object to serialize. |
| buf | Destination buffer for the header block. |
| buf_size | Total capacity of buf in bytes. |
| cwist_error_t cwist_http_server_loop | ( | int | server_fd, |
| cwist_server_config * | config, | ||
| void(*)(int, void *) | handler, | ||
| void * | ctx | ||
| ) |
Run the main HTTP accept loop using the configured concurrency strategy.
| server_fd | Listening server socket. |
| config | Server concurrency configuration flags. |
| handler | Callback that handles one accepted client. |
| ctx | Opaque callback context. |
Return the standard reason phrase for an HTTP status code (e.g. 404 -> "Not Found"). Unknown codes return NULL; applications may also assign any int to a response status_code for non-standard codes.
Return the standard reason phrase for an HTTP status code (e.g. 404 -> "Not Found"). Unknown codes return NULL; applications may also assign any int to a response status_code for non-standard codes.
Definition at line 3970 of file http.c.
References cap.
Referenced by cwist_http_coalesce_error_response(), and cwist_http_send_error_response().
| cwist_http_method_t cwist_http_string_to_method | ( | const char * | method_str | ) |
| cwist_http_method_t cwist_http_string_to_method_len | ( | const char * | str, |
| size_t | len | ||
| ) |
Parse a method token (with explicit length) into a method enum.
Uses a SWAR 4-byte magic fast path for GET/POST/PUT/DELETE/HEAD, then exact-length comparisons.
Definition at line 1584 of file http.c.
References cap, CWIST_HTTP_DELETE, CWIST_HTTP_GET, CWIST_HTTP_HEAD, CWIST_HTTP_OPTIONS, CWIST_HTTP_PATCH, CWIST_HTTP_POST, CWIST_HTTP_PUT, CWIST_HTTP_UNKNOWN, MAGIC_DELE, MAGIC_GET, MAGIC_HEAD, MAGIC_POST, and MAGIC_PUT.
Referenced by cwist_http_string_to_method().
| cwist_sstring * cwist_http_stringify_response | ( | cwist_http_response * | res | ) |
| int cwist_make_socket_ipv4 | ( | struct sockaddr_in * | sockv4, |
| const char * | address, | ||
| uint16_t | port, | ||
| uint16_t | backlog | ||
| ) |
Create an IPv4 socket and perform bind/listen.
Create an IPv4 socket and perform bind/listen.
Create an IPv4 socket and bind/listen.
| sockv4 | Output sockaddr structure populated for the bind call. |
| address | IPv4 address string to bind. |
| port | TCP port to listen on. |
| backlog | Listen backlog passed to listen(2). |
Whether the TCP_CORK coalescing layer is active for cleartext HTTP/1.1 responses. Enabled at runtime with CWIST_USE_TCP_CORK=1 (burst size via CWIST_TCP_CORK_BURST, default 256 KiB); always false off-Linux.
Whether the TCP_CORK coalescing layer is active for cleartext HTTP/1.1 responses. Enabled at runtime with CWIST_USE_TCP_CORK=1 (burst size via CWIST_TCP_CORK_BURST, default 256 KiB); always false off-Linux.
Definition at line 2684 of file http.c.
Referenced by cwist_http_send_response().
Return the number of CPUs available to this process.
Honors the process CPU affinity mask where the platform supports it (sched_getaffinity on Linux); falls back to sysconf(3)/sysctl and ultimately 1 when the count cannot be determined.
Definition at line 99 of file http.c.
Referenced by get_optimal_thread_count().
Compute the HTTP worker/event-loop thread count.
Resolution order: a value fixed with cwist_http_pool_limit_core(), then the CWIST_WORKER_THREADS environment override, then CPU-core based sizing modified by CWIST_WORKERS (worker-process count) and CWIST_C1M_MODE. C1M mode divides the core budget across worker processes (one event loop per CPU); classic mode multiplies it to cover blocking keep-alive handlers.
Definition at line 159 of file http.c.
References cap, count, and get_cpu_cores().
Referenced by cwist_http_pool_init_mode(), https_pool_destroy(), and https_pool_init().
| int headers_have_content_length | ( | cwist_http_header_node * | headers | ) |
Definition at line 1541 of file http.c.
Referenced by cwist_make_socket_ipv4().
Definition at line 1543 of file http.c.
Referenced by cwist_make_socket_ipv4().
Definition at line 1545 of file http.c.
Referenced by cwist_make_socket_ipv4().
Definition at line 1544 of file http.c.
Referenced by cwist_make_socket_ipv4().
Definition at line 1542 of file http.c.
Referenced by cwist_make_socket_ipv4().