fix error forwarding in http_read_buffered when IO is performed

Thu, 19 Feb 2026 17:05:13 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Thu, 19 Feb 2026 17:05:13 +0100
changeset 685
349d62bfae29
parent 684
48da20bde908
child 686
9adf57ddcd0f

fix error forwarding in http_read_buffered when IO is performed

src/server/util/io.c file | annotate | diff | comparison | revisions
--- a/src/server/util/io.c	Wed Feb 18 13:41:10 2026 +0100
+++ b/src/server/util/io.c	Thu Feb 19 17:05:13 2026 +0100
@@ -556,26 +556,27 @@
 /*
  * read from st->readbuf first, read from st->fd if perform_io is true
  */
-static ssize_t http_read_buffered(HttpStream *st, char *buf, size_t nbytes, WSBool read_data, WSBool *perform_io) {
+static ssize_t http_read_buffered(HttpStream *httpstr, char *buf, size_t nbytes, WSBool read_data, WSBool *perform_io) {
     ssize_t r = 0;
     
     //memset(buf, 'x', nbytes);
     //char *orig_buf = buf;
     
     // copy available data from st->readbuf to buf
-    int pos = *st->bufpos;
-    size_t buf_available = *st->buflen - pos;
-    if(buf_available) {
+    int pos = *httpstr->bufpos;
+    int buflen = *httpstr->buflen;
+    int buf_available = buflen > 0 ? buflen - pos : 0;
+    if(buf_available > 0) {
         size_t cplen = buf_available > nbytes ? nbytes : buf_available;
         if(read_data) {
             // if we read data (and not a chunk header), we limit the
             // amount of bytes we copy
-            size_t chunk_available = st->max_read - st->read;
+            size_t chunk_available = httpstr->max_read - httpstr->read;
             cplen = cplen > chunk_available ? chunk_available : cplen;
-            st->read += cplen;
+            httpstr->read += cplen;
         }
-        memcpy(buf, st->readbuf + pos, cplen);
-        *st->bufpos += cplen;
+        memcpy(buf, httpstr->readbuf + pos, cplen);
+        *httpstr->bufpos += cplen;
         r += cplen;
         buf += cplen;
         nbytes -= cplen;
@@ -588,22 +589,24 @@
     // if we read a chunk header (read_data == false) it is very important
     // to not perform IO, if we have previously copied data from readbuf
     // this ensures we never override non-chunk-header data
-    if(*perform_io && ((read_data && nbytes > 0 && st->max_read - st->read) || (!read_data && r == 0))) {
-        if(*st->buflen - *st->bufpos > 0) {
+    if(*perform_io && ((read_data && nbytes > 0 && httpstr->max_read - httpstr->read) || (!read_data && r == 0))) {
+        if(*httpstr->buflen - *httpstr->bufpos > 0) {
             printf("todo: fix, should not happen, remove later\n");
         }
         // fill buffer again
-        ssize_t rlen = st->fd->read(st->fd, st->readbuf, st->bufsize);
-        *st->buflen = rlen;
-        *st->bufpos = 0;
+        ssize_t rlen = httpstr->fd->read(httpstr->fd, httpstr->readbuf, httpstr->bufsize);
+        *httpstr->buflen = rlen;
+        *httpstr->bufpos = 0;
         *perform_io = WS_FALSE;
         if(rlen < 0) {
-            st->st.io_errno = st->fd->io_errno;
+            httpstr->st.io_errno = httpstr->fd->io_errno;
         }
         
         if(rlen > 0) {
             // call func again to get data from buffer (no IO will be performed)
-            r += http_read_buffered(st, buf, nbytes, read_data, perform_io);
+            r += http_read_buffered(httpstr, buf, nbytes, read_data, perform_io);
+        } else if(r == 0) {
+            r = rlen;
         }
     }
     

mercurial