|
KEEL 1.0.0
Minimal C11 HTTP client/server library built on epoll/kqueue/io_uring/poll
|
HTTP/1.1 client (sync + async). More...
#include <keel/allocator.h>#include <keel/decompress.h>#include <keel/error.h>#include <keel/event_ctx.h>#include <keel/parser.h>#include <keel/resolver.h>#include <keel/tls.h>#include <keel/url.h>

Go to the source code of this file.
Data Structures | |
| struct | KlProxyConfig |
| HTTP proxy configuration (borrowed pointers, caller-owned). More... | |
| struct | KlClientHeader |
| struct | KlClientResponse |
| struct | KlClientConfig |
| struct | KlClientStreamCfg |
| Per-request streaming configuration. More... | |
Macros | |
| #define | KL_CLIENT_HOSTNAME_MAX 256 |
| Maximum hostname length. | |
| #define | KL_CLIENT_REQ_BUF_SIZE 4096 |
| Request buffer size. | |
| #define | KL_CLIENT_MAX_REQ_HEADERS 64 |
| Maximum request headers. | |
| #define | KL_CLIENT_DEFAULT_TIMEOUT_MS 30000 |
| Default timeout (ms). | |
| #define | KL_CLIENT_DEFAULT_MAX_RESP (4 * 1024 * 1024) |
| Default max response size. | |
| #define | KL_CLIENT_RECV_BUF_SIZE 8192 |
| Receive buffer size. | |
| #define | KL_CLIENT_CHUNK_BUF_SIZE 4096 |
| Chunked encoding buffer size. | |
| #define | KL_CLIENT_CHUNK_HDR_SIZE 16 |
| Chunked header size. | |
| #define | KL_CLIENT_FINAL_CHUNK_LEN 5 |
| Final chunk length. | |
Typedefs | |
| typedef struct KlClientResponse | KlClientResponse |
| typedef int(* | KlClientBodyFn) (const char *data, size_t len, void *user_data) |
| Response body streaming callback (push-based). | |
| typedef int(* | KlClientHeadersFn) (int status, const KlClientHeader *headers, int num_headers, void *user_data) |
| Called when response headers are complete. | |
| typedef ssize_t(* | KlClientReadFn) (char *buf, size_t buf_len, void *user_data) |
| Request body streaming callback (pull-based, like read()). | |
| typedef struct KlClient | KlClient |
| typedef void(* | KlClientDoneFn) (KlClient *client, void *user_data) |
| Callback invoked when an async HTTP request completes. | |
Functions | |
| int | kl_client_request (KlAllocator *alloc, const KlClientConfig *cfg, const char *method, const char *url, const KlClientHeader *headers, int num_headers, const char *body, size_t body_len, KlClientResponse *resp) |
| Perform a synchronous (blocking) HTTP request. | |
| int | kl_client_request_s (KlAllocator *alloc, const KlClientConfig *cfg, const char *method, const char *url, const KlClientHeader *headers, int num_headers, const char *body, size_t body_len, const KlClientStreamCfg *stream, KlClientResponse *resp) |
| Perform a synchronous (blocking) HTTP request with streaming. | |
| void | kl_client_response_free (KlClientResponse *resp) |
| Free response resources (body, headers). | |
| KlClient * | kl_client_start (KlEventCtx *ev_ctx, KlAllocator *alloc, const KlClientConfig *cfg, const char *method, const char *url, const KlClientHeader *headers, int num_headers, const char *body, size_t body_len, KlClientDoneFn on_done, void *user_data) |
| Start an asynchronous HTTP request. | |
| KlClient * | kl_client_start_s (KlEventCtx *ev_ctx, KlAllocator *alloc, const KlClientConfig *cfg, const char *method, const char *url, const KlClientHeader *headers, int num_headers, const char *body, size_t body_len, const KlClientStreamCfg *stream, KlClientDoneFn on_done, void *user_data) |
| Start an asynchronous HTTP request with streaming. | |
| const KlClientResponse * | kl_client_response (const KlClient *client) |
| Get the response from a completed async request. | |
| int | kl_client_error (const KlClient *client) |
| Check if the async request completed with an error. | |
| KlError | kl_client_last_error (const KlClient *client) |
| Get the specific error code from a completed async request. | |
| void | kl_client_cancel (KlClient *client) |
| Cancel an in-flight async request (removes watcher, closes socket). | |
| void | kl_client_free (KlClient *client) |
| Free all client resources (response, buffers, parser). | |
| KlResponseParser * | kl_response_parser_llhttp_s (size_t max_response_size, KlAllocator *alloc, KlClientBodyFn on_body, KlClientHeadersFn on_headers, void(*on_complete)(void *), void *stream_user_data) |
| Create a streaming-capable llhttp response parser. | |
HTTP/1.1 client (sync + async).
Sync API: blocking request/response with poll()-based I/O. Async API: non-blocking state machine driven by KlEventCtx watchers.
The async client requires only KlEventCtx (not KlServer), so it can be used standalone or embedded in any event-loop-based program.
| #define KL_CLIENT_HOSTNAME_MAX 256 |
Maximum hostname length.
| #define KL_CLIENT_REQ_BUF_SIZE 4096 |
Request buffer size.
| #define KL_CLIENT_MAX_REQ_HEADERS 64 |
Maximum request headers.
| #define KL_CLIENT_DEFAULT_TIMEOUT_MS 30000 |
Default timeout (ms).
| #define KL_CLIENT_DEFAULT_MAX_RESP (4 * 1024 * 1024) |
Default max response size.
| #define KL_CLIENT_RECV_BUF_SIZE 8192 |
Receive buffer size.
| #define KL_CLIENT_CHUNK_BUF_SIZE 4096 |
Chunked encoding buffer size.
| #define KL_CLIENT_CHUNK_HDR_SIZE 16 |
Chunked header size.
Fits "FFFFFFFFFFFFFFFF\\r\\n"
| #define KL_CLIENT_FINAL_CHUNK_LEN 5 |
Final chunk length.
"0\\r\\n\\r\\n"
| typedef struct KlClientResponse KlClientResponse |
| typedef int(* KlClientBodyFn) (const char *data, size_t len, void *user_data) |
Response body streaming callback (push-based).
| data | Body chunk data. |
| len | Chunk length. |
| user_data | User context from KlClientStreamCfg. |
| typedef int(* KlClientHeadersFn) (int status, const KlClientHeader *headers, int num_headers, void *user_data) |
Called when response headers are complete.
| typedef ssize_t(* KlClientReadFn) (char *buf, size_t buf_len, void *user_data) |
Request body streaming callback (pull-based, like read()).
| buf | Buffer to fill. |
| buf_len | Buffer capacity. |
| user_data | User context from KlClientStreamCfg. |
| typedef void(* KlClientDoneFn) (KlClient *client, void *user_data) |
Callback invoked when an async HTTP request completes.
Called on the event loop thread. Check kl_client_error() for status, then kl_client_response() for the response data.
| int kl_client_request | ( | KlAllocator * | alloc, |
| const KlClientConfig * | cfg, | ||
| const char * | method, | ||
| const char * | url, | ||
| const KlClientHeader * | headers, | ||
| int | num_headers, | ||
| const char * | body, | ||
| size_t | body_len, | ||
| KlClientResponse * | resp | ||
| ) |
Perform a synchronous (blocking) HTTP request.
Connects, optionally performs TLS handshake, sends request, receives and parses response. Blocks until complete, error, or timeout.
| alloc | Allocator for response data. |
| cfg | Client config (timeouts, TLS, limits). May be NULL for defaults. |
| method | HTTP method ("GET", "POST", etc.). |
| url | Full URL ("http://host/path" or "https://host/path"). |
| headers | Request headers (may be NULL if num_headers == 0). |
| num_headers | Number of request headers. |
| body | Request body (may be NULL). |
| body_len | Request body length. |
| resp | Output: populated on success. Caller must call kl_client_response_free(). |
| int kl_client_request_s | ( | KlAllocator * | alloc, |
| const KlClientConfig * | cfg, | ||
| const char * | method, | ||
| const char * | url, | ||
| const KlClientHeader * | headers, | ||
| int | num_headers, | ||
| const char * | body, | ||
| size_t | body_len, | ||
| const KlClientStreamCfg * | stream, | ||
| KlClientResponse * | resp | ||
| ) |
Perform a synchronous (blocking) HTTP request with streaming.
Same as kl_client_request but supports response and request body streaming. When stream is NULL, behaves identically to kl_client_request.
| alloc | Allocator for response data. |
| cfg | Client config (timeouts, TLS, limits). May be NULL for defaults. |
| method | HTTP method ("GET", "POST", etc.). |
| url | Full URL ("http://host/path" or "https://host/path"). |
| headers | Request headers (may be NULL if num_headers == 0). |
| num_headers | Number of request headers. |
| body | Request body (may be NULL). |
| body_len | Request body length. |
| stream | Streaming config (NULL = buffer mode, same as kl_client_request). |
| resp | Output: populated on success. Caller must call kl_client_response_free(). |
| void kl_client_response_free | ( | KlClientResponse * | resp | ) |
Free response resources (body, headers).
| KlClient * kl_client_start | ( | KlEventCtx * | ev_ctx, |
| KlAllocator * | alloc, | ||
| const KlClientConfig * | cfg, | ||
| const char * | method, | ||
| const char * | url, | ||
| const KlClientHeader * | headers, | ||
| int | num_headers, | ||
| const char * | body, | ||
| size_t | body_len, | ||
| KlClientDoneFn | on_done, | ||
| void * | user_data | ||
| ) |
Start an asynchronous HTTP request.
Creates a non-blocking socket, initiates connect, and registers a watcher on the event context. The state machine drives: connect → TLS handshake → send → recv/parse
When complete (or on error), on_done is called on the event loop thread. The caller must then inspect the result and call kl_client_free().
| ev_ctx | Event context for watcher registration (NOT KlServer). |
| alloc | Allocator for client state and response. |
| cfg | Client config (timeouts, TLS, limits). May be NULL for defaults. |
| method | HTTP method. |
| url | Full URL. |
| headers | Request headers (may be NULL). |
| num_headers | Number of request headers. |
| body | Request body (may be NULL). |
| body_len | Request body length. |
| on_done | Callback invoked on completion or error. |
| user_data | User data passed to on_done. |
| KlClient * kl_client_start_s | ( | KlEventCtx * | ev_ctx, |
| KlAllocator * | alloc, | ||
| const KlClientConfig * | cfg, | ||
| const char * | method, | ||
| const char * | url, | ||
| const KlClientHeader * | headers, | ||
| int | num_headers, | ||
| const char * | body, | ||
| size_t | body_len, | ||
| const KlClientStreamCfg * | stream, | ||
| KlClientDoneFn | on_done, | ||
| void * | user_data | ||
| ) |
Start an asynchronous HTTP request with streaming.
Same as kl_client_start but supports response and request body streaming. When stream is NULL, behaves identically to kl_client_start.
| ev_ctx | Event context for watcher registration. |
| alloc | Allocator for client state and response. |
| cfg | Client config (timeouts, TLS, limits). May be NULL for defaults. |
| method | HTTP method. |
| url | Full URL. |
| headers | Request headers (may be NULL). |
| num_headers | Number of request headers. |
| body | Request body (may be NULL). |
| body_len | Request body length. |
| stream | Streaming config (NULL = buffer mode, same as kl_client_start). |
| on_done | Callback invoked on completion or error. |
| user_data | User data passed to on_done. |
| const KlClientResponse * kl_client_response | ( | const KlClient * | client | ) |
Get the response from a completed async request.
| int kl_client_error | ( | const KlClient * | client | ) |
Check if the async request completed with an error.
Get the specific error code from a completed async request.
| void kl_client_cancel | ( | KlClient * | client | ) |
Cancel an in-flight async request (removes watcher, closes socket).
| void kl_client_free | ( | KlClient * | client | ) |
Free all client resources (response, buffers, parser).
Safe to call after kl_client_cancel() or after completion callback.
| KlResponseParser * kl_response_parser_llhttp_s | ( | size_t | max_response_size, |
| KlAllocator * | alloc, | ||
| KlClientBodyFn | on_body, | ||
| KlClientHeadersFn | on_headers, | ||
| void(*)(void *) | on_complete, | ||
| void * | stream_user_data | ||
| ) |
Create a streaming-capable llhttp response parser.
When on_body is non-NULL, body chunks are forwarded to the callback instead of being accumulated. Headers/status are still populated in KlClientResponse. Body is NULL and body_len is 0 in the response.
| max_response_size | Body size limit (still enforced in streaming mode). |
| alloc | Allocator for parser state. |
| on_body | Body chunk callback (NULL = accumulate). |
| on_headers | Headers-complete callback (NULL = skip). |
| on_complete | Body-complete callback (NULL = skip). |
| stream_user_data | User data passed to all callbacks. |