Async Http request client

Module <cweb/fetch.h> — asynchronous HTTP client

HTTP requests via libcurl, tied to the same libevent loop as the server (event_base). JSON helpers use the internal fetch_json_t model.

Dependencies: event2/event.h, curl/curl.h.


Macros (AUTOFREE)

Macro Applies to
AUTOFREE_FETCH_REQUEST cleanup_free_request for fetch_request_t**
AUTOFREE_FETCH_RESPONSE cleanup_free_response for fetch_response_t**
AUTOFREE_CJSON cleanup_free_json for fetch_json_t**

Types and constants

fetch_method_t

FETCH_GET, FETCH_POST, FETCH_PUT, FETCH_DELETE, FETCH_PATCH, FETCH_HEAD, FETCH_OPTIONS.

fetch_error_t

FETCH_OK, FETCH_ERROR_MEMORY, FETCH_ERROR_INVALID_PARAM, FETCH_ERROR_CURL, FETCH_ERROR_JSON, FETCH_ERROR_TIMEOUT, FETCH_ERROR_NETWORK.

fetch_response_t (fields)

status_code, body, body_size, headers, headers_size, json, total_time, error.

Callback types

  • fetch_callback_t — request completion: (request, response, user_data).
  • fetch_progress_callback_t — progress (download/upload bytes).

fetch_config_t

Default JSON-style configuration: user agent, timeouts, redirects, SSL verify, CA path, proxy, compression.


Short API

void fetch(fetch_method_t method, const char *url, fetch_callback_t callback, const fetch_json_t *json, void *data)

  • Purpose: Convenience helper: calls fetch_global_init if needed, uses g_event_base (must be set or abort with log), creates a default client, builds a request, calls cweb_speedbench_start with request pointer, sets callback, and starts fetch_request_execute (non-blocking).
  • Parameters: json is currently unused in the implementation (TODO); set body via the full request API.
  • Return: none — errors are logged; after successful submit client/request are currently not destroyed in this function (long-term use: prefer explicit fetch_client_create/fetch_request_* and clear lifetimes).

Global initialization

fetch_error_t fetch_global_init(void)

  • Purpose: Once per process before first requests (libcurl global).

void fetch_global_cleanup(void)

  • Purpose: Pair with fetch_global_init on shutdown.

Client

fetch_client_t *fetch_client_create(struct event_base *base, const fetch_config_t *config)

  • Purpose: Creates a client bound to base (typically cweb_get_event_base()).
  • Parameters: config may be NULL — then defaults (fetch_config_default).

void fetch_client_destroy(fetch_client_t *client)

  • Purpose: Frees client and pending resources.

fetch_error_t fetch_client_set_default_header(fetch_client_t *client, const char *name, const char *value)

  • Purpose: Header for all subsequent requests.

fetch_error_t fetch_client_remove_default_header(fetch_client_t *client, const char *name)

  • Purpose: Removes a default header.

Request

fetch_request_t *fetch_request_create(fetch_client_t *client, fetch_method_t method, const char *url)

  • Purpose: New request instance.

void fetch_request_destroy(fetch_request_t *request)

  • Purpose: Free when no longer executing/completed.

fetch_error_t fetch_request_set_header(fetch_request_t *request, const char *name, const char *value)

  • Purpose: Per-request header.

fetch_error_t fetch_request_set_body(fetch_request_t *request, const void *data, size_t size)

  • Purpose: Raw body.

fetch_error_t fetch_request_set_json_body(fetch_request_t *request, const fetch_json_t *json)

  • Purpose: Body as JSON (set Content-Type accordingly / let implementation set).

fetch_error_t fetch_request_add_form_field(fetch_request_t *request, const char *name, const char *value)

  • Purpose: application/x-www-form-urlencoded or multipart field.

fetch_error_t fetch_request_add_form_file(fetch_request_t *request, const char *name, const char *filename, const char *content_type)

  • Purpose: File upload field.

fetch_error_t fetch_request_add_query_param(fetch_request_t *request, const char *name, const char *value)

  • Purpose: Add query string parameters.

fetch_error_t fetch_request_set_callback(fetch_request_t *request, fetch_callback_t callback, void *user_data)

  • Purpose: Completion callback required before/after execute per implementation.

fetch_error_t fetch_request_set_progress_callback(fetch_request_t *request, fetch_progress_callback_t callback, void *user_data)

  • Purpose: Progress updates.

fetch_error_t fetch_request_execute(fetch_request_t *request)

  • Purpose: Starts asynchronous transfer on the event loop.

fetch_error_t fetch_request_cancel(fetch_request_t *request)

  • Purpose: Cancels an in-flight request.

Response (read in callback)

long fetch_response_get_status(const fetch_response_t *response)

  • Purpose: HTTP status code.

const char *fetch_response_get_body(const fetch_response_t *response) / size_t fetch_response_get_body_size(...)

  • Purpose: Raw response body and length.

const char *fetch_response_get_headers(const fetch_response_t *response)

  • Purpose: All headers as one block (curl raw format).

const char *fetch_response_get_header(const fetch_response_t *response, const char *name)

  • Purpose: Single header lookup.

const fetch_json_t *fetch_response_get_json(const fetch_response_t *response)

  • Purpose: Parsed JSON if successful and present.

double fetch_response_get_total_time(const fetch_response_t *response)

  • Purpose: Total transfer duration (seconds, libcurl).

JSON (fetch_json_t)

Create and destroy

Function Purpose
fetch_json_t *fetch_json_create_object(void) Empty object {}
fetch_json_t *fetch_json_create_array(void) Empty array []
fetch_json_t *fetch_json_parse(const char *json_string) Parse from text
char *fetch_json_to_string(const fetch_json_t *json) Compact serialize
char *fetch_json_to_string_pretty(const fetch_json_t *json) Indented
void fetch_json_destroy(fetch_json_t *json) Free

Memory: char* returns from to_string must be freed with free (framework convention).

Object set

Function Purpose
fetch_json_object_set_string(json, key, value) string property
fetch_json_object_set_number(json, key, value) number
fetch_json_object_set_bool(json, key, value) boolean
fetch_json_object_set_null(json, key) null
fetch_json_object_set_object(json, key, value) nested object (ownership of value transfers to container — check implementation)

All return fetch_error_t.

Object read

Function Return
fetch_json_object_get_string const char* or NULL
fetch_json_object_get_number double
fetch_json_object_get_bool bool
fetch_json_object_get_object child fetch_json_t*

Array

Function Purpose
fetch_json_array_add_string / _number / _bool / _object append element
size_t fetch_json_array_size length
fetch_json_array_get(json, index) element at index

Helpers

char *fetch_url_encode(const char *str) / char *fetch_url_decode(const char *str)

  • Purpose: RFC-like URL encode/decode.
  • Memory: returns typically freed with free.

const char *fetch_error_string(fetch_error_t error)

  • Purpose: Human-readable error description (static string).

fetch_config_t fetch_config_default(void)

  • Purpose: Sensible defaults for fetch_client_create.

Cleanup helpers (direct / AUTOFREE)

void cleanup_free_json(void *jsonp)

  • Purpose: For AUTOFREE_CJSON — destroys *(fetch_json_t**)jsonp.

void cleanup_free_client(fetch_client_t **client)

void cleanup_free_request(fetch_request_t **request)

void cleanup_free_response(fetch_response_t **response)

  • Purpose: Wrappers for destructive cleanup in cleanup attributes.

Usage notes

  1. fetch_global_init before first client/request.
  2. Create client with the same event_base as CWEB.
  3. In the response callback: avoid long blocking work — prefer cweb_async or pending response again.
  4. JSON ownership: nested objects after set often owned by parent — avoid double destroy.

See also

  • server.mdcweb_get_event_base, pending responses
  • async.md — deferred callbacks