[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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.