libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

commit 0ee242e3a9fe8ea2a624e8bb92e6e1314de10276
parent 4ce620be913b9f9817e2937883f92bd3217ce0b3
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
Date:   Sat, 12 Dec 2020 13:30:31 +0300

mhd_send: emulate sendmsg when sendmsg unsupported

Use second send() to send reply body. It is more efficient as keeps
caches hot.

Diffstat:
Msrc/microhttpd/mhd_send.c | 38+++++++++++++++++++++++++++++++-------
1 file changed, 31 insertions(+), 7 deletions(-)

diff --git a/src/microhttpd/mhd_send.c b/src/microhttpd/mhd_send.c @@ -831,9 +831,9 @@ MHD_send_on_connection2_ (struct MHD_Connection *connection, const char *buffer, size_t buffer_size) { + ssize_t ret; #if defined(HAVE_SENDMSG) || defined(HAVE_WRITEV) MHD_socket s = connection->socket_fd; - ssize_t ret; struct iovec vector[2]; #ifdef HTTPS_SUPPORT const bool no_vec = (connection->daemon->options & MHD_USE_TLS); @@ -852,11 +852,34 @@ MHD_send_on_connection2_ (struct MHD_Connection *connection, #endif /* ! (HAVE_SENDMSG || HAVE_WRITEV) */ ) { - return MHD_send_on_connection_ (connection, - header, - header_size, - MHD_SSO_HDR_CORK); - + ret = MHD_send_on_connection_ (connection, + header, + header_size, + MHD_SSO_HDR_CORK); + if ( ((size_t) header_size == ret) && + (((size_t) SSIZE_MAX > header_size)) && + (0 != buffer_size) ) + { + int ret2; + /* The header has been sent completely. + * Try to send the reply body without waiting for + * the next round. */ + /* Make sure that sum of ret + ret2 will not exceed SSIZE_MAX. */ + if ( (((size_t) SSIZE_MAX) - ((size_t) ret)) < buffer_size) + buffer_size = (((size_t) SSIZE_MAX) - ((size_t) ret)); + + ret2 = MHD_send_on_connection_ (connection, + buffer, + buffer_size, + MHD_SSO_PUSH_DATA); + if (0 < ret2) + return ret + ret2; /* Total data sent */ + if (MHD_ERR_AGAIN_ == ret2) + return ret; + + return ret2; /* Error code */ + } + return ret; } #if defined(HAVE_SENDMSG) || defined(HAVE_WRITEV) @@ -922,7 +945,8 @@ MHD_send_on_connection2_ (struct MHD_Connection *connection, return ret; #else /* ! (HAVE_SENDMSG || HAVE_WRITEV) */ - return 0; /* Unreachable. Mute warnings. */ + mhd_assert (false); + return MHD_ERR_CONNRESET_; /* Unreachable. Mute warnings. */ #endif /* ! (HAVE_SENDMSG || HAVE_WRITEV) */ }