aboutsummaryrefslogtreecommitdiff
path: root/src/testzzuf/test_post.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/testzzuf/test_post.c')
-rw-r--r--src/testzzuf/test_post.c416
1 files changed, 0 insertions, 416 deletions
diff --git a/src/testzzuf/test_post.c b/src/testzzuf/test_post.c
deleted file mode 100644
index 895c5fce..00000000
--- a/src/testzzuf/test_post.c
+++ /dev/null
@@ -1,416 +0,0 @@
1/*
2 This file is part of libmicrohttpd
3 Copyright (C) 2007, 2008 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 test_post.c
23 * @brief Testcase for libmicrohttpd POST operations using URL-encoding
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
40#include "socat.c"
41
42#define POST_DATA "name=daniel&project=curl"
43
44static int oneone;
45
46struct CBC
47{
48 char *buf;
49 size_t pos;
50 size_t size;
51};
52
53
54static void
55completed_cb (void *cls,
56 struct MHD_Connection *connection,
57 void **req_cls,
58 enum MHD_RequestTerminationCode toe)
59{
60 struct MHD_PostProcessor *pp = *req_cls;
61 (void) cls; (void) connection; (void) toe; /* Unused. Silent compiler warning. */
62
63 if (NULL != pp)
64 MHD_destroy_post_processor (pp);
65 *req_cls = NULL;
66}
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
81
82/**
83 * Note that this post_iterator is not perfect
84 * in that it fails to support incremental processing.
85 * (to be fixed in the future)
86 */
87static enum MHD_Result
88post_iterator (void *cls,
89 enum MHD_ValueKind kind,
90 const char *key,
91 const char *filename,
92 const char *content_type,
93 const char *transfer_encoding,
94 const char *value, uint64_t off, size_t size)
95{
96 int *eok = cls;
97 (void) kind; (void) filename; (void) content_type; /* Unused. Silent compiler warning. */
98 (void) transfer_encoding; (void) off; /* Unused. Silent compiler warning. */
99
100 if ((0 == strcmp (key, "name")) &&
101 (size == strlen ("daniel")) && (0 == strncmp (value, "daniel", size)))
102 (*eok) |= 1;
103 if ((0 == strcmp (key, "project")) &&
104 (size == strlen ("curl")) && (0 == strncmp (value, "curl", size)))
105 (*eok) |= 2;
106 return MHD_YES;
107}
108
109
110static enum MHD_Result
111ahc_echo (void *cls,
112 struct MHD_Connection *connection,
113 const char *url,
114 const char *method,
115 const char *version,
116 const char *upload_data, size_t *upload_data_size,
117 void **req_cls)
118{
119 static int eok;
120 struct MHD_Response *response;
121 struct MHD_PostProcessor *pp;
122 enum MHD_Result ret;
123 (void) cls; (void) version; /* Unused. Silent compiler warning. */
124
125 if (NULL == url)
126 fprintf (stderr, "The \"url\" parameter is NULL.\n");
127 if (NULL == method)
128 fprintf (stderr, "The \"method\" parameter is NULL.\n");
129 if (NULL == version)
130 fprintf (stderr, "The \"version\" parameter is NULL.\n");
131 if (NULL == upload_data_size)
132 fprintf (stderr, "The \"upload_data_size\" parameter is NULL.\n");
133 if ((0 != *upload_data_size) && (NULL == upload_data))
134 fprintf (stderr, "Upload data is NULL with non-zero size.\n");
135 if (0 != strcmp ("POST", method))
136 {
137 return MHD_NO; /* unexpected method */
138 }
139 pp = *req_cls;
140 if (pp == NULL)
141 {
142 eok = 0;
143 pp = MHD_create_post_processor (connection, 1024, &post_iterator, &eok);
144 *req_cls = pp;
145 }
146 MHD_post_process (pp, upload_data, *upload_data_size);
147 if ((eok == 3) && (0 == *upload_data_size))
148 {
149 response = MHD_create_response_from_buffer (strlen (url),
150 (void *) url,
151 MHD_RESPMEM_MUST_COPY);
152 ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
153 MHD_destroy_response (response);
154 MHD_destroy_post_processor (pp);
155 *req_cls = NULL;
156 return ret;
157 }
158 *upload_data_size = 0;
159 return MHD_YES;
160}
161
162
163static unsigned int
164testInternalPost ()
165{
166 struct MHD_Daemon *d;
167 CURL *c;
168 char buf[2048];
169 struct CBC cbc;
170 int i;
171
172 cbc.buf = buf;
173 cbc.size = 2048;
174 cbc.pos = 0;
175 d =
176 MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD /* | MHD_USE_ERROR_LOG */,
177 11080, NULL, NULL, &ahc_echo, NULL,
178 MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,
179 MHD_OPTION_END);
180 if (d == NULL)
181 return 1;
182 zzuf_socat_start ();
183 for (i = 0; i < LOOP_COUNT; i++)
184 {
185 fprintf (stderr, ".");
186
187 c = curl_easy_init ();
188 curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
189 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
190 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
191 curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA);
192 curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, strlen (POST_DATA));
193 curl_easy_setopt (c, CURLOPT_POST, 1L);
194 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
195 curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
196 if (oneone)
197 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
198 else
199 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
200 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
201 /* NOTE: use of CONNECTTIMEOUT without also
202 * setting NOSIGNAL results in really weird
203 * crashes on my system! */
204 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
205 curl_easy_perform (c);
206 curl_easy_cleanup (c);
207 }
208 fprintf (stderr, "\n");
209 zzuf_socat_stop ();
210 MHD_stop_daemon (d);
211
212 return 0;
213}
214
215
216static unsigned int
217testMultithreadedPost ()
218{
219 struct MHD_Daemon *d;
220 CURL *c;
221 char buf[2048];
222 struct CBC cbc;
223 int i;
224
225 cbc.buf = buf;
226 cbc.size = 2048;
227 cbc.pos = 0;
228 d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
229 | MHD_USE_INTERNAL_POLLING_THREAD /* | MHD_USE_ERROR_LOG */,
230 11080, NULL, NULL, &ahc_echo, NULL,
231 MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,
232 MHD_OPTION_END);
233 if (d == NULL)
234 return 16;
235
236 zzuf_socat_start ();
237 for (i = 0; i < LOOP_COUNT; i++)
238 {
239 fprintf (stderr, ".");
240
241 c = curl_easy_init ();
242 curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
243 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
244 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
245 curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA);
246 curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, strlen (POST_DATA));
247 curl_easy_setopt (c, CURLOPT_POST, 1L);
248 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
249 curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
250 if (oneone)
251 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
252 else
253 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
254 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
255 /* NOTE: use of CONNECTTIMEOUT without also
256 * setting NOSIGNAL results in really weird
257 * crashes on my system! */
258 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
259 curl_easy_perform (c);
260 curl_easy_cleanup (c);
261 }
262 fprintf (stderr, "\n");
263 zzuf_socat_stop ();
264
265 MHD_stop_daemon (d);
266 return 0;
267}
268
269
270static unsigned int
271testExternalPost ()
272{
273 struct MHD_Daemon *d;
274 CURL *c;
275 char buf[2048];
276 struct CBC cbc;
277 CURLM *multi;
278 CURLMcode mret;
279 fd_set rs;
280 fd_set ws;
281 fd_set es;
282 int max;
283 int running;
284 time_t start;
285 struct timeval tv;
286 int i;
287
288 multi = NULL;
289 cbc.buf = buf;
290 cbc.size = 2048;
291 cbc.pos = 0;
292 d = MHD_start_daemon (MHD_NO_FLAG /* | MHD_USE_ERROR_LOG */,
293 1082, NULL, NULL, &ahc_echo, NULL,
294 MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,
295 MHD_OPTION_END);
296 if (d == NULL)
297 return 256;
298 multi = curl_multi_init ();
299 if (multi == NULL)
300 {
301 MHD_stop_daemon (d);
302 return 512;
303 }
304
305 zzuf_socat_start ();
306 for (i = 0; i < LOOP_COUNT; i++)
307 {
308 fprintf (stderr, ".");
309
310
311 c = curl_easy_init ();
312 curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1082/hello_world");
313 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
314 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
315 curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA);
316 curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, strlen (POST_DATA));
317 curl_easy_setopt (c, CURLOPT_POST, 1L);
318 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
319 curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
320 if (oneone)
321 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
322 else
323 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
324 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
325 /* NOTE: use of CONNECTTIMEOUT without also
326 * setting NOSIGNAL results in really weird
327 * crashes on my system! */
328 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
329
330
331 mret = curl_multi_add_handle (multi, c);
332 if (mret != CURLM_OK)
333 {
334 curl_multi_cleanup (multi);
335 curl_easy_cleanup (c);
336 zzuf_socat_stop ();
337 MHD_stop_daemon (d);
338 return 1024;
339 }
340 start = time (NULL);
341 while ((time (NULL) - start < 5) && (c != NULL))
342 {
343 max = 0;
344 FD_ZERO (&rs);
345 FD_ZERO (&ws);
346 FD_ZERO (&es);
347 curl_multi_perform (multi, &running);
348 mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
349 if (mret != CURLM_OK)
350 {
351 curl_multi_remove_handle (multi, c);
352 curl_multi_cleanup (multi);
353 curl_easy_cleanup (c);
354 zzuf_socat_stop ();
355 MHD_stop_daemon (d);
356 return 2048;
357 }
358 if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
359 {
360 curl_multi_remove_handle (multi, c);
361 curl_multi_cleanup (multi);
362 curl_easy_cleanup (c);
363 zzuf_socat_stop ();
364 MHD_stop_daemon (d);
365 return 4096;
366 }
367 tv.tv_sec = 0;
368 tv.tv_usec = 1000;
369 select (max + 1, &rs, &ws, &es, &tv);
370 curl_multi_perform (multi, &running);
371 if (running == 0)
372 {
373 curl_multi_info_read (multi, &running);
374 curl_multi_remove_handle (multi, c);
375 curl_easy_cleanup (c);
376 c = NULL;
377 }
378 MHD_run (d);
379 }
380 if (c != NULL)
381 {
382 curl_multi_remove_handle (multi, c);
383 curl_easy_cleanup (c);
384 }
385
386 }
387 fprintf (stderr, "\n");
388 curl_multi_cleanup (multi);
389 zzuf_socat_stop ();
390
391 MHD_stop_daemon (d);
392 return 0;
393}
394
395
396int
397main (int argc, char *const *argv)
398{
399 unsigned int errorCount = 0;
400 (void) argc; /* Unused. Silent compiler warning. */
401
402 oneone = (NULL != strrchr (argv[0], (int) '/')) ?
403 (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
404 if (0 != curl_global_init (CURL_GLOBAL_WIN32))
405 return 2;
406 if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_THREADS))
407 {
408 errorCount += testInternalPost ();
409 errorCount += testMultithreadedPost ();
410 }
411 errorCount += testExternalPost ();
412 if (errorCount != 0)
413 fprintf (stderr, "Error (code: %u)\n", errorCount);
414 curl_global_cleanup ();
415 return (0 == errorCount) ? 0 : 1; /* 0 == pass */
416}