gnunet-svn
[Top][All Lists]
Advanced

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

[libmicrohttpd] branch master updated (b6dcf9d2 -> 77303a4a)


From: gnunet
Subject: [libmicrohttpd] branch master updated (b6dcf9d2 -> 77303a4a)
Date: Tue, 27 Sep 2022 13:59:19 +0200

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

karlson2k pushed a change to branch master
in repository libmicrohttpd.

    from b6dcf9d2 w32: sync projects with autotools
     new 14b7b4d3 w32: updated custom MHD_config.h file
     new db4d4cb4 test-suite: sorted and fixed build flags
     new ebb17e5d connection: skip no-op calling of body generation functions 
when response body is not used
     new 77303a4a test_head: new test-case for HEAD requests

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/Makefile.am     |  28 +-
 src/microhttpd/connection.c    |  11 +-
 src/testcurl/Makefile.am       |  20 +-
 src/testcurl/https/Makefile.am |   4 +-
 src/testcurl/test_head.c       | 809 +++++++++++++++++++++++++++++++++++++++++
 w32/common/MHD_config.h        |  44 +--
 6 files changed, 874 insertions(+), 42 deletions(-)
 create mode 100644 src/testcurl/test_head.c

diff --git a/src/microhttpd/Makefile.am b/src/microhttpd/Makefile.am
index c4c15608..c25abab7 100644
--- a/src/microhttpd/Makefile.am
+++ b/src/microhttpd/Makefile.am
@@ -419,37 +419,45 @@ test_postprocessor_md_SOURCES = \
 
 test_shutdown_select_SOURCES = \
   test_shutdown_select.c
+test_shutdown_select_CFLAGS = $(AM_CFLAGS)
+test_shutdown_select_LDADD = $(LDADD)
 if USE_POSIX_THREADS
-test_shutdown_select_CFLAGS = \
-  $(AM_CFLAGS) $(PTHREAD_CFLAGS)
-test_shutdown_select_LDADD = \
+test_shutdown_select_CFLAGS += \
+  $(PTHREAD_CFLAGS)
+test_shutdown_select_LDADD += \
   $(PTHREAD_LIBS)
 endif
 
 test_shutdown_poll_SOURCES = \
   test_shutdown_select.c mhd_threads.h
+test_shutdown_poll_CFLAGS = $(AM_CFLAGS)
+test_shutdown_poll_LDADD = $(LDADD)
 if USE_POSIX_THREADS
-test_shutdown_poll_CFLAGS = \
+test_shutdown_poll_CFLAGS += \
   $(AM_CFLAGS) $(PTHREAD_CFLAGS)
-test_shutdown_poll_LDADD = \
+test_shutdown_poll_LDADD += \
   $(PTHREAD_LIBS)
 endif
 
 test_shutdown_select_ignore_SOURCES = \
   test_shutdown_select.c
+test_shutdown_select_ignore_CFLAGS = $(AM_CFLAGS)
+test_shutdown_select_ignore_LDADD = $(LDADD)
 if USE_POSIX_THREADS
-test_shutdown_select_ignore_CFLAGS = \
-  $(AM_CFLAGS) $(PTHREAD_CFLAGS)
-test_shutdown_select_ignore_LDADD = \
+test_shutdown_select_ignore_CFLAGS += \
+  $(PTHREAD_CFLAGS)
+test_shutdown_select_ignore_LDADD += \
   $(PTHREAD_LIBS)
 endif
 
 test_shutdown_poll_ignore_SOURCES = \
   test_shutdown_select.c mhd_threads.h
+test_shutdown_poll_ignore_CFLAGS = $(AM_CFLAGS)
+test_shutdown_poll_ignore_LDADD = $(LDADD)
 if USE_POSIX_THREADS
-test_shutdown_poll_ignore_CFLAGS = \
+test_shutdown_poll_ignore_CFLAGS += \
   $(AM_CFLAGS) $(PTHREAD_CFLAGS)
-test_shutdown_poll_ignore_LDADD = \
+test_shutdown_poll_ignore_LDADD += \
   $(PTHREAD_LIBS)
 endif
 
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index f33f9a9f..7624711a 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -5091,10 +5091,15 @@ MHD_connection_handle_idle (struct MHD_Connection 
*connection)
       }
 #endif /* UPGRADE_SUPPORT */
 
-      if (connection->rp.props.chunked)
-        connection->state = MHD_CONNECTION_CHUNKED_BODY_UNREADY;
+      if (connection->rp.props.send_reply_body)
+      {
+        if (connection->rp.props.chunked)
+          connection->state = MHD_CONNECTION_CHUNKED_BODY_UNREADY;
+        else
+          connection->state = MHD_CONNECTION_NORMAL_BODY_UNREADY;
+      }
       else
-        connection->state = MHD_CONNECTION_NORMAL_BODY_UNREADY;
+        connection->state = MHD_CONNECTION_FOOTERS_SENT;
       continue;
     case MHD_CONNECTION_NORMAL_BODY_READY:
       /* nothing to do here */
diff --git a/src/testcurl/Makefile.am b/src/testcurl/Makefile.am
index a4bc94ef..cd6dcd21 100644
--- a/src/testcurl/Makefile.am
+++ b/src/testcurl/Makefile.am
@@ -81,6 +81,8 @@ endif
 if HAVE_CURL
 check_PROGRAMS = \
   test_get \
+  test_head \
+  test_head10 \
   test_get_iovec \
   test_get_sendfile \
   test_get_close \
@@ -225,24 +227,30 @@ endif
 test_concurrent_stop_SOURCES = \
   test_concurrent_stop.c
 test_concurrent_stop_CFLAGS = \
-  $(PTHREAD_CFLAGS) $(AM_CFLAGS)
+  $(AM_CFLAGS) $(PTHREAD_CFLAGS)
 test_concurrent_stop_LDADD = \
   $(PTHREAD_LIBS) $(LDADD)
 
 test_get_SOURCES = \
   test_get.c mhd_has_in_name.h mhd_has_param.h
 
+test_head_SOURCES = \
+  test_head.c mhd_has_in_name.h mhd_has_param.h
+
+test_head10_SOURCES = \
+  test_head.c mhd_has_in_name.h mhd_has_param.h
+
 test_quiesce_SOURCES = \
   test_quiesce.c mhd_has_param.h mhd_has_in_name.h
 test_quiesce_CFLAGS = \
-  $(PTHREAD_CFLAGS) $(AM_CFLAGS)
+  $(AM_CFLAGS) $(PTHREAD_CFLAGS)
 test_quiesce_LDADD = \
   $(PTHREAD_LIBS) $(LDADD)
 
 test_quiesce_stream_SOURCES = \
   test_quiesce_stream.c
 test_quiesce_stream_CFLAGS = \
-  $(PTHREAD_CFLAGS) $(AM_CFLAGS)
+  $(AM_CFLAGS) $(PTHREAD_CFLAGS)
 test_quiesce_stream_LDADD = \
   $(PTHREAD_LIBS) $(LDADD)
 
@@ -257,7 +265,7 @@ perf_get_concurrent_SOURCES = \
   perf_get_concurrent.c \
   gauger.h mhd_has_in_name.h
 perf_get_concurrent_CFLAGS = \
-  $(PTHREAD_CFLAGS) $(AM_CFLAGS)
+  $(AM_CFLAGS) $(PTHREAD_CFLAGS)
 perf_get_concurrent_LDADD = \
   $(PTHREAD_LIBS) $(LDADD)
 
@@ -265,7 +273,7 @@ perf_get_concurrent11_SOURCES = \
   perf_get_concurrent.c \
   gauger.h mhd_has_in_name.h
 perf_get_concurrent11_CFLAGS = \
-  $(PTHREAD_CFLAGS) $(AM_CFLAGS)
+  $(AM_CFLAGS) $(PTHREAD_CFLAGS)
 perf_get_concurrent11_LDADD = \
   $(PTHREAD_LIBS) $(LDADD)
 
@@ -299,7 +307,7 @@ test_digestauth_with_arguments_LDADD = \
 test_digestauth_concurrent_SOURCES = \
   test_digestauth_concurrent.c
 test_digestauth_concurrent_CFLAGS = \
-  $(PTHREAD_CFLAGS) $(AM_CFLAGS)
+  $(AM_CFLAGS) $(PTHREAD_CFLAGS)
 test_digestauth_concurrent_LDADD = \
   @LIBGCRYPT_LIBS@ $(LDADD) $(PTHREAD_LIBS) $(LDADD)
 
diff --git a/src/testcurl/https/Makefile.am b/src/testcurl/https/Makefile.am
index 11b1ea20..39394db1 100644
--- a/src/testcurl/https/Makefile.am
+++ b/src/testcurl/https/Makefile.am
@@ -87,7 +87,7 @@ test_https_get_parallel_SOURCES = \
   tls_test_common.h \
   tls_test_common.c
 test_https_get_parallel_CFLAGS = \
-  $(PTHREAD_CFLAGS) $(AM_CFLAGS)
+  $(AM_CFLAGS) $(PTHREAD_CFLAGS)
 test_https_get_parallel_LDADD = \
   $(PTHREAD_LIBS) $(LDADD)
 
@@ -103,7 +103,7 @@ test_https_get_parallel_threads_SOURCES = \
   tls_test_common.h \
   tls_test_common.c
 test_https_get_parallel_threads_CFLAGS = \
-  $(PTHREAD_CFLAGS) $(AM_CFLAGS)
+  $(AM_CFLAGS) $(PTHREAD_CFLAGS)
 test_https_get_parallel_threads_LDADD = \
   $(PTHREAD_LIBS) $(LDADD)
 
diff --git a/src/testcurl/test_head.c b/src/testcurl/test_head.c
new file mode 100644
index 00000000..f435a4f4
--- /dev/null
+++ b/src/testcurl/test_head.c
@@ -0,0 +1,809 @@
+/*
+     This file is part of GNU libmicrohttpd
+     Copyright (C) 2010 Christian Grothoff
+     Copyright (C) 2016-2022 Evgeny Grin (Karlson2k)
+
+     GNU libmicrohttpd is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 2, or (at your
+     option) any later version.
+
+     GNU libmicrohttpd is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with libmicrohttpd; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+     Boston, MA 02110-1301, USA.
+*/
+
+/**
+ * @file testcurl/test_head.c
+ * @brief  Testcase for HEAD requests
+ * @author Karlson2k (Evgeny Grin)
+ */
+
+#include "mhd_options.h"
+#include "platform.h"
+#include <curl/curl.h>
+#include <microhttpd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#ifndef _WIN32
+#include <sys/socket.h>
+#include <unistd.h>
+#else
+#include <wincrypt.h>
+#endif
+
+#include "mhd_has_param.h"
+#include "mhd_has_in_name.h"
+
+#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 */
+
+#ifndef _MHD_INSTRMACRO
+/* Quoted macro parameter */
+#define _MHD_INSTRMACRO(a) #a
+#endif /* ! _MHD_INSTRMACRO */
+#ifndef _MHD_STRMACRO
+/* Quoted expanded macro parameter */
+#define _MHD_STRMACRO(a) _MHD_INSTRMACRO (a)
+#endif /* ! _MHD_STRMACRO */
+
+#if defined(HAVE___FUNC__)
+#define externalErrorExit(ignore) \
+  _externalErrorExit_func (NULL, __func__, __LINE__)
+#define externalErrorExitDesc(errDesc) \
+  _externalErrorExit_func (errDesc, __func__, __LINE__)
+#define libcurlErrorExit(ignore) \
+  _libcurlErrorExit_func (NULL, __func__, __LINE__)
+#define libcurlErrorExitDesc(errDesc) \
+  _libcurlErrorExit_func (errDesc, __func__, __LINE__)
+#define mhdErrorExit(ignore) \
+  _mhdErrorExit_func (NULL, __func__, __LINE__)
+#define mhdErrorExitDesc(errDesc) \
+  _mhdErrorExit_func (errDesc, __func__, __LINE__)
+#define checkCURLE_OK(libcurlcall) \
+  _checkCURLE_OK_func ((libcurlcall), _MHD_STRMACRO (libcurlcall), \
+                       __func__, __LINE__)
+#elif defined(HAVE___FUNCTION__)
+#define externalErrorExit(ignore) \
+  _externalErrorExit_func (NULL, __FUNCTION__, __LINE__)
+#define externalErrorExitDesc(errDesc) \
+  _externalErrorExit_func (errDesc, __FUNCTION__, __LINE__)
+#define libcurlErrorExit(ignore) \
+  _libcurlErrorExit_func (NULL, __FUNCTION__, __LINE__)
+#define libcurlErrorExitDesc(errDesc) \
+  _libcurlErrorExit_func (errDesc, __FUNCTION__, __LINE__)
+#define mhdErrorExit(ignore) \
+  _mhdErrorExit_func (NULL, __FUNCTION__, __LINE__)
+#define mhdErrorExitDesc(errDesc) \
+  _mhdErrorExit_func (errDesc, __FUNCTION__, __LINE__)
+#define checkCURLE_OK(libcurlcall) \
+  _checkCURLE_OK_func ((libcurlcall), _MHD_STRMACRO (libcurlcall), \
+                       __FUNCTION__, __LINE__)
+#else
+#define externalErrorExit(ignore) _externalErrorExit_func (NULL, NULL, 
__LINE__)
+#define externalErrorExitDesc(errDesc) \
+  _externalErrorExit_func (errDesc, NULL, __LINE__)
+#define libcurlErrorExit(ignore) _libcurlErrorExit_func (NULL, NULL, __LINE__)
+#define libcurlErrorExitDesc(errDesc) \
+  _libcurlErrorExit_func (errDesc, NULL, __LINE__)
+#define mhdErrorExit(ignore) _mhdErrorExit_func (NULL, NULL, __LINE__)
+#define mhdErrorExitDesc(errDesc) _mhdErrorExit_func (errDesc, NULL, __LINE__)
+#define checkCURLE_OK(libcurlcall) \
+  _checkCURLE_OK_func ((libcurlcall), _MHD_STRMACRO (libcurlcall), NULL, \
+                       __LINE__)
+#endif
+
+
+_MHD_NORETURN static void
+_externalErrorExit_func (const char *errDesc, const char *funcName, int 
lineNum)
+{
+  fflush (stdout);
+  if ((NULL != errDesc) && (0 != errDesc[0]))
+    fprintf (stderr, "%s", errDesc);
+  else
+    fprintf (stderr, "System or external library call failed");
+  if ((NULL != funcName) && (0 != funcName[0]))
+    fprintf (stderr, " in %s", funcName);
+  if (0 < lineNum)
+    fprintf (stderr, " at line %d", lineNum);
+
+  fprintf (stderr, ".\nLast errno value: %d (%s)\n", (int) errno,
+           strerror (errno));
+#ifdef MHD_WINSOCK_SOCKETS
+  fprintf (stderr, "WSAGetLastError() value: %d\n", (int) WSAGetLastError ());
+#endif /* MHD_WINSOCK_SOCKETS */
+  fflush (stderr);
+  exit (99);
+}
+
+
+static char libcurl_errbuf[CURL_ERROR_SIZE] = "";
+
+_MHD_NORETURN static void
+_libcurlErrorExit_func (const char *errDesc, const char *funcName, int lineNum)
+{
+  fflush (stdout);
+  if ((NULL != errDesc) && (0 != errDesc[0]))
+    fprintf (stderr, "%s", errDesc);
+  else
+    fprintf (stderr, "CURL library call failed");
+  if ((NULL != funcName) && (0 != funcName[0]))
+    fprintf (stderr, " in %s", funcName);
+  if (0 < lineNum)
+    fprintf (stderr, " at line %d", lineNum);
+
+  fprintf (stderr, ".\nLast errno value: %d (%s)\n", (int) errno,
+           strerror (errno));
+#ifdef MHD_WINSOCK_SOCKETS
+  fprintf (stderr, "WSAGetLastError() value: %d\n", (int) WSAGetLastError ());
+#endif /* MHD_WINSOCK_SOCKETS */
+  if (0 != libcurl_errbuf[0])
+    fprintf (stderr, "Last libcurl error description: %s\n", libcurl_errbuf);
+
+  fflush (stderr);
+  exit (99);
+}
+
+
+_MHD_NORETURN static void
+_mhdErrorExit_func (const char *errDesc, const char *funcName, int lineNum)
+{
+  fflush (stdout);
+  if ((NULL != errDesc) && (0 != errDesc[0]))
+    fprintf (stderr, "%s", errDesc);
+  else
+    fprintf (stderr, "MHD unexpected error");
+  if ((NULL != funcName) && (0 != funcName[0]))
+    fprintf (stderr, " in %s", funcName);
+  if (0 < lineNum)
+    fprintf (stderr, " at line %d", lineNum);
+
+  fprintf (stderr, ".\nLast errno value: %d (%s)\n", (int) errno,
+           strerror (errno));
+#ifdef MHD_WINSOCK_SOCKETS
+  fprintf (stderr, "WSAGetLastError() value: %d\n", (int) WSAGetLastError ());
+#endif /* MHD_WINSOCK_SOCKETS */
+
+  fflush (stderr);
+  exit (8);
+}
+
+
+/* Could be increased to facilitate debugging */
+#define TIMEOUTS_VAL 5
+
+#define EXPECTED_URI_BASE_PATH  "/"
+
+#define EXISTING_URI  EXPECTED_URI_BASE_PATH
+
+#define EXPECTED_URI_BASE_PATH_MISSING  "/wrong_uri"
+
+#define URL_SCHEME "http:/" "/"
+
+#define URL_HOST "127.0.0.1"
+
+#define URL_SCHEME_HOST URL_SCHEME URL_HOST
+
+#define HEADER1_NAME "First"
+#define HEADER1_VALUE "1st"
+#define HEADER1 HEADER1_NAME ": " HEADER1_VALUE
+#define HEADER1_CRLF HEADER1 "\r\n"
+#define HEADER2_NAME "Normal"
+#define HEADER2_VALUE "it's fine"
+#define HEADER2 HEADER2_NAME ": " HEADER2_VALUE
+#define HEADER2_CRLF HEADER2 "\r\n"
+
+#define PAGE \
+  "<html><head><title>libmicrohttpd demo page</title></head>" \
+  "<body>Success!</body></html>"
+
+#define PAGE_404 \
+  "<html><head><title>404 error</title></head>" \
+  "<body>Error 404: The requested URI does not exist</body></html>"
+
+/* Global parameters */
+static int verbose;
+static int oneone;                  /**< If false use HTTP/1.0 for requests*/
+
+static void
+test_global_init (void)
+{
+  libcurl_errbuf[0] = 0;
+
+  if (0 != curl_global_init (CURL_GLOBAL_WIN32))
+    externalErrorExit ();
+}
+
+
+static void
+test_global_cleanup (void)
+{
+  curl_global_cleanup ();
+}
+
+
+struct headers_check_result
+{
+  unsigned int expected_size;
+  int header1_found;
+  int header2_found;
+  int size_found;
+};
+
+static size_t
+lcurl_hdr_callback (char *buffer, size_t size, size_t nitems,
+                    void *userdata)
+{
+  const size_t data_size = size * nitems;
+  struct headers_check_result *check_res =
+    (struct headers_check_result *) userdata;
+
+  if ((MHD_STATICSTR_LEN_ (HEADER1_CRLF) == data_size) &&
+      (0 == memcmp (HEADER1_CRLF, buffer, data_size)))
+    check_res->header1_found++;
+  else if ((MHD_STATICSTR_LEN_ (HEADER2_CRLF) == data_size) &&
+           (0 == memcmp (HEADER2_CRLF, buffer, data_size)))
+    check_res->header2_found++;
+  else if ((MHD_STATICSTR_LEN_ (MHD_HTTP_HEADER_CONTENT_LENGTH ": ")
+            < data_size) &&
+           (0 ==
+            memcmp (MHD_HTTP_HEADER_CONTENT_LENGTH ": ", buffer,
+                    MHD_STATICSTR_LEN_ (MHD_HTTP_HEADER_CONTENT_LENGTH ": "))))
+  {
+    char cmpbuf[256];
+    int res;
+    const unsigned int numbers_pos =
+      MHD_STATICSTR_LEN_ (MHD_HTTP_HEADER_CONTENT_LENGTH ": ");
+    res = snprintf (cmpbuf, sizeof(cmpbuf), "%u\r\n", 
check_res->expected_size);
+    if ((res <= 0) || (res > ((int) (sizeof(cmpbuf) - 1))))
+      externalErrorExit ();
+    if (0 != strcmp (buffer + numbers_pos, cmpbuf))
+    {
+      fprintf (stderr, "Wrong Content-Length.\n"
+               "Expected:\n%u\n"
+               "Received:\n%s", check_res->expected_size,
+               buffer + numbers_pos);
+      mhdErrorExitDesc ("Wrong Content-Length");
+    }
+    check_res->size_found++;
+  }
+
+  return data_size;
+}
+
+
+struct CBC
+{
+  char *buf;
+  size_t pos;
+  size_t size;
+};
+
+
+static size_t
+copyBuffer (void *ptr,
+            size_t size,
+            size_t nmemb,
+            void *ctx)
+{
+  (void) ptr; /* Unused, mute compiler warning */
+  (void) ctx; /* Unused, mute compiler warning */
+  if ((0 != size) && (0 != nmemb))
+    libcurlErrorExitDesc ("Received unexpected body data");
+  return size * nmemb;
+}
+
+
+struct ahc_cls_type
+{
+  const char *rq_method;
+  const char *rq_url;
+};
+
+
+static enum MHD_Result
+ahcCheck (void *cls,
+          struct MHD_Connection *connection,
+          const char *url,
+          const char *method,
+          const char *version,
+          const char *upload_data, size_t *upload_data_size,
+          void **req_cls)
+{
+  static int marker;
+  struct MHD_Response *response;
+  enum MHD_Result ret;
+  struct ahc_cls_type *const param = (struct ahc_cls_type *) cls;
+  unsigned int http_code;
+
+  if (NULL == param)
+    mhdErrorExitDesc ("cls parameter is NULL");
+
+  if (oneone)
+  {
+    if (0 != strcmp (version, MHD_HTTP_VERSION_1_1))
+      mhdErrorExitDesc ("Unexpected HTTP version");
+  }
+  else
+  {
+    if (0 != strcmp (version, MHD_HTTP_VERSION_1_0))
+      mhdErrorExitDesc ("Unexpected HTTP version");
+  }
+
+  if (0 != strcmp (url, param->rq_url))
+    mhdErrorExitDesc ("Unexpected URI");
+
+  if (NULL != upload_data)
+    mhdErrorExitDesc ("'upload_data' is not NULL");
+
+  if (NULL == upload_data_size)
+    mhdErrorExitDesc ("'upload_data_size' pointer is NULL");
+
+  if (0 != *upload_data_size)
+    mhdErrorExitDesc ("'*upload_data_size' value is not zero");
+
+  if (0 != strcmp (param->rq_method, method))
+    mhdErrorExitDesc ("Unexpected request method");
+
+  if (&marker != *req_cls)
+  {
+    *req_cls = &marker;
+    return MHD_YES;
+  }
+  *req_cls = NULL;
+
+  if (0 == strcmp (url, EXISTING_URI))
+  {
+    response =
+      MHD_create_response_from_buffer_static (MHD_STATICSTR_LEN_ (PAGE),
+                                              PAGE);
+    http_code = MHD_HTTP_OK;
+  }
+  else
+  {
+    response =
+      MHD_create_response_from_buffer_static (MHD_STATICSTR_LEN_ (PAGE_404),
+                                              PAGE_404);
+    http_code = MHD_HTTP_NOT_FOUND;
+  }
+  if (NULL == response)
+    mhdErrorExitDesc ("Failed to create response");
+
+  if (MHD_YES != MHD_add_response_header (response,
+                                          HEADER1_NAME,
+                                          HEADER1_VALUE))
+    mhdErrorExitDesc ("Cannot add header1");
+  if (MHD_YES != MHD_add_response_header (response,
+                                          HEADER2_NAME,
+                                          HEADER2_VALUE))
+    mhdErrorExitDesc ("Cannot add header2");
+
+  ret = MHD_queue_response (connection,
+                            http_code,
+                            response);
+  MHD_destroy_response (response);
+  if (MHD_YES != ret)
+    mhdErrorExitDesc ("Failed to queue response");
+
+  return ret;
+}
+
+
+/**
+ * Set required URI for the request
+ * @param c the CURL handle to use
+ * @param uri_exist if non-zero use request for "existing" URI
+ */
+static void
+setCURL_rq_path (CURL *c, int uri_exist)
+{
+  if (uri_exist)
+  {
+    if (CURLE_OK !=
+        curl_easy_setopt (c, CURLOPT_URL,
+                          URL_SCHEME_HOST EXPECTED_URI_BASE_PATH))
+      libcurlErrorExitDesc ("Cannot set request URL");
+  }
+  else
+  {
+    if (CURLE_OK !=
+        curl_easy_setopt (c, CURLOPT_URL,
+                          URL_SCHEME_HOST EXPECTED_URI_BASE_PATH_MISSING))
+      libcurlErrorExitDesc ("Cannot set request URL");
+  }
+}
+
+
+static CURL *
+setupCURL (void *cbc, unsigned int port,
+           struct headers_check_result *hdr_chk_result)
+{
+  CURL *c;
+
+  c = curl_easy_init ();
+  if (NULL == c)
+    libcurlErrorExitDesc ("curl_easy_init() failed");
+
+  if ((CURLE_OK != curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L)) ||
+      (CURLE_OK != curl_easy_setopt (c, CURLOPT_WRITEFUNCTION,
+                                     &copyBuffer)) ||
+      (CURLE_OK != curl_easy_setopt (c, CURLOPT_WRITEDATA, cbc)) ||
+      (CURLE_OK != curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT,
+                                     ((long) TIMEOUTS_VAL))) ||
+      (CURLE_OK != curl_easy_setopt (c, CURLOPT_HTTP_VERSION,
+                                     (oneone) ?
+                                     CURL_HTTP_VERSION_1_1 :
+                                     CURL_HTTP_VERSION_1_0)) ||
+      (CURLE_OK != curl_easy_setopt (c, CURLOPT_TIMEOUT,
+                                     ((long) TIMEOUTS_VAL))) ||
+      (CURLE_OK != curl_easy_setopt (c, CURLOPT_HEADERFUNCTION,
+                                     lcurl_hdr_callback)) ||
+      (CURLE_OK != curl_easy_setopt (c, CURLOPT_HEADERDATA,
+                                     hdr_chk_result)) ||
+      (CURLE_OK != curl_easy_setopt (c, CURLOPT_ERRORBUFFER,
+                                     libcurl_errbuf)) ||
+      (CURLE_OK != curl_easy_setopt (c, CURLOPT_FAILONERROR, 0L)) ||
+#ifdef _DEBUG
+      (CURLE_OK != curl_easy_setopt (c, CURLOPT_VERBOSE, 1L)) ||
+#endif /* _DEBUG */
+#if CURL_AT_LEAST_VERSION (7, 19, 4)
+      (CURLE_OK != curl_easy_setopt (c, CURLOPT_PROTOCOLS, CURLPROTO_HTTP)) ||
+#endif /* CURL_AT_LEAST_VERSION (7, 19, 4) */
+#if CURL_AT_LEAST_VERSION (7, 45, 0)
+      (CURLE_OK != curl_easy_setopt (c, CURLOPT_DEFAULT_PROTOCOL, "http")) ||
+#endif /* CURL_AT_LEAST_VERSION (7, 45, 0) */
+      (CURLE_OK != curl_easy_setopt (c, CURLOPT_PORT, ((long) port))))
+    libcurlErrorExitDesc ("curl_easy_setopt() failed");
+
+  /* When 'CURLOPT_NOBODY' is set, libcurl should use HEAD request. */
+  if (CURLE_OK != curl_easy_setopt (c, CURLOPT_NOBODY, (long) 1))
+    libcurlErrorExitDesc ("curl_easy_setopt() failed");
+
+  return c;
+}
+
+
+static CURLcode
+performQueryExternal (struct MHD_Daemon *d, CURL *c, CURLM **multi_reuse)
+{
+  CURLM *multi;
+  time_t start;
+  struct timeval tv;
+  CURLcode ret;
+
+  ret = CURLE_FAILED_INIT; /* will be replaced with real result */
+  if (NULL != *multi_reuse)
+    multi = *multi_reuse;
+  else
+  {
+    multi = curl_multi_init ();
+    if (multi == NULL)
+      libcurlErrorExitDesc ("curl_multi_init() failed");
+    *multi_reuse = multi;
+  }
+  if (CURLM_OK != curl_multi_add_handle (multi, c))
+    libcurlErrorExitDesc ("curl_multi_add_handle() failed");
+
+  start = time (NULL);
+  while (time (NULL) - start <= TIMEOUTS_VAL)
+  {
+    fd_set rs;
+    fd_set ws;
+    fd_set es;
+    MHD_socket maxMhdSk;
+    int maxCurlSk;
+    int running;
+
+    maxMhdSk = MHD_INVALID_SOCKET;
+    maxCurlSk = -1;
+    FD_ZERO (&rs);
+    FD_ZERO (&ws);
+    FD_ZERO (&es);
+    if (NULL != multi)
+    {
+      curl_multi_perform (multi, &running);
+      if (0 == running)
+      {
+        struct CURLMsg *msg;
+        int msgLeft;
+        int totalMsgs = 0;
+        do
+        {
+          msg = curl_multi_info_read (multi, &msgLeft);
+          if (NULL == msg)
+            libcurlErrorExitDesc ("curl_multi_info_read() failed");
+          totalMsgs++;
+          if (CURLMSG_DONE == msg->msg)
+            ret = msg->data.result;
+        } while (msgLeft > 0);
+        if (1 != totalMsgs)
+        {
+          fprintf (stderr,
+                   "curl_multi_info_read returned wrong "
+                   "number of results (%d).\n",
+                   totalMsgs);
+          externalErrorExit ();
+        }
+        curl_multi_remove_handle (multi, c);
+        multi = NULL;
+      }
+      else
+      {
+        if (CURLM_OK != curl_multi_fdset (multi, &rs, &ws, &es, &maxCurlSk))
+          libcurlErrorExitDesc ("curl_multi_fdset() failed");
+      }
+    }
+    if (NULL == multi)
+    { /* libcurl has finished, check whether MHD still needs to perform 
cleanup */
+      if (0 != MHD_get_timeout64s (d))
+        break; /* MHD finished as well */
+    }
+    if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxMhdSk))
+      mhdErrorExitDesc ("MHD_get_fdset() failed");
+    tv.tv_sec = 0;
+    tv.tv_usec = 200000;
+#ifdef MHD_POSIX_SOCKETS
+    if (maxMhdSk > maxCurlSk)
+      maxCurlSk = maxMhdSk;
+#endif /* MHD_POSIX_SOCKETS */
+    if (-1 == select (maxCurlSk + 1, &rs, &ws, &es, &tv))
+    {
+#ifdef MHD_POSIX_SOCKETS
+      if (EINTR != errno)
+        externalErrorExitDesc ("Unexpected select() error");
+#else
+      if ((WSAEINVAL != WSAGetLastError ()) ||
+          (0 != rs.fd_count) || (0 != ws.fd_count) || (0 != es.fd_count) )
+        externalErrorExitDesc ("Unexpected select() error");
+      Sleep (200);
+#endif
+    }
+    if (MHD_YES != MHD_run_from_select (d, &rs, &ws, &es))
+      mhdErrorExitDesc ("MHD_run_from_select() failed");
+  }
+
+  return ret;
+}
+
+
+/**
+ * Check request result
+ * @param curl_code the CURL easy return code
+ * @param pcbc the pointer struct CBC
+ * @return non-zero if success, zero if failed
+ */
+static unsigned int
+check_result (CURLcode curl_code, CURL *c, long expected_code,
+              struct headers_check_result *hdr_res)
+{
+  long code;
+  unsigned int ret;
+
+  if (CURLE_OK != curl_code)
+  {
+    fflush (stdout);
+    if (0 != libcurl_errbuf[0])
+      fprintf (stderr, "Request failed. "
+               "libcurl error: '%s'.\n"
+               "libcurl error description: '%s'.\n",
+               curl_easy_strerror (curl_code),
+               libcurl_errbuf);
+    else
+      fprintf (stderr, "Request failed. "
+               "libcurl error: '%s'.\n",
+               curl_easy_strerror (curl_code));
+    fflush (stderr);
+    return 0;
+  }
+
+  if (CURLE_OK != curl_easy_getinfo (c, CURLINFO_RESPONSE_CODE, &code))
+    libcurlErrorExit ();
+
+  if (expected_code != code)
+  {
+    fprintf (stderr, "The response has wrong HTTP code: %ld\tExpected: %ld.\n",
+             code, expected_code);
+    return 0;
+  }
+  else if (verbose)
+    printf ("The response has expected HTTP code: %ld\n", expected_code);
+
+  ret = 1;
+  if (1 != hdr_res->header1_found)
+  {
+    if (0 == hdr_res->header1_found)
+      fprintf (stderr, "Response header1 was not found.\n");
+    else
+      fprintf (stderr, "Response header1 was found %d times "
+               "instead of one time only.\n", hdr_res->header1_found);
+    ret = 0;
+  }
+  else if (verbose)
+    printf ("Header1 is present in the response.\n");
+  if (1 != hdr_res->header2_found)
+  {
+    if (0 == hdr_res->header2_found)
+      fprintf (stderr, "Response header2 was not found.\n");
+    else
+      fprintf (stderr, "Response header2 was found %d times "
+               "instead of one time only.\n", hdr_res->header2_found);
+    ret = 0;
+  }
+  else if (verbose)
+    printf ("Header2 is present in the response.\n");
+  if (1 != hdr_res->size_found)
+  {
+    if (0 == hdr_res->size_found)
+      fprintf (stderr, "Response 'Content-Length' header was not found.\n");
+    else
+      fprintf (stderr, "Response 'Content-Length' header was found %d times "
+               "instead of one time only.\n", hdr_res->size_found);
+    ret = 0;
+  }
+  else if (verbose)
+    printf ("'Content-Length' header with correct value "
+            "is present in the response.\n");
+
+  return ret;
+}
+
+
+static unsigned int
+testHead (void)
+{
+  struct MHD_Daemon *d;
+  uint16_t port;
+  struct CBC cbc;
+  struct ahc_cls_type ahc_param;
+  struct headers_check_result rp_headers_check;
+  char buf[2048];
+  CURL *c;
+  CURLM *multi_reuse;
+  int failed = 0;
+
+  if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+    port = 0;
+  else
+    port = 4220 + oneone ? 0 : 1;
+
+  d = MHD_start_daemon (MHD_USE_ERROR_LOG,
+                        port, NULL, NULL,
+                        &ahcCheck, &ahc_param,
+                        MHD_OPTION_END);
+  if (d == NULL)
+    return 1;
+  if (0 == port)
+  {
+    const union MHD_DaemonInfo *dinfo;
+
+    dinfo = MHD_get_daemon_info (d,
+                                 MHD_DAEMON_INFO_BIND_PORT);
+    if ( (NULL == dinfo) ||
+         (0 == dinfo->port) )
+      mhdErrorExitDesc ("MHD_get_daemon_info() failed");
+    port = dinfo->port;
+  }
+
+  /* First request */
+  ahc_param.rq_method = MHD_HTTP_METHOD_HEAD;
+  ahc_param.rq_url = EXPECTED_URI_BASE_PATH;
+  rp_headers_check.expected_size = MHD_STATICSTR_LEN_ (PAGE);
+  rp_headers_check.header1_found = 0;
+  rp_headers_check.header2_found = 0;
+  rp_headers_check.size_found = 0;
+  cbc.buf = buf;
+  cbc.size = sizeof (buf);
+  cbc.pos = 0;
+  memset (cbc.buf, 0, cbc.size);
+  c = setupCURL (&cbc, (unsigned int) port, &rp_headers_check);
+  setCURL_rq_path (c, 1);
+  multi_reuse = NULL;
+  /* First request */
+  if (check_result (performQueryExternal (d, c, &multi_reuse), c,
+                    MHD_HTTP_OK, &rp_headers_check))
+  {
+    fflush (stderr);
+    if (verbose)
+      printf ("Got first expected response.\n");
+    fflush (stdout);
+  }
+  else
+  {
+    fprintf (stderr, "First request FAILED.\n");
+    fflush (stderr);
+    failed = 1;
+  }
+  /* Second request */
+  rp_headers_check.expected_size = MHD_STATICSTR_LEN_ (PAGE_404);
+  rp_headers_check.header1_found = 0;
+  rp_headers_check.header2_found = 0;
+  rp_headers_check.size_found = 0;
+  cbc.pos = 0; /* Reset buffer position */
+  ahc_param.rq_url = EXPECTED_URI_BASE_PATH_MISSING;
+  setCURL_rq_path (c, 0);
+  if (check_result (performQueryExternal (d, c, &multi_reuse), c,
+                    MHD_HTTP_NOT_FOUND, &rp_headers_check))
+  {
+    fflush (stderr);
+    if (verbose)
+      printf ("Got second expected response.\n");
+    fflush (stdout);
+  }
+  else
+  {
+    fprintf (stderr, "Second request FAILED.\n");
+    fflush (stderr);
+    failed = 1;
+  }
+  /* Third request */
+  rp_headers_check.header1_found = 0;
+  rp_headers_check.header2_found = 0;
+  rp_headers_check.size_found = 0;
+  cbc.pos = 0; /* Reset buffer position */
+  if (NULL != multi_reuse)
+    curl_multi_cleanup (multi_reuse);
+  multi_reuse = NULL; /* Force new connection */
+  if (check_result (performQueryExternal (d, c, &multi_reuse), c,
+                    MHD_HTTP_NOT_FOUND, &rp_headers_check))
+  {
+    fflush (stderr);
+    if (verbose)
+      printf ("Got third expected response.\n");
+    fflush (stdout);
+  }
+  else
+  {
+    fprintf (stderr, "Third request FAILED.\n");
+    fflush (stderr);
+    failed = 1;
+  }
+
+  curl_easy_cleanup (c);
+  if (NULL != multi_reuse)
+    curl_multi_cleanup (multi_reuse);
+
+  MHD_stop_daemon (d);
+  return failed ? 1 : 0;
+}
+
+
+int
+main (int argc, char *const *argv)
+{
+  unsigned int errorCount = 0;
+
+  /* Test type and test parameters */
+  verbose = ! (has_param (argc, argv, "-q") ||
+               has_param (argc, argv, "--quiet") ||
+               has_param (argc, argv, "-s") ||
+               has_param (argc, argv, "--silent"));
+  oneone = ! has_in_name (argv[0], "10");
+
+  test_global_init ();
+
+  errorCount += testHead ();
+  if (errorCount != 0)
+    fprintf (stderr, "Error (code: %u)\n", errorCount);
+  test_global_cleanup ();
+  return (0 == errorCount) ? 0 : 1;       /* 0 == pass */
+}
diff --git a/w32/common/MHD_config.h b/w32/common/MHD_config.h
index 04e39ea3..c6acf32e 100644
--- a/w32/common/MHD_config.h
+++ b/w32/common/MHD_config.h
@@ -134,6 +134,27 @@
 /* Define if you have usable assert() and assert.h */
 #define HAVE_ASSERT 1
 
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* Define to 1 if you have the <stddef.h> header file. */
+#define HAVE_STDDEF_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H   1
+
+/* Define to 1 if you have the <time.h> header file. */
+#define HAVE_TIME_H       1
+
 #if _MSC_VER >= 1900 /* snprintf() supported natively since VS2015 */
 /* Define to 1 if you have the `snprintf' function. */
 #define HAVE_SNPRINTF 1
@@ -148,6 +169,8 @@
 /* Define to 1 if you have the <stdbool.h> header file and <stdbool.h> defines
    'bool' type. */
 #define HAVE_STDBOOL_H 1
+/* Define to 1 if you have the real boolean type. */
+#define HAVE_REAL_BOOL 1
 #else  /* before VS 2013 */
 
 /* Define to type name which will be used as boolean type. */
@@ -192,12 +215,6 @@
 /* Define to 1 if you have the <fcntl.h> header file. */
 #define HAVE_FCNTL_H 1
 
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define to 1 if you have the <limits.h> header file. */
-#define HAVE_LIMITS_H 1
-
 /* Define to 1 if you have the <locale.h> header file. */
 #define HAVE_LOCALE_H 1
 
@@ -216,27 +233,12 @@
 /* Define to 1 if you have the <stdio.h> header file. */
 #define HAVE_STDIO_H 1
 
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
 /* Define to 1 if you have the <strings.h> header file. */
 #define HAVE_STRINGS_H 1
 
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
 /* Define to 1 if you have the <sys/types.h> header file. */
 #define HAVE_SYS_TYPES_H 1
 
-/* Define to 1 if you have the <time.h> header file. */
-#define HAVE_TIME_H 1
-
-/* Define to 1 if you have the <stddef.h> header file. */
-#define HAVE_STDDEF_H 1
-
 /* Define to 1 if you have the <windows.h> header file. */
 #define HAVE_WINDOWS_H 1
 

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