add error handling in proxy_request_read

Wed, 25 Feb 2026 23:14:47 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Wed, 25 Feb 2026 23:14:47 +0100
changeset 706
df64b4b79912
parent 705
30de3bfd0412
child 707
5fb102d2c745

add error handling in proxy_request_read

src/server/proxy/httpclient.c file | annotate | diff | comparison | revisions
src/server/proxy/httpclient.h file | annotate | diff | comparison | revisions
src/server/safs/proxy.c file | annotate | diff | comparison | revisions
--- a/src/server/proxy/httpclient.c	Wed Feb 25 22:38:51 2026 +0100
+++ b/src/server/proxy/httpclient.c	Wed Feb 25 23:14:47 2026 +0100
@@ -240,6 +240,9 @@
 }
 
 int http_client_process(HttpClient *client) {
+    if(client->stage < 0) {
+        return 0;
+    }
     return client_io(client->ev, &client->event);
 }
 
@@ -293,6 +296,9 @@
 
 static int client_connected(EventHandler *ev, Event *event) {
     HttpClient *client = event->cookie;
+    if(client->stage < 0) {
+        return 0;
+    }
     if(create_req_buffer(client)) {
         // TODO: set error
         return 0; // end
@@ -304,6 +310,10 @@
 
 static int client_io(EventHandler *ev, Event *event) {
     HttpClient *client = event->cookie;
+    if(client->stage < 0) {
+        return 0;
+    }
+    
     if(client->stage == 0) {
         if(client->transfer_buffer_pos < client->transfer_buffer_len) {
             if(client_send_buf(client)) {
--- a/src/server/proxy/httpclient.h	Wed Feb 25 22:38:51 2026 +0100
+++ b/src/server/proxy/httpclient.h	Wed Feb 25 23:14:47 2026 +0100
@@ -160,7 +160,7 @@
     
     size_t req_contentlength_pos;
     
-    int stage; // 0: request, 1: response, 2: websocket
+    int stage; // 0: request, 1: response, 2: websocket, -1: finished
     int request_body_complete;
     int request_body_terminated;
     int response_header_complete;
--- a/src/server/safs/proxy.c	Wed Feb 25 22:38:51 2026 +0100
+++ b/src/server/safs/proxy.c	Wed Feb 25 23:14:47 2026 +0100
@@ -37,6 +37,7 @@
 
 #include "../util/pblock.h"
 #include "../util/util.h"
+#include "../util/io.h"
 #include "../proxy/httpclient.h"
 
 
@@ -44,6 +45,8 @@
     Session *sn;
     Request *rq;
     
+    HttpClient *client;
+    
     /*
      * request header rewrite map
      * name: header name
@@ -59,11 +62,28 @@
     pblock  *response_header_rewrite;
     
     /*
+     * event structure for sn->csd
+     */
+    Event event;
+    
+    /*
      * Has the response started (proxy_response_start called)
      */
     int response_started;
+    
+    /*
+     * reference counter
+     */
+    int ref;
 } ProxyRequest;
 
+static void proxy_unref(ProxyRequest *proxy) {
+    if(--proxy->ref == 0) {
+        http_client_free(proxy->client);
+        free(proxy);
+    }
+}
+
 static int proxy_response_start(HttpClient *client, int status, char *message, void *userdata) {
     ProxyRequest *proxy = userdata;
     
@@ -110,9 +130,25 @@
         ret = REQ_ABORTED;
     }
     
-    http_client_free(client);
+    nsapi_function_return(proxy->sn, proxy->rq, ret);
     
-    nsapi_function_return(proxy->sn, proxy->rq, ret);
+    proxy_unref(proxy);
+}
+
+static int proxy_request_read_event(EventHandler *eh, Event *event) {
+    ProxyRequest *proxy = event->cookie;
+    if(http_client_process(proxy->client)) {
+        if(proxy->client->error == 0) {
+            return 1;
+        }
+    }
+    return 0;
+}
+
+static int proxy_request_read_finished(EventHandler *eh, Event *event) {
+    ProxyRequest *proxy = event->cookie;
+    proxy_unref(proxy);
+    return 0;
 }
 
 static ssize_t proxy_request_read(HttpClient *client, void *buf, size_t nbytes, void *userdata) {
@@ -120,8 +156,25 @@
     int ret = netbuf_getbytes(proxy->sn->inbuf, buf, nbytes);
     if(ret == NETBUF_EOF) {
         ret = 0;
+    } else if(ret < 0) {
+        IOStream *st = proxy->sn->csd;
+        if(st->io_errno == EWOULDBLOCK) {
+            ret = HTTP_CLIENT_CALLBACK_WOULD_BLOCK;
+            // is there already an poll event for csd?
+            if(!proxy->event.cookie) {
+                proxy->ref++;
+                proxy->event.cookie = proxy;
+                proxy->event.fn = proxy_request_read_event;
+                proxy->event.finish = proxy_request_read_finished;
+                if(event_pollin(client->ev, st, &proxy->event)) {
+                    ret = HTTP_CLIENT_CALLBACK_ERROR;
+                }
+            }
+        } else {
+            ret = HTTP_CLIENT_CALLBACK_ERROR;
+        }
     }
-    // TODO: handle errors
+    
     return ret;
 }
 
@@ -228,12 +281,13 @@
     // or other SAFs
     pblock_removekey(pb_key_content_type, rq->srvhdrs);
     
-    ProxyRequest *proxy = pool_malloc(sn->pool, sizeof(ProxyRequest));
+    ProxyRequest *proxy = malloc(sizeof(ProxyRequest));
     proxy->sn = sn;
     proxy->rq = rq;
     proxy->request_header_rewrite = pblock_create_pool(sn->pool, 16);
     proxy->response_header_rewrite = pblock_create_pool(sn->pool, 16);
     proxy->response_started = 0;
+    proxy->ref = 1;
     
     // Some request/response headers should be removed or altered
     // An empty string means, the header should be removed
@@ -249,6 +303,7 @@
     if(!client) {
         return REQ_ABORTED;
     }
+    proxy->client = client;
     
     if(http_client_set_method(client, method)) {
         http_client_free(client);

mercurial