gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[libmicrohttpd] branch master updated (466a56e3 -> 225268ae)


From: gnunet
Subject: [libmicrohttpd] branch master updated (466a56e3 -> 225268ae)
Date: Sun, 15 Aug 2021 17:29:08 +0200

This is an automated email from the git hooks/post-receive script.

karlson2k pushed a change to branch master
in repository libmicrohttpd.

    from 466a56e3 test_get_chunked: set footer when last chunk is being sending
     new 564c9533 Fixed chunked response with known size
     new 4595a443 Added more chunked response tests
     new 5383019b connection.c: fixed chunked response without callback
     new 225268ae chunked response: do not try to send more than needed

The 4 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     | 88 ++++++++++++++++++++++++-----------------
 src/testcurl/.gitignore         |  2 +
 src/testcurl/Makefile.am        | 14 +++++++
 src/testcurl/test_get_chunked.c | 16 ++++++--
 4 files changed, 80 insertions(+), 40 deletions(-)

diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index 8de231aa..d438a3a5 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -992,10 +992,14 @@ try_ready_normal_body (struct MHD_Connection *connection)
  * return #MHD_NO).
  *
  * @param connection the connection
+ * @param[out] p_finished the pointer to variable that will be set to "true"
+ *                        when application returned indication of the end
+ *                        of the stream
  * @return #MHD_NO if readying the response failed
  */
 static enum MHD_Result
-try_ready_chunked_body (struct MHD_Connection *connection)
+try_ready_chunked_body (struct MHD_Connection *connection,
+                        bool *p_finished)
 {
   ssize_t ret;
   struct MHD_Response *response;
@@ -1006,14 +1010,15 @@ try_ready_chunked_body (struct MHD_Connection 
*connection)
   /* "FFFFFF" + "\r\n" + "\r\n" (chunk termination) */
   static const size_t max_chunk_overhead = sizeof(chunk_hdr) + 2 + 2;
   size_t chunk_hdr_len;
+  uint64_t left_to_send;
+  size_t size_to_fill;
 
   response = connection->response;
-  if (NULL == response->crc)
-    return MHD_YES;
+  mhd_assert (NULL != response->crc || NULL != response->data);
 
   mhd_assert (0 == connection->write_buffer_append_offset);
 
-  /* The buffer must reasonably large enough */
+  /* The buffer must be reasonably large enough */
   if (128 > connection->write_buffer_size)
   {
     size_t size;
@@ -1039,9 +1044,23 @@ try_ready_chunked_body (struct MHD_Connection 
*connection)
     mhd_assert (NULL != connection->write_buffer);
     connection->write_buffer_size = size;
   }
+  mhd_assert (max_chunk_overhead < connection->write_buffer_size);
 
-  if (0 == response->total_size)
-    ret = 0; /* response must be empty, don't bother calling crc */
+  if (MHD_SIZE_UNKNOWN == response->total_size)
+    left_to_send = MHD_SIZE_UNKNOWN;
+  else
+    left_to_send = MHD_SIZE_UNKNOWN - connection->response_write_position;
+
+  size_to_fill = connection->write_buffer_size - max_chunk_overhead;
+  /* Limit size for the callback to the max usable size */
+  if (max_chunk < size_to_fill)
+    size_to_fill = max_chunk;
+  if (left_to_send < size_to_fill)
+    size_to_fill = left_to_send;
+
+  if (0 == left_to_send)
+    /* nothing to send, don't bother calling crc */
+    ret = MHD_CONTENT_READER_END_OF_STREAM;
   else if ( (response->data_start <=
              connection->response_write_position) &&
             (response->data_start + response->data_size >
@@ -1053,21 +1072,14 @@ try_ready_chunked_body (struct MHD_Connection 
*connection)
       = (size_t) (connection->response_write_position - response->data_start);
     /* buffer already ready, use what is there for the chunk */
     ret = response->data_size - data_write_offset;
-    if ( ((size_t) ret) > connection->write_buffer_size - max_chunk_overhead)
-      ret = connection->write_buffer_size - max_chunk_overhead;
+    if ( ((size_t) ret) > size_to_fill)
+      ret = (ssize_t) size_to_fill;
     memcpy (&connection->write_buffer[max_chunk_hdr_len],
             &response->data[data_write_offset],
             ret);
   }
   else
   {
-    /* buffer not in range, try to fill it */
-    size_t size_to_fill;
-
-    size_to_fill = connection->write_buffer_size - max_chunk_overhead;
-    /* Limit size for the callback to the max usable size */
-    if (max_chunk < size_to_fill)
-      size_to_fill = max_chunk;
     ret = response->crc (response->crc_cls,
                          connection->response_write_position,
                          &connection->write_buffer[max_chunk_hdr_len],
@@ -1085,15 +1097,9 @@ try_ready_chunked_body (struct MHD_Connection 
*connection)
                               "Closing connection (application error 
generating response)."));
     return MHD_NO;
   }
-  if ( (((ssize_t) MHD_CONTENT_READER_END_OF_STREAM) == ret) ||
-       (0 == response->total_size) )
+  if (((ssize_t) MHD_CONTENT_READER_END_OF_STREAM) == ret)
   {
-    /* end of message, signal other side! */
-    connection->write_buffer[0] = '0';
-    connection->write_buffer[1] = '\r';
-    connection->write_buffer[2] = '\n';
-    connection->write_buffer_append_offset = 3;
-    connection->write_buffer_send_offset = 0;
+    *p_finished = true;
     /* TODO: remove update of the response size */
     response->total_size = connection->response_write_position;
     return MHD_YES;
@@ -1109,6 +1115,7 @@ try_ready_chunked_body (struct MHD_Connection *connection)
   chunk_hdr_len = MHD_uint32_to_strx (ret, chunk_hdr, sizeof(chunk_hdr));
   mhd_assert (chunk_hdr_len != 0);
   mhd_assert (chunk_hdr_len < sizeof(chunk_hdr));
+  *p_finished = false;
   connection->write_buffer_send_offset =
     (max_chunk_hdr_len - (chunk_hdr_len + 2));
   memcpy (connection->write_buffer + connection->write_buffer_send_offset,
@@ -1885,13 +1892,16 @@ build_connection_chunked_response_footer (struct 
MHD_Connection *connection)
   mhd_assert (NULL != c->response);
 
   buf_size = connection_maximize_write_buffer (c);
-  /* '2' is the minimal size of chunked footer ("\r\n") */
-  if (buf_size < 2)
+  /* '5' is the minimal size of chunked footer ("0\r\n\r\n") */
+  if (buf_size < 5)
     return MHD_NO;
   mhd_assert (NULL != c->write_buffer);
   buf = c->write_buffer + c->write_buffer_append_offset;
   mhd_assert (NULL != buf);
   used_size = 0;
+  buf[used_size++] = '0';
+  buf[used_size++] = '\r';
+  buf[used_size++] = '\n';
 
   for (pos = c->response->first_header; NULL != pos; pos = pos->next)
   {
@@ -1915,8 +1925,8 @@ build_connection_chunked_response_footer (struct 
MHD_Connection *connection)
   }
   if (used_size + 2 > buf_size)
     return MHD_NO;
-  memcpy (buf + used_size, "\r\n", 2);
-  used_size += 2;
+  buf[used_size++] = '\r';
+  buf[used_size++] = '\n';
 
   c->write_buffer_append_offset += used_size;
   mhd_assert (c->write_buffer_append_offset <= c->write_buffer_size);
@@ -3476,7 +3486,8 @@ MHD_connection_handle_write (struct MHD_Connection 
*connection)
 
       if ( (NULL == resp->crc) &&
            (NULL == resp->data_iov) &&
-           (0 == connection->response_write_position) )
+           (0 == connection->response_write_position) &&
+           (! connection->have_chunked_upload) )
       {
         mhd_assert (resp->total_size >= resp->data_size);
         /* Send response headers alongside the response body, if the body
@@ -4236,18 +4247,21 @@ MHD_connection_handle_idle (struct MHD_Connection 
*connection)
         connection->state = MHD_CONNECTION_BODY_SENT;
         continue;
       }
-      if (MHD_NO != try_ready_chunked_body (connection))
-      {
+      if (1)
+      { /* pseudo-branch for local variables scope */
+        bool finished;
+        if (MHD_NO != try_ready_chunked_body (connection, &finished))
+        {
 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
-        if (NULL != connection->response->crc)
-          MHD_mutex_unlock_chk_ (&connection->response->mutex);
+          if (NULL != connection->response->crc)
+            MHD_mutex_unlock_chk_ (&connection->response->mutex);
 #endif
-        connection->state = MHD_CONNECTION_CHUNKED_BODY_READY;
-        /* Buffering for flushable socket was already enabled */
-
-        continue;
+          connection->state = finished ? MHD_CONNECTION_BODY_SENT :
+                              MHD_CONNECTION_CHUNKED_BODY_READY;
+          continue;
+        }
+        /* mutex was already unlocked by try_ready_chunked_body */
       }
-      /* mutex was already unlocked by try_ready_chunked_body */
       break;
     case MHD_CONNECTION_BODY_SENT:
       /* TODO: replace with 'use_chunked_send' */
diff --git a/src/testcurl/.gitignore b/src/testcurl/.gitignore
index 23c83b66..cf4ba3bd 100644
--- a/src/testcurl/.gitignore
+++ b/src/testcurl/.gitignore
@@ -37,6 +37,8 @@
 /test_get_chunked_close_sized
 /test_get_chunked_empty_sized
 /test_get_chunked_close_empty_sized
+/test_get_chunked_forced
+/test_get_chunked_empty_forced
 /test_get11
 /test_get
 /test_digestauth_with_arguments
diff --git a/src/testcurl/Makefile.am b/src/testcurl/Makefile.am
index 873017c2..cc13962c 100644
--- a/src/testcurl/Makefile.am
+++ b/src/testcurl/Makefile.am
@@ -110,6 +110,8 @@ check_PROGRAMS = \
   test_get_chunked_close_sized \
   test_get_chunked_empty_sized \
   test_get_chunked_close_empty_sized \
+  test_get_chunked_forced \
+  test_get_chunked_empty_forced \
   test_put_chunked \
   test_callback \
   $(EMPTY_ITEM)
@@ -346,6 +348,18 @@ test_get_chunked_close_empty_sized_LDADD = \
   $(top_builddir)/src/microhttpd/libmicrohttpd.la \
   @LIBCURL@
 
+test_get_chunked_forced_SOURCES = \
+  test_get_chunked.c
+test_get_chunked_forced_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_get_chunked_empty_forced_SOURCES = \
+  test_get_chunked.c
+test_get_chunked_empty_forced_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
 test_post_SOURCES = \
   test_post.c mhd_has_in_name.h
 test_post_LDADD = \
diff --git a/src/testcurl/test_get_chunked.c b/src/testcurl/test_get_chunked.c
index cb46b6dc..dbe7b7f8 100644
--- a/src/testcurl/test_get_chunked.c
+++ b/src/testcurl/test_get_chunked.c
@@ -76,6 +76,11 @@ int resp_sized;
  */
 int resp_empty;
 
+/**
+ * Force chunked response by response header?
+ */
+int chunked_forced;
+
 
 struct headers_check_result
 {
@@ -225,14 +230,14 @@ ahc_echo (void *cls,
   }
   if (NULL == response)
     abort ();
-  if (conn_close || resp_sized)
-  { /* Enforce chunked response even for non-Keep-Alive and static responses */
+  if (chunked_forced)
+  {
     if (MHD_NO == MHD_add_response_header (response,
                                            MHD_HTTP_HEADER_TRANSFER_ENCODING,
                                            "chunked"))
       abort ();
   }
-  if (resp_string)
+  if (resp_string || (resp_sized && resp_empty))
   {
     /* There is no chance to add footer later */
     if (MHD_YES != MHD_add_response_footer (response,
@@ -737,8 +742,13 @@ main (int argc, char *const *argv)
   resp_string = has_in_name (argv[0], "_string");
   resp_sized = has_in_name (argv[0], "_sized");
   resp_empty = has_in_name (argv[0], "_empty");
+  chunked_forced = has_in_name (argv[0], "_forced");
   if (resp_string)
     resp_sized = ! 0;
+  if (resp_sized)
+    chunked_forced = ! 0;
+  if (conn_close) /* TODO: remove when supported by MHD */
+    chunked_forced = ! 0;
   if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_THREADS))
   {
     errorCount += testInternalGet ();

-- 
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]