diff options
author | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2021-04-01 17:52:08 +0300 |
---|---|---|
committer | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2021-04-01 17:52:08 +0300 |
commit | bf25ee3a3220596b83b6530b06d4106f2f0bfda1 (patch) | |
tree | 0174373da1f855a666b0cfe8408af3b187a9d54b /src/testcurl | |
parent | fcca12c2708013aef90efc15e34805a158ce58d6 (diff) | |
download | libmicrohttpd-bf25ee3a3220596b83b6530b06d4106f2f0bfda1.tar.gz libmicrohttpd-bf25ee3a3220596b83b6530b06d4106f2f0bfda1.zip |
Implemented new API function MHD_run_wait().
Diffstat (limited to 'src/testcurl')
-rw-r--r-- | src/testcurl/.gitignore | 2 | ||||
-rw-r--r-- | src/testcurl/Makefile.am | 20 | ||||
-rw-r--r-- | src/testcurl/test_get_wait.c | 238 |
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 | |||
118 | core | 118 | core |
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 += \ | |||
46 | endif | 46 | endif |
47 | 47 | ||
48 | THREAD_ONLY_TESTS += \ | 48 | THREAD_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 | ||
237 | test_get_wait_SOURCES = \ | ||
238 | test_get_wait.c \ | ||
239 | mhd_has_in_name.h | ||
240 | test_get_wait_CFLAGS = \ | ||
241 | $(PTHREAD_CFLAGS) $(AM_CFLAGS) | ||
242 | test_get_wait_LDADD = \ | ||
243 | $(top_builddir)/src/microhttpd/libmicrohttpd.la \ | ||
244 | $(PTHREAD_LIBS) @LIBCURL@ | ||
245 | |||
246 | test_get_wait11_SOURCES = \ | ||
247 | test_get_wait.c \ | ||
248 | mhd_has_in_name.h | ||
249 | test_get_wait11_CFLAGS = \ | ||
250 | $(PTHREAD_CFLAGS) $(AM_CFLAGS) | ||
251 | test_get_wait11_LDADD = \ | ||
252 | $(top_builddir)/src/microhttpd/libmicrohttpd.la \ | ||
253 | $(PTHREAD_LIBS) @LIBCURL@ | ||
254 | |||
235 | test_urlparse_SOURCES = \ | 255 | test_urlparse_SOURCES = \ |
236 | test_urlparse.c mhd_has_in_name.h | 256 | test_urlparse.c mhd_has_in_name.h |
237 | test_urlparse_LDADD = \ | 257 | test_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 | */ | ||
59 | static int oneone; | ||
60 | |||
61 | /** | ||
62 | * Response to return (re-used). | ||
63 | */ | ||
64 | static struct MHD_Response *response; | ||
65 | |||
66 | /** | ||
67 | * Set to 1 if the worker threads are done. | ||
68 | */ | ||
69 | static volatile int signal_done; | ||
70 | |||
71 | |||
72 | static size_t | ||
73 | copyBuffer (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 | |||
82 | static enum MHD_Result | ||
83 | ahc_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 | |||
112 | static void * | ||
113 | thread_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, ©Buffer); | ||
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 | |||
159 | static int | ||
160 | testRunWaitGet (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 | |||
214 | int | ||
215 | main (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 | } | ||