aboutsummaryrefslogtreecommitdiff
path: root/src/testcurl/daemontest_get.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/testcurl/daemontest_get.c')
-rw-r--r--src/testcurl/daemontest_get.c330
1 files changed, 330 insertions, 0 deletions
diff --git a/src/testcurl/daemontest_get.c b/src/testcurl/daemontest_get.c
new file mode 100644
index 00000000..2d5729c1
--- /dev/null
+++ b/src/testcurl/daemontest_get.c
@@ -0,0 +1,330 @@
1/*
2 This file is part of libmicrohttpd
3 (C) 2007 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 daemontest_get.c
23 * @brief Testcase for libmicrohttpd GET operations
24 * TODO: test parsing of query
25 * @author Christian Grothoff
26 */
27
28#include "config.h"
29#include <curl/curl.h>
30#include <microhttpd.h>
31#include <stdlib.h>
32#include <string.h>
33#include <time.h>
34
35#ifndef WINDOWS
36#include <unistd.h>
37#endif
38
39static int oneone;
40
41struct CBC
42{
43 char *buf;
44 size_t pos;
45 size_t size;
46};
47
48static size_t
49copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
50{
51 struct CBC *cbc = ctx;
52
53 if (cbc->pos + size * nmemb > cbc->size)
54 return 0; /* overflow */
55 memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
56 cbc->pos += size * nmemb;
57 return size * nmemb;
58}
59
60static int
61ahc_echo (void *cls,
62 struct MHD_Connection *connection,
63 const char *url,
64 const char *method,
65 const char *version,
66 const char *upload_data, unsigned int *upload_data_size,
67 void **unused)
68{
69 static int ptr;
70 const char *me = cls;
71 struct MHD_Response *response;
72 int ret;
73
74 if (0 != strcmp (me, method))
75 return MHD_NO; /* unexpected method */
76 if (&ptr != *unused)
77 {
78 *unused = &ptr;
79 return MHD_YES;
80 }
81 *unused = NULL;
82 response = MHD_create_response_from_data (strlen (url),
83 (void *) url, MHD_NO, MHD_YES);
84 ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
85 MHD_destroy_response (response);
86 if (ret == MHD_NO)
87 abort ();
88 return ret;
89}
90
91
92static int
93testInternalGet ()
94{
95 struct MHD_Daemon *d;
96 CURL *c;
97 char buf[2048];
98 struct CBC cbc;
99 CURLcode errornum;
100
101 cbc.buf = buf;
102 cbc.size = 2048;
103 cbc.pos = 0;
104 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
105 11080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
106 if (d == NULL)
107 return 1;
108 c = curl_easy_init ();
109 curl_easy_setopt (c, CURLOPT_URL, "http://localhost:11080/hello_world");
110 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
111 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
112 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
113 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
114 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
115 if (oneone)
116 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
117 else
118 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
119 // NOTE: use of CONNECTTIMEOUT without also
120 // setting NOSIGNAL results in really weird
121 // crashes on my system!
122 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
123 if (CURLE_OK != (errornum = curl_easy_perform (c)))
124 {
125 fprintf (stderr,
126 "curl_easy_perform failed: `%s'\n",
127 curl_easy_strerror (errornum));
128 curl_easy_cleanup (c);
129 MHD_stop_daemon (d);
130 return 2;
131 }
132 curl_easy_cleanup (c);
133 MHD_stop_daemon (d);
134 if (cbc.pos != strlen ("/hello_world"))
135 return 4;
136 if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
137 return 8;
138 return 0;
139}
140
141static int
142testMultithreadedGet ()
143{
144 struct MHD_Daemon *d;
145 CURL *c;
146 char buf[2048];
147 struct CBC cbc;
148 CURLcode errornum;
149
150 cbc.buf = buf;
151 cbc.size = 2048;
152 cbc.pos = 0;
153 d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG,
154 1081, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
155 if (d == NULL)
156 return 16;
157 c = curl_easy_init ();
158 curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1081/hello_world");
159 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
160 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
161 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
162 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
163 if (oneone)
164 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
165 else
166 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
167 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
168 // NOTE: use of CONNECTTIMEOUT without also
169 // setting NOSIGNAL results in really weird
170 // crashes on my system!
171 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
172 if (CURLE_OK != (errornum = curl_easy_perform (c)))
173 {
174 fprintf (stderr,
175 "curl_easy_perform failed: `%s'\n",
176 curl_easy_strerror (errornum));
177 curl_easy_cleanup (c);
178 MHD_stop_daemon (d);
179 return 32;
180 }
181 curl_easy_cleanup (c);
182 MHD_stop_daemon (d);
183 if (cbc.pos != strlen ("/hello_world"))
184 return 64;
185 if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
186 return 128;
187 return 0;
188}
189
190
191static int
192testExternalGet ()
193{
194 struct MHD_Daemon *d;
195 CURL *c;
196 char buf[2048];
197 struct CBC cbc;
198 CURLM *multi;
199 CURLMcode mret;
200 fd_set rs;
201 fd_set ws;
202 fd_set es;
203 int max;
204 int running;
205 struct CURLMsg *msg;
206 time_t start;
207 struct timeval tv;
208
209 multi = NULL;
210 cbc.buf = buf;
211 cbc.size = 2048;
212 cbc.pos = 0;
213 d = MHD_start_daemon (MHD_USE_DEBUG,
214 1082, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
215 if (d == NULL)
216 return 256;
217 c = curl_easy_init ();
218 curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1082/hello_world");
219 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
220 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
221 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
222 if (oneone)
223 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
224 else
225 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
226 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
227 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
228 // NOTE: use of CONNECTTIMEOUT without also
229 // setting NOSIGNAL results in really weird
230 // crashes on my system!
231 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
232
233
234 multi = curl_multi_init ();
235 if (multi == NULL)
236 {
237 curl_easy_cleanup (c);
238 MHD_stop_daemon (d);
239 return 512;
240 }
241 mret = curl_multi_add_handle (multi, c);
242 if (mret != CURLM_OK)
243 {
244 curl_multi_cleanup (multi);
245 curl_easy_cleanup (c);
246 MHD_stop_daemon (d);
247 return 1024;
248 }
249 start = time (NULL);
250 while ((time (NULL) - start < 5) && (multi != NULL))
251 {
252 max = 0;
253 FD_ZERO (&rs);
254 FD_ZERO (&ws);
255 FD_ZERO (&es);
256 curl_multi_perform (multi, &running);
257 mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
258 if (mret != CURLM_OK)
259 {
260 curl_multi_remove_handle (multi, c);
261 curl_multi_cleanup (multi);
262 curl_easy_cleanup (c);
263 MHD_stop_daemon (d);
264 return 2048;
265 }
266 if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
267 {
268 curl_multi_remove_handle (multi, c);
269 curl_multi_cleanup (multi);
270 curl_easy_cleanup (c);
271 MHD_stop_daemon (d);
272 return 4096;
273 }
274 tv.tv_sec = 0;
275 tv.tv_usec = 1000;
276 select (max + 1, &rs, &ws, &es, &tv);
277 curl_multi_perform (multi, &running);
278 if (running == 0)
279 {
280 msg = curl_multi_info_read (multi, &running);
281 if (msg == NULL)
282 break;
283 if (msg->msg == CURLMSG_DONE)
284 {
285 if (msg->data.result != CURLE_OK)
286 printf ("%s failed at %s:%d: `%s'\n",
287 "curl_multi_perform",
288 __FILE__,
289 __LINE__, curl_easy_strerror (msg->data.result));
290 curl_multi_remove_handle (multi, c);
291 curl_multi_cleanup (multi);
292 curl_easy_cleanup (c);
293 c = NULL;
294 multi = NULL;
295 }
296 }
297 MHD_run (d);
298 }
299 if (multi != NULL)
300 {
301 curl_multi_remove_handle (multi, c);
302 curl_easy_cleanup (c);
303 curl_multi_cleanup (multi);
304 }
305 MHD_stop_daemon (d);
306 if (cbc.pos != strlen ("/hello_world"))
307 return 8192;
308 if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
309 return 16384;
310 return 0;
311}
312
313
314
315int
316main (int argc, char *const *argv)
317{
318 unsigned int errorCount = 0;
319
320 oneone = NULL != strstr (argv[0], "11");
321 if (0 != curl_global_init (CURL_GLOBAL_WIN32))
322 return 2;
323 errorCount += testInternalGet ();
324 errorCount += testMultithreadedGet ();
325 errorCount += testExternalGet ();
326 if (errorCount != 0)
327 fprintf (stderr, "Error (code: %u)\n", errorCount);
328 curl_global_cleanup ();
329 return errorCount != 0; /* 0 == pass */
330}