gnunet-svn
[Top][All Lists]
Advanced

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

[libmicrohttpd] branch master updated: test_long_header: improved, fixed


From: gnunet
Subject: [libmicrohttpd] branch master updated: test_long_header: improved, fixed, added error reporting
Date: Wed, 27 Sep 2023 16:44:45 +0200

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

karlson2k pushed a commit to branch master
in repository libmicrohttpd.

The following commit(s) were added to refs/heads/master by this push:
     new 78e28ecc test_long_header: improved, fixed, added error reporting
78e28ecc is described below

commit 78e28ecca82bafbe4569c8e9c5307853a4a8dbdf
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
AuthorDate: Wed Sep 27 17:44:21 2023 +0300

    test_long_header: improved, fixed, added error reporting
---
 src/testcurl/test_long_header.c | 470 +++++++++++++++++++++++++++++-----------
 1 file changed, 339 insertions(+), 131 deletions(-)

diff --git a/src/testcurl/test_long_header.c b/src/testcurl/test_long_header.c
index 30744934..15469147 100644
--- a/src/testcurl/test_long_header.c
+++ b/src/testcurl/test_long_header.c
@@ -1,7 +1,7 @@
 /*
      This file is part of libmicrohttpd
      Copyright (C) 2007 Christian Grothoff
-     Copyright (C) 2016-2022 Evgeny Grin (Karlson2k)
+     Copyright (C) 2016-2023 Evgeny Grin (Karlson2k)
 
      libmicrohttpd is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
@@ -26,11 +26,12 @@
  * @author Karlson2k (Evgeny Grin)
  */
 
-#include "MHD_config.h"
+#include "mhd_options.h"
 #include "platform.h"
 #include <curl/curl.h>
 #include <microhttpd.h>
 #include <stdlib.h>
+#include <stdio.h>
 #include <string.h>
 #include <time.h>
 #include "mhd_has_in_name.h"
@@ -39,6 +40,21 @@
 #include <unistd.h>
 #endif
 
+#ifndef MHD_STATICSTR_LEN_
+/**
+ * Determine length of static string / macro strings at compile time.
+ */
+#define MHD_STATICSTR_LEN_(macro) (sizeof(macro) / sizeof(char) - 1)
+#endif /* ! MHD_STATICSTR_LEN_ */
+
+#ifndef CURL_VERSION_BITS
+#define CURL_VERSION_BITS(x,y,z) ((x) << 16 | (y) << 8 | (z))
+#endif /* ! CURL_VERSION_BITS */
+#ifndef CURL_AT_LEAST_VERSION
+#define CURL_AT_LEAST_VERSION(x,y,z) \
+  (LIBCURL_VERSION_NUM >= CURL_VERSION_BITS (x, y, z))
+#endif /* ! CURL_AT_LEAST_VERSION */
+
 /**
  * We will set the memory available per connection to
  * half of this value, so the actual value does not have
@@ -46,17 +62,24 @@
  */
 #define VERY_LONG (1024 * 8)
 
+/* Could be increased to facilitate debugging */
+#define TIMEOUTS_VAL 5
+
+#define EXPECTED_URI_BASE_PATH  "/"
+
+#define URL_SCHEME "http:/" "/"
+
+#define URL_HOST "127.0.0.1"
+
+#define URL_SCHEME_HOST_PATH URL_SCHEME URL_HOST EXPECTED_URI_BASE_PATH
+
+
 static int oneone;
 
 static uint16_t daemon_port;
 
-static enum MHD_Result
-apc_all (void *cls, const struct sockaddr *addr, socklen_t addrlen)
-{
-  (void) cls; (void) addr; (void) addrlen;   /* Unused. Silent compiler 
warning. */
-  return MHD_YES;
-}
 
+static char libcurl_err_buf[CURL_ERROR_SIZE];
 
 struct CBC
 {
@@ -73,6 +96,132 @@ copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
 }
 
 
+/* Return non-zero on success, zero on failure */
+static int
+setup_easy_handler_params (CURL *c, struct CBC *pcbc, const char *url,
+                           struct curl_slist *header)
+{
+  libcurl_err_buf[0] = 0; /* Reset error message */
+
+  if (CURLE_OK != curl_easy_setopt (c, CURLOPT_ERRORBUFFER, libcurl_err_buf))
+  {
+    fprintf (stderr, "Failed to set CURLOPT_ERRORBUFFER option.\n");
+    return 0;
+  }
+  if (CURLE_OK != curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L))
+  {
+    fprintf (stderr, "Failed to set CURLOPT_NOSIGNAL option.\n");
+    return 0;
+  }
+  if (CURLE_OK != curl_easy_setopt (c, CURLOPT_WRITEFUNCTION,
+                                    &copyBuffer))
+  {
+    fprintf (stderr, "Failed to set CURLOPT_WRITEFUNCTION option.\n");
+    return 0;
+  }
+  if (CURLE_OK != curl_easy_setopt (c, CURLOPT_WRITEDATA, pcbc))
+  {
+    fprintf (stderr, "Failed to set CURLOPT_WRITEDATA option.\n");
+    return 0;
+  }
+  if (CURLE_OK != curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT,
+                                    ((long) TIMEOUTS_VAL)))
+  {
+    fprintf (stderr, "Failed to set CURLOPT_CONNECTTIMEOUT option.\n");
+    return 0;
+  }
+  if (CURLE_OK != curl_easy_setopt (c, CURLOPT_TIMEOUT,
+                                    ((long) TIMEOUTS_VAL)))
+  {
+    fprintf (stderr, "Failed to set CURLOPT_TIMEOUT option.\n");
+    return 0;
+  }
+  if (CURLE_OK != curl_easy_setopt (c, CURLOPT_HTTP_VERSION,
+                                    (oneone) ?
+                                    CURL_HTTP_VERSION_1_1 :
+                                    CURL_HTTP_VERSION_1_0))
+  {
+    fprintf (stderr, "Failed to set CURLOPT_HTTP_VERSION option.\n");
+    return 0;
+  }
+  if (CURLE_OK != curl_easy_setopt (c, CURLOPT_FAILONERROR, 0L))
+  {
+    fprintf (stderr, "Failed to set CURLOPT_FAILONERROR option.\n");
+    return 0;
+  }
+#ifdef _DEBUG
+  if (CURLE_OK != curl_easy_setopt (c, CURLOPT_VERBOSE, 1L))
+  {
+    fprintf (stderr, "Failed to set CURLOPT_VERBOSE option.\n");
+    return 0;
+  }
+#endif /* _DEBUG */
+#if CURL_AT_LEAST_VERSION (7, 45, 0)
+  if (CURLE_OK != curl_easy_setopt (c, CURLOPT_DEFAULT_PROTOCOL, "http"))
+  {
+    fprintf (stderr, "Failed to set CURLOPT_DEFAULT_PROTOCOL option.\n");
+    return 0;
+  }
+#endif /* CURL_AT_LEAST_VERSION (7, 45, 0) */
+#if CURL_AT_LEAST_VERSION (7, 85, 0)
+  if (CURLE_OK != curl_easy_setopt (c, CURLOPT_PROTOCOLS_STR, "http"))
+  {
+    fprintf (stderr, "Failed to set CURLOPT_PROTOCOLS_STR option.\n");
+    return 0;
+  }
+#elif CURL_AT_LEAST_VERSION (7, 19, 4)
+  if (CURLE_OK != curl_easy_setopt (c, CURLOPT_PROTOCOLS, CURLPROTO_HTTP))
+  {
+    fprintf (stderr, "Failed to set CURLOPT_PROTOCOLS option.\n");
+    return 0;
+  }
+#endif /* CURL_AT_LEAST_VERSION (7, 19, 4) */
+  if (CURLE_OK != curl_easy_setopt (c, CURLOPT_URL,
+                                    (NULL != url) ?
+                                    url : URL_SCHEME_HOST_PATH))
+  {
+    fprintf (stderr, "Failed to set CURLOPT_PROTOCOLS option.\n");
+    return 0;
+  }
+  if (CURLE_OK != curl_easy_setopt (c, CURLOPT_PORT, ((long) daemon_port)))
+  {
+    fprintf (stderr, "Failed to set CURLOPT_PROTOCOLS option.\n");
+    return 0;
+  }
+
+  if (NULL != header)
+  {
+    if (CURLE_OK != curl_easy_setopt (c, CURLOPT_HTTPHEADER, header))
+    {
+      fprintf (stderr, "Failed to set CURLOPT_HTTPHEADER option.\n");
+      return 0;
+    }
+  }
+  return ! 0;
+}
+
+
+static CURL *
+setup_easy_handler (struct CBC *pcbc, const char *url, struct
+                    curl_slist *header)
+{
+  CURL *c;
+
+  c = curl_easy_init ();
+  if (NULL == c)
+  {
+    fprintf (stderr, "curl_easy_init() error.\n");
+    return NULL;
+  }
+  if (setup_easy_handler_params (c, pcbc, url, header))
+  {
+    return c; /* Success exit point */
+  }
+  curl_easy_cleanup (c);
+  return NULL;
+}
+
+
 static enum MHD_Result
 ahc_echo (void *cls,
           struct MHD_Connection *connection,
@@ -84,10 +233,17 @@ ahc_echo (void *cls,
 {
   struct MHD_Response *response;
   enum MHD_Result ret;
+  static int marker;
+
   (void) cls;
   (void) version; (void) upload_data;      /* Unused. Silent compiler warning. 
*/
   (void) upload_data_size; (void) req_cls; /* Unused. Silent compiler warning. 
*/
 
+  if (&marker != *req_cls)
+  {
+    *req_cls = &marker;
+    return MHD_YES;
+  }
   if (0 != strcmp (MHD_HTTP_METHOD_GET, method))
     return MHD_NO;              /* unexpected method */
   response = MHD_create_response_from_buffer_copy (strlen (url),
@@ -102,81 +258,106 @@ static unsigned int
 testLongUrlGet (size_t buff_size)
 {
   struct MHD_Daemon *d;
-  CURL *c;
-  char buf[2048];
-  struct CBC cbc;
-  char *url;
-  long code;
-
-  cbc.buf = buf;
-  cbc.size = 2048;
-  cbc.pos = 0;
+  unsigned int ret;
+
+  ret = 1; /* Error value, shall be reset to zero if succeed */
   d =
     MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD /* | MHD_USE_ERROR_LOG 
*/,
                       daemon_port,
-                      &apc_all,
+                      NULL,
                       NULL,
                       &ahc_echo, NULL,
                       MHD_OPTION_CONNECTION_MEMORY_LIMIT,
                       (size_t) buff_size, MHD_OPTION_END);
   if (d == NULL)
-    return 1;
+  {
+    fprintf (stderr, "MHD_start_daemon() failed.\n");
+    return 16;
+  }
   if (0 == daemon_port)
   {
     const union MHD_DaemonInfo *dinfo;
     dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
     if ((NULL == dinfo) || (0 == dinfo->port) )
-    {
-      MHD_stop_daemon (d); return 32;
-    }
-    daemon_port = dinfo->port;
-  }
-  c = curl_easy_init ();
-  url = malloc (VERY_LONG);
-  if (NULL == url)
-  {
-    curl_easy_cleanup (c);
-    MHD_stop_daemon (d);
-    return 1;
-  }
-  memset (url, 'a', VERY_LONG);
-  url[VERY_LONG - 1] = '\0';
-  memcpy (url, "http://127.0.0.1/";, strlen ("http://127.0.0.1/";));
-  curl_easy_setopt (c, CURLOPT_URL, url);
-  curl_easy_setopt (c, CURLOPT_PORT, (long) daemon_port);
-  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
-  curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
-  curl_easy_setopt (c, CURLOPT_FAILONERROR, 0L);
-  curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
-  curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
-  if (oneone)
-    curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
-  else
-    curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
-  /* NOTE: use of CONNECTTIMEOUT without also
-     setting NOSIGNAL results in really weird
-     crashes on my system! */
-  curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
-  if (CURLE_OK != curl_easy_perform (c))
-  {
-    curl_easy_cleanup (c);
-    MHD_stop_daemon (d);
-    free (url);
-    return 2;
+      fprintf (stderr, "MHD_get_daemon_info(d, MHD_DAEMON_INFO_BIND_PORT) " \
+               "failed.\n");
+    else
+      daemon_port = dinfo->port;
   }
-  if (CURLE_OK != curl_easy_getinfo (c, CURLINFO_RESPONSE_CODE, &code))
+  if (0 != daemon_port)
   {
-    curl_easy_cleanup (c);
-    MHD_stop_daemon (d);
-    free (url);
-    return 4;
+    char *url_str;
+    url_str = malloc (VERY_LONG);
+    if (NULL == url_str)
+      fprintf (stderr, "malloc (VERY_LONG) failed.\n");
+    else
+    {
+      CURL *c;
+      char buf[2048];
+      struct CBC cbc;
+
+      memset (url_str, 'a', VERY_LONG);
+      url_str[VERY_LONG - 1] = '\0';
+      memcpy (url_str, URL_SCHEME_HOST_PATH,
+              MHD_STATICSTR_LEN_ (URL_SCHEME_HOST_PATH));
+
+      cbc.buf = buf;
+      cbc.size = sizeof (buf);
+      cbc.pos = 0;
+
+      c = setup_easy_handler (&cbc, url_str, NULL);
+      if (NULL != c)
+      {
+        CURLcode r;
+        r = curl_easy_perform (c);
+        if (CURLE_OK != r)
+        {
+          fprintf (stderr, "curl_easy_perform() failed. Error message: %s\n",
+                   curl_easy_strerror (r));
+          if (0 != libcurl_err_buf[0])
+            fprintf (stderr, "Detailed error message: %s\n", libcurl_err_buf);
+        }
+        else
+        {
+          long code;
+
+          r = curl_easy_getinfo (c, CURLINFO_RESPONSE_CODE, &code);
+          if (CURLE_OK != r)
+          {
+            fprintf (stderr, "curl_easy_getinfo() failed. "
+                     "Error message: %s\n",
+                     curl_easy_strerror (r));
+            if (0 != libcurl_err_buf[0])
+              fprintf (stderr, "Detailed error message: %s\n",
+                       libcurl_err_buf);
+          }
+          else
+          {
+            if (code != MHD_HTTP_URI_TOO_LONG)
+            {
+              fprintf (stderr, "testLongHeaderGet(%lu) failed. HTTP "
+                       "response code is %ld, while it should be %ld.\n",
+                       (unsigned long) buff_size,
+                       code,
+                       (long) MHD_HTTP_URI_TOO_LONG);
+            }
+            else
+            {
+              printf ("testLongHeaderGet(%lu) succeed. HTTP "
+                      "response code is %ld, as expected.\n",
+                      (unsigned long) buff_size,
+                      (long) MHD_HTTP_URI_TOO_LONG);
+              ret = 0; /* Success */
+            }
+          }
+        }
+        curl_easy_cleanup (c);
+      }
+      free (url_str);
+    }
   }
-  curl_easy_cleanup (c);
   MHD_stop_daemon (d);
-  free (url);
-  if (code != MHD_HTTP_URI_TOO_LONG)
-    return 8;
-  return 0;
+  return ret;
 }
 
 
@@ -184,89 +365,115 @@ static unsigned int
 testLongHeaderGet (size_t buff_size)
 {
   struct MHD_Daemon *d;
-  CURL *c;
-  char buf[2048];
-  struct CBC cbc;
-  char *url;
-  long code;
-  struct curl_slist *header = NULL;
-
-  cbc.buf = buf;
-  cbc.size = 2048;
-  cbc.pos = 0;
+  unsigned int ret;
+
+  ret = 1; /* Error value, shall be reset to zero if succeed */
   d =
     MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD /* | MHD_USE_ERROR_LOG 
*/,
                       daemon_port,
-                      &apc_all,
+                      NULL,
                       NULL,
                       &ahc_echo, NULL,
                       MHD_OPTION_CONNECTION_MEMORY_LIMIT,
                       (size_t) buff_size, MHD_OPTION_END);
   if (d == NULL)
+  {
+    fprintf (stderr, "MHD_start_daemon() failed.\n");
     return 16;
+  }
   if (0 == daemon_port)
   {
     const union MHD_DaemonInfo *dinfo;
     dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
     if ((NULL == dinfo) || (0 == dinfo->port) )
-    {
-      MHD_stop_daemon (d); return 32;
-    }
-    daemon_port = dinfo->port;
-  }
-  c = curl_easy_init ();
-  url = malloc (VERY_LONG);
-  if (NULL == url)
-  {
-    curl_easy_cleanup (c);
-    MHD_stop_daemon (d);
-    return 16;
-  }
-  memset (url, 'a', VERY_LONG);
-  url[VERY_LONG - 1] = '\0';
-  url[VERY_LONG / 2] = ':';
-  url[VERY_LONG / 2 + 1] = ' ';
-  header = curl_slist_append (header, url);
-
-  curl_easy_setopt (c, CURLOPT_HTTPHEADER, header);
-  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world";);
-  curl_easy_setopt (c, CURLOPT_PORT, (long) daemon_port);
-  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
-  curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
-  curl_easy_setopt (c, CURLOPT_FAILONERROR, 0L);
-  curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
-  curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
-  if (oneone)
-    curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
-  else
-    curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
-  /* NOTE: use of CONNECTTIMEOUT without also
-     setting NOSIGNAL results in really weird
-     crashes on my system! */
-  curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
-  if (CURLE_OK != curl_easy_perform (c))
-  {
-    curl_easy_cleanup (c);
-    MHD_stop_daemon (d);
-    curl_slist_free_all (header);
-    free (url);
-    return 32;
+      fprintf (stderr, "MHD_get_daemon_info(d, MHD_DAEMON_INFO_BIND_PORT) " \
+               "failed.\n");
+    else
+      daemon_port = dinfo->port;
   }
-  if (CURLE_OK != curl_easy_getinfo (c, CURLINFO_RESPONSE_CODE, &code))
+  if (0 != daemon_port)
   {
-    curl_slist_free_all (header);
-    curl_easy_cleanup (c);
-    MHD_stop_daemon (d);
-    free (url);
-    return 64;
+    char *header_str;
+    header_str = malloc (VERY_LONG);
+    if (NULL == header_str)
+      fprintf (stderr, "malloc (VERY_LONG) failed.\n");
+    else
+    {
+      struct curl_slist *header = NULL;
+
+      memset (header_str, 'a', VERY_LONG);
+      header_str[VERY_LONG - 1] = '\0';
+      header_str[VERY_LONG / 2] = ':';
+      header_str[VERY_LONG / 2 + 1] = ' ';
+
+      header = curl_slist_append (header, header_str);
+      if (NULL == header)
+        fprintf (stderr, "curl_slist_append () failed.\n");
+      else
+      {
+        CURL *c;
+        char buf[2048];
+        struct CBC cbc;
+
+        cbc.buf = buf;
+        cbc.size = sizeof (buf);
+        cbc.pos = 0;
+
+        c = setup_easy_handler (&cbc, NULL, header);
+        if (NULL != c)
+        {
+          CURLcode r;
+          r = curl_easy_perform (c);
+          if (CURLE_OK != r)
+          {
+            fprintf (stderr, "curl_easy_perform() failed. Error message: %s\n",
+                     curl_easy_strerror (r));
+            if (0 != libcurl_err_buf[0])
+              fprintf (stderr, "Detailed error message: %s\n", 
libcurl_err_buf);
+          }
+          else
+          {
+            long code;
+
+            r = curl_easy_getinfo (c, CURLINFO_RESPONSE_CODE, &code);
+            if (CURLE_OK != r)
+            {
+              fprintf (stderr, "curl_easy_getinfo() failed. "
+                       "Error message: %s\n",
+                       curl_easy_strerror (r));
+              if (0 != libcurl_err_buf[0])
+                fprintf (stderr, "Detailed error message: %s\n",
+                         libcurl_err_buf);
+            }
+            else
+            {
+              if (code != MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE)
+              {
+                fprintf (stderr, "testLongHeaderGet(%lu) failed. HTTP "
+                         "response code is %ld, while it should be %ld.\n",
+                         (unsigned long) buff_size,
+                         code,
+                         (long) MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE);
+              }
+              else
+              {
+                printf ("testLongHeaderGet(%lu) succeed. HTTP "
+                        "response code is %ld, as expected.\n",
+                        (unsigned long) buff_size,
+                        (long) MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE);
+                ret = 0; /* Success */
+              }
+            }
+          }
+          curl_easy_cleanup (c);
+        }
+        curl_slist_free_all (header);
+      }
+      free (header_str);
+    }
   }
-  curl_slist_free_all (header);
-  curl_easy_cleanup (c);
   MHD_stop_daemon (d);
-  free (url);
-  if (code != MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE)
-    return 128;
-  return 0;
+  return ret;
 }
 
 
@@ -285,6 +492,7 @@ main (int argc, char *const *argv)
     daemon_port = 0;
   else
     daemon_port = oneone ? 1336 : 1331;
+
   errorCount += testLongUrlGet (VERY_LONG / 2);
   errorCount += testLongUrlGet (VERY_LONG / 2 + 978);
   errorCount += testLongHeaderGet (VERY_LONG / 2);

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