6#ifndef __CWIST_HTTP_H__
7#define __CWIST_HTTP_H__
18#ifndef CWIST_BAREMETAL
19#include <netinet/in.h>
20#include <sys/socket.h>
142#define CWIST_HTTP_MAX_HEADER_SIZE (8 * 1024)
143#define CWIST_HTTP_MAX_BODY_SIZE (10 * 1024 * 1024)
144#define CWIST_HTTP_READ_BUFFER_SIZE (16 * 1024)
145#define CWIST_HTTP_TIMEOUT_MS 30000
146#define CWIST_HTTPS_HANDSHAKE_TIMEOUT_MS 45000
147#define CWIST_HTTP_HEADERS_TIMEOUT_MS 120000
148#define CWIST_HTTP_BODY_IDLE_TIMEOUT_MS 60000
149#define CWIST_HTTP2_IDLE_TIMEOUT_MS 300000
150#define CWIST_HTTP_KEEP_ALIVE_TIMEOUT_SEC \
353 const char *content_type_hint,
size_t *out_size);
411 void (*handler_func)(
int client_fd,
void *ctx),
void *ctx);
421 void (*handler)(
int,
void *),
void *ctx);
526 bool keep_alive,
bool head_only);
536 bool keep_alive,
bool head_only);
547#define CWIST_HTTP_COALESCE_MAX (256 * 1024)
563 bool keep_alive,
bool head_only);
Auto-Caching Layer for repetitive requests.
Database operations wrapper (SQLite3).
Safe string type with helper methods.
Endpoint-level behavior flags for CWIST apps.
uint32_t cwist_endpoint_opt_t
Bitmask type controlling endpoint behavior.
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)
Receive and parse an HTTP request from a socket.
int headers_have_content_length(cwist_http_header_node *headers)
Detect whether a header list already defines Content-Length.
void cwist_http_send_error_response(int fd, int status, const char *msg)
Send a minimal error response (Connection: close) for a failed request.
struct cwist_http_request cwist_http_request
const int CWIST_HTTP_LISTEN_FAILED
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.
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.
const int CWIST_CREATE_SOCKET_FAILED
cwist_error_t cwist_http_send_response(int client_fd, cwist_http_response *res)
Send a response over a socket.
struct cwist_http_response cwist_http_response
cwist_http_parse_error_t
Failure reason reported by the request receive APIs.
@ CWIST_HTTP_PARSE_BODY_TOO_LARGE
@ CWIST_HTTP_PARSE_HEADER_OVERFLOW
@ CWIST_HTTP_PARSE_MALFORMED
@ CWIST_HTTP_PARSE_TE_UNSUPPORTED
@ CWIST_HTTP_PARSE_EXPECT_FAILED
int cwist_make_socket_ipv4(struct sockaddr_in *sockv4, const char *address, uint16_t port, uint16_t backlog)
Create an IPv4 socket and bind/listen.
char * cwist_http_header_get(cwist_http_header_node *head, const char *key)
Find a header value by key.
cwist_error_t cwist_http_send_response_head(int client_fd, cwist_http_response *res)
Send only the status line and headers (HEAD replies).
@ CWIST_HTTP_UNAUTHORIZED
@ CWIST_HTTP_INTERNAL_ERROR
@ CWIST_HTTP_NOT_IMPLEMENTED
void cwist_http_request_destroy(cwist_http_request *req)
Destroy an HTTP request object.
cwist_http_request * cwist_http_parse_request(const char *raw_request)
Parse a raw HTTP request string.
void cwist_http_response_add_security_headers(cwist_http_response *res)
Add default security headers (CSP, X-Frame-Options, etc.) if missing.
cwist_sstring * cwist_http_stringify_response(cwist_http_response *res)
Serialize a response to a string.
cwist_error_t cwist_http_header_add(cwist_http_header_node **head, const char *key, const char *value)
Add a header to the list.
void cwist_http_response_destroy(cwist_http_response *res)
Destroy an HTTP response object.
const int CWIST_HTTP_BIND_FAILED
void cwist_http_header_free_all(cwist_http_header_node *head)
Free all headers.
cwist_http_response * cwist_http_response_create(void)
Create a new HTTP response object.
struct cwist_server_config cwist_server_config
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.
const int CWIST_HTTP_UNAVAILABLE_ADDRESS
const char * cwist_http_method_to_string(cwist_http_method_t method)
Convert method enum to string.
cwist_http_method_t cwist_http_string_to_method(const char *method_str)
Convert method string to enum.
const int CWIST_HTTP_SETSOCKOPT_FAILED
struct cwist_http_header_node cwist_http_header_node
Linked list for headers to handle multiple headers easily.
cwist_http_request * cwist_http_request_create(void)
Create a new HTTP request object.
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.
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...
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 lev...
cwist_async_action_t(* cwist_async_handler_t)(int fd, struct cwist_http_async_conn *conn)
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.
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 connect...
long get_cpu_cores(void)
Return the number of CPUs available to this process.
long cwist_http_inflight_count(void)
cwist_async_send_status_t
@ CWIST_ASYNC_SEND_DEFERRED
@ CWIST_ASYNC_SEND_KEEPALIVE
time_t cwist_http_parse_date(const char *str)
Parse an HTTP-date string into a time_t.
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 rea...
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.
int cwist_http_response_stream_end(cwist_http_response *res)
Terminate a streaming response with the final zero-length chunk and flush.
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 memor...
int cwist_http_pool_init(void)
Initialize the handler pool in the mode CWIST_C1M_MODE selects.
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).
cwist_sstring * cwist_get_client_ip_from_fd(int fd)
Resolve the peer IP address for a connected client socket.
bool cwist_tcp_cork_enabled(void)
Whether the TCP_CORK coalescing layer is active for cleartext HTTP/1.1 responses. Enabled at runtime ...
void cwist_http_pool_limit_core(unsigned int limit)
Fix the HTTP pool worker count to a specific value.
void cwist_http_format_date(time_t t, char *buf, size_t len)
Format a time_t as an HTTP-date (RFC 7231).
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.
long get_optimal_thread_count(void)
Compute the HTTP worker/event-loop thread count.
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.
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 con...
@ CWIST_HTTP_MULTI_STATUS
@ CWIST_HTTP_NETWORK_AUTHENTICATION_REQUIRED
@ CWIST_HTTP_VARIANT_ALSO_NEGOTIATES
@ CWIST_HTTP_PAYMENT_REQUIRED
@ CWIST_HTTP_MOVED_PERMANENTLY
@ CWIST_HTTP_INSUFFICIENT_STORAGE
@ CWIST_HTTP_PROXY_AUTHENTICATION_REQUIRED
@ CWIST_HTTP_UPGRADE_REQUIRED
@ CWIST_HTTP_VERSION_NOT_SUPPORTED
@ CWIST_HTTP_NOT_EXTENDED
@ CWIST_HTTP_MISDIRECTED_REQUEST
@ CWIST_HTTP_NOT_MODIFIED
@ CWIST_HTTP_RESET_CONTENT
@ CWIST_HTTP_UNPROCESSABLE_CONTENT
@ CWIST_HTTP_METHOD_NOT_ALLOWED
@ CWIST_HTTP_PAYLOAD_TOO_LARGE
@ CWIST_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS
@ CWIST_HTTP_PARTIAL_CONTENT
@ CWIST_HTTP_GATEWAY_TIMEOUT
@ CWIST_HTTP_LOOP_DETECTED
@ CWIST_HTTP_EXPECTATION_FAILED
@ CWIST_HTTP_TEMPORARY_REDIRECT
@ CWIST_HTTP_MULTIPLE_CHOICES
@ CWIST_HTTP_TOO_MANY_REQUESTS
@ CWIST_HTTP_NON_AUTHORITATIVE_INFORMATION
@ CWIST_HTTP_PRECONDITION_REQUIRED
@ CWIST_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE
@ CWIST_HTTP_UNSUPPORTED_MEDIA_TYPE
@ CWIST_HTTP_FAILED_DEPENDENCY
@ CWIST_HTTP_ALREADY_REPORTED
@ CWIST_HTTP_NOT_ACCEPTABLE
@ CWIST_HTTP_PERMANENT_REDIRECT
@ CWIST_HTTP_LENGTH_REQUIRED
@ CWIST_HTTP_REQUEST_TIMEOUT
@ CWIST_HTTP_RANGE_NOT_SATISFIABLE
@ CWIST_HTTP_URI_TOO_LONG
@ CWIST_HTTP_PRECONDITION_FAILED
@ CWIST_HTTP_SWITCHING_PROTOCOLS
@ CWIST_HTTP_INTERNAL_SERVER_ERROR
@ CWIST_HTTP_CONTENT_TOO_LARGE
@ CWIST_HTTP_SERVICE_UNAVAILABLE
void cwist_http_response_add_hsts(cwist_http_response *res)
Add Strict-Transport-Security to a TLS response (HTTPS only).
int cwist_http_coalesce_error_response(cwist_http_async_conn_t *conn, int status)
Build a minimal text error response into the coalesce stash.
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.
cwist_coalesce_flush_status_t
@ CWIST_COALESCE_FLUSH_DONE
@ CWIST_COALESCE_FLUSH_ERROR
@ CWIST_COALESCE_FLUSH_PARKED
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.
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...
void cwist_http_pool_submit(int client_fd, void(*handler)(int, void *), void *ctx)
Queue a connection for handling on the classic dynamic pool.
long cwist_http_continuation_shed_count(void)
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_response_stream_write(cwist_http_response *res, const char *data, size_t len)
Append one data chunk to a streaming response.
void cwist_http_pool_destroy(void)
Tear down both pool variants.
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 s...
void(* cwist_http_body_cleanup_fn)(const void *ptr, size_t len, void *ctx)
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)....
int cwist_http_response_stream_begin(cwist_http_response *res)
Switch a response to chunked streaming mode.
int cwist_http_pool_init_mode(bool use_c1m)
Initialize the handler pool as reactor workers (use_c1m) or the classic thread pool,...
struct cwist_http_async_conn cwist_http_async_conn_t
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.
const char * cwist_http_status_reason(int status)
Return the standard reason phrase for an HTTP status code (e.g. 404 -> "Not Found")....
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.
Query string parser and map.
struct cwist_reactor cwist_reactor_t
Main Application Context.
Wrapper for Database Operations. Currently uses SQLite3.
Integrated error structure used throughout the system.
bool expect_continue_sent
cwist_reactor_t * reactor
cwist_async_handler_t handler
uint64_t kern_last_mono_ns
cwist_bdr_cursor_t bdr_cursor
cwist_query_map * query_params
Parsed query parameters.
bool te_chunked_seen
Parser saw and validated Transfer-Encoding: chunked (HTTP/1.1).
char * csrf_token
CSRF token populated by csrf middleware.
cwist_query_map * flash
Flash messages for this request (one-time read).
cwist_sstring * path
e.g., "/users/1"
void * async_conn
C1M connection shell when on the reactor path (internal).
cwist_sstring * query
e.g., "active=true" (raw)
bool expect_100_seen
Parser saw and validated Expect: 100-continue (HTTP/1.1).
void * route_middleware_state
Router middleware chain state (internal).
void * h2_queue
HTTP/2 async queue when on H2 path (internal).
struct cwist_app * app
Owning app context (if any).
uint32_t stream_id
HTTP/2 or HTTP/3 stream ID (0 for HTTP/1.1).
bool ws_async_handoff
WebSocket async path took fd ownership; C1M layer must detach.
void * arena
Per-request arena for bump-allocated structs (internal).
void * session
cwist_session_t pointer set by session middleware.
cwist_sstring * version
e.g., "HTTP/1.1"
void * private_data
Internal framework use (protocol-specific context).
cwist_query_map * path_params
Parsed path parameters (e.g. :id)
void * https_conn
HTTPS connection wrapper when on TLS path (internal).
cwist_http_header_node * headers
cwist_endpoint_opt_t endpoint_opts
Behavior hints for the active endpoint.
cwist_db * db
Shared database handle from cwist_app.
cwist_http_method_t method
HTTP Response Object. Supports standard string body or Zero-Copy pointer body.
cwist_endpoint_opt_t endpoint_opts
Mirrors req->endpoint_opts.
cwist_sstring * version
e.g., "HTTP/1.1"
cwist_sstring * status_text
e.g., "OK"
void * ptr_body_cleanup_ctx
User data for release hook.
int file_stream_fd
Open descriptor for sendfile.
bool use_file_stream
Fast File Streaming.
const void * ptr_body
Pointer to external data (e.g., mmap region)
cwist_http_status_t status_code
bool file_stream_auto_close
Close fd after streaming.
off_t file_stream_offset
Current offset for sendfile loop.
char * alt_svc
Alt-Svc header for HTTP/3 upgrade advertisement.
cwist_http_header_node * headers
bool is_ptr_body
Zero-Copy Pointer Body.
cwist_http_body_cleanup_fn ptr_body_cleanup
Optional release hook.
size_t stream_flushed
stream_buf prefix already pushed to stream_sink.
bool stream_head_sent
Head serialized and pushed to the sink.
int(* stream_sink)(void *ctx, const char *data, size_t len)
Live sink (streaming dispatch only).
void * arena
Per-response arena for bump-allocated structs (internal).
bool stream_mode
cwist_http_response_stream_begin() ran.
cwist_sstring * stream_buf
Framed chunk payload (hex\r\ndata\r ...).
void * async
Owning cwist_async while deferred (read-only).
size_t ptr_body_len
Length of external data.
bool stream_failed
A live sink rejected a chunk/head.
size_t file_stream_len
Total bytes to stream.
bool deferred
Deferred-response handoff (internal; see net/http/async.h)
bool stream_ended
cwist_http_response_stream_end() ran.
bool use_forking
Process per request.
bool use_threading
Thread per request.
bool use_epoll
Use epoll for accepting.
Unified error code and type definitions for the CWIST system layer.