|
cwist
Modern C web framework with libttak runtime
|
HTTPS/TLS wrapper interface. More...
#include <cwist/net/http/http.h>#include <cwist/sys/err/cwist_err.h>#include <openssl/ssl.h>#include <openssl/err.h>#include <pthread.h>

Go to the source code of this file.
Classes | |
| struct | cwist_https_context |
| struct | cwist_https_connection |
| struct | cwist_https_options |
Macros | |
| #define | HTTPS_THREAD_POOL_SIZE HTTP_THREAD_POOL_SIZE |
Enumerations | |
| enum | cwist_https_protocol { CWIST_HTTPS_PROTOCOL_NONE = 0 , CWIST_HTTPS_PROTOCOL_HTTP11 , CWIST_HTTPS_PROTOCOL_HTTP2 , CWIST_HTTPS_PROTOCOL_HTTP3 } |
| enum | cwist_https_park_class { CWIST_HTTPS_PARK_HTTP1 = 0 , CWIST_HTTPS_PARK_HTTP2 = 1 } |
Functions | |
| bool | cwist_https_park (cwist_https_connection *conn, uint64_t idle_ms, cwist_https_park_class cls) |
| Hand an idle connection back to the HTTPS pool's park set. | |
| bool | cwist_https_conn_idle (cwist_https_connection *conn) |
True when conn has no buffered TLS bytes and nothing readable. | |
| uint64_t | cwist_https_idle_timeout_ms (void) |
| Idle keep-alive budget for parked HTTP/1.1 TLS connections, in ms. CWIST_HTTPS_IDLE_TIMEOUT_MS overrides the default (CWIST_HTTP_TIMEOUT_MS, the same 30 s the blocking header read waited). | |
| cwist_error_t | cwist_https_init_context (cwist_https_context **ctx, const char *cert_path, const char *key_path) |
| cwist_error_t | cwist_https_init_context_with_options (cwist_https_context **ctx, const char *cert_path, const char *key_path, const cwist_https_options *options, cwist_app *app) |
| void | cwist_https_destroy_context (cwist_https_context *ctx) |
| Free an HTTPS context and release its OpenSSL resources. | |
| cwist_error_t | cwist_https_reload_context (cwist_https_context *ctx, const char *cert_path, const char *key_path, cwist_app *app) |
| Hot-reload the certificate chain and key of a live HTTPS context. | |
| cwist_error_t | cwist_https_accept (cwist_https_context *ctx, int client_fd, cwist_https_connection **conn) |
| bool | cwist_https_connection_uses_http2 (const cwist_https_connection *conn) |
| Gracefully close an HTTPS connection and free its buffers. | |
| cwist_https_protocol | cwist_https_connection_protocol (const cwist_https_connection *conn) |
| void | cwist_https_close_connection (cwist_https_connection *conn) |
| cwist_http_request * | cwist_https_receive_request (cwist_https_connection *conn) |
| Read from the TLS stream until a full HTTP request has been assembled. | |
| cwist_error_t | cwist_https_send_response (cwist_https_connection *conn, cwist_http_response *res) |
| Serialize an HTTP response and send it over an active TLS connection. | |
| cwist_error_t | cwist_https_send_response_head (cwist_https_connection *conn, cwist_http_response *res) |
| cwist_error_t | cwist_https_server_loop (int server_fd, cwist_https_context *ctx, void(*handler)(cwist_https_connection *conn, void *), void *user_ctx) |
| int | https_pool_init (void) |
| Create the worker threads, mutex, and condition variables of the global HTTPS thread pool. No-op if already initialized. | |
| void | https_pool_submit (int client_fd, cwist_https_context *ctx, void(*handler)(cwist_https_connection *, void *), void *user_ctx) |
| Queue a freshly accepted client socket whose TLS handshake still needs to run in a pool worker. | |
| void | https_pool_submit_conn (cwist_https_connection *conn, cwist_https_context *ctx, void(*handler)(cwist_https_connection *, void *), void *user_ctx) |
| Submit an established connection back to the worker pool (e.g. keep-alive re-arm after async defer). Blocks while the queue is full; on pool shutdown closes the connection instead of queueing. | |
| void | https_pool_destroy (void) |
| Shut down the global HTTPS thread pool: signal workers to exit, join them, close any connections still queued, and destroy the pool's mutex and condition variables. No-op if never initialized. | |
| void | cwist_https_dispatch (int client_fd, cwist_https_context *ctx, void(*handler)(cwist_https_connection *, void *), void *user_ctx) |
| Accept a TLS connection without parking a worker on the handshake. Completes the handshake inline when the ClientHello is already pending, otherwise parks the connection with the handshake shepherd thread and returns immediately. Established sessions are submitted to the HTTPS worker pool. Safe to call from reactor callbacks. | |
| long | cwist_https_pending_handshakes (void) |
| Number of TLS handshakes currently parked in the shepherd. | |
| long | cwist_https_tls_handshakes_total (void) |
| Total TLS handshakes that completed (full + resumed). | |
| long | cwist_https_tls_handshakes_resumed_total (void) |
| TLS handshakes completed via session resumption/ticket. | |
| long | cwist_https_tls_handshakes_tls12_total (void) |
| Handshakes that negotiated TLS 1.2. | |
| long | cwist_https_tls_handshakes_tls13_total (void) |
| Handshakes that negotiated TLS 1.3. | |
| long | cwist_https_tls_ciphers_aes128_gcm_total (void) |
| Handshakes negotiated with TLS_AES_128_GCM_SHA256. | |
| long | cwist_https_tls_ciphers_aes256_gcm_total (void) |
| Handshakes negotiated with TLS_AES_256_GCM_SHA384. | |
| long | cwist_https_tls_ciphers_chacha20_total (void) |
| Handshakes negotiated with TLS_CHACHA20_POLY1305_SHA256. | |
| long | cwist_https_tls_ciphers_other_total (void) |
| Handshakes negotiated with any other cipher. | |
| long | cwist_https_tls_connections_active (void) |
| Currently established TLS connections (wrap minus teardown). | |
HTTPS/TLS wrapper interface.
Definition in file https.h.
| #define HTTPS_THREAD_POOL_SIZE HTTP_THREAD_POOL_SIZE |
Idle class of a parked connection; each class has its own expiry order.
— SSL Structures —
| cwist_error_t cwist_https_accept | ( | cwist_https_context * | ctx, |
| int | client_fd, | ||
| cwist_https_connection ** | conn | ||
| ) |
Perform SSL handshake on an accepted socket. Returns a new cwist_https_connection wrapper.
| void cwist_https_close_connection | ( | cwist_https_connection * | conn | ) |
Close and free the HTTPS connection.
Definition at line 1875 of file https.c.
Referenced by https_pool_destroy(), and https_pool_submit_conn().
| bool cwist_https_conn_idle | ( | cwist_https_connection * | conn | ) |
True when conn has no buffered TLS bytes and nothing readable.
Definition at line 683 of file https.c.
References cwist_https_connection::buf_len, cap, cwist_https_connection::fd, cwist_https_connection::ssl, and SSL_pending.
Referenced by cwist_http2_serve_connection_ex().
| cwist_https_protocol cwist_https_connection_protocol | ( | const cwist_https_connection * | conn | ) |
Returns the protocol selected by ALPN, or HTTP/1.1 when no higher protocol matched.
Definition at line 1821 of file https.c.
References CWIST_HTTPS_PROTOCOL_NONE, and cwist_https_connection::negotiated_protocol.
| bool cwist_https_connection_uses_http2 | ( | const cwist_https_connection * | conn | ) |
Gracefully close an HTTPS connection and free its buffers.
Returns true when ALPN negotiated h2 on this TLS connection.
| conn | HTTPS connection wrapper to close. |
Definition at line 1817 of file https.c.
References CWIST_HTTPS_PROTOCOL_HTTP2, and cwist_https_connection::negotiated_protocol.
| void cwist_https_destroy_context | ( | cwist_https_context * | ctx | ) |
| void cwist_https_dispatch | ( | int | client_fd, |
| cwist_https_context * | ctx, | ||
| void(*)(cwist_https_connection *, void *) | handler, | ||
| void * | user_ctx | ||
| ) |
Accept a TLS connection without parking a worker on the handshake. Completes the handshake inline when the ClientHello is already pending, otherwise parks the connection with the handshake shepherd thread and returns immediately. Established sessions are submitted to the HTTPS worker pool. Safe to call from reactor callbacks.
Definition at line 1141 of file https.c.
References cap, and https_pool_submit().
Referenced by cwist_https_server_loop().
Idle keep-alive budget for parked HTTP/1.1 TLS connections, in ms. CWIST_HTTPS_IDLE_TIMEOUT_MS overrides the default (CWIST_HTTP_TIMEOUT_MS, the same 30 s the blocking header read waited).
Definition at line 710 of file https.c.
References cap, and CWIST_HTTP_TIMEOUT_MS.
| cwist_error_t cwist_https_init_context | ( | cwist_https_context ** | ctx, |
| const char * | cert_path, | ||
| const char * | key_path | ||
| ) |
| cwist_error_t cwist_https_init_context_with_options | ( | cwist_https_context ** | ctx, |
| const char * | cert_path, | ||
| const char * | key_path, | ||
| const cwist_https_options * | options, | ||
| cwist_app * | app | ||
| ) |
Initialize an HTTPS context with explicit transport options. The HTTP/2 option only applies the standard TLS/ALPN profile today. Application request handling remains HTTP/1.1 unless a frame engine is added.
Definition at line 1451 of file https.c.
References cap, cwist_alloc(), CWIST_ERR_INT16, cwist_https_options::enable_http2, cwist_https_options::enable_http3, make_error(), SSL_CTX_free, and SSL_CTX_set_alpn_select_cb.
Referenced by cwist_https_init_context().
| bool cwist_https_park | ( | cwist_https_connection * | conn, |
| uint64_t | idle_ms, | ||
| cwist_https_park_class | cls | ||
| ) |
Hand an idle connection back to the HTTPS pool's park set.
— API Functions —
A pool thread that has nothing to read on conn calls this instead of blocking in poll(): the connection is watched by one epoll thread and resubmitted to the pool when bytes arrive, so an idle keep-alive connection costs memory but no thread. Returns true when the connection was parked; the caller must then return without touching conn again (another pool thread may already be serving it). Returns false when parking is unavailable (full GC, CWIST_HTTPS_PARK=0, shutdown); the caller keeps serving the connection the blocking way.
| idle_ms | Idle budget before the class-specific expiry action. |
Definition at line 672 of file https.c.
References cap.
Referenced by cwist_http2_serve_connection_ex().
| cwist_http_request * cwist_https_receive_request | ( | cwist_https_connection * | conn | ) |
Read from the TLS stream until a full HTTP request has been assembled.
Read data from the SSL connection and parse it as an HTTP request. Uses cwist_http_parse_request internally.
| conn | Active HTTPS connection wrapper. |
| cwist_error_t cwist_https_reload_context | ( | cwist_https_context * | ctx, |
| const char * | cert_path, | ||
| const char * | key_path, | ||
| cwist_app * | app | ||
| ) |
Hot-reload the certificate chain and key of a live HTTPS context.
Builds and fully validates a new SSL_CTX, then atomically swaps it into ctx: established connections and in-progress handshakes keep running on the old SSL_CTX (held alive by BoringSSL reference counting), while new handshakes present the new certificate. The shared session-ticket key is carried over, so session resumption survives the reload.
Safe to call from any thread while listeners are serving.
| ctx | HTTPS context created by cwist_https_init_context*(). |
| cert_path | Path to the new PEM certificate chain. |
| key_path | Path to the new PEM private key. |
| app | Application context for the PQC layer (may be NULL). |
Hot-reload the certificate chain and key of a live HTTPS context.
| ctx | Live HTTPS context whose SSL_CTX is replaced. |
| cert_path | Path to the new PEM certificate chain. |
| key_path | Path to the new PEM private key. |
| app | Application context for the PQC layer (may be NULL). |
The new SSL_CTX is fully built and validated before the swap. Connections established (or handshaking) on the old SSL_CTX keep it alive through BoringSSL's reference counting and finish on the old certificate; new handshakes use the new one. The shared session-ticket key is carried over unchanged, so tickets issued before the reload still resume afterwards (see docs/decisions/0002-tls-hot-reload.md).
Definition at line 1508 of file https.c.
References cap, cwist_https_context::ctx, cwist_https_context::ctx_lock, CWIST_ERR_INT16, cwist_https_options::enable_http2, cwist_https_context::http2_enabled, cwist_https_context::http3_enabled, make_error(), SSL_CTX_free, SSL_CTX_set_alpn_select_cb, SSL_CTX_set_ex_data, SSL_CTX_set_tlsext_ticket_key_cb, and cwist_https_context::ticket_key.
Referenced by cwist_app_reload_tls().
| cwist_error_t cwist_https_send_response | ( | cwist_https_connection * | conn, |
| cwist_http_response * | res | ||
| ) |
Serialize an HTTP response and send it over an active TLS connection.
Serialize an HTTP response and send it over the SSL connection. Streams the header block and body separately (zero-copy; no intermediate serialization blob) and supports pointer bodies and file streams.
Zero-copy counterpart of the plaintext send path: the header block is serialized into a stack buffer and written first, then the body is streamed straight from its origin (pointer body, sstring, or file stream) instead of materializing one contiguous heap blob.
| conn | Active HTTPS connection wrapper. |
| res | Response object to serialize. |
| cwist_error_t cwist_https_send_response_head | ( | cwist_https_connection * | conn, |
| cwist_http_response * | res | ||
| ) |
Definition at line 2197 of file https.c.
References cap, CWIST_ERR_INT16, cwist_http_header_add(), cwist_http_header_get(), CWIST_HTTP_MAX_HEADER_SIZE, cwist_http_serialize_headers(), cwist_https_connection::fd, cwist_http_response::headers, cwist_https_connection::http3_enabled, make_error(), and cwist_https_connection::ssl.
| cwist_error_t cwist_https_server_loop | ( | int | server_fd, |
| cwist_https_context * | ctx, | ||
| void(*)(cwist_https_connection *conn, void *) | handler, | ||
| void * | user_ctx | ||
| ) |
Helper to start a simple HTTPS server loop. Note: The handler receives a cwist_https_connection pointer, not an int fd.
Shut down the global HTTPS thread pool: signal workers to exit, join them, close any connections still queued, and destroy the pool's mutex and condition variables. No-op if never initialized.
Definition at line 370 of file https.c.
References cap, cwist_free(), cwist_https_close_connection(), get_optimal_thread_count(), https_hs_shepherd_stop(), and SSL_free.
Referenced by cwist_async_server_loop(), and cwist_https_server_loop().
Create the worker threads, mutex, and condition variables of the global HTTPS thread pool. No-op if already initialized.
Thread pool helpers for hybrid async-accept + threaded-process mode.
Definition at line 268 of file https.c.
References cap, and get_optimal_thread_count().
Referenced by cwist_async_server_loop(), and cwist_https_server_loop().
| void https_pool_submit | ( | int | client_fd, |
| cwist_https_context * | ctx, | ||
| void(*)(cwist_https_connection *, void *) | handler, | ||
| void * | user_ctx | ||
| ) |
Queue a freshly accepted client socket whose TLS handshake still needs to run in a pool worker.
| client_fd | Accepted TCP socket descriptor. |
| ctx | HTTPS context for the handshake. |
| handler | Callback invoked once the connection is established. |
| user_ctx | Opaque pointer forwarded to the handler. |
Definition at line 292 of file https.c.
References cap, and https_pool_submit_ready().
Referenced by cwist_https_dispatch().
| void https_pool_submit_conn | ( | cwist_https_connection * | conn, |
| cwist_https_context * | ctx, | ||
| void(*)(cwist_https_connection *, void *) | handler, | ||
| void * | user_ctx | ||
| ) |
Submit an established connection back to the worker pool (e.g. keep-alive re-arm after async defer). Blocks while the queue is full; on pool shutdown closes the connection instead of queueing.
| conn | Established connection wrapper (ownership transfers to the pool). |
| ctx | HTTPS context. |
| handler | Callback invoked for the connection. |
| user_ctx | Opaque pointer forwarded to the handler. |
Definition at line 341 of file https.c.
References cap, cwist_https_close_connection(), and cwist_https_connection::fd.