gnunet-svn
[Top][All Lists]
Advanced

[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.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]