src/server/proxy/httpclient.c

changeset 691
4d8a55a7618b
parent 690
c7b73000a1ed
child 692
32faa1d6a744
--- a/src/server/proxy/httpclient.c	Sat Feb 21 11:17:37 2026 +0100
+++ b/src/server/proxy/httpclient.c	Sat Feb 21 13:12:39 2026 +0100
@@ -207,7 +207,7 @@
             log_ereport(LOG_FAILURE, "http-client-start: connect failed: %s", strerror(err));
         }
     } else {
-        // TODO: call client_connected directly
+        ret = 0; // TODO
     }
     
     if(ret) {
@@ -261,21 +261,26 @@
 
 static int client_io(EventHandler *ev, Event *event) {
     HttpClient *client = event->cookie;
-    if(client->transfer_buffer_pos < client->transfer_buffer_len) {
-        if(client_send_request(client)) {
-            return client->error == 0;
+    if(client->stage == 0) {
+        if(client->transfer_buffer_pos < client->transfer_buffer_len) {
+            if(client_send_request(client)) {
+                return client->error == 0;
+            }
         }
-    }
-    
-    // do we need to send a request body?
-    if(client->req_content_length != 0) {
-        if(client_send_request_body(client)) {
-            return client->error == 0;
+
+        // do we need to send a request body?
+        if(client->req_content_length != 0) {
+            if(client_send_request_body(client)) {
+                return client->error == 0;
+            }
         }
     }
     
     // writing complete, switch to read events
     event->events = EVENT_POLLIN;
+    client->stage = 1;
+    client->transfer_buffer_pos = 0;
+    client->transfer_buffer_len = 0;
     
     if(client_read_response_header(client)) {
         return client->error == 0;
@@ -404,6 +409,8 @@
     return 0;
 }
 
+// returns 0 success
+//         1 would block or error
 static int client_read_response_header(HttpClient *client) {
     if(client->response_header_complete) {
         return 0;
@@ -432,7 +439,12 @@
                         int ret = client->response_start(client, client->statuscode, msg.ptr, client->response_start_userdata);
                         msg.ptr[msg.length] = t;
                         
-                        // TODO: check ret
+                        if(ret != 0) {
+                            if(ret != HTTP_CLIENT_CALLBACK_WOULD_BLOCK) {
+                                client->error = 1;
+                            }
+                            return 1;
+                        }
                     }
                     break;
                 }
@@ -508,19 +520,55 @@
     return 0;
 }
 
+// uses the response_body_write callback to write the content of the
+// transfer buffer
+// returns 0 success
+//         1 would block or error
+static int client_write_response(HttpClient *client) {
+    while(client->transfer_buffer_pos < client->transfer_buffer_len) {
+        char *buf = client->transfer_buffer + client->transfer_buffer_pos;
+        size_t len = client->transfer_buffer_len - client->transfer_buffer_pos;
+        int ret = client->response_body_write(client, buf, len, client->response_body_write_userdata);
+        if(ret > 0) {
+           client->transfer_buffer_pos += ret; 
+        } else if(ret == 0) {
+            // EOF?
+            // check if the write is incomplete, which would be an error
+            client->error == client->transfer_buffer_pos < client->transfer_buffer_len;
+            return client->error;
+        } else {
+            if(ret != HTTP_CLIENT_CALLBACK_WOULD_BLOCK) {
+                client->error = 1;
+            }
+            return 1;
+        }
+    }
+    return 0;
+}
+
+// returns 0 success
+//         1 would block or error
 static int client_read_response_body(HttpClient *client) {
     if(!client->stream) {
         return 0; // no input stream -> no response body
     }
     
+    // does the transfer buffer still contains bytes, that should be written?
+    if(client_write_response(client)) {
+        return 1;
+    }
+    
     char *buf = client->transfer_buffer;
     size_t nbytes = client->transfer_buffer_alloc;
     
     ssize_t r;
     while((r = net_read(&client->stream->st, buf, nbytes)) > 0) {
+        client->transfer_buffer_len = r;
+        client->transfer_buffer_pos = 0;
         if(client->response_body_write) {
-            int ret = client->response_body_write(client, buf, r, client->response_body_write_userdata);
-            // TODO: check ret
+            if(client_write_response(client)) {
+                return 1;
+            }
         }
     }
     
@@ -765,6 +813,8 @@
     EventHandler dummy;
     HttpClient *client = http_client_new(&dummy);
     create_req_buffer(client);
+    client->transfer_buffer_pos = 0;
+    client->transfer_buffer_len = 0;
     client->req_content_length = -1;
 
     int fds[2];

mercurial