[PATCH 06/10] net: lwip: add an HTTP client abort operation
James Hilliard <[email protected]>
| Newsgroups | org.u-boot-project.lists.u-boot |
|---|---|
| Message-ID | <20260825-submit-lwip-runtime-netconsole-v1-v1-6-0892966aa758@gmail.com> |
The HTTP client has no public way to cancel a request. Returning from wget while DNS or TCP work remains pending can therefore leave callbacks referencing its released command state. Track pending DNS resolution and add httpc_abort(). The operation removes a pending DNS callback, detaches the HTTP callbacks and immediately aborts the altcp connection. Report a local abort through the normal result callback. Signed-off-by: James Hilliard <[email protected]> --- lib/lwip/lwip/src/apps/http/http_client.c | 71 ++++++++++++++++++++--- lib/lwip/lwip/src/include/lwip/apps/http_client.h | 1 + 2 files changed, 64 insertions(+), 8 deletions(-) diff --git a/lib/lwip/lwip/src/apps/http/http_client.c b/lib/lwip/lwip/src/apps/http/http_client.c index 1973e79e723..2bc2a0db97e 100644 --- a/lib/lwip/lwip/src/apps/http/http_client.c +++ b/lib/lwip/lwip/src/apps/http/http_client.c @@ -146,15 +146,23 @@ typedef struct _httpc_state u32_t rx_content_len; u32_t hdr_content_len; httpc_parse_state_t parse_state; +#if LWIP_DNS + u8_t dns_pending; +#endif #if HTTPC_DEBUG_REQUEST char* server_name; char* uri; #endif } httpc_state_t; -/** Free http client state and deallocate all resources within */ -static err_t -httpc_free_state(httpc_state_t* req) +#if LWIP_DNS +static void httpc_dns_found(const char* hostname, const ip_addr_t *ipaddr, + void *arg); +#endif + +/** Free http client state and detach its connection callbacks */ +static struct altcp_pcb * +httpc_detach_state(httpc_state_t* req) { struct altcp_pcb* tpcb; @@ -168,16 +176,26 @@ httpc_free_state(httpc_state_t* req) } tpcb = req->pcb; - mem_free(req); - req = NULL; - if (tpcb != NULL) { - err_t r; altcp_arg(tpcb, NULL); altcp_recv(tpcb, NULL); altcp_err(tpcb, NULL); altcp_poll(tpcb, NULL, 0); altcp_sent(tpcb, NULL); + } + mem_free(req); + return tpcb; +} + +/** Free http client state and deallocate all resources within */ +static err_t +httpc_free_state(httpc_state_t* req) +{ + struct altcp_pcb* tpcb; + + tpcb = httpc_detach_state(req); + if (tpcb != NULL) { + err_t r; r = altcp_close(tpcb); if (r != ERR_OK) { altcp_abort(tpcb); @@ -202,6 +220,38 @@ httpc_close(httpc_state_t* req, httpc_result_t result, u32_t server_response, er return ERR_OK; } +/** Abort an HTTP client request. */ +err_t +httpc_abort(httpc_state_t *req) +{ + struct altcp_pcb *tpcb; + + if (req == NULL) { + return ERR_ARG; + } + +#if LWIP_DNS + if (req->dns_pending) { + dns_cancel(httpc_dns_found, req); + req->dns_pending = 0; + } +#endif + + if (req->conn_settings != NULL) { + if (req->conn_settings->result_fn != NULL) { + req->conn_settings->result_fn(req->callback_arg, + HTTPC_RESULT_LOCAL_ABORT, req->rx_content_len, 0, ERR_ABRT); + } + } + + tpcb = httpc_detach_state(req); + if (tpcb != NULL) { + altcp_abort(tpcb); + } + + return ERR_OK; +} + /** Parse http header response line 1 */ static err_t http_parse_response_status(struct pbuf *p, u16_t *http_version, u16_t *http_status, u16_t *http_status_str_offset) @@ -447,6 +497,7 @@ httpc_dns_found(const char* hostname, const ip_addr_t *ipaddr, void *arg) LWIP_UNUSED_ARG(hostname); + req->dns_pending = 0; if (ipaddr != NULL) { err = httpc_get_internal_addr(req, ipaddr); if (err == ERR_OK) { @@ -479,9 +530,13 @@ httpc_get_internal_dns(httpc_state_t* req, const char* server_name) if (err == ERR_OK) { /* cached or IP-string */ err = httpc_get_internal_addr(req, &req->remote_addr); - } else if (err == ERR_INPROGRESS) { + } +#if LWIP_DNS + else if (err == ERR_INPROGRESS) { + req->dns_pending = 1; return ERR_OK; } +#endif return err; } diff --git a/lib/lwip/lwip/src/include/lwip/apps/http_client.h b/lib/lwip/lwip/src/include/lwip/apps/http_client.h index d39e1bf829a..3f62150dca1 100644 --- a/lib/lwip/lwip/src/include/lwip/apps/http_client.h +++ b/lib/lwip/lwip/src/include/lwip/apps/http_client.h @@ -143,6 +143,7 @@ err_t httpc_get_file(const ip_addr_t* server_addr, u16_t port, const char* uri, altcp_recv_fn recv_fn, void* callback_arg, httpc_state_t **connection); err_t httpc_get_file_dns(const char* server_name, u16_t port, const char* uri, const httpc_connection_t *settings, altcp_recv_fn recv_fn, void* callback_arg, httpc_state_t **connection); +err_t httpc_abort(httpc_state_t *connection); #if LWIP_HTTPC_HAVE_FILE_IO err_t httpc_get_file_to_disk(const ip_addr_t* server_addr, u16_t port, const char* uri, const httpc_connection_t *settings, -- 2.53.0