[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[libmicrohttpd] branch master updated (526de1a8 -> 179f57bc)
From: |
gnunet |
Subject: |
[libmicrohttpd] branch master updated (526de1a8 -> 179f57bc) |
Date: |
Sun, 13 Dec 2020 17:43:49 +0100 |
This is an automated email from the git hooks/post-receive script.
karlson2k pushed a change to branch master
in repository libmicrohttpd.
from 526de1a8 MHD_send_hdr_and_body_: streamlined code
new ee8b3198 MHD_send_hdr_and_body_: deduplicated code
new 005c7686 mhd_send.c: fixed: properly handle send errors
new 179f57bc mhd_send.c: streamlined code, fixed doxy
The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
src/microhttpd/connection.c | 8 +--
src/microhttpd/mhd_send.c | 117 ++++++++++++++++++++++++--------------------
src/microhttpd/mhd_send.h | 2 +-
3 files changed, 70 insertions(+), 57 deletions(-)
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index 51384788..bb3faaa4 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -2882,7 +2882,7 @@ MHD_connection_handle_write (struct MHD_Connection
*connection)
[connection->continue_message_write_offset],
MHD_STATICSTR_LEN_ (HTTP_100_CONTINUE)
- connection->continue_message_write_offset,
- MHD_SSO_PUSH_DATA);
+ true);
if (ret < 0)
{
if (MHD_ERR_AGAIN_ == ret)
@@ -3025,7 +3025,7 @@ MHD_connection_handle_write (struct MHD_Connection
*connection)
[(size_t) data_write_offset],
response->data_size
- (size_t) data_write_offset,
- MHD_SSO_PUSH_DATA);
+ true);
#if _MHD_DEBUG_SEND_DATA
if (ret > 0)
fprintf (stderr,
@@ -3069,7 +3069,7 @@ MHD_connection_handle_write (struct MHD_Connection
*connection)
[connection->write_buffer_send_offset],
connection->write_buffer_append_offset
- connection->write_buffer_send_offset,
- MHD_SSO_PUSH_DATA);
+ true);
if (ret < 0)
{
if (MHD_ERR_AGAIN_ == ret)
@@ -3099,7 +3099,7 @@ MHD_connection_handle_write (struct MHD_Connection
*connection)
[connection->write_buffer_send_offset],
connection->write_buffer_append_offset
- connection->write_buffer_send_offset,
- MHD_SSO_PUSH_DATA);
+ true);
if (ret < 0)
{
if (MHD_ERR_AGAIN_ == ret)
diff --git a/src/microhttpd/mhd_send.c b/src/microhttpd/mhd_send.c
index 1f187902..78acdc8c 100644
--- a/src/microhttpd/mhd_send.c
+++ b/src/microhttpd/mhd_send.c
@@ -661,31 +661,25 @@ post_send_setopt (struct MHD_Connection *connection,
/**
- * Send buffer on connection, and remember the current state of
- * the socket options; only call setsockopt when absolutely
- * necessary.
+ * Send buffer to the client, push data from network buffer if requested
+ * and full buffer is sent.
*
* @param connection the MHD_Connection structure
* @param buffer content of the buffer to send
- * @param buffer_size the size of the buffer (in bytes)
- * @param options the #MHD_SendSocketOptions enum,
- * #MHD_SSO_NO_CORK: definitely no corking (use NODELAY, or explicitly
disable cork),
- * #MHD_SSO_MAY_CORK: should enable corking (use MSG_MORE, or
explicitly enable cork),
- * #MHD_SSO_HDR_CORK: consider tcpi_snd_mss and consider not corking
for the header
- * part if the size of the header is close to the MSS.
- * Only used if we are NOT doing 100 Continue and are still sending the
- * header (provided in full as the buffer to #MHD_send_on_connection_
or as
- * the header to #MHD_send_on_connection2_).
+ * @param buffer_size the size of the @a buffer (in bytes)
+ * @param push_data set to true to force push the data to the network from
+ * system buffers (usually set for the last piece of data),
+ * set to false to prefer holding incomplete network packets
+ * (more data will be send for the same reply).
* @return sum of the number of bytes sent from both buffers or
- * -1 on error
+ * error code (negative)
*/
ssize_t
MHD_send_on_connection_ (struct MHD_Connection *connection,
const char *buffer,
size_t buffer_size,
- enum MHD_SendSocketOptions options)
+ bool push_data)
{
- bool push_data;
MHD_socket s = connection->socket_fd;
ssize_t ret;
#ifdef HTTPS_SUPPORT
@@ -701,45 +695,35 @@ MHD_send_on_connection_ (struct MHD_Connection
*connection,
return MHD_ERR_NOTCONN_;
}
- /* Get socket options, change/set options if necessary. */
- switch (options)
- {
- /* No corking */
- case MHD_SSO_PUSH_DATA:
- push_data = true;
- break;
- /* Do corking, consider MSG_MORE instead if available. */
- case MHD_SSO_PREFER_BUFF:
- push_data = false;
- break;
- /* Cork the header. */
- case MHD_SSO_HDR_CORK:
- push_data = (buffer_size > 1024);
- break;
- }
-
- pre_send_setopt (connection, (! tls_conn), push_data);
if (tls_conn)
{
#ifdef HTTPS_SUPPORT
if (buffer_size > SSIZE_MAX)
+ {
buffer_size = SSIZE_MAX;
+ push_data = false; /* Incomplete send */
+ }
+ pre_send_setopt (connection, (! tls_conn), push_data);
ret = gnutls_record_send (connection->tls_session,
buffer,
buffer_size);
- if ( (GNUTLS_E_AGAIN == ret) ||
- (GNUTLS_E_INTERRUPTED == ret) )
+ if (GNUTLS_E_AGAIN == ret)
{
#ifdef EPOLL_SUPPORT
- if (GNUTLS_E_AGAIN == ret)
- connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
+ connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
#endif
return MHD_ERR_AGAIN_;
}
+ if (GNUTLS_E_INTERRUPTED == ret)
+ return MHD_ERR_AGAIN_;
+ if ( (GNUTLS_E_ENCRYPTION_FAILED == ret) ||
+ (GNUTLS_E_INVALID_SESSION == ret) )
+ return MHD_ERR_CONNRESET_;
+ if (GNUTLS_E_MEMORY_ERROR == ret)
+ return MHD_ERR_NOMEM_;
if (ret < 0)
{
- /* Likely 'GNUTLS_E_INVALID_SESSION' (client communication
- disrupted); interpret as a hard error */
+ /* Treat any other error as hard error. */
return MHD_ERR_NOTCONN_;
}
#ifdef EPOLL_SUPPORT
@@ -754,8 +738,12 @@ MHD_send_on_connection_ (struct MHD_Connection *connection,
{
/* plaintext transmission */
if (buffer_size > MHD_SCKT_SEND_MAX_SIZE_)
+ {
buffer_size = MHD_SCKT_SEND_MAX_SIZE_; /* return value limit */
+ push_data = false; /* Incomplete send */
+ }
+ pre_send_setopt (connection, (! tls_conn), push_data);
#ifdef MHD_USE_MSG_MORE
ret = MHD_send4_ (s,
buffer,
@@ -784,6 +772,8 @@ MHD_send_on_connection_ (struct MHD_Connection *connection,
return MHD_ERR_AGAIN_;
if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_ECONNRESET_))
return MHD_ERR_CONNRESET_;
+ if (MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err))
+ return MHD_ERR_NOMEM_;
/* Treat any other error as hard error. */
return MHD_ERR_NOTCONN_;
}
@@ -819,8 +809,8 @@ MHD_send_hdr_and_body_ (struct MHD_Connection *connection,
ssize_t ret;
bool push_hdr;
bool push_body;
-#if defined(HAVE_SENDMSG) || defined(HAVE_WRITEV)
MHD_socket s = connection->socket_fd;
+#if defined(HAVE_SENDMSG) || defined(HAVE_WRITEV)
struct iovec vector[2];
#ifdef HAVE_SENDMSG
struct msghdr msg;
@@ -833,6 +823,12 @@ MHD_send_hdr_and_body_ (struct MHD_Connection *connection,
#endif /* HAVE_SENDMSG || HAVE_WRITEV */
mhd_assert ( (NULL != body) || (0 == body_size) );
+ if ( (MHD_INVALID_SOCKET == s) ||
+ (MHD_CONNECTION_CLOSED == connection->state) )
+ {
+ return MHD_ERR_NOTCONN_;
+ }
+
push_body = complete_response;
if (! never_push_hdr)
@@ -872,8 +868,7 @@ MHD_send_hdr_and_body_ (struct MHD_Connection *connection,
ret = MHD_send_on_connection_ (connection,
header,
header_size,
- push_hdr ?
- MHD_SSO_PUSH_DATA: MHD_SSO_PREFER_BUFF);
+ push_hdr);
if ( ((size_t) header_size == ret) &&
(((size_t) SSIZE_MAX > header_size)) &&
(0 != body_size) )
@@ -893,8 +888,7 @@ MHD_send_hdr_and_body_ (struct MHD_Connection *connection,
ret2 = MHD_send_on_connection_ (connection,
body,
body_size,
- push_body ?
- MHD_SSO_PUSH_DATA: MHD_SSO_PREFER_BUFF);
+ push_body);
if (0 < ret2)
return ret + ret2; /* Total data sent */
if (MHD_ERR_AGAIN_ == ret2)
@@ -928,20 +922,39 @@ MHD_send_hdr_and_body_ (struct MHD_Connection *connection,
vector[1].iov_len = body_size;
#if HAVE_SENDMSG
- memset (&msg, 0, sizeof(struct msghdr));
+ memset (&msg, 0, sizeof(msg));
msg.msg_iov = vector;
msg.msg_iovlen = 2;
ret = sendmsg (s, &msg, MSG_NOSIGNAL_OR_ZERO);
- if ( (-1 == ret) &&
- (EAGAIN == errno) )
- return MHD_ERR_AGAIN_;
#elif HAVE_WRITEV
ret = writev (s, vector, 2);
- if ( (-1 == ret) &&
- (EAGAIN == errno) )
- return MHD_ERR_AGAIN_;
#endif
+ if (0 > ret)
+ {
+ const int err = MHD_socket_get_error_ ();
+
+ if (MHD_SCKT_ERR_IS_EAGAIN_ (err))
+ {
+#if EPOLL_SUPPORT
+ /* EAGAIN, no longer write-ready */
+ connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
+#endif /* EPOLL_SUPPORT */
+ return MHD_ERR_AGAIN_;
+ }
+ if (MHD_SCKT_ERR_IS_EINTR_ (err))
+ return MHD_ERR_AGAIN_;
+ if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_ECONNRESET_))
+ return MHD_ERR_CONNRESET_;
+ if (MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err))
+ return MHD_ERR_NOMEM_;
+ /* Treat any other error as hard error. */
+ return MHD_ERR_NOTCONN_;
+ }
+#if EPOLL_SUPPORT
+ else if ((header_size + body_size) > (size_t) ret)
+ connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
+#endif /* EPOLL_SUPPORT */
/* If there is a need to push the data from network buffers
* call post_send_setopt(). */
@@ -1186,7 +1199,7 @@ MHD_send_sendfile_ (struct MHD_Connection *connection)
/* If there is a need to push the data from network buffers
* call post_send_setopt(). */
/* It's unknown whether sendfile() will be used in the next
- * response so assume that next response will be the same. */
+ * response so assume that next response will be the same. */
if ( (push_data) &&
(send_size == (size_t) ret) )
post_send_setopt (connection, false, push_data);
diff --git a/src/microhttpd/mhd_send.h b/src/microhttpd/mhd_send.h
index 69a06769..9d64b07b 100644
--- a/src/microhttpd/mhd_send.h
+++ b/src/microhttpd/mhd_send.h
@@ -84,7 +84,7 @@ ssize_t
MHD_send_on_connection_ (struct MHD_Connection *connection,
const char *buffer,
size_t buffer_size,
- enum MHD_SendSocketOptions options);
+ bool push_data);
/**
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
- [libmicrohttpd] branch master updated (526de1a8 -> 179f57bc),
gnunet <=