aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/testcurl/Makefile.am7
-rw-r--r--src/testcurl/test_delete.c458
-rw-r--r--src/testcurl/test_get.c4
-rw-r--r--src/testcurl/test_post.c8
-rw-r--r--src/testcurl/test_put.c2
5 files changed, 472 insertions, 7 deletions
diff --git a/src/testcurl/Makefile.am b/src/testcurl/Makefile.am
index 55f35ee7..80f11d56 100644
--- a/src/testcurl/Makefile.am
+++ b/src/testcurl/Makefile.am
@@ -28,6 +28,7 @@ check_PROGRAMS = \
28 test_get \ 28 test_get \
29 test_get_sendfile \ 29 test_get_sendfile \
30 test_urlparse \ 30 test_urlparse \
31 test_delete \
31 test_put \ 32 test_put \
32 test_process_headers \ 33 test_process_headers \
33 test_process_arguments \ 34 test_process_arguments \
@@ -206,6 +207,12 @@ test_post_loop_LDADD = \
206 $(top_builddir)/src/microhttpd/libmicrohttpd.la \ 207 $(top_builddir)/src/microhttpd/libmicrohttpd.la \
207 @LIBCURL@ 208 @LIBCURL@
208 209
210test_delete_SOURCES = \
211 test_delete.c
212test_delete_LDADD = \
213 $(top_builddir)/src/microhttpd/libmicrohttpd.la \
214 @LIBCURL@
215
209test_put_SOURCES = \ 216test_put_SOURCES = \
210 test_put.c 217 test_put.c
211test_put_LDADD = \ 218test_put_LDADD = \
diff --git a/src/testcurl/test_delete.c b/src/testcurl/test_delete.c
new file mode 100644
index 00000000..22e79fe8
--- /dev/null
+++ b/src/testcurl/test_delete.c
@@ -0,0 +1,458 @@
1/*
2 This file is part of libmicrohttpd
3 Copyright (C) 2007, 2016 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., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file daemontest_delete.c
23 * @brief Testcase for libmicrohttpd DELETE operations
24 * @author Christian Grothoff
25 */
26
27#include "MHD_config.h"
28#include "platform.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
39#if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
40#undef CPU_COUNT
41#endif
42#if !defined(CPU_COUNT)
43#define CPU_COUNT 2
44#endif
45
46static int oneone;
47
48struct CBC
49{
50 char *buf;
51 size_t pos;
52 size_t size;
53};
54
55static size_t
56putBuffer (void *stream, size_t size, size_t nmemb, void *ptr)
57{
58 unsigned int *pos = ptr;
59 unsigned int wrt;
60
61 wrt = size * nmemb;
62 if (wrt > 8 - (*pos))
63 wrt = 8 - (*pos);
64 memcpy (stream, &("Hello123"[*pos]), wrt);
65 (*pos) += wrt;
66 return wrt;
67}
68
69static size_t
70copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
71{
72 struct CBC *cbc = ctx;
73
74 if (cbc->pos + size * nmemb > cbc->size)
75 return 0; /* overflow */
76 memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
77 cbc->pos += size * nmemb;
78 return size * nmemb;
79}
80
81static int
82ahc_echo (void *cls,
83 struct MHD_Connection *connection,
84 const char *url,
85 const char *method,
86 const char *version,
87 const char *upload_data, size_t *upload_data_size,
88 void **unused)
89{
90 int *done = cls;
91 struct MHD_Response *response;
92 int ret;
93
94 if (0 != strcasecmp ("DELETE", method))
95 return MHD_NO; /* unexpected method */
96 if ((*done) == 0)
97 {
98 if (*upload_data_size != 8)
99 return MHD_YES; /* not yet ready */
100 if (0 == memcmp (upload_data, "Hello123", 8))
101 {
102 *upload_data_size = 0;
103 }
104 else
105 {
106 printf ("Invalid upload data `%8s'!\n", upload_data);
107 return MHD_NO;
108 }
109 *done = 1;
110 return MHD_YES;
111 }
112 response = MHD_create_response_from_buffer (strlen (url), (void*) url,
113 MHD_RESPMEM_MUST_COPY);
114 ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
115 MHD_destroy_response (response);
116 return ret;
117}
118
119
120static int
121testInternalDelete ()
122{
123 struct MHD_Daemon *d;
124 CURL *c;
125 char buf[2048];
126 struct CBC cbc;
127 unsigned int pos = 0;
128 int done_flag = 0;
129 CURLcode errornum;
130
131 cbc.buf = buf;
132 cbc.size = 2048;
133 cbc.pos = 0;
134 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
135 1080,
136 NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END);
137 if (d == NULL)
138 return 1;
139 c = curl_easy_init ();
140 curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1080/hello_world");
141 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
142 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
143 curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
144 curl_easy_setopt (c, CURLOPT_READDATA, &pos);
145 curl_easy_setopt (c, CURLOPT_CUSTOMREQUEST, "DELETE");
146 curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
147 curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
148 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
149 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
150 if (oneone)
151 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
152 else
153 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
154 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
155 // NOTE: use of CONNECTTIMEOUT without also
156 // setting NOSIGNAL results in really weird
157 // crashes on my system!
158 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
159 if (CURLE_OK != (errornum = curl_easy_perform (c)))
160 {
161 fprintf (stderr,
162 "curl_easy_perform failed: `%s'\n",
163 curl_easy_strerror (errornum));
164 curl_easy_cleanup (c);
165 MHD_stop_daemon (d);
166 return 2;
167 }
168 curl_easy_cleanup (c);
169 MHD_stop_daemon (d);
170 if (cbc.pos != strlen ("/hello_world"))
171 return 4;
172 if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
173 return 8;
174 return 0;
175}
176
177
178static int
179testMultithreadedDelete ()
180{
181 struct MHD_Daemon *d;
182 CURL *c;
183 char buf[2048];
184 struct CBC cbc;
185 unsigned int pos = 0;
186 int done_flag = 0;
187 CURLcode errornum;
188
189 cbc.buf = buf;
190 cbc.size = 2048;
191 cbc.pos = 0;
192 d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG,
193 1081,
194 NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END);
195 if (d == NULL)
196 return 16;
197 c = curl_easy_init ();
198 curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1081/hello_world");
199 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
200 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
201 curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
202 curl_easy_setopt (c, CURLOPT_READDATA, &pos);
203 curl_easy_setopt (c, CURLOPT_CUSTOMREQUEST, "DELETE");
204 curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
205 curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
206 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
207 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
208 if (oneone)
209 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
210 else
211 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
212 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
213 // NOTE: use of CONNECTTIMEOUT without also
214 // setting NOSIGNAL results in really weird
215 // crashes on my system!
216 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
217 if (CURLE_OK != (errornum = curl_easy_perform (c)))
218 {
219 fprintf (stderr,
220 "curl_easy_perform failed: `%s'\n",
221 curl_easy_strerror (errornum));
222 curl_easy_cleanup (c);
223 MHD_stop_daemon (d);
224 return 32;
225 }
226 curl_easy_cleanup (c);
227 MHD_stop_daemon (d);
228 if (cbc.pos != strlen ("/hello_world"))
229 return 64;
230 if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
231 return 128;
232
233 return 0;
234}
235
236static int
237testMultithreadedPoolDelete ()
238{
239 struct MHD_Daemon *d;
240 CURL *c;
241 char buf[2048];
242 struct CBC cbc;
243 unsigned int pos = 0;
244 int done_flag = 0;
245 CURLcode errornum;
246
247 cbc.buf = buf;
248 cbc.size = 2048;
249 cbc.pos = 0;
250 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
251 1081,
252 NULL, NULL, &ahc_echo, &done_flag,
253 MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT, MHD_OPTION_END);
254 if (d == NULL)
255 return 16;
256 c = curl_easy_init ();
257 curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1081/hello_world");
258 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
259 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
260 curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
261 curl_easy_setopt (c, CURLOPT_READDATA, &pos);
262 curl_easy_setopt (c, CURLOPT_CUSTOMREQUEST, "DELETE");
263 curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
264 curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
265 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
266 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
267 if (oneone)
268 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
269 else
270 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
271 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
272 // NOTE: use of CONNECTTIMEOUT without also
273 // setting NOSIGNAL results in really weird
274 // crashes on my system!
275 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
276 if (CURLE_OK != (errornum = curl_easy_perform (c)))
277 {
278 fprintf (stderr,
279 "curl_easy_perform failed: `%s'\n",
280 curl_easy_strerror (errornum));
281 curl_easy_cleanup (c);
282 MHD_stop_daemon (d);
283 return 32;
284 }
285 curl_easy_cleanup (c);
286 MHD_stop_daemon (d);
287 if (cbc.pos != strlen ("/hello_world"))
288 return 64;
289 if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
290 return 128;
291
292 return 0;
293}
294
295
296static int
297testExternalDelete ()
298{
299 struct MHD_Daemon *d;
300 CURL *c;
301 char buf[2048];
302 struct CBC cbc;
303 CURLM *multi;
304 CURLMcode mret;
305 fd_set rs;
306 fd_set ws;
307 fd_set es;
308 MHD_socket maxsock;
309#ifdef MHD_WINSOCK_SOCKETS
310 int maxposixs; /* Max socket number unused on W32 */
311#else /* MHD_POSIX_SOCKETS */
312#define maxposixs maxsock
313#endif /* MHD_POSIX_SOCKETS */
314 int running;
315 struct CURLMsg *msg;
316 time_t start;
317 struct timeval tv;
318 unsigned int pos = 0;
319 int done_flag = 0;
320
321 multi = NULL;
322 cbc.buf = buf;
323 cbc.size = 2048;
324 cbc.pos = 0;
325 d = MHD_start_daemon (MHD_USE_DEBUG,
326 1082,
327 NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END);
328 if (d == NULL)
329 return 256;
330 c = curl_easy_init ();
331 curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1082/hello_world");
332 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
333 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
334 curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
335 curl_easy_setopt (c, CURLOPT_READDATA, &pos);
336 curl_easy_setopt (c, CURLOPT_CUSTOMREQUEST, "DELETE");
337 curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
338 curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
339 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
340 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
341 if (oneone)
342 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
343 else
344 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
345 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
346 // NOTE: use of CONNECTTIMEOUT without also
347 // setting NOSIGNAL results in really weird
348 // crashes on my system!
349 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
350
351
352 multi = curl_multi_init ();
353 if (multi == NULL)
354 {
355 curl_easy_cleanup (c);
356 MHD_stop_daemon (d);
357 return 512;
358 }
359 mret = curl_multi_add_handle (multi, c);
360 if (mret != CURLM_OK)
361 {
362 curl_multi_cleanup (multi);
363 curl_easy_cleanup (c);
364 MHD_stop_daemon (d);
365 return 1024;
366 }
367 start = time (NULL);
368 while ((time (NULL) - start < 5) && (multi != NULL))
369 {
370 maxsock = MHD_INVALID_SOCKET;
371 maxposixs = -1;
372 FD_ZERO (&rs);
373 FD_ZERO (&ws);
374 FD_ZERO (&es);
375 curl_multi_perform (multi, &running);
376 mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
377 if (mret != CURLM_OK)
378 {
379 curl_multi_remove_handle (multi, c);
380 curl_multi_cleanup (multi);
381 curl_easy_cleanup (c);
382 MHD_stop_daemon (d);
383 return 2048;
384 }
385 if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
386 {
387 curl_multi_remove_handle (multi, c);
388 curl_multi_cleanup (multi);
389 curl_easy_cleanup (c);
390 MHD_stop_daemon (d);
391 return 4096;
392 }
393 tv.tv_sec = 0;
394 tv.tv_usec = 1000;
395 if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
396 {
397 if (EINTR != errno)
398 abort ();
399 }
400 curl_multi_perform (multi, &running);
401 if (running == 0)
402 {
403 msg = curl_multi_info_read (multi, &running);
404 if (msg == NULL)
405 break;
406 if (msg->msg == CURLMSG_DONE)
407 {
408 if (msg->data.result != CURLE_OK)
409 printf ("%s failed at %s:%d: `%s'\n",
410 "curl_multi_perform",
411 __FILE__,
412 __LINE__, curl_easy_strerror (msg->data.result));
413 curl_multi_remove_handle (multi, c);
414 curl_multi_cleanup (multi);
415 curl_easy_cleanup (c);
416 c = NULL;
417 multi = NULL;
418 }
419 }
420 MHD_run (d);
421 }
422 if (multi != NULL)
423 {
424 curl_multi_remove_handle (multi, c);
425 curl_easy_cleanup (c);
426 curl_multi_cleanup (multi);
427 }
428 MHD_stop_daemon (d);
429 if (cbc.pos != strlen ("/hello_world"))
430 return 8192;
431 if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
432 return 16384;
433 return 0;
434}
435
436
437
438int
439main (int argc, char *const *argv)
440{
441 unsigned int errorCount = 0;
442
443 oneone = (NULL != strrchr (argv[0], (int) '/')) ?
444 (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
445 if (0 != curl_global_init (CURL_GLOBAL_WIN32))
446 return 2;
447 if (0)
448 {
449 errorCount += testInternalDelete ();
450 errorCount += testMultithreadedDelete ();
451 errorCount += testMultithreadedPoolDelete ();
452 }
453 errorCount += testExternalDelete ();
454 if (errorCount != 0)
455 fprintf (stderr, "Error (code: %u)\n", errorCount);
456 curl_global_cleanup ();
457 return errorCount != 0; /* 0 == pass */
458}
diff --git a/src/testcurl/test_get.c b/src/testcurl/test_get.c
index 6b21aa9e..abcd848b 100644
--- a/src/testcurl/test_get.c
+++ b/src/testcurl/test_get.c
@@ -96,7 +96,7 @@ ahc_echo (void *cls,
96 struct MHD_Response *response; 96 struct MHD_Response *response;
97 int ret; 97 int ret;
98 98
99 if (0 != strcmp (me, method)) 99 if (0 != strcasecmp (me, method))
100 return MHD_NO; /* unexpected method */ 100 return MHD_NO; /* unexpected method */
101 if (&ptr != *unused) 101 if (&ptr != *unused)
102 { 102 {
@@ -532,7 +532,7 @@ ahc_empty (void *cls,
532 struct MHD_Response *response; 532 struct MHD_Response *response;
533 int ret; 533 int ret;
534 534
535 if (0 != strcmp ("GET", method)) 535 if (0 != strcasecmp ("GET", method))
536 return MHD_NO; /* unexpected method */ 536 return MHD_NO; /* unexpected method */
537 if (&ptr != *unused) 537 if (&ptr != *unused)
538 { 538 {
diff --git a/src/testcurl/test_post.c b/src/testcurl/test_post.c
index 291c5ce3..18ad0499 100644
--- a/src/testcurl/test_post.c
+++ b/src/testcurl/test_post.c
@@ -105,10 +105,10 @@ post_iterator (void *cls,
105{ 105{
106 int *eok = cls; 106 int *eok = cls;
107 107
108 if ((0 == strcmp (key, "name")) && 108 if ((0 == strcasecmp (key, "name")) &&
109 (size == strlen ("daniel")) && (0 == strncmp (value, "daniel", size))) 109 (size == strlen ("daniel")) && (0 == strncmp (value, "daniel", size)))
110 (*eok) |= 1; 110 (*eok) |= 1;
111 if ((0 == strcmp (key, "project")) && 111 if ((0 == strcasecmp (key, "project")) &&
112 (size == strlen ("curl")) && (0 == strncmp (value, "curl", size))) 112 (size == strlen ("curl")) && (0 == strncmp (value, "curl", size)))
113 (*eok) |= 2; 113 (*eok) |= 2;
114 return MHD_YES; 114 return MHD_YES;
@@ -129,7 +129,7 @@ ahc_echo (void *cls,
129 struct MHD_PostProcessor *pp; 129 struct MHD_PostProcessor *pp;
130 int ret; 130 int ret;
131 131
132 if (0 != strcmp ("POST", method)) 132 if (0 != strcasecmp ("POST", method))
133 { 133 {
134 printf ("METHOD: %s\n", method); 134 printf ("METHOD: %s\n", method);
135 return MHD_NO; /* unexpected method */ 135 return MHD_NO; /* unexpected method */
@@ -470,7 +470,7 @@ ahc_cancel (void *cls,
470 struct MHD_Response *response; 470 struct MHD_Response *response;
471 int ret; 471 int ret;
472 472
473 if (0 != strcmp ("POST", method)) 473 if (0 != strcasecmp ("POST", method))
474 { 474 {
475 fprintf (stderr, 475 fprintf (stderr,
476 "Unexpected method `%s'\n", method); 476 "Unexpected method `%s'\n", method);
diff --git a/src/testcurl/test_put.c b/src/testcurl/test_put.c
index d32c0af1..f6636f12 100644
--- a/src/testcurl/test_put.c
+++ b/src/testcurl/test_put.c
@@ -91,7 +91,7 @@ ahc_echo (void *cls,
91 struct MHD_Response *response; 91 struct MHD_Response *response;
92 int ret; 92 int ret;
93 93
94 if (0 != strcmp ("PUT", method)) 94 if (0 != strcasecmp ("PUT", method))
95 return MHD_NO; /* unexpected method */ 95 return MHD_NO; /* unexpected method */
96 if ((*done) == 0) 96 if ((*done) == 0)
97 { 97 {