gnunet-svn
[Top][All Lists]
Advanced

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

[libmicrohttpd] branch master updated (b70fa61d -> be106588)


From: gnunet
Subject: [libmicrohttpd] branch master updated (b70fa61d -> be106588)
Date: Wed, 18 Aug 2021 18:57:11 +0200

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

karlson2k pushed a change to branch master
in repository libmicrohttpd.

    from b70fa61d test_get_chunked: check whether chunked is used for 
non-Keep-Alive
     new ea1edc3d test_get_chunked: re-use the same port for all tests
     new be106588 keepalive_possible: simplified; added new value for 
MHD_ConnKeepAlive

The 2 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     | 139 ++++++++++++++++++++--------------------
 src/microhttpd/internal.h       |   7 +-
 src/testcurl/test_get_chunked.c |  55 ++++++++++------
 3 files changed, 112 insertions(+), 89 deletions(-)

diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index bb0bd681..96d1a39e 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -1138,77 +1138,82 @@ try_ready_chunked_body (struct MHD_Connection 
*connection,
 
 
 /**
- * Are we allowed to keep the given connection alive?  We can use the
- * TCP stream for a second request if the connection is HTTP 1.1 and
- * the "Connection" header either does not exist or is not set to
- * "close", or if the connection is HTTP 1.0 and the "Connection"
- * header is explicitly set to "keep-alive".  If no HTTP version is
- * specified (or if it is not 1.0 or 1.1), we definitively close the
- * connection.  If the "Connection" header is not exactly "close" or
- * "keep-alive", we proceed to use the default for the respective HTTP
- * version (which is conservative for HTTP 1.0, but might be a bit
- * optimistic for HTTP 1.1).
+ * Are we allowed to keep the given connection alive?
+ * We can use the TCP stream for a second request if the connection
+ * is HTTP 1.1 and the "Connection" header either does not exist or
+ * is not set to "close", or if the connection is HTTP 1.0 and the
+ * "Connection" header is explicitly set to "keep-alive".
+ * If no HTTP version is specified (or if it is not 1.0 or 1.1), we
+ * definitively close the connection.  If the "Connection" header is
+ * not exactly "close" or "keep-alive", we proceed to use the default
+ * for the respective HTTP version.
+ * If response has HTTP/1.0 flag or has "Connection: close" header
+ * then connection must be closed.
+ * If full request has not been read then connection must be closed
+ * as well.
  *
  * @param connection the connection to check for keepalive
- * @return #MHD_YES if (based on the request), a keepalive is
- *        legal
+ * @return MHD_CONN_USE_KEEPALIVE if (based on the request and the response),
+ *         a keepalive is legal,
+ *         MHD_CONN_MUST_CLOSE if connection must be closed after sending
+ *         complete reply,
+ *         MHD_CONN_MUST_UPGRADE if connection must be upgraded.
  */
-static enum MHD_Result
-/* TODO: use 'bool' as result type */
+static enum MHD_ConnKeepAlive
 keepalive_possible (struct MHD_Connection *connection)
 {
-  if (MHD_CONN_MUST_CLOSE == connection->keepalive)
-    return MHD_NO;
-  /* TODO: use additional flags, like "error_closure" */
-  if (connection->read_closed)
-    return MHD_NO;
-  /* TODO: Remove check to response presence / replace with assert */
-  if ( (NULL != connection->response) &&
-       (0 != (connection->response->flags & MHD_RF_HTTP_VERSION_1_0_ONLY) ) )
-    return MHD_NO;
-  if ( (NULL != connection->response) &&
-       (0 != (connection->response->flags_auto
-              & MHD_RAF_HAS_CONNECTION_CLOSE) ) )
-    return MHD_NO;
+  struct MHD_Connection *const c = connection; /**< a short alias */
+  struct MHD_Response *const r = c->response;  /**< a short alias */
+
+  mhd_assert (NULL != r);
+  if (MHD_CONN_MUST_CLOSE == c->keepalive)
+    return MHD_CONN_MUST_CLOSE;
 
 #ifdef UPGRADE_SUPPORT
-  /* TODO: use special value 'keep-alive' for upgrade */
-  if ( (NULL != connection->response)
-       && (NULL != connection->response->upgrade_handler) )
-    /* If this connection will not be "upgraded", it must be closed. */
-    return MHD_NO;
+  /* TODO: Move below the next check when MHD stops closing connections
+   * when response is queued in first callback */
+  if (NULL != r->upgrade_handler)
+  {
+    /* No "close" token is enforced by 'add_response_header_connection()' */
+    mhd_assert (0 == (r->flags_auto & MHD_RAF_HAS_CONNECTION_CLOSE));
+    /* Valid HTTP version is enforced by 'MHD_queue_response()' */
+    mhd_assert (MHD_IS_HTTP_VER_SUPPORTED (c->http_ver));
+    return MHD_CONN_MUST_UPGRADE;
+  }
 #endif /* UPGRADE_SUPPORT */
 
-  if (! MHD_IS_HTTP_VER_SUPPORTED (connection->http_ver))
-    return MHD_NO;
+  /* TODO: use additional flags, like "error_closure" or
+   * "! read_completed" */
+  if (c->read_closed)
+    return MHD_CONN_MUST_CLOSE;
+
+  if (0 != (r->flags & MHD_RF_HTTP_VERSION_1_0_ONLY))
+    return MHD_CONN_MUST_CLOSE;
+  if (0 != (r->flags_auto & MHD_RAF_HAS_CONNECTION_CLOSE))
+    return MHD_CONN_MUST_CLOSE;
+
+  if (! MHD_IS_HTTP_VER_SUPPORTED (c->http_ver))
+    return MHD_CONN_MUST_CLOSE;
 
-  if (MHD_lookup_header_s_token_ci (connection,
+  if (MHD_lookup_header_s_token_ci (c,
                                     MHD_HTTP_HEADER_CONNECTION,
                                     "close"))
-    return MHD_NO;
+    return MHD_CONN_MUST_CLOSE;
 
-  if (MHD_IS_HTTP_VER_1_1_COMPAT (connection->http_ver) &&
-      ( (NULL == connection->response) ||
-        (0 == (connection->response->flags
-               & MHD_RF_HTTP_VERSION_1_0_RESPONSE) ) ) )
-  {
-    if (MHD_lookup_header_s_token_ci (connection,
-                                      MHD_HTTP_HEADER_CONNECTION,
-                                      "upgrade"))
-      return MHD_NO;
+  if (MHD_IS_HTTP_VER_1_1_COMPAT (c->http_ver) &&
+      (0 == (connection->response->flags & MHD_RF_HTTP_VERSION_1_0_RESPONSE)) )
+    return MHD_CONN_USE_KEEPALIVE;
 
-    return MHD_YES;
-  }
   if (MHD_HTTP_VER_1_0 == connection->http_ver)
   {
     if (MHD_lookup_header_s_token_ci (connection,
                                       MHD_HTTP_HEADER_CONNECTION,
                                       "Keep-Alive"))
-      return MHD_YES;
+      return MHD_CONN_USE_KEEPALIVE;
 
-    return MHD_NO;
+    return MHD_CONN_MUST_CLOSE;
   }
-  return MHD_NO;
+  return MHD_CONN_MUST_CLOSE;
 }
 
 
@@ -1604,13 +1609,12 @@ setup_reply_properties (struct MHD_Connection 
*connection)
   struct MHD_Connection *const c = connection; /**< a short alias */
   struct MHD_Response *const r = c->response;  /**< a short alias */
   bool use_chunked;
-  bool use_keepalive;
 
   mhd_assert (NULL != r);
 
   /* ** Adjust reply properties ** */
 
-  use_keepalive = keepalive_possible (c);
+  c->keepalive = keepalive_possible (c);
   c->rp_props.use_reply_body_headers = is_reply_body_headers_needed (c);
   if (c->rp_props.use_reply_body_headers)
     c->rp_props.send_reply_body = is_reply_body_needed (c);
@@ -1644,7 +1648,8 @@ setup_reply_properties (struct MHD_Connection *connection)
     if ( (MHD_SIZE_UNKNOWN == r->total_size) && ! use_chunked)
     {
       mhd_assert (! MHD_IS_HTTP_VER_1_1_COMPAT (c->http_ver));
-      use_keepalive = false; /* End of the stream is indicated by closure */
+      /* End of the stream is indicated by closure */
+      c->keepalive = MHD_CONN_MUST_CLOSE;
     }
   }
 
@@ -1652,7 +1657,6 @@ setup_reply_properties (struct MHD_Connection *connection)
   c->rp_props.set = true;
   /* TODO: remove 'have_chunked_upload' assignment, use 'rp_props.chunked' */
   c->have_chunked_upload = c->rp_props.chunked;
-  c->keepalive = use_keepalive ? MHD_CONN_USE_KEEPALIVE : MHD_CONN_MUST_CLOSE;
 }
 
 
@@ -1832,9 +1836,17 @@ build_header_response (struct MHD_Connection *connection)
   /* ** Adjust response properties ** */
 
   setup_reply_properties (c);
+
   mhd_assert (c->rp_props.set);
   mhd_assert ((MHD_CONN_MUST_CLOSE == c->keepalive) || \
-              (MHD_CONN_USE_KEEPALIVE == c->keepalive));
+              (MHD_CONN_USE_KEEPALIVE == c->keepalive) || \
+              (MHD_CONN_MUST_UPGRADE == c->keepalive));
+#ifdef UPGRADE_SUPPORT
+  mhd_assert ((NULL == r->upgrade_handler) || \
+              (MHD_CONN_MUST_UPGRADE == c->keepalive));
+#else  /* ! UPGRADE_SUPPORT */
+  mhd_assert (MHD_CONN_MUST_UPGRADE != c->keepalive);
+#endif /* ! UPGRADE_SUPPORT */
   mhd_assert ((! c->rp_props.chunked) || c->rp_props.use_reply_body_headers);
   mhd_assert ((! c->rp_props.send_reply_body) || \
               c->rp_props.use_reply_body_headers);
@@ -1842,6 +1854,7 @@ build_header_response (struct MHD_Connection *connection)
   mhd_assert (NULL == r->upgrade_handler || \
               ! c->rp_props.use_reply_body_headers);
 #endif /* UPGRADE_SUPPORT */
+
   rcode = (unsigned) (c->responseCode & (~MHD_ICY_FLAG));
 
   /* ** Actually build the response header ** */
@@ -1914,18 +1927,13 @@ build_header_response (struct MHD_Connection 
*connection)
   /* The "Connection:" header */
   if (0 == (r->flags_auto & MHD_RAF_HAS_CONNECTION_HDR))
   {
-    if ((MHD_CONN_MUST_CLOSE == c->keepalive)
-#ifdef UPGRADE_SUPPORT
-        /* TODO: don't mark as "close" upgraded connection */
-        && (NULL == r->upgrade_handler)
-#endif
-        )
+    if (MHD_CONN_MUST_CLOSE == c->keepalive)
     {
       if (! buffer_append_s (buf, &pos, buf_size,
                              MHD_HTTP_HEADER_CONNECTION ": close\r\n"))
         return MHD_NO;
     }
-    else /* Keep-Alive */
+    else if (MHD_CONN_USE_KEEPALIVE == c->keepalive)
     {
       if (MHD_HTTP_VER_1_0 == c->http_ver)
       {
@@ -1940,12 +1948,7 @@ build_header_response (struct MHD_Connection *connection)
 
   if (! add_user_headers (buf, &pos, buf_size, r, MHD_HEADER_KIND,
                           ! c->rp_props.chunked,
-                          ((MHD_CONN_MUST_CLOSE == c->keepalive)
-#ifdef UPGRADE_SUPPORT
-                           /* TODO: don't mark as "close" upgraded connection 
*/
-                           && (NULL == r->upgrade_handler)
-#endif
-                          ),
+                          (MHD_CONN_MUST_CLOSE == c->keepalive),
                           (MHD_HTTP_VER_1_0 == c->http_ver) &&
                           (MHD_CONN_USE_KEEPALIVE == c->keepalive)))
     return MHD_NO;
diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h
index b649f52d..fc521832 100644
--- a/src/microhttpd/internal.h
+++ b/src/microhttpd/internal.h
@@ -755,7 +755,12 @@ enum MHD_ConnKeepAlive
   /**
    * Connection can be used for serving next request
    */
-  MHD_CONN_USE_KEEPALIVE = 1
+  MHD_CONN_USE_KEEPALIVE = 1,
+
+  /**
+   * Connection will be upgraded
+   */
+  MHD_CONN_MUST_UPGRADE = 2
 } _MHD_FIXED_ENUM;
 
 enum MHD_HTTP_Version
diff --git a/src/testcurl/test_get_chunked.c b/src/testcurl/test_get_chunked.c
index 5e6bdd76..5338a489 100644
--- a/src/testcurl/test_get_chunked.c
+++ b/src/testcurl/test_get_chunked.c
@@ -81,6 +81,11 @@ int resp_empty;
  */
 int chunked_forced;
 
+/**
+ * MHD port used for testing
+ */
+int port_global;
+
 
 struct headers_check_result
 {
@@ -310,11 +315,7 @@ testInternalGet ()
   struct curl_slist *h_list = NULL;
   struct headers_check_result hdr_check;
 
-  if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
-    port = 0;
-  else
-    port = 1170;
-
+  port = port_global;
   cbc.buf = buf;
   cbc.size = 2048;
   cbc.pos = 0;
@@ -331,6 +332,8 @@ testInternalGet ()
       MHD_stop_daemon (d); return 32;
     }
     port = (int) dinfo->port;
+    if (0 == port_global)
+      port_global = port; /* Re-use the same port for all checks */
   }
   hdr_check.found_chunked = 0;
   hdr_check.found_footer = 0;
@@ -394,11 +397,7 @@ testMultithreadedGet ()
   struct curl_slist *h_list = NULL;
   struct headers_check_result hdr_check;
 
-  if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
-    port = 0;
-  else
-    port = 1171;
-
+  port = port_global;
   cbc.buf = buf;
   cbc.size = 2048;
   cbc.pos = 0;
@@ -416,6 +415,8 @@ testMultithreadedGet ()
       MHD_stop_daemon (d); return 32;
     }
     port = (int) dinfo->port;
+    if (0 == port_global)
+      port_global = port; /* Re-use the same port for all checks */
   }
   c = curl_easy_init ();
   curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world";);
@@ -479,11 +480,7 @@ testMultithreadedPoolGet ()
   struct curl_slist *h_list = NULL;
   struct headers_check_result hdr_check;
 
-  if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
-    port = 0;
-  else
-    port = 1172;
-
+  port = port_global;
   cbc.buf = buf;
   cbc.size = 2048;
   cbc.pos = 0;
@@ -502,6 +499,8 @@ testMultithreadedPoolGet ()
       MHD_stop_daemon (d); return 32;
     }
     port = (int) dinfo->port;
+    if (0 == port_global)
+      port_global = port; /* Re-use the same port for all checks */
   }
   c = curl_easy_init ();
   curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world";);
@@ -579,11 +578,7 @@ testExternalGet ()
   struct curl_slist *h_list = NULL;
   struct headers_check_result hdr_check;
 
-  if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
-    port = 0;
-  else
-    port = 1173;
-
+  port = port_global;
   multi = NULL;
   cbc.buf = buf;
   cbc.size = 2048;
@@ -601,6 +596,8 @@ testExternalGet ()
       MHD_stop_daemon (d); return 32;
     }
     port = (int) dinfo->port;
+    if (0 == port_global)
+      port_global = port; /* Re-use the same port for all checks */
   }
   c = curl_easy_init ();
   curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world";);
@@ -771,6 +768,24 @@ main (int argc, char *const *argv)
     resp_sized = ! 0;
   if (resp_sized)
     chunked_forced = ! 0;
+
+  if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+    port_global = 0;
+  else
+  {
+    port_global = 4100;
+    if (conn_close)
+      port_global += 1 << 0;
+    if (resp_string)
+      port_global += 1 << 1;
+    if (resp_sized)
+      port_global += 1 << 2;
+    if (resp_empty)
+      port_global += 1 << 3;
+    if (chunked_forced)
+      port_global += 1 << 4;
+  }
+
   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]