I've attached a patch to fix this bug. It includes a 2K buffer and two ints in the structure used for the sockets, this is 2056 bytes of extra RAM for each connection (even by the standards of 10 years ago it's not much).
Now the minimum read attempt will be 2048 bytes. I've tested this with my own soap code. My test program goes from 651 system calls (according to strace) to 141 system calls when using the patched version of the libraries. Note that there seems to be some inter-dependencies between the libraries, upgrading one without the rest can cause a SEGV. So the new versions of libnanohttp1 and libcsoap1 will have to conflict with the old versions of each other.
diff -ru libcsoap-1.1.0.bak/nanohttp/nanohttp-socket.c libcsoap-1.1.0/nanohttp/nanohttp-socket.c --- libcsoap-1.1.0.bak/nanohttp/nanohttp-socket.c 2006-07-10 02:24:19.000000000 +1000 +++ libcsoap-1.1.0/nanohttp/nanohttp-socket.c 2009-03-28 10:21:04.000000000 +1100 @@ -473,27 +473,69 @@ /* log_verbose3("Entering hsocket_read(total=%d,force=%d)", total, force); */ totalRead = 0; + if(sock->buf_used) + { + if(total <= sock->buf_used) + { + memcpy(buffer, &sock->read_buf[sock->buf_start], total); + sock->buf_start += total; + sock->buf_used -= total; + *received = total; + return H_OK; + } + totalRead = sock->buf_used; + memcpy(buffer, &sock->read_buf[sock->buf_start], totalRead); + sock->buf_used = 0; + } + do { - if ((status = + if(total - totalRead < sizeof(sock->read_buf)) + { + if ((status = + hssl_read(sock, sock->read_buf, + sizeof(sock->read_buf), &count)) != H_OK) + { + log_warn2("hssl_read failed (%s)", herror_message(status)); + return status; + } + if(count >= total - totalRead) + { + memcpy(&buffer[totalRead], sock->read_buf, total - totalRead); + *received = total; + sock->buf_used = count - total - totalRead; + sock->buf_start = total - totalRead; + return H_OK; + } + else + { + memcpy(&buffer[totalRead], sock->read_buf, count); + sock->buf_used = 0; + /* 10 lines below we do totalRead += count; */ + } + } + else + { + if ((status = hssl_read(sock, &buffer[totalRead], (size_t) total - totalRead, &count)) != H_OK) - { - log_warn2("hssl_read failed (%s)", herror_message(status)); - return status; + { + log_warn2("hssl_read failed (%s)", herror_message(status)); + return status; + } } + totalRead += count; + if (!force) { /* log_verbose3("Leaving !force (received=%d)(status=%d)", *received, status); */ - *received = count; + *received = totalRead; return H_OK; } - totalRead += count; - if (totalRead == total) { *received = totalRead; diff -ru libcsoap-1.1.0.bak/nanohttp/nanohttp-socket.h libcsoap-1.1.0/nanohttp/nanohttp-socket.h --- libcsoap-1.1.0.bak/nanohttp/nanohttp-socket.h 2006-05-02 03:56:32.000000000 +1000 +++ libcsoap-1.1.0/nanohttp/nanohttp-socket.h 2009-03-28 10:23:27.000000000 +1100 @@ -55,6 +55,8 @@ #endif struct sockaddr_in addr; void *ssl; + char read_buf[2048]; + int buf_start, buf_used; } hsocket_t; /* end of socket definition */