net: http: client: Allow to abort download from response callback

Update the response callback function signature to allow the callback to
return an error code, which in turn will cause the HTTP client to abort
the download.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
This commit is contained in:
Robert Lubos 2025-05-20 14:30:16 +02:00 committed by Benjamin Cabé
commit 3572c9f825
7 changed files with 45 additions and 23 deletions

View file

@ -56,9 +56,9 @@ The following is an example of a very simple response handling function:
.. code-block:: c
static void response_cb(struct http_response *rsp,
enum http_final_call final_data,
void *user_data)
static int response_cb(struct http_response *rsp,
enum http_final_call final_data,
void *user_data)
{
if (final_data == HTTP_DATA_MORE) {
LOG_INF("Partial data received (%zd bytes)", rsp->data_len);
@ -67,6 +67,8 @@ The following is an example of a very simple response handling function:
}
LOG_INF("Response status %s", rsp->http_status);
return 0;
}
See :zephyr:code-sample:`HTTP client sample application <sockets-http-client>` for

View file

@ -94,10 +94,13 @@ typedef int (*http_header_cb_t)(int sock,
* @param final_data Does this data buffer contain all the data or
* is there still more data to come.
* @param user_data User specified data specified in http_client_req()
*
* @return 0 if http_client_req() should proceed with the download,
* <0 if http_client_req() should abort the download.
*/
typedef void (*http_response_cb_t)(struct http_response *rsp,
enum http_final_call final_data,
void *user_data);
typedef int (*http_response_cb_t)(struct http_response *rsp,
enum http_final_call final_data,
void *user_data);
/**
* HTTP response from the server.

View file

@ -18,9 +18,9 @@ LOG_MODULE_REGISTER(tagoio_http_post, CONFIG_TAGOIO_HTTP_POST_LOG_LEVEL);
static struct tagoio_context ctx;
static void response_cb(struct http_response *rsp,
enum http_final_call final_data,
void *user_data)
static int response_cb(struct http_response *rsp,
enum http_final_call final_data,
void *user_data)
{
if (final_data == HTTP_DATA_MORE) {
LOG_DBG("Partial data received (%zd bytes)", rsp->data_len);
@ -29,6 +29,8 @@ static void response_cb(struct http_response *rsp,
}
LOG_DBG("Response status %s", rsp->http_status);
return 0;
}
static int collect_data(void)

View file

@ -112,9 +112,9 @@ static int payload_cb(int sock, struct http_request *req, void *user_data)
return pos;
}
static void response_cb(struct http_response *rsp,
enum http_final_call final_data,
void *user_data)
static int response_cb(struct http_response *rsp,
enum http_final_call final_data,
void *user_data)
{
if (final_data == HTTP_DATA_MORE) {
LOG_INF("Partial data received (%zd bytes)", rsp->data_len);
@ -124,6 +124,8 @@ static void response_cb(struct http_response *rsp,
LOG_INF("Response to %s", (const char *)user_data);
LOG_INF("Response status %s", rsp->http_status);
return 0;
}
static int connect_socket(sa_family_t family, const char *server, int port,

View file

@ -996,7 +996,7 @@ static void response_download_cb(struct http_response *rsp, enum http_final_call
}
}
static void response_cb(struct http_response *rsp, enum http_final_call final_data, void *userdata)
static int response_cb(struct http_response *rsp, enum http_final_call final_data, void *userdata)
{
struct hawkbit_context *hb_context = userdata;
@ -1007,7 +1007,7 @@ static void response_cb(struct http_response *rsp, enum http_final_call final_da
} else {
hb_context->code_status = HAWKBIT_METADATA_ERROR;
}
return;
return 0;
}
switch (hb_context->type) {
@ -1023,6 +1023,8 @@ static void response_cb(struct http_response *rsp, enum http_final_call final_da
default:
break;
}
return 0;
}
static bool send_request(struct hawkbit_context *hb_context, enum hawkbit_http_request type,

View file

@ -460,21 +460,25 @@ static void http_report_complete(struct http_request *req)
{
if (req->internal.response.cb) {
NET_DBG("Calling callback for %zd len data", req->internal.response.data_len);
req->internal.response.cb(&req->internal.response, HTTP_DATA_FINAL,
req->internal.user_data);
(void)req->internal.response.cb(&req->internal.response,
HTTP_DATA_FINAL,
req->internal.user_data);
}
}
/* Report that some data has been received, but the HTTP transaction is still ongoing. */
static void http_report_progress(struct http_request *req)
static int http_report_progress(struct http_request *req)
{
if (req->internal.response.cb) {
NET_DBG("Calling callback for partitioned %zd len data",
req->internal.response.data_len);
req->internal.response.cb(&req->internal.response, HTTP_DATA_MORE,
req->internal.user_data);
return req->internal.response.cb(&req->internal.response,
HTTP_DATA_MORE,
req->internal.user_data);
}
return 0;
}
static int http_wait_data(int sock, struct http_request *req, const k_timepoint_t req_end_timepoint)
@ -568,7 +572,12 @@ static int http_wait_data(int sock, struct http_request *req, const k_timepoint_
if (req->internal.response.message_complete) {
http_report_complete(req);
} else {
http_report_progress(req);
ret = http_report_progress(req);
if (ret < 0) {
LOG_DBG("Connection aborted by the application (%d)",
ret);
return -ECONNABORTED;
}
/* Re-use the result buffer and start to fill it again */
req->internal.response.data_len = 0;

View file

@ -149,9 +149,9 @@ static struct websocket_context *websocket_find(int real_sock)
return ctx;
}
static void response_cb(struct http_response *rsp,
enum http_final_call final_data,
void *user_data)
static int response_cb(struct http_response *rsp,
enum http_final_call final_data,
void *user_data)
{
struct websocket_context *ctx = user_data;
@ -164,6 +164,8 @@ static void response_cb(struct http_response *rsp,
rsp->data_len);
ctx->all_received = true;
}
return 0;
}
static int on_header_field(struct http_parser *parser, const char *at,