1 /*
2 This file is part of libmicrohttpd
3 Copyright (C) 2007, 2009, 2011 Christian Grothoff
4
5 libmicrohttpd is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 libmicrohttpd is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with libmicrohttpd; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
21 /**
22 * @file test_get.c
23 * @brief Testcase for libmicrohttpd GET operations
24 * TODO: test parsing of query
25 * @author Christian Grothoff
26 */
27
28 #include "MHD_config.h"
29 #include "platform.h"
30 #include "platform_interface.h"
31 #include <curl/curl.h>
32 #include <microhttpd.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <time.h>
36
37 #ifdef _WIN32
38 #ifndef WIN32_LEAN_AND_MEAN
39 #define WIN32_LEAN_AND_MEAN 1
40 #endif /* !WIN32_LEAN_AND_MEAN */
41 #include <windows.h>
42 #endif
43
44 #ifndef WINDOWS
45 #include <unistd.h>
46 #include <sys/socket.h>
47 #endif
48
49 #if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
50 #undef CPU_COUNT
51 #endif
52 #if !defined(CPU_COUNT)
53 #define CPU_COUNT 2
54 #endif
55
56 static int oneone;
57
58 struct CBC
59 {
60 char *buf;
61 size_t pos;
62 size_t size;
63 };
64
65 static size_t
copyBuffer(void * ptr,size_t size,size_t nmemb,void * ctx)66 copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
67 {
68 struct CBC *cbc = ctx;
69
70 if (cbc->pos + size * nmemb > cbc->size)
71 return 0; /* overflow */
72 memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
73 cbc->pos += size * nmemb;
74 return size * nmemb;
75 }
76
77 static int
ahc_echo(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 ** unused)78 ahc_echo (void *cls,
79 struct MHD_Connection *connection,
80 const char *url,
81 const char *method,
82 const char *version,
83 const char *upload_data, size_t *upload_data_size,
84 void **unused)
85 {
86 static int ptr;
87 const char *me = cls;
88 struct MHD_Response *response;
89 int ret;
90
91 if (0 != strcmp (me, method))
92 return MHD_NO; /* unexpected method */
93 if (&ptr != *unused)
94 {
95 *unused = &ptr;
96 return MHD_YES;
97 }
98 *unused = NULL;
99 response = MHD_create_response_from_buffer (strlen (url),
100 (void *) url,
101 MHD_RESPMEM_MUST_COPY);
102 ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
103 MHD_destroy_response (response);
104 if (ret == MHD_NO)
105 abort ();
106 return ret;
107 }
108
109
110 static int
testInternalGet(int poll_flag)111 testInternalGet (int poll_flag)
112 {
113 struct MHD_Daemon *d;
114 CURL *c;
115 char buf[2048];
116 struct CBC cbc;
117 CURLcode errornum;
118
119 cbc.buf = buf;
120 cbc.size = 2048;
121 cbc.pos = 0;
122 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG | poll_flag,
123 11080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
124 if (d == NULL)
125 return 1;
126 c = curl_easy_init ();
127 curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11080/hello_world");
128 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
129 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
130 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
131 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
132 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
133 if (oneone)
134 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
135 else
136 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
137 /* NOTE: use of CONNECTTIMEOUT without also
138 setting NOSIGNAL results in really weird
139 crashes on my system!*/
140 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
141 if (CURLE_OK != (errornum = curl_easy_perform (c)))
142 {
143 fprintf (stderr,
144 "curl_easy_perform failed: `%s'\n",
145 curl_easy_strerror (errornum));
146 curl_easy_cleanup (c);
147 MHD_stop_daemon (d);
148 return 2;
149 }
150 curl_easy_cleanup (c);
151 MHD_stop_daemon (d);
152 if (cbc.pos != strlen ("/hello_world"))
153 return 4;
154 if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
155 return 8;
156 return 0;
157 }
158
159
160 static int
testMultithreadedGet(int poll_flag)161 testMultithreadedGet (int poll_flag)
162 {
163 struct MHD_Daemon *d;
164 CURL *c;
165 char buf[2048];
166 struct CBC cbc;
167 CURLcode errornum;
168
169 cbc.buf = buf;
170 cbc.size = 2048;
171 cbc.pos = 0;
172 d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG | poll_flag,
173 1081, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
174 if (d == NULL)
175 return 16;
176 c = curl_easy_init ();
177 curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1081/hello_world");
178 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
179 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
180 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
181 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
182 if (oneone)
183 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
184 else
185 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
186 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
187 /* NOTE: use of CONNECTTIMEOUT without also
188 setting NOSIGNAL results in really weird
189 crashes on my system! */
190 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
191 if (CURLE_OK != (errornum = curl_easy_perform (c)))
192 {
193 fprintf (stderr,
194 "curl_easy_perform failed: `%s'\n",
195 curl_easy_strerror (errornum));
196 curl_easy_cleanup (c);
197 MHD_stop_daemon (d);
198 return 32;
199 }
200 curl_easy_cleanup (c);
201 MHD_stop_daemon (d);
202 if (cbc.pos != strlen ("/hello_world"))
203 return 64;
204 if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
205 return 128;
206 return 0;
207 }
208
209
210 static int
testMultithreadedPoolGet(int poll_flag)211 testMultithreadedPoolGet (int poll_flag)
212 {
213 struct MHD_Daemon *d;
214 CURL *c;
215 char buf[2048];
216 struct CBC cbc;
217 CURLcode errornum;
218
219 cbc.buf = buf;
220 cbc.size = 2048;
221 cbc.pos = 0;
222 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG | poll_flag,
223 1081, NULL, NULL, &ahc_echo, "GET",
224 MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT, MHD_OPTION_END);
225 if (d == NULL)
226 return 16;
227 c = curl_easy_init ();
228 curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1081/hello_world");
229 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
230 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
231 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
232 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
233 if (oneone)
234 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
235 else
236 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
237 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
238 /* NOTE: use of CONNECTTIMEOUT without also
239 setting NOSIGNAL results in really weird
240 crashes on my system!*/
241 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
242 if (CURLE_OK != (errornum = curl_easy_perform (c)))
243 {
244 fprintf (stderr,
245 "curl_easy_perform failed: `%s'\n",
246 curl_easy_strerror (errornum));
247 curl_easy_cleanup (c);
248 MHD_stop_daemon (d);
249 return 32;
250 }
251 curl_easy_cleanup (c);
252 MHD_stop_daemon (d);
253 if (cbc.pos != strlen ("/hello_world"))
254 return 64;
255 if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
256 return 128;
257 return 0;
258 }
259
260
261 static int
testExternalGet()262 testExternalGet ()
263 {
264 struct MHD_Daemon *d;
265 CURL *c;
266 char buf[2048];
267 struct CBC cbc;
268 CURLM *multi;
269 CURLMcode mret;
270 fd_set rs;
271 fd_set ws;
272 fd_set es;
273 MHD_socket max;
274 int running;
275 struct CURLMsg *msg;
276 time_t start;
277 struct timeval tv;
278
279 multi = NULL;
280 cbc.buf = buf;
281 cbc.size = 2048;
282 cbc.pos = 0;
283 d = MHD_start_daemon (MHD_USE_DEBUG,
284 1082, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
285 if (d == NULL)
286 return 256;
287 c = curl_easy_init ();
288 curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1082/hello_world");
289 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
290 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
291 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
292 if (oneone)
293 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
294 else
295 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
296 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
297 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
298 /* NOTE: use of CONNECTTIMEOUT without also
299 setting NOSIGNAL results in really weird
300 crashes on my system! */
301 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
302
303
304 multi = curl_multi_init ();
305 if (multi == NULL)
306 {
307 curl_easy_cleanup (c);
308 MHD_stop_daemon (d);
309 return 512;
310 }
311 mret = curl_multi_add_handle (multi, c);
312 if (mret != CURLM_OK)
313 {
314 curl_multi_cleanup (multi);
315 curl_easy_cleanup (c);
316 MHD_stop_daemon (d);
317 return 1024;
318 }
319 start = time (NULL);
320 while ((time (NULL) - start < 5) && (multi != NULL))
321 {
322 max = 0;
323 FD_ZERO (&rs);
324 FD_ZERO (&ws);
325 FD_ZERO (&es);
326 curl_multi_perform (multi, &running);
327 mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
328 if (mret != CURLM_OK)
329 {
330 curl_multi_remove_handle (multi, c);
331 curl_multi_cleanup (multi);
332 curl_easy_cleanup (c);
333 MHD_stop_daemon (d);
334 return 2048;
335 }
336 if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
337 {
338 curl_multi_remove_handle (multi, c);
339 curl_multi_cleanup (multi);
340 curl_easy_cleanup (c);
341 MHD_stop_daemon (d);
342 return 4096;
343 }
344 tv.tv_sec = 0;
345 tv.tv_usec = 1000;
346 select (max + 1, &rs, &ws, &es, &tv);
347 curl_multi_perform (multi, &running);
348 if (running == 0)
349 {
350 msg = curl_multi_info_read (multi, &running);
351 if (msg == NULL)
352 break;
353 if (msg->msg == CURLMSG_DONE)
354 {
355 if (msg->data.result != CURLE_OK)
356 printf ("%s failed at %s:%d: `%s'\n",
357 "curl_multi_perform",
358 __FILE__,
359 __LINE__, curl_easy_strerror (msg->data.result));
360 curl_multi_remove_handle (multi, c);
361 curl_multi_cleanup (multi);
362 curl_easy_cleanup (c);
363 c = NULL;
364 multi = NULL;
365 }
366 }
367 MHD_run (d);
368 }
369 if (multi != NULL)
370 {
371 curl_multi_remove_handle (multi, c);
372 curl_easy_cleanup (c);
373 curl_multi_cleanup (multi);
374 }
375 MHD_stop_daemon (d);
376 if (cbc.pos != strlen ("/hello_world"))
377 return 8192;
378 if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
379 return 16384;
380 return 0;
381 }
382
383
384 static int
testUnknownPortGet(int poll_flag)385 testUnknownPortGet (int poll_flag)
386 {
387 struct MHD_Daemon *d;
388 const union MHD_DaemonInfo *di;
389 CURL *c;
390 char buf[2048];
391 struct CBC cbc;
392 CURLcode errornum;
393
394 struct sockaddr_in addr;
395 socklen_t addr_len = sizeof(addr);
396 memset(&addr, 0, sizeof(addr));
397 addr.sin_family = AF_INET;
398 addr.sin_port = 0;
399 addr.sin_addr.s_addr = INADDR_ANY;
400
401 cbc.buf = buf;
402 cbc.size = 2048;
403 cbc.pos = 0;
404 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG | poll_flag,
405 1, NULL, NULL, &ahc_echo, "GET",
406 MHD_OPTION_SOCK_ADDR, &addr,
407 MHD_OPTION_END);
408 if (d == NULL)
409 return 32768;
410
411 di = MHD_get_daemon_info (d, MHD_DAEMON_INFO_LISTEN_FD);
412 if (di == NULL)
413 return 65536;
414
415 if (0 != getsockname(di->listen_fd, (struct sockaddr *) &addr, &addr_len))
416 return 131072;
417
418 if (addr.sin_family != AF_INET)
419 return 26214;
420
421 snprintf(buf, sizeof(buf), "http://127.0.0.1:%hu/hello_world",
422 ntohs(addr.sin_port));
423
424 c = curl_easy_init ();
425 curl_easy_setopt (c, CURLOPT_URL, buf);
426 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
427 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
428 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
429 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
430 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
431 if (oneone)
432 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
433 else
434 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
435 /* NOTE: use of CONNECTTIMEOUT without also
436 setting NOSIGNAL results in really weird
437 crashes on my system! */
438 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
439 if (CURLE_OK != (errornum = curl_easy_perform (c)))
440 {
441 fprintf (stderr,
442 "curl_easy_perform failed: `%s'\n",
443 curl_easy_strerror (errornum));
444 curl_easy_cleanup (c);
445 MHD_stop_daemon (d);
446 return 524288;
447 }
448 curl_easy_cleanup (c);
449 MHD_stop_daemon (d);
450 if (cbc.pos != strlen ("/hello_world"))
451 return 1048576;
452 if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
453 return 2097152;
454 return 0;
455 }
456
457
458 static int
testStopRace(int poll_flag)459 testStopRace (int poll_flag)
460 {
461 struct sockaddr_in sin;
462 MHD_socket fd;
463 struct MHD_Daemon *d;
464
465 d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG | poll_flag,
466 1081, NULL, NULL, &ahc_echo, "GET",
467 MHD_OPTION_CONNECTION_TIMEOUT, 5, MHD_OPTION_END);
468 if (d == NULL)
469 return 16;
470
471 fd = socket (PF_INET, SOCK_STREAM, 0);
472 if (fd == MHD_INVALID_SOCKET)
473 {
474 fprintf(stderr, "socket error\n");
475 return 256;
476 }
477
478 memset(&sin, 0, sizeof(sin));
479 sin.sin_family = AF_INET;
480 sin.sin_port = htons(1081);
481 sin.sin_addr.s_addr = htonl(0x7f000001);
482
483 if (connect (fd, (struct sockaddr *)(&sin), sizeof(sin)) < 0)
484 {
485 fprintf(stderr, "connect error\n");
486 MHD_socket_close_ (fd);
487 return 512;
488 }
489
490 /* printf("Waiting\n"); */
491 /* Let the thread get going. */
492 usleep(500000);
493
494 /* printf("Stopping daemon\n"); */
495 MHD_stop_daemon (d);
496
497 MHD_socket_close_ (fd);
498
499 /* printf("good\n"); */
500 return 0;
501 }
502
503
504 static int
ahc_empty(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 ** unused)505 ahc_empty (void *cls,
506 struct MHD_Connection *connection,
507 const char *url,
508 const char *method,
509 const char *version,
510 const char *upload_data, size_t *upload_data_size,
511 void **unused)
512 {
513 static int ptr;
514 struct MHD_Response *response;
515 int ret;
516
517 if (0 != strcmp ("GET", method))
518 return MHD_NO; /* unexpected method */
519 if (&ptr != *unused)
520 {
521 *unused = &ptr;
522 return MHD_YES;
523 }
524 *unused = NULL;
525 response = MHD_create_response_from_buffer (0,
526 NULL,
527 MHD_RESPMEM_PERSISTENT);
528 ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
529 MHD_destroy_response (response);
530 if (ret == MHD_NO)
531 abort ();
532 return ret;
533 }
534
535
536 static int
curlExcessFound(CURL * c,curl_infotype type,char * data,size_t size,void * cls)537 curlExcessFound(CURL *c, curl_infotype type, char *data, size_t size, void *cls)
538 {
539 static const char *excess_found = "Excess found";
540 const size_t str_size = strlen (excess_found);
541
542 if (CURLINFO_TEXT == type
543 && size >= str_size
544 && 0 == strncmp(excess_found, data, str_size))
545 *(int *)cls = 1;
546 return 0;
547 }
548
549
550 static int
testEmptyGet(int poll_flag)551 testEmptyGet (int poll_flag)
552 {
553 struct MHD_Daemon *d;
554 CURL *c;
555 char buf[2048];
556 struct CBC cbc;
557 CURLcode errornum;
558 int excess_found = 0;
559
560 cbc.buf = buf;
561 cbc.size = 2048;
562 cbc.pos = 0;
563 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG | poll_flag,
564 11081, NULL, NULL, &ahc_empty, NULL, MHD_OPTION_END);
565 if (d == NULL)
566 return 4194304;
567 c = curl_easy_init ();
568 curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
569 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
570 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
571 curl_easy_setopt (c, CURLOPT_DEBUGFUNCTION, &curlExcessFound);
572 curl_easy_setopt (c, CURLOPT_DEBUGDATA, &excess_found);
573 curl_easy_setopt (c, CURLOPT_VERBOSE, 1);
574 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
575 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
576 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
577 if (oneone)
578 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
579 else
580 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
581 /* NOTE: use of CONNECTTIMEOUT without also
582 setting NOSIGNAL results in really weird
583 crashes on my system!*/
584 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
585 if (CURLE_OK != (errornum = curl_easy_perform (c)))
586 {
587 fprintf (stderr,
588 "curl_easy_perform failed: `%s'\n",
589 curl_easy_strerror (errornum));
590 curl_easy_cleanup (c);
591 MHD_stop_daemon (d);
592 return 8388608;
593 }
594 curl_easy_cleanup (c);
595 MHD_stop_daemon (d);
596 if (cbc.pos != 0)
597 return 16777216;
598 if (excess_found)
599 return 33554432;
600 return 0;
601 }
602
603
604 int
main(int argc,char * const * argv)605 main (int argc, char *const *argv)
606 {
607 unsigned int errorCount = 0;
608
609 oneone = (NULL != strrchr (argv[0], (int) '/')) ?
610 (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
611 if (0 != curl_global_init (CURL_GLOBAL_WIN32))
612 return 2;
613 errorCount += testInternalGet (0);
614 errorCount += testMultithreadedGet (0);
615 errorCount += testMultithreadedPoolGet (0);
616 errorCount += testUnknownPortGet (0);
617 errorCount += testStopRace (0);
618 errorCount += testExternalGet ();
619 errorCount += testEmptyGet (0);
620 if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_POLL))
621 {
622 errorCount += testInternalGet(MHD_USE_POLL);
623 errorCount += testMultithreadedGet(MHD_USE_POLL);
624 errorCount += testMultithreadedPoolGet(MHD_USE_POLL);
625 errorCount += testUnknownPortGet(MHD_USE_POLL);
626 errorCount += testStopRace(MHD_USE_POLL);
627 errorCount += testEmptyGet(MHD_USE_POLL);
628 }
629 if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_EPOLL))
630 {
631 errorCount += testInternalGet(MHD_USE_EPOLL_LINUX_ONLY);
632 errorCount += testMultithreadedPoolGet(MHD_USE_EPOLL_LINUX_ONLY);
633 errorCount += testUnknownPortGet(MHD_USE_EPOLL_LINUX_ONLY);
634 errorCount += testEmptyGet(MHD_USE_EPOLL_LINUX_ONLY);
635 }
636 if (errorCount != 0)
637 fprintf (stderr, "Error (code: %u)\n", errorCount);
638 curl_global_cleanup ();
639 return errorCount != 0; /* 0 == pass */
640 }
641