From 1ef6187b2d84d8dcea419c63cd99f88789294e0b Mon Sep 17 00:00:00 2001 From: Francesco Cozzuto Date: Thu, 27 Nov 2025 09:47:15 +0100 Subject: [PATCH] Add simplified client API (http_get, http_put, http_post, http_delete) --- chttp.c | 63 ++++++++++++++++++++++++++++++++++ chttp.h | 18 ++++++++++ examples/000_simple_client.c | 32 +++-------------- examples/006_parallel_client.c | 40 +++++++++++++++++++++ src/client.c | 63 ++++++++++++++++++++++++++++++++++ src/client.h | 18 ++++++++++ 6 files changed, 206 insertions(+), 28 deletions(-) create mode 100644 examples/006_parallel_client.c diff --git a/chttp.c b/chttp.c index 0cae274..6365b76 100644 --- a/chttp.c +++ b/chttp.c @@ -4330,6 +4330,69 @@ void http_client_wait_response(HTTP_Client *client, } } +static _Thread_local HTTP_Client *implicit_client; + +static int perform_request(HTTP_Method method, + HTTP_String url, HTTP_String *headers, + int num_headers, HTTP_String body, + HTTP_Response **response) +{ + if (implicit_client == NULL) { + + implicit_client = malloc(sizeof(HTTP_Client)); + if (implicit_client == NULL) + return HTTP_ERROR_OOM; + + int ret = http_client_init(implicit_client); + if (ret < 0) { + free(implicit_client); + implicit_client = NULL; + return ret; + } + } + HTTP_Client *client = implicit_client; + + HTTP_RequestBuilder builder = http_client_get_builder(client); + http_request_builder_method(builder, method); + http_request_builder_target(builder, url); + for (int i = 0; i < num_headers; i++) + http_request_builder_header(builder, headers[i]); + http_request_builder_body(builder, body); + int ret = http_request_builder_send(builder); + if (ret < 0) return ret; + + int result; + void *user; + http_client_wait_response(client, &result, &user, response); + return result; +} + +int http_get(HTTP_String url, HTTP_String *headers, + int num_headers, HTTP_Response **response) +{ + return perform_request(HTTP_METHOD_GET, url, headers, num_headers, HTTP_STR(""), response); +} + +int http_post(HTTP_String url, HTTP_String *headers, + int num_headers, HTTP_String body, + HTTP_Response **response) +{ + return perform_request(HTTP_METHOD_POST, url, headers, num_headers, body, response); +} + +int http_put(HTTP_String url, HTTP_String *headers, + int num_headers, HTTP_String body, + HTTP_Response **response) +{ + return perform_request(HTTP_METHOD_PUT, url, headers, num_headers, body, response); +} + +int http_delete(HTTP_String url, HTTP_String *headers, + int num_headers, HTTP_Response **response) +{ + return perform_request(HTTP_METHOD_DELETE, url, headers, num_headers, HTTP_STR(""), response); +} + //////////////////////////////////////////////////////////////////////////////////////// // src/server.c //////////////////////////////////////////////////////////////////////////////////////// diff --git a/chttp.h b/chttp.h index 35b089d..0691528 100644 --- a/chttp.h +++ b/chttp.h @@ -1058,6 +1058,24 @@ void http_client_wait_response(HTTP_Client *client, // again after this. void http_free_response(HTTP_Response *response); +// Perform a blocking GET request +int http_get(HTTP_String url, HTTP_String *headers, + int num_headers, HTTP_Response **response); + +// Perform a blocking POST request +int http_post(HTTP_String url, HTTP_String *headers, + int num_headers, HTTP_String body, + HTTP_Response **response); + +// Perform a blocking PUT request +int http_put(HTTP_String url, HTTP_String *headers, + int num_headers, HTTP_String body, + HTTP_Response **response); + +// Perform a blocking DELETE request +int http_delete(HTTP_String url, HTTP_String *headers, + int num_headers, HTTP_Response **response); + //////////////////////////////////////////////////////////////////////////////////////// // src/server.h //////////////////////////////////////////////////////////////////////////////////////// diff --git a/examples/000_simple_client.c b/examples/000_simple_client.c index 1a31362..14261b4 100644 --- a/examples/000_simple_client.c +++ b/examples/000_simple_client.c @@ -2,38 +2,14 @@ int main(void) { - int ret; - - HTTP_Client client; - ret = http_client_init(&client); - if (ret < 0) { - printf("Couldn't initialize client (%s)\n", http_strerror(ret)); - return -1; - } - - HTTP_RequestBuilder builder = http_client_get_builder(&client); - - http_request_builder_method(builder, HTTP_METHOD_GET); - http_request_builder_target(builder, HTTP_STR("http://coz.is")); - http_request_builder_header(builder, HTTP_STR("Greeting: Hello from the cHTTP example!")); - - ret = http_request_builder_send(builder); - if (ret < 0) { - printf("Couldn't build request (%s)\n", http_strerror(ret)); - return -1; - } - - int result; - void *user; HTTP_Response *response; - http_client_wait_response(&client, &result, &user, &response); - if (result == HTTP_OK) { + int ret = http_get(HTTP_STR("http://coz.is/"), NULL, 0, &response); + if (ret == HTTP_OK) { printf("Received %d bytes\n", response->body.len); + http_free_response(response); } else { - printf("Couldn't receive response (%s)\n", http_strerror(result)); + printf("Request failure: %s\n", http_strerror(ret)); } - - http_client_free(&client); return 0; } diff --git a/examples/006_parallel_client.c b/examples/006_parallel_client.c new file mode 100644 index 0000000..4991679 --- /dev/null +++ b/examples/006_parallel_client.c @@ -0,0 +1,40 @@ +#include "../chttp.h" + +int main(void) +{ + int ret; + + HTTP_Client client; + ret = http_client_init(&client); + if (ret < 0) { + printf("Couldn't initialize client (%s)\n", http_strerror(ret)); + return -1; + } + + HTTP_RequestBuilder builder = http_client_get_builder(&client); + + http_request_builder_method(builder, HTTP_METHOD_GET); + http_request_builder_target(builder, HTTP_STR("http://coz.is")); + http_request_builder_header(builder, HTTP_STR("Greeting: Hello from the cHTTP example!")); + + ret = http_request_builder_send(builder); + if (ret < 0) { + printf("Couldn't build request (%s)\n", http_strerror(ret)); + return -1; + } + + int result; + void *user; + HTTP_Response *response; + http_client_wait_response(&client, &result, &user, &response); + + if (result == HTTP_OK) { + printf("Received %d bytes\n", response->body.len); + } else { + printf("Couldn't receive response (%s)\n", http_strerror(result)); + } + + http_free_response(response); + http_client_free(&client); + return 0; +} diff --git a/src/client.c b/src/client.c index 6c5544c..fb307ff 100644 --- a/src/client.c +++ b/src/client.c @@ -707,3 +707,66 @@ void http_client_wait_response(HTTP_Client *client, break; } } + +static _Thread_local HTTP_Client *implicit_client; + +static int perform_request(HTTP_Method method, + HTTP_String url, HTTP_String *headers, + int num_headers, HTTP_String body, + HTTP_Response **response) +{ + if (implicit_client == NULL) { + + implicit_client = malloc(sizeof(HTTP_Client)); + if (implicit_client == NULL) + return HTTP_ERROR_OOM; + + int ret = http_client_init(implicit_client); + if (ret < 0) { + free(implicit_client); + implicit_client = NULL; + return ret; + } + } + HTTP_Client *client = implicit_client; + + HTTP_RequestBuilder builder = http_client_get_builder(client); + http_request_builder_method(builder, method); + http_request_builder_target(builder, url); + for (int i = 0; i < num_headers; i++) + http_request_builder_header(builder, headers[i]); + http_request_builder_body(builder, body); + int ret = http_request_builder_send(builder); + if (ret < 0) return ret; + + int result; + void *user; + http_client_wait_response(client, &result, &user, response); + return result; +} + +int http_get(HTTP_String url, HTTP_String *headers, + int num_headers, HTTP_Response **response) +{ + return perform_request(HTTP_METHOD_GET, url, headers, num_headers, HTTP_STR(""), response); +} + +int http_post(HTTP_String url, HTTP_String *headers, + int num_headers, HTTP_String body, + HTTP_Response **response) +{ + return perform_request(HTTP_METHOD_POST, url, headers, num_headers, body, response); +} + +int http_put(HTTP_String url, HTTP_String *headers, + int num_headers, HTTP_String body, + HTTP_Response **response) +{ + return perform_request(HTTP_METHOD_PUT, url, headers, num_headers, body, response); +} + +int http_delete(HTTP_String url, HTTP_String *headers, + int num_headers, HTTP_Response **response) +{ + return perform_request(HTTP_METHOD_DELETE, url, headers, num_headers, HTTP_STR(""), response); +} diff --git a/src/client.h b/src/client.h index 0b49316..ef5c4df 100644 --- a/src/client.h +++ b/src/client.h @@ -223,3 +223,21 @@ void http_client_wait_response(HTTP_Client *client, // Free a response object. You can't access its fields // again after this. void http_free_response(HTTP_Response *response); + +// Perform a blocking GET request +int http_get(HTTP_String url, HTTP_String *headers, + int num_headers, HTTP_Response **response); + +// Perform a blocking POST request +int http_post(HTTP_String url, HTTP_String *headers, + int num_headers, HTTP_String body, + HTTP_Response **response); + +// Perform a blocking PUT request +int http_put(HTTP_String url, HTTP_String *headers, + int num_headers, HTTP_String body, + HTTP_Response **response); + +// Perform a blocking DELETE request +int http_delete(HTTP_String url, HTTP_String *headers, + int num_headers, HTTP_Response **response);