[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[libmicrohttpd] 02/02: test_quiesce: added more checking and error repor
From: |
gnunet |
Subject: |
[libmicrohttpd] 02/02: test_quiesce: added more checking and error reporting |
Date: |
Mon, 10 Jan 2022 20:48:09 +0100 |
This is an automated email from the git hooks/post-receive script.
karlson2k pushed a commit to branch master
in repository libmicrohttpd.
commit 14a46d9c0958f7e3ac481af5175d6c53dd614ee7
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
AuthorDate: Mon Jan 10 22:47:46 2022 +0300
test_quiesce: added more checking and error reporting
---
src/testcurl/Makefile.am | 2 +-
src/testcurl/mhd_has_param.h | 53 ++++
src/testcurl/test_quiesce.c | 576 ++++++++++++++++++++++++++-----------------
3 files changed, 403 insertions(+), 228 deletions(-)
diff --git a/src/testcurl/Makefile.am b/src/testcurl/Makefile.am
index 5d7839f1..3d9f6000 100644
--- a/src/testcurl/Makefile.am
+++ b/src/testcurl/Makefile.am
@@ -186,7 +186,7 @@ test_get_SOURCES = \
test_get.c
test_quiesce_SOURCES = \
- test_quiesce.c
+ test_quiesce.c mhd_has_param.h mhd_has_in_name.h
test_quiesce_CFLAGS = \
$(PTHREAD_CFLAGS) $(AM_CFLAGS)
test_quiesce_LDADD = \
diff --git a/src/testcurl/mhd_has_param.h b/src/testcurl/mhd_has_param.h
new file mode 100644
index 00000000..0186b5de
--- /dev/null
+++ b/src/testcurl/mhd_has_param.h
@@ -0,0 +1,53 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2016-2022 Karlson2k (Evgeny Grin)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
USA
+*/
+
+/**
+ * @file testcurl/mhd_has_param.h
+ * @brief Static functions and macros helpers for testsuite.
+ * @author Karlson2k (Evgeny Grin)
+ */
+
+#include <string.h>
+
+
+/**
+ * Check whether one of strings in array is equal to @a param.
+ * String @a argv[0] is ignored.
+ * @param argc number of strings in @a argv, as passed to main function
+ * @param argv array of strings, as passed to main function
+ * @param param parameter to look for.
+ * @return zero if @a argv is NULL, @a param is NULL or empty string,
+ * @a argc is less then 2 or @a param is not found in @a argv,
+ * non-zero if one of strings in @a argv is equal to @a param.
+ */
+static int
+has_param (int argc, char *const argv[], const char *param)
+{
+ int i;
+ if (! argv || ! param || ! param[0])
+ return 0;
+
+ for (i = 1; i < argc; i++)
+ {
+ if (argv[i] && (strcmp (argv[i], param) == 0) )
+ return ! 0;
+ }
+
+ return 0;
+}
diff --git a/src/testcurl/test_quiesce.c b/src/testcurl/test_quiesce.c
index 33d34dd5..8b350237 100644
--- a/src/testcurl/test_quiesce.c
+++ b/src/testcurl/test_quiesce.c
@@ -1,7 +1,7 @@
/*
This file is part of libmicrohttpd
Copyright (C) 2013, 2015 Christian Grothoff
- Copyright (C) 2014-2021 Evgeny Grin (Karlson2k)
+ Copyright (C) 2014-2022 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
@@ -35,6 +35,8 @@
#include <sys/types.h>
#include <pthread.h>
#include "mhd_sockets.h" /* only macros used */
+#include "mhd_has_in_name.h"
+#include "mhd_has_param.h"
#ifndef WINDOWS
@@ -50,6 +52,120 @@
#endif
+#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__)
+#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__)
+#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__)
+#endif
+
+
+_MHD_NORETURN static void
+_externalErrorExit_func (const char *errDesc, const char *funcName, int
lineNum)
+{
+ 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)
+{
+ 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));
+ if (0 != libcurl_errbuf[0])
+ fprintf (stderr, "Last libcurl error details: %s\n", libcurl_errbuf);
+
+ fflush (stderr);
+ exit (99);
+}
+
+
+_MHD_NORETURN static void
+_mhdErrorExit_func (const char *errDesc, const char *funcName, int lineNum)
+{
+ 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));
+
+ fflush (stderr);
+ exit (8);
+}
+
+
+/* Could be increased to facilitate debugging */
+#define TIMEOUTS_VAL 4
+
+#define MHD_URI_BASE_PATH "/hello_world"
+
+/* Global parameters */
+static int verbose; /**< Be verbose */
+static int oneone; /**< If false use HTTP/1.0 for requests*/
+static int global_port; /**< MHD daemons listen port number */
+
struct CBC
{
char *buf;
@@ -57,8 +173,6 @@ struct CBC
size_t size;
};
-static int port;
-
static size_t
copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
{
@@ -84,11 +198,13 @@ ahc_echo (void *cls,
static int ptr;
const char *me = cls;
struct MHD_Response *response;
- enum MHD_Result ret;
(void) version; (void) upload_data; (void) upload_data_size; /*
Unused. Silent compiler warning. */
if (0 != strcmp (me, method))
- return MHD_NO; /* unexpected method */
+ {
+ fprintf (stderr, "Unexpected HTTP method '%s'. ", method);
+ externalErrorExit ();
+ }
if (&ptr != *unused)
{
*unused = &ptr;
@@ -98,11 +214,16 @@ ahc_echo (void *cls,
response = MHD_create_response_from_buffer (strlen (url),
(void *) url,
MHD_RESPMEM_MUST_COPY);
- ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+ if (NULL == response)
+ mhdErrorExitDesc ("MHD_create_response failed");
+ /* Make sure that connection will not be reused */
+ if (MHD_NO == MHD_add_response_header (response, MHD_HTTP_HEADER_CONNECTION,
+ "close"))
+ mhdErrorExitDesc ("MHD_add_response_header() failed");
+ if (MHD_NO == MHD_queue_response (connection, MHD_HTTP_OK, response))
+ mhdErrorExitDesc ("MHD_queue_response() failed");
MHD_destroy_response (response);
- if (ret == MHD_NO)
- abort ();
- return ret;
+ return MHD_YES;
}
@@ -112,7 +233,14 @@ request_completed (void *cls, struct MHD_Connection
*connection,
{
int *done = (int *) cls;
(void) connection; (void) con_cls; (void) code; /* Unused. Silent
compiler warning. */
+ if (MHD_REQUEST_TERMINATED_COMPLETED_OK != code)
+ {
+ fprintf (stderr, "Unexpected termination code: %d. ", (int) code);
+ mhdErrorExit ();
+ }
*done = 1;
+ if (verbose)
+ printf ("Notify callback has been called with OK code.\n");
}
@@ -126,9 +254,12 @@ ServeOneRequest (void *param)
MHD_socket fd, max;
time_t start;
struct timeval tv;
- int done = 0;
+ volatile int done = 0;
+
+ if (NULL == param)
+ externalErrorExit ();
- fd = (MHD_socket) (intptr_t) param;
+ fd = *((MHD_socket *) param);
d = MHD_start_daemon (MHD_USE_ERROR_LOG,
0, NULL, NULL, &ahc_echo, "GET",
@@ -136,47 +267,44 @@ ServeOneRequest (void *param)
MHD_OPTION_NOTIFY_COMPLETED, &request_completed, &done,
MHD_OPTION_END);
if (d == NULL)
- return "MHD_start_daemon() failed";
+ mhdErrorExit ();
+
+ if (verbose)
+ printf ("Started MHD daemon in ServeOneRequest().\n");
start = time (NULL);
- while ((time (NULL) - start < 5) && done == 0)
+ while ((time (NULL) - start < TIMEOUTS_VAL * 2) && done == 0)
{
max = 0;
FD_ZERO (&rs);
FD_ZERO (&ws);
FD_ZERO (&es);
if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
- {
- MHD_stop_daemon (d);
- MHD_socket_close_chk_ (fd);
- return "MHD_get_fdset() failed";
- }
+ mhdErrorExit ("MHD_get_fdset() failed");
tv.tv_sec = 0;
- tv.tv_usec = 1000;
+ tv.tv_usec = 100000;
if (-1 == MHD_SYS_select_ (max + 1, &rs, &ws, &es, &tv))
{
#ifdef MHD_POSIX_SOCKETS
if (EINTR != errno)
- abort ();
+ externalErrorExitDesc ("Unexpected select() error");
#else
- if ((WSAEINVAL != WSAGetLastError ()) || (0 != rs.fd_count) || (0 !=
- ws.
- fd_count)
- || (0 != es.fd_count) )
- abort ();
- Sleep (1000);
+ if ((WSAEINVAL != WSAGetLastError ()) ||
+ (0 != rs.fd_count) || (0 != ws.fd_count) || (0 != es.fd_count) )
+ externalErrorExitDesc ("Unexpected select() error");
+ Sleep (tv.tv_sec * 1000 + tv.tv_usec / 1000);
#endif
}
MHD_run (d);
}
+ if (! done)
+ mhdErrorExit ("ServeOneRequest() failed and finished by timeout");
fd = MHD_quiesce_daemon (d);
if (MHD_INVALID_SOCKET == fd)
- {
- MHD_stop_daemon (d);
- return "MHD_quiesce_daemon() failed in ServeOneRequest()";
- }
+ mhdErrorExit ("MHD_quiesce_daemon() failed in ServeOneRequest()");
+
MHD_stop_daemon (d);
- return done ? NULL : "Requests was not served by ServeOneRequest()";
+ return NULL;
}
@@ -186,19 +314,29 @@ setupCURL (void *cbc)
CURL *c;
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
- curl_easy_setopt (c, CURLOPT_PORT, (long) port);
- curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
- curl_easy_setopt (c, CURLOPT_WRITEDATA, cbc);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
- curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, 150L);
- curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, 150L);
- 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 (NULL == c)
+ libcurlErrorExitDesc ("curl_easy_init() failed");
+
+ if ((CURLE_OK != curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L)) ||
+ (CURLE_OK != curl_easy_setopt (c, CURLOPT_URL,
+ "http://127.0.0.1" MHD_URI_BASE_PATH)) ||
+ (CURLE_OK != curl_easy_setopt (c, CURLOPT_PORT, (long) global_port)) ||
+ (CURLE_OK != curl_easy_setopt (c, CURLOPT_WRITEFUNCTION,
+ ©Buffer)) ||
+ (CURLE_OK != curl_easy_setopt (c, CURLOPT_WRITEDATA, cbc)) ||
+ (CURLE_OK != curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT,
+ (long) (TIMEOUTS_VAL / 2))) ||
+ (CURLE_OK != curl_easy_setopt (c, CURLOPT_TIMEOUT,
+ (long) TIMEOUTS_VAL)) ||
+ (CURLE_OK != curl_easy_setopt (c, CURLOPT_ERRORBUFFER,
+ libcurl_errbuf)) ||
+ (CURLE_OK != curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L)) ||
+ ((oneone) ?
+ (CURLE_OK != curl_easy_setopt (c, CURLOPT_HTTP_VERSION,
+ CURL_HTTP_VERSION_1_1)) :
+ (CURLE_OK != curl_easy_setopt (c, CURLOPT_HTTP_VERSION,
+ CURL_HTTP_VERSION_1_0))))
+ libcurlErrorExitDesc ("curl_easy_setopt() failed");
return c;
}
@@ -215,38 +353,37 @@ testGet (int type, int pool_count, int poll_flag)
pthread_t thrd;
const char *thrdRet;
- if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
- port = 0;
- else
- port = 1480;
+ if (verbose)
+ printf ("testGet(%d, %d, %d) test started.\n",
+ type, pool_count, poll_flag);
cbc.buf = buf;
- cbc.size = 2048;
+ cbc.size = sizeof(buf);
cbc.pos = 0;
if (pool_count > 0)
{
d = MHD_start_daemon (type | MHD_USE_ERROR_LOG | MHD_USE_ITC | poll_flag,
- port, NULL, NULL, &ahc_echo, "GET",
- MHD_OPTION_THREAD_POOL_SIZE, pool_count,
+ global_port, NULL, NULL, &ahc_echo, "GET",
+ MHD_OPTION_THREAD_POOL_SIZE,
+ (unsigned int) pool_count,
MHD_OPTION_END);
}
else
{
d = MHD_start_daemon (type | MHD_USE_ERROR_LOG | MHD_USE_ITC | poll_flag,
- port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+ global_port, NULL, NULL, &ahc_echo, "GET",
+ MHD_OPTION_END);
}
if (d == NULL)
- return 1;
- if (0 == port)
+ mhdErrorExitDesc ("MHD_start_daemon() failed");
+ if (0 == global_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;
- }
- port = (int) dinfo->port;
+ mhdErrorExit ();
+ global_port = (int) dinfo->port;
}
c = setupCURL (&cbc);
@@ -254,108 +391,101 @@ testGet (int type, int pool_count, int poll_flag)
if (CURLE_OK != (errornum = curl_easy_perform (c)))
{
fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
+ "curl_easy_perform() failed: '%s'. ",
curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 2;
+ libcurlErrorExit ();
}
- if (cbc.pos != strlen ("/hello_world"))
+ if (cbc.pos != strlen (MHD_URI_BASE_PATH))
{
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 4;
+ fprintf (stderr, "Got %u bytes ('%.*s'), expected %u bytes. ",
+ (unsigned) cbc.pos, (int) cbc.pos, cbc.buf,
+ (unsigned) strlen (MHD_URI_BASE_PATH));
+ mhdErrorExitDesc ("Wrong returned data length");
}
- if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
+ if (0 != strncmp (MHD_URI_BASE_PATH, cbc.buf, strlen (MHD_URI_BASE_PATH)))
{
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 8;
+ fprintf (stderr, "Got invalid response '%.*s'. ", (int) cbc.pos, cbc.buf);
+ mhdErrorExitDesc ("Wrong returned data");
}
+ if (verbose)
+ printf ("Received valid response data.\n");
fd = MHD_quiesce_daemon (d);
if (MHD_INVALID_SOCKET == fd)
- {
- fprintf (stderr,
- "MHD_quiesce_daemon failed.\n");
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 2;
- }
+ mhdErrorExitDesc ("MHD_quiesce_daemon failed");
+
if (0 != pthread_create (&thrd, NULL, &ServeOneRequest,
- (void *) (intptr_t) fd))
- {
- fprintf (stderr, "pthread_create failed\n");
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 16;
- }
+ (void *) &fd))
+ externalErrorExitDesc ("pthread_create() failed");
+ /* No need for the thread sync as socket is already listening,
+ * so libcurl may start connecting before MHD is started in another thread */
cbc.pos = 0;
if (CURLE_OK != (errornum = curl_easy_perform (c)))
{
fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
+ "curl_easy_perform() failed: `%s'\n",
curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 2;
+ mhdErrorExit ();
}
- if (0 != pthread_join (thrd, (void **) &thrdRet))
+ if (cbc.pos != strlen (MHD_URI_BASE_PATH))
{
- fprintf (stderr, "pthread_join failed\n");
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 16;
+ fprintf (stderr, "Got %u bytes ('%.*s'), expected %u bytes. ",
+ (unsigned) cbc.pos, (int) cbc.pos, cbc.buf,
+ (unsigned) strlen (MHD_URI_BASE_PATH));
+ mhdErrorExitDesc ("Wrong returned data length");
}
- if (NULL != thrdRet)
+ if (0 != strncmp (MHD_URI_BASE_PATH, cbc.buf, strlen (MHD_URI_BASE_PATH)))
{
- fprintf (stderr, "ServeOneRequest() error: %s\n", thrdRet);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 16;
+ fprintf (stderr, "Got invalid response '%.*s'. ", (int) cbc.pos, cbc.buf);
+ mhdErrorExitDesc ("Wrong returned data");
}
- if (cbc.pos != strlen ("/hello_world"))
- {
- fprintf (stderr, "%s\n", cbc.buf);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- MHD_socket_close_chk_ (fd);
- return 4;
- }
- if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
+ if (0 != pthread_join (thrd, (void **) &thrdRet))
+ externalErrorExitDesc ("pthread_join() failed");
+ if (NULL != thrdRet)
+ externalErrorExitDesc ("ServeOneRequest() returned non-NULL result");
+
+ if (verbose)
{
- fprintf (stderr, "%s\n", cbc.buf);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- MHD_socket_close_chk_ (fd);
- return 8;
+ printf ("ServeOneRequest() thread was joined.\n");
+ fflush (stdout);
}
- /* at this point, the forked server quit, and the new
- * server has quiesced, so new requests should fail
+ /* at this point, the forked server quiesced and quit,
+ * so new requests should fail
*/
+ cbc.pos = 0;
if (CURLE_OK == curl_easy_perform (c))
{
- fprintf (stderr, "curl_easy_perform should fail\n");
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- MHD_socket_close_chk_ (fd);
- return 2;
+ fprintf (stderr, "curl_easy_perform() succeed while it should fail. ");
+ fprintf (stderr, "Got %u bytes ('%.*s'), "
+ "valid data would be %u bytes (%s). ",
+ (unsigned) cbc.pos, (int) cbc.pos, cbc.buf,
+ (unsigned) strlen (MHD_URI_BASE_PATH), MHD_URI_BASE_PATH);
+ mhdErrorExitDesc ("Unexpected succeed request");
}
+ if (verbose)
+ printf ("curl_easy_perform() failed as expected.\n");
curl_easy_cleanup (c);
MHD_stop_daemon (d);
MHD_socket_close_chk_ (fd);
+ if (verbose)
+ {
+ printf ("testGet(%d, %d, %d) test succeed.\n",
+ type, pool_count, poll_flag);
+ fflush (stdout);
+ }
+
return 0;
}
static int
-testExternalGet ()
+testExternalGet (void)
{
struct MHD_Daemon *d;
CURL *c;
@@ -366,12 +496,6 @@ testExternalGet ()
fd_set rs;
fd_set ws;
fd_set es;
- MHD_socket maxsock;
-#ifdef MHD_WINSOCK_SOCKETS
- int maxposixs; /* Max socket number unused on W32 */
-#else /* MHD_POSIX_SOCKETS */
-#define maxposixs maxsock
-#endif /* MHD_POSIX_SOCKETS */
int running;
struct CURLMsg *msg;
time_t start;
@@ -379,56 +503,48 @@ testExternalGet ()
int i;
MHD_socket fd;
- if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
- port = 0;
- else
- port = 1481;
+ if (verbose)
+ printf ("testExternalGet test started.\n");
+ fd = MHD_INVALID_SOCKET;
multi = NULL;
cbc.buf = buf;
- cbc.size = 2048;
+ cbc.size = sizeof(buf);
cbc.pos = 0;
d = MHD_start_daemon (MHD_USE_ERROR_LOG,
- port,
+ global_port,
NULL, NULL,
&ahc_echo, "GET",
MHD_OPTION_END);
if (d == NULL)
- return 256;
- if (0 == port)
+ mhdErrorExitDesc ("Failed to start MHD daemon");
+ if (0 == global_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;
- }
- port = (int) dinfo->port;
- }
- c = setupCURL (&cbc);
-
- multi = curl_multi_init ();
- if (multi == NULL)
- {
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 512;
- }
- mret = curl_multi_add_handle (multi, c);
- if (mret != CURLM_OK)
- {
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 1024;
+ mhdErrorExit ();
+ global_port = (int) dinfo->port;
}
for (i = 0; i < 2; i++)
{
+ c = setupCURL (&cbc);
+
+ multi = curl_multi_init ();
+ if (multi == NULL)
+ libcurlErrorExit ();
+
+ mret = curl_multi_add_handle (multi, c);
+ if (mret != CURLM_OK)
+ libcurlErrorExit ();
+
start = time (NULL);
- while ( (time (NULL) - start < 5) &&
+ while ( (time (NULL) - start < TIMEOUTS_VAL * 2) &&
(NULL != multi) )
{
+ MHD_socket maxsock;
+ int maxposixs;
maxsock = MHD_INVALID_SOCKET;
maxposixs = -1;
FD_ZERO (&rs);
@@ -437,44 +553,26 @@ testExternalGet ()
curl_multi_perform (multi, &running);
mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
if (mret != CURLM_OK)
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 2048;
- }
+ libcurlErrorExit ();
if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 4096;
- }
+ mhdErrorExit ();
+#ifndef MHD_WINSOCK_SOCKETS
+ if (maxsock > maxposixs)
+ maxposixs = maxsock;
+#endif /* MHD_POSIX_SOCKETS */
tv.tv_sec = 0;
- tv.tv_usec = 1000;
+ tv.tv_usec = 100000;
if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
{
- #ifdef MHD_POSIX_SOCKETS
+#ifdef MHD_POSIX_SOCKETS
if (EINTR != errno)
- {
- fprintf (stderr, "Unexpected select() error: %d. Line: %d\n",
- (int) errno, __LINE__);
- fflush (stderr);
- exit (99);
- }
- #else
+ externalErrorExitDesc ("Unexpected select() error");
+#else
if ((WSAEINVAL != WSAGetLastError ()) ||
(0 != rs.fd_count) || (0 != ws.fd_count) || (0 != es.fd_count) )
- {
- fprintf (stderr, "Unexpected select() error: %d. Line: %d\n",
- (int) WSAGetLastError (), __LINE__);
- fflush (stderr);
- exit (99);
- }
- Sleep (1);
- #endif
+ externalErrorExitDesc ("Unexpected select() error");
+ Sleep (tv.tv_sec * 1000 + tv.tv_usec / 1000);
+#endif
}
curl_multi_perform (multi, &running);
if (0 == running)
@@ -486,26 +584,57 @@ testExternalGet ()
if (msg->msg == CURLMSG_DONE)
{
if (msg->data.result == CURLE_OK)
+ {
curl_fine = 1;
+ if (verbose)
+ printf ("libcurl reported success.\n");
+ }
else if (i == 0)
{
fprintf (stderr,
- "%s failed at %s:%d: `%s'\n",
- "curl_multi_perform",
- __FILE__,
- __LINE__, curl_easy_strerror (msg->data.result));
+ "curl_multi_perform() failed with '%s'. ",
+ curl_easy_strerror (msg->data.result));
+ mhdErrorExit ();
}
}
}
- if ((i == 0) && (! curl_fine))
+ if (i == 0)
{
- fprintf (stderr, "libcurl haven't returned OK code\n");
- abort ();
+ if (! curl_fine)
+ {
+ fprintf (stderr, "libcurl haven't returned OK code\n");
+ mhdErrorExit ();
+ }
+ /* MHD is running, result should be correct */
+ if (cbc.pos != strlen (MHD_URI_BASE_PATH))
+ {
+ fprintf (stderr, "Got %u bytes ('%.*s'), expected %u bytes. ",
+ (unsigned) cbc.pos, (int) cbc.pos, cbc.buf,
+ (unsigned) strlen (MHD_URI_BASE_PATH));
+ mhdErrorExitDesc ("Wrong returned data length");
+ }
+ if (0 != strncmp (MHD_URI_BASE_PATH, cbc.buf,
+ strlen (MHD_URI_BASE_PATH)))
+ {
+ fprintf (stderr, "Got invalid response '%.*s'. ", (int) cbc.pos,
+ cbc.buf);
+ mhdErrorExitDesc ("Wrong returned data");
+ }
+ if (verbose)
+ {
+ printf ("First request was successful.\n");
+ fflush (stdout);
+ }
}
- else if ((i == 1) && (curl_fine))
+ else if (i == 1)
{
- fprintf (stderr, "libcurl returned OK code, while it shouldn't\n");
- abort ();
+ if (curl_fine)
+ {
+ fprintf (stderr, "libcurl returned OK code, while it shouldn't\n");
+ mhdErrorExit ();
+ }
+ if (verbose)
+ printf ("Second request failed as expected.\n");
}
curl_multi_remove_handle (multi, c);
curl_multi_cleanup (multi);
@@ -517,45 +646,31 @@ testExternalGet ()
MHD_run (d);
}
+ if (NULL != multi)
+ mhdErrorExitDesc ("Test failed and finished by timeout");
+
if (0 == i)
{
/* quiesce the daemon on the 1st iteration, so the 2nd should fail */
fd = MHD_quiesce_daemon (d);
if (MHD_INVALID_SOCKET == fd)
- {
- fprintf (stderr,
- "MHD_quiesce_daemon failed.\n");
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 2;
- }
- c = setupCURL (&cbc);
- multi = curl_multi_init ();
- mret = curl_multi_add_handle (multi, c);
- if (mret != CURLM_OK)
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 32768;
- }
+ mhdErrorExitDesc ("MHD_quiesce_daemon() failed");
}
}
- if (NULL != multi)
+ MHD_stop_daemon (d);
+ if (MHD_INVALID_SOCKET == fd)
{
- curl_multi_remove_handle (multi, c);
- curl_easy_cleanup (c);
- curl_multi_cleanup (multi);
+ fprintf (stderr, "Failed to MHD_quiesce_daemon() at some point. ");
+ externalErrorExit ();
}
- MHD_stop_daemon (d);
MHD_socket_close_chk_ (fd);
- if (cbc.pos != strlen ("/hello_world"))
- return 8192;
- if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
- return 16384;
+
+ if (verbose)
+ {
+ printf ("testExternalGet succeed.\n");
+ fflush (stdout);
+ }
+
return 0;
}
@@ -564,10 +679,17 @@ int
main (int argc, char *const *argv)
{
unsigned int errorCount = 0;
- (void) argc; (void) argv; /* Unused. Silent compiler warning. */
+ oneone = ! has_in_name (argv[0], "10");
+ verbose = ! has_param (argc, argv, "-q") || has_param (argc, argv,
"--quiet");
if (0 != curl_global_init (CURL_GLOBAL_WIN32))
return 2;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ global_port = 0;
+ else
+ global_port = 1480 + (oneone ? 1 : 0);
+
errorCount += testExternalGet ();
if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_THREADS))
{
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.