# HG changeset patch # User Olaf Wintermann # Date 1772057687 -3600 # Node ID df64b4b79912c1121ed00e9b902b42d9ce4b272f # Parent 30de3bfd0412a5aecae3c8b03c3f3cc2074e556a add error handling in proxy_request_read diff -r 30de3bfd0412 -r df64b4b79912 src/server/proxy/httpclient.c --- 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)) { diff -r 30de3bfd0412 -r df64b4b79912 src/server/proxy/httpclient.h --- 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; diff -r 30de3bfd0412 -r df64b4b79912 src/server/safs/proxy.c --- 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);