aboutsummaryrefslogtreecommitdiff
path: root/src/testcurl
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2022-05-28 19:42:14 +0300
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2022-05-28 19:54:44 +0300
commit435cd008a8c1caee536f539283aa59adf25d94a6 (patch)
tree6699994728ab6dbd9f02168357f70a9955b06076 /src/testcurl
parentd73c6d20e301775597feea322416e475262a9558 (diff)
downloadlibmicrohttpd-435cd008a8c1caee536f539283aa59adf25d94a6.tar.gz
libmicrohttpd-435cd008a8c1caee536f539283aa59adf25d94a6.zip
test_basicauth: added new test
Diffstat (limited to 'src/testcurl')
-rw-r--r--src/testcurl/Makefile.am8
-rw-r--r--src/testcurl/test_basicauth.c636
2 files changed, 644 insertions, 0 deletions
diff --git a/src/testcurl/Makefile.am b/src/testcurl/Makefile.am
index 4b0c3d1c..ed585527 100644
--- a/src/testcurl/Makefile.am
+++ b/src/testcurl/Makefile.am
@@ -151,6 +151,11 @@ check_PROGRAMS += \
151 perf_get 151 perf_get
152endif 152endif
153 153
154if ENABLE_BAUTH
155check_PROGRAMS += \
156 test_basicauth
157endif
158
154if HAVE_POSTPROCESSOR 159if HAVE_POSTPROCESSOR
155 check_PROGRAMS += \ 160 check_PROGRAMS += \
156 test_post \ 161 test_post \
@@ -228,6 +233,9 @@ perf_get_concurrent11_CFLAGS = \
228perf_get_concurrent11_LDADD = \ 233perf_get_concurrent11_LDADD = \
229 $(PTHREAD_LIBS) $(LDADD) 234 $(PTHREAD_LIBS) $(LDADD)
230 235
236test_basicauth_SOURCES = \
237 test_basicauth.c
238
231test_digestauth_SOURCES = \ 239test_digestauth_SOURCES = \
232 test_digestauth.c 240 test_digestauth.c
233test_digestauth_LDADD = \ 241test_digestauth_LDADD = \
diff --git a/src/testcurl/test_basicauth.c b/src/testcurl/test_basicauth.c
new file mode 100644
index 00000000..1b84ac15
--- /dev/null
+++ b/src/testcurl/test_basicauth.c
@@ -0,0 +1,636 @@
1/*
2 This file is part of libmicrohttpd
3 Copyright (C) 2010 Christian Grothoff
4 Copyright (C) 2016-2022 Evgeny Grin (Karlson2k)
5
6 libmicrohttpd is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published
8 by the Free Software Foundation; either version 2, or (at your
9 option) any later version.
10
11 libmicrohttpd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with libmicrohttpd; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
20*/
21
22/**
23 * @file test_basicauth.c
24 * @brief Testcase for libmicrohttpd concurrent Basic Authorisation
25 * @author Amr Ali
26 * @author Karlson2k (Evgeny Grin)
27 */
28
29#include "MHD_config.h"
30#include "platform.h"
31#include <curl/curl.h>
32#include <microhttpd.h>
33#include <stdlib.h>
34#include <string.h>
35#include <time.h>
36
37#ifndef WINDOWS
38#include <sys/socket.h>
39#include <unistd.h>
40#else
41#include <wincrypt.h>
42#endif
43
44#include "mhd_has_param.h"
45
46#ifndef MHD_STATICSTR_LEN_
47/**
48 * Determine length of static string / macro strings at compile time.
49 */
50#define MHD_STATICSTR_LEN_(macro) (sizeof(macro) / sizeof(char) - 1)
51#endif /* ! MHD_STATICSTR_LEN_ */
52
53#ifndef CURL_VERSION_BITS
54#define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|(z))
55#endif /* ! CURL_VERSION_BITS */
56#ifndef CURL_AT_LEAST_VERSION
57#define CURL_AT_LEAST_VERSION(x,y,z) \
58 (LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z))
59#endif /* ! CURL_AT_LEAST_VERSION */
60
61#ifndef _MHD_INSTRMACRO
62/* Quoted macro parameter */
63#define _MHD_INSTRMACRO(a) #a
64#endif /* ! _MHD_INSTRMACRO */
65#ifndef _MHD_STRMACRO
66/* Quoted expanded macro parameter */
67#define _MHD_STRMACRO(a) _MHD_INSTRMACRO (a)
68#endif /* ! _MHD_STRMACRO */
69
70#if defined(HAVE___FUNC__)
71#define externalErrorExit(ignore) \
72 _externalErrorExit_func(NULL, __func__, __LINE__)
73#define externalErrorExitDesc(errDesc) \
74 _externalErrorExit_func(errDesc, __func__, __LINE__)
75#define libcurlErrorExit(ignore) \
76 _libcurlErrorExit_func(NULL, __func__, __LINE__)
77#define libcurlErrorExitDesc(errDesc) \
78 _libcurlErrorExit_func(errDesc, __func__, __LINE__)
79#define mhdErrorExit(ignore) \
80 _mhdErrorExit_func(NULL, __func__, __LINE__)
81#define mhdErrorExitDesc(errDesc) \
82 _mhdErrorExit_func(errDesc, __func__, __LINE__)
83#define checkCURLE_OK(libcurlcall) \
84 _checkCURLE_OK_func((libcurlcall), _MHD_STRMACRO(libcurlcall), \
85 __func__, __LINE__)
86#elif defined(HAVE___FUNCTION__)
87#define externalErrorExit(ignore) \
88 _externalErrorExit_func(NULL, __FUNCTION__, __LINE__)
89#define externalErrorExitDesc(errDesc) \
90 _externalErrorExit_func(errDesc, __FUNCTION__, __LINE__)
91#define libcurlErrorExit(ignore) \
92 _libcurlErrorExit_func(NULL, __FUNCTION__, __LINE__)
93#define libcurlErrorExitDesc(errDesc) \
94 _libcurlErrorExit_func(errDesc, __FUNCTION__, __LINE__)
95#define mhdErrorExit(ignore) \
96 _mhdErrorExit_func(NULL, __FUNCTION__, __LINE__)
97#define mhdErrorExitDesc(errDesc) \
98 _mhdErrorExit_func(errDesc, __FUNCTION__, __LINE__)
99#define checkCURLE_OK(libcurlcall) \
100 _checkCURLE_OK_func((libcurlcall), _MHD_STRMACRO(libcurlcall), \
101 __FUNCTION__, __LINE__)
102#else
103#define externalErrorExit(ignore) _externalErrorExit_func(NULL, NULL, __LINE__)
104#define externalErrorExitDesc(errDesc) \
105 _externalErrorExit_func(errDesc, NULL, __LINE__)
106#define libcurlErrorExit(ignore) _libcurlErrorExit_func(NULL, NULL, __LINE__)
107#define libcurlErrorExitDesc(errDesc) \
108 _libcurlErrorExit_func(errDesc, NULL, __LINE__)
109#define mhdErrorExit(ignore) _mhdErrorExit_func(NULL, NULL, __LINE__)
110#define mhdErrorExitDesc(errDesc) _mhdErrorExit_func(errDesc, NULL, __LINE__)
111#define checkCURLE_OK(libcurlcall) \
112 _checkCURLE_OK_func((libcurlcall), _MHD_STRMACRO(libcurlcall), NULL, __LINE__)
113#endif
114
115
116_MHD_NORETURN static void
117_externalErrorExit_func (const char *errDesc, const char *funcName, int lineNum)
118{
119 fflush (stdout);
120 if ((NULL != errDesc) && (0 != errDesc[0]))
121 fprintf (stderr, "%s", errDesc);
122 else
123 fprintf (stderr, "System or external library call failed");
124 if ((NULL != funcName) && (0 != funcName[0]))
125 fprintf (stderr, " in %s", funcName);
126 if (0 < lineNum)
127 fprintf (stderr, " at line %d", lineNum);
128
129 fprintf (stderr, ".\nLast errno value: %d (%s)\n", (int) errno,
130 strerror (errno));
131#ifdef MHD_WINSOCK_SOCKETS
132 fprintf (stderr, "WSAGetLastError() value: %d\n", (int) WSAGetLastError ());
133#endif /* MHD_WINSOCK_SOCKETS */
134 fflush (stderr);
135 exit (99);
136}
137
138
139/* Not actually used in this test */
140static char libcurl_errbuf[CURL_ERROR_SIZE] = "";
141
142_MHD_NORETURN static void
143_libcurlErrorExit_func (const char *errDesc, const char *funcName, int lineNum)
144{
145 fflush (stdout);
146 if ((NULL != errDesc) && (0 != errDesc[0]))
147 fprintf (stderr, "%s", errDesc);
148 else
149 fprintf (stderr, "CURL library call failed");
150 if ((NULL != funcName) && (0 != funcName[0]))
151 fprintf (stderr, " in %s", funcName);
152 if (0 < lineNum)
153 fprintf (stderr, " at line %d", lineNum);
154
155 fprintf (stderr, ".\nLast errno value: %d (%s)\n", (int) errno,
156 strerror (errno));
157#ifdef MHD_WINSOCK_SOCKETS
158 fprintf (stderr, "WSAGetLastError() value: %d\n", (int) WSAGetLastError ());
159#endif /* MHD_WINSOCK_SOCKETS */
160 if (0 != libcurl_errbuf[0])
161 fprintf (stderr, "Last libcurl error description: %s\n", libcurl_errbuf);
162
163 fflush (stderr);
164 exit (99);
165}
166
167
168_MHD_NORETURN static void
169_mhdErrorExit_func (const char *errDesc, const char *funcName, int lineNum)
170{
171 fflush (stdout);
172 if ((NULL != errDesc) && (0 != errDesc[0]))
173 fprintf (stderr, "%s", errDesc);
174 else
175 fprintf (stderr, "MHD unexpected error");
176 if ((NULL != funcName) && (0 != funcName[0]))
177 fprintf (stderr, " in %s", funcName);
178 if (0 < lineNum)
179 fprintf (stderr, " at line %d", lineNum);
180
181 fprintf (stderr, ".\nLast errno value: %d (%s)\n", (int) errno,
182 strerror (errno));
183#ifdef MHD_WINSOCK_SOCKETS
184 fprintf (stderr, "WSAGetLastError() value: %d\n", (int) WSAGetLastError ());
185#endif /* MHD_WINSOCK_SOCKETS */
186
187 fflush (stderr);
188 exit (8);
189}
190
191
192#if 0
193/* Function unused in this test */
194static void
195_checkCURLE_OK_func (CURLcode code, const char *curlFunc,
196 const char *funcName, int lineNum)
197{
198 if (CURLE_OK == code)
199 return;
200
201 fflush (stdout);
202 if ((NULL != curlFunc) && (0 != curlFunc[0]))
203 fprintf (stderr, "'%s' resulted in '%s'", curlFunc,
204 curl_easy_strerror (code));
205 else
206 fprintf (stderr, "libcurl function call resulted in '%s'",
207 curl_easy_strerror (code));
208 if ((NULL != funcName) && (0 != funcName[0]))
209 fprintf (stderr, " in %s", funcName);
210 if (0 < lineNum)
211 fprintf (stderr, " at line %d", lineNum);
212
213 fprintf (stderr, ".\nLast errno value: %d (%s)\n", (int) errno,
214 strerror (errno));
215 if (0 != libcurl_errbuf[0])
216 fprintf (stderr, "Last libcurl error description: %s\n", libcurl_errbuf);
217
218 fflush (stderr);
219 exit (9);
220}
221
222
223#endif
224
225
226/* Could be increased to facilitate debugging */
227#define TIMEOUTS_VAL 10
228
229#define MHD_URI_BASE_PATH "/bar%20foo%3Fkey%3Dvalue"
230
231#define REALM "TestRealm"
232#define USERNAME "Aladdin"
233#define PASSWORD "open sesame"
234
235
236#define PAGE \
237 "<html><head><title>libmicrohttpd demo page</title>" \
238 "</head><body>Access granted</body></html>"
239
240#define DENIED \
241 "<html><head><title>libmicrohttpd - Access denied</title>" \
242 "</head><body>Access denied</body></html>"
243
244struct CBC
245{
246 char *buf;
247 size_t pos;
248 size_t size;
249};
250
251static int verbose;
252
253static size_t
254copyBuffer (void *ptr,
255 size_t size,
256 size_t nmemb,
257 void *ctx)
258{
259 struct CBC *cbc = ctx;
260
261 if (cbc->pos + size * nmemb > cbc->size)
262 mhdErrorExitDesc ("Wrong too large data"); /* overflow */
263 memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
264 cbc->pos += size * nmemb;
265 return size * nmemb;
266}
267
268
269static enum MHD_Result
270ahc_echo (void *cls,
271 struct MHD_Connection *connection,
272 const char *url,
273 const char *method,
274 const char *version,
275 const char *upload_data,
276 size_t *upload_data_size,
277 void **req_cls)
278{
279 struct MHD_Response *response;
280 char *username;
281 char *password;
282 enum MHD_Result ret;
283 static int already_called_marker;
284 (void) cls; (void) url; /* Unused. Silent compiler warning. */
285 (void) method; (void) version; (void) upload_data; /* Unused. Silent compiler warning. */
286 (void) upload_data_size; /* Unused. Silent compiler warning. */
287
288 if (&already_called_marker != *req_cls)
289 { /* Called for the first time, request not fully read yet */
290 *req_cls = &already_called_marker;
291 /* Wait for complete request */
292 return MHD_YES;
293 }
294
295 if (0 != strcmp (method, MHD_HTTP_METHOD_GET))
296 mhdErrorExitDesc ("Unexpected HTTP method");
297
298 /* require: USERNAME with password PASSWORD */
299 password = NULL;
300 username = MHD_basic_auth_get_username_password (connection,
301 &password);
302 if (NULL != username)
303 {
304 if (0 != strcmp (username, USERNAME))
305 {
306 fprintf (stderr, "'username' does not match.\n"
307 "Expected: '%s'\tRecieved: '%s'. ", USERNAME, username);
308 mhdErrorExitDesc ("Wrong 'username'");
309 }
310 if (NULL == password)
311 mhdErrorExitDesc ("The password pointer is NULL");
312 if (0 != strcmp (password, PASSWORD))
313 fprintf (stderr, "'password' does not match.\n"
314 "Expected: '%s'\tRecieved: '%s'. ", PASSWORD, password);
315 response =
316 MHD_create_response_from_buffer_static (MHD_STATICSTR_LEN_ (PAGE),
317 (const void *) PAGE);
318 if (NULL == response)
319 mhdErrorExitDesc ("Response creation failed");
320 ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
321 if (MHD_YES != ret)
322 mhdErrorExitDesc ("'MHD_queue_response()' failed");
323 }
324 else
325 {
326 if (NULL != password)
327 mhdErrorExitDesc ("The password pointer is NOT NULL");
328 response =
329 MHD_create_response_from_buffer_static (MHD_STATICSTR_LEN_ (DENIED),
330 (const void *) DENIED);
331 ret = MHD_queue_basic_auth_fail_response (connection, REALM,
332 response);
333 }
334
335 if (NULL != username)
336 MHD_free (username);
337 if (NULL != password)
338 MHD_free (password);
339 MHD_destroy_response (response);
340 return ret;
341}
342
343
344static CURL *
345setupCURL (void *cbc, int port, char *errbuf)
346{
347 CURL *c;
348 char url[512];
349
350 if (1)
351 {
352 int res;
353 /* A workaround for some old libcurl versions, which ignore the specified
354 * port by CURLOPT_PORT when authorisation is used. */
355 res = snprintf (url, (sizeof(url) / sizeof(url[0])),
356 "http://127.0.0.1:%d%s", port, MHD_URI_BASE_PATH);
357 if ((0 >= res) || ((sizeof(url) / sizeof(url[0])) <= (size_t) res))
358 externalErrorExitDesc ("Cannot form request URL");
359 }
360
361 c = curl_easy_init ();
362 if (NULL == c)
363 libcurlErrorExitDesc ("curl_easy_init() failed");
364
365 if ((CURLE_OK != curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L)) ||
366 (CURLE_OK != curl_easy_setopt (c, CURLOPT_ERRORBUFFER,
367 errbuf)) ||
368 (CURLE_OK != curl_easy_setopt (c, CURLOPT_WRITEFUNCTION,
369 &copyBuffer)) ||
370 (CURLE_OK != curl_easy_setopt (c, CURLOPT_WRITEDATA, cbc)) ||
371 (CURLE_OK != curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT,
372 ((long) TIMEOUTS_VAL))) ||
373 (CURLE_OK != curl_easy_setopt (c, CURLOPT_TIMEOUT,
374 ((long) TIMEOUTS_VAL))) ||
375 (CURLE_OK != curl_easy_setopt (c, CURLOPT_HTTP_VERSION,
376 CURL_HTTP_VERSION_1_1)) ||
377 (CURLE_OK != curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L)) ||
378#if CURL_AT_LEAST_VERSION (7, 19, 4)
379 (CURLE_OK != curl_easy_setopt (c, CURLOPT_PROTOCOLS, CURLPROTO_HTTP)) ||
380#endif /* CURL_AT_LEAST_VERSION (7, 19, 4) */
381#if CURL_AT_LEAST_VERSION (7, 45, 0)
382 (CURLE_OK != curl_easy_setopt (c, CURLOPT_DEFAULT_PROTOCOL, "http")) ||
383#endif /* CURL_AT_LEAST_VERSION (7, 45, 0) */
384 (CURLE_OK != curl_easy_setopt (c, CURLOPT_PORT, ((long) port))) ||
385 (CURLE_OK != curl_easy_setopt (c, CURLOPT_URL, url)))
386 libcurlErrorExitDesc ("curl_easy_setopt() failed");
387 if ((CURLE_OK != curl_easy_setopt (c, CURLOPT_HTTPAUTH, CURLAUTH_BASIC)) ||
388 (CURLE_OK != curl_easy_setopt (c, CURLOPT_USERPWD,
389 USERNAME ":" PASSWORD)))
390 libcurlErrorExitDesc ("curl_easy_setopt() authorization options failed");
391 return c;
392}
393
394
395static CURLcode
396performQueryExternal (struct MHD_Daemon *d, CURL *c)
397{
398 CURLM *multi;
399 time_t start;
400 struct timeval tv;
401 CURLcode ret;
402
403 ret = CURLE_FAILED_INIT; /* will be replaced with real result */
404 multi = NULL;
405 multi = curl_multi_init ();
406 if (multi == NULL)
407 libcurlErrorExitDesc ("curl_multi_init() failed");
408 if (CURLM_OK != curl_multi_add_handle (multi, c))
409 libcurlErrorExitDesc ("curl_multi_add_handle() failed");
410
411 start = time (NULL);
412 while (time (NULL) - start <= TIMEOUTS_VAL)
413 {
414 fd_set rs;
415 fd_set ws;
416 fd_set es;
417 MHD_socket maxMhdSk;
418 int maxCurlSk;
419 int running;
420
421 maxMhdSk = MHD_INVALID_SOCKET;
422 maxCurlSk = -1;
423 FD_ZERO (&rs);
424 FD_ZERO (&ws);
425 FD_ZERO (&es);
426 if (NULL != multi)
427 {
428 curl_multi_perform (multi, &running);
429 if (0 == running)
430 {
431 struct CURLMsg *msg;
432 int msgLeft;
433 int totalMsgs = 0;
434 do
435 {
436 msg = curl_multi_info_read (multi, &msgLeft);
437 if (NULL == msg)
438 libcurlErrorExitDesc ("curl_multi_info_read() failed");
439 totalMsgs++;
440 if (CURLMSG_DONE == msg->msg)
441 ret = msg->data.result;
442 } while (msgLeft > 0);
443 if (1 != totalMsgs)
444 {
445 fprintf (stderr,
446 "curl_multi_info_read returned wrong "
447 "number of results (%d).\n",
448 totalMsgs);
449 externalErrorExit ();
450 }
451 curl_multi_remove_handle (multi, c);
452 curl_multi_cleanup (multi);
453 multi = NULL;
454 }
455 else
456 {
457 if (CURLM_OK != curl_multi_fdset (multi, &rs, &ws, &es, &maxCurlSk))
458 libcurlErrorExitDesc ("curl_multi_fdset() failed");
459 }
460 }
461 if (NULL == multi)
462 { /* libcurl has finished, check whether MHD still needs to perform cleanup */
463 if (0 != MHD_get_timeout64s (d))
464 break; /* MHD finished as well */
465 }
466 if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxMhdSk))
467 mhdErrorExitDesc ("MHD_get_fdset() failed");
468 tv.tv_sec = 0;
469 tv.tv_usec = 200000;
470#ifdef MHD_POSIX_SOCKETS
471 if (maxMhdSk > maxCurlSk)
472 maxCurlSk = maxMhdSk;
473#endif /* MHD_POSIX_SOCKETS */
474 if (-1 == select (maxCurlSk + 1, &rs, &ws, &es, &tv))
475 {
476#ifdef MHD_POSIX_SOCKETS
477 if (EINTR != errno)
478 externalErrorExitDesc ("Unexpected select() error");
479#else
480 if ((WSAEINVAL != WSAGetLastError ()) ||
481 (0 != rs.fd_count) || (0 != ws.fd_count) || (0 != es.fd_count) )
482 externalErrorExitDesc ("Unexpected select() error");
483 Sleep (200);
484#endif
485 }
486 if (MHD_YES != MHD_run_from_select (d, &rs, &ws, &es))
487 mhdErrorExitDesc ("MHD_run_from_select() failed");
488 }
489
490 return ret;
491}
492
493
494/**
495 * Check request result
496 * @param curl_code the CURL easy return code
497 * @param pcbc the pointer struct CBC
498 * @return non-zero if success, zero if failed
499 */
500static unsigned int
501check_result (CURLcode curl_code, struct CBC *pcbc)
502{
503 if (CURLE_OK != curl_code)
504 {
505 fflush (stdout);
506 if (0 != libcurl_errbuf[0])
507 fprintf (stderr, "First request failed. "
508 "libcurl error: '%s'.\n"
509 "libcurl error description: '%s'.\n",
510 curl_easy_strerror (curl_code),
511 libcurl_errbuf);
512 else
513 fprintf (stderr, "First request failed. "
514 "libcurl error: '%s'.\n",
515 curl_easy_strerror (curl_code));
516 fflush (stderr);
517 return 0;
518 }
519
520 if (pcbc->pos != strlen (PAGE))
521 {
522 fprintf (stderr, "Got %u bytes ('%.*s'), expected %u bytes. ",
523 (unsigned) pcbc->pos, (int) pcbc->pos, pcbc->buf,
524 (unsigned) strlen (PAGE));
525 mhdErrorExitDesc ("Wrong returned data length");
526 }
527 if (0 != memcmp (PAGE, pcbc->buf, pcbc->pos))
528 {
529 fprintf (stderr, "Got invalid response '%.*s'. ",
530 (int) pcbc->pos, pcbc->buf);
531 mhdErrorExitDesc ("Wrong returned data");
532 }
533 return 1;
534}
535
536
537static unsigned int
538testBasicAuth (void)
539{
540 struct MHD_Daemon *d;
541 uint16_t port;
542 struct CBC cbc;
543 char buf[2048];
544 CURL *c;
545 int failed = 0;
546
547 if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
548 port = 0;
549 else
550 port = 4210;
551
552 d = MHD_start_daemon (MHD_USE_ERROR_LOG,
553 port, NULL, NULL,
554 &ahc_echo, NULL,
555 MHD_OPTION_END);
556 if (d == NULL)
557 return 1;
558 if (0 == port)
559 {
560 const union MHD_DaemonInfo *dinfo;
561
562 dinfo = MHD_get_daemon_info (d,
563 MHD_DAEMON_INFO_BIND_PORT);
564 if ( (NULL == dinfo) ||
565 (0 == dinfo->port) )
566 mhdErrorExitDesc ("MHD_get_daemon_info() failed");
567 port = (uint16_t) dinfo->port;
568 }
569
570 /* First request */
571 cbc.buf = buf;
572 cbc.size = sizeof (buf);
573 cbc.pos = 0;
574 memset (cbc.buf, 0, cbc.size);
575 c = setupCURL (&cbc, port, libcurl_errbuf);
576 if (check_result (performQueryExternal (d, c), &cbc))
577 {
578 if (verbose)
579 printf ("First request successful.\n");
580 }
581 else
582 {
583 fprintf (stderr, "First request FAILED.\n");
584 failed = 1;
585 }
586 curl_easy_cleanup (c);
587
588 /* Second request */
589 cbc.buf = buf;
590 cbc.size = sizeof (buf);
591 cbc.pos = 0;
592 memset (cbc.buf, 0, cbc.size);
593 c = setupCURL (&cbc, port, libcurl_errbuf);
594 if (check_result (performQueryExternal (d, c), &cbc))
595 {
596 if (verbose)
597 printf ("Second request successful.\n");
598 }
599 else
600 {
601 fprintf (stderr, "Second request FAILED.\n");
602 failed = 1;
603 }
604 curl_easy_cleanup (c);
605 MHD_stop_daemon (d);
606 return failed ? 1 : 0;
607}
608
609
610int
611main (int argc, char *const *argv)
612{
613 unsigned int errorCount = 0;
614 (void) argc; (void) argv; /* Unused. Silent compiler warning. */
615
616 verbose = ! (has_param (argc, argv, "-q") ||
617 has_param (argc, argv, "--quiet") ||
618 has_param (argc, argv, "-s") ||
619 has_param (argc, argv, "--silent"));
620
621 #ifdef MHD_HTTPS_REQUIRE_GRYPT
622#ifdef HAVE_GCRYPT_H
623 gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
624#ifdef GCRYCTL_INITIALIZATION_FINISHED
625 gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
626#endif
627#endif
628#endif /* MHD_HTTPS_REQUIRE_GRYPT */
629 if (0 != curl_global_init (CURL_GLOBAL_WIN32))
630 return 2;
631 errorCount += testBasicAuth ();
632 if (errorCount != 0)
633 fprintf (stderr, "Error (code: %u)\n", errorCount);
634 curl_global_cleanup ();
635 return (0 == errorCount) ? 0 : 1; /* 0 == pass */
636}