aboutsummaryrefslogtreecommitdiff
path: root/src/testcurl
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2021-04-01 17:52:08 +0300
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2021-04-01 17:52:08 +0300
commitbf25ee3a3220596b83b6530b06d4106f2f0bfda1 (patch)
tree0174373da1f855a666b0cfe8408af3b187a9d54b /src/testcurl
parentfcca12c2708013aef90efc15e34805a158ce58d6 (diff)
downloadlibmicrohttpd-bf25ee3a3220596b83b6530b06d4106f2f0bfda1.tar.gz
libmicrohttpd-bf25ee3a3220596b83b6530b06d4106f2f0bfda1.zip
Implemented new API function MHD_run_wait().
Diffstat (limited to 'src/testcurl')
-rw-r--r--src/testcurl/.gitignore2
-rw-r--r--src/testcurl/Makefile.am20
-rw-r--r--src/testcurl/test_get_wait.c238
3 files changed, 260 insertions, 0 deletions
diff --git a/src/testcurl/.gitignore b/src/testcurl/.gitignore
index 008262bd..bbc1b2a9 100644
--- a/src/testcurl/.gitignore
+++ b/src/testcurl/.gitignore
@@ -118,3 +118,5 @@ test_patch11
118core 118core
119/test_get_iovec 119/test_get_iovec
120/test_get_iovec11 120/test_get_iovec11
121/test_get_wait
122/test_get_wait11
diff --git a/src/testcurl/Makefile.am b/src/testcurl/Makefile.am
index d0580554..66aebe3e 100644
--- a/src/testcurl/Makefile.am
+++ b/src/testcurl/Makefile.am
@@ -46,6 +46,8 @@ THREAD_ONLY_TESTS += \
46endif 46endif
47 47
48THREAD_ONLY_TESTS += \ 48THREAD_ONLY_TESTS += \
49 test_get_wait \
50 test_get_wait11 \
49 test_quiesce \ 51 test_quiesce \
50 $(EMPTY_ITEM) 52 $(EMPTY_ITEM)
51 53
@@ -232,6 +234,24 @@ test_get_sendfile_LDADD = \
232 $(top_builddir)/src/microhttpd/libmicrohttpd.la \ 234 $(top_builddir)/src/microhttpd/libmicrohttpd.la \
233 @LIBCURL@ 235 @LIBCURL@
234 236
237test_get_wait_SOURCES = \
238 test_get_wait.c \
239 mhd_has_in_name.h
240test_get_wait_CFLAGS = \
241 $(PTHREAD_CFLAGS) $(AM_CFLAGS)
242test_get_wait_LDADD = \
243 $(top_builddir)/src/microhttpd/libmicrohttpd.la \
244 $(PTHREAD_LIBS) @LIBCURL@
245
246test_get_wait11_SOURCES = \
247 test_get_wait.c \
248 mhd_has_in_name.h
249test_get_wait11_CFLAGS = \
250 $(PTHREAD_CFLAGS) $(AM_CFLAGS)
251test_get_wait11_LDADD = \
252 $(top_builddir)/src/microhttpd/libmicrohttpd.la \
253 $(PTHREAD_LIBS) @LIBCURL@
254
235test_urlparse_SOURCES = \ 255test_urlparse_SOURCES = \
236 test_urlparse.c mhd_has_in_name.h 256 test_urlparse.c mhd_has_in_name.h
237test_urlparse_LDADD = \ 257test_urlparse_LDADD = \
diff --git a/src/testcurl/test_get_wait.c b/src/testcurl/test_get_wait.c
new file mode 100644
index 00000000..cfabd2d1
--- /dev/null
+++ b/src/testcurl/test_get_wait.c
@@ -0,0 +1,238 @@
1/*
2 This file is part of libmicrohttpd
3 Copyright (C) 2007, 2009, 2011 Christian Grothoff
4 Copyright (C) 2016-2021 Karlson2k (Evgeny Grin)
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_get_wait.c
24 * @brief Test 'MHD_run_wait()' function.
25 * @author Christian Grothoff
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#include <pthread.h>
37#include "mhd_has_in_name.h"
38
39#if defined(MHD_CPU_COUNT) && (MHD_CPU_COUNT + 0) < 2
40#undef MHD_CPU_COUNT
41#endif
42#if ! defined(MHD_CPU_COUNT)
43#define MHD_CPU_COUNT 2
44#endif
45
46/**
47 * How many rounds of operations do we do for each
48 * test.
49 * Check all three types of requests for HTTP/1.1:
50 * * first request, new connection;
51 * * "middle" request, existing connection with stay-alive;
52 * * final request, no data processed after.
53 */
54#define ROUNDS 3
55
56/**
57 * Do we use HTTP 1.1?
58 */
59static int oneone;
60
61/**
62 * Response to return (re-used).
63 */
64static struct MHD_Response *response;
65
66/**
67 * Set to 1 if the worker threads are done.
68 */
69static volatile int signal_done;
70
71
72static size_t
73copyBuffer (void *ptr,
74 size_t size, size_t nmemb,
75 void *ctx)
76{
77 (void) ptr; (void) ctx; /* Unused. Silent compiler warning. */
78 return size * nmemb;
79}
80
81
82static enum MHD_Result
83ahc_echo (void *cls,
84 struct MHD_Connection *connection,
85 const char *url,
86 const char *method,
87 const char *version,
88 const char *upload_data, size_t *upload_data_size,
89 void **unused)
90{
91 static int ptr;
92 const char *me = cls;
93 enum MHD_Result ret;
94 (void) url; (void) version; /* Unused. Silent compiler warning. */
95 (void) upload_data; (void) upload_data_size; /* Unused. Silent compiler warning. */
96
97 if (0 != strcmp (me, method))
98 return MHD_NO; /* unexpected method */
99 if (&ptr != *unused)
100 {
101 *unused = &ptr;
102 return MHD_YES;
103 }
104 *unused = NULL;
105 ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
106 if (ret == MHD_NO)
107 abort ();
108 return ret;
109}
110
111
112static void *
113thread_gets (void *param)
114{
115 CURL *c;
116 CURLcode errornum;
117 unsigned int i;
118 char url[64];
119 int port = (int) (intptr_t) param;
120
121 snprintf (url,
122 sizeof (url),
123 "http://127.0.0.1:%d/hello_world",
124 port);
125
126 c = curl_easy_init ();
127 if (NULL == c)
128 _exit (99);
129 curl_easy_setopt (c, CURLOPT_URL, url);
130 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
131 curl_easy_setopt (c, CURLOPT_WRITEDATA, NULL);
132 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
133 curl_easy_setopt (c, CURLOPT_TIMEOUT, 15L);
134 if (oneone)
135 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
136 else
137 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
138 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
139 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
140 for (i = 0; i < ROUNDS; i++)
141 {
142 if (CURLE_OK != (errornum = curl_easy_perform (c)))
143 {
144 signal_done = 1;
145 fprintf (stderr,
146 "curl_easy_perform failed: `%s'\n",
147 curl_easy_strerror (errornum));
148 curl_easy_cleanup (c);
149 abort ();
150 }
151 }
152 curl_easy_cleanup (c);
153 signal_done = 1;
154
155 return NULL;
156}
157
158
159static int
160testRunWaitGet (int port, int poll_flag)
161{
162 pthread_t get_tid;
163 struct MHD_Daemon *d;
164 const char *const test_desc = ((poll_flag & MHD_USE_AUTO) ?
165 "MHD_USE_AUTO" :
166 (poll_flag & MHD_USE_POLL) ?
167 "MHD_USE_POLL" :
168 (poll_flag & MHD_USE_EPOLL) ?
169 "MHD_USE_EPOLL" :
170 "select()");
171
172 if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
173 port = 0;
174
175 printf ("Starting MHD_run_wait() test with MHD in %s polling mode.\n",
176 test_desc);
177 signal_done = 0;
178 d = MHD_start_daemon (MHD_USE_ERROR_LOG | poll_flag,
179 port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
180 if (d == NULL)
181 abort ();
182 if (0 == port)
183 {
184 const union MHD_DaemonInfo *dinfo;
185 dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
186 if ((NULL == dinfo) || (0 == dinfo->port) )
187 abort ();
188 port = (int) dinfo->port;
189 }
190
191 if (0 != pthread_create (&get_tid, NULL,
192 &thread_gets, (void*) (intptr_t) port))
193 _exit (99);
194
195 /* As another thread sets "done" flag after ending of network
196 * activity, it's required to set positive timeout value for MHD_run_wait().
197 * Alternatively, to use timeout value "-1" here, another thread should start
198 * additional connection to wake MHD after setting "done" flag. */
199 do
200 {
201 if (MHD_NO == MHD_run_wait (d, 50))
202 abort ();
203 } while (0 == signal_done);
204
205 if (0 != pthread_join (get_tid, NULL))
206 _exit (99);
207
208 MHD_stop_daemon (d);
209 printf ("Test succeeded.\n");
210 return 0;
211}
212
213
214int
215main (int argc, char *const *argv)
216{
217 int port = 1675;
218 (void) argc; /* Unused. Silent compiler warning. */
219
220 if ((NULL == argv) || (0 == argv[0]))
221 return 99;
222 oneone = has_in_name (argv[0], "11");
223 if (oneone)
224 port += 5;
225 if (0 != curl_global_init (CURL_GLOBAL_WIN32))
226 return 2;
227 response = MHD_create_response_from_buffer (strlen ("/hello_world"),
228 "/hello_world",
229 MHD_RESPMEM_MUST_COPY);
230 testRunWaitGet (port++, 0);
231 if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_EPOLL))
232 testRunWaitGet (port++, MHD_USE_EPOLL);
233 testRunWaitGet (port++, MHD_USE_AUTO);
234
235 MHD_destroy_response (response);
236 curl_global_cleanup ();
237 return 0; /* Errors produce abort() or _exit() */
238}