aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/daemon/daemon.c131
-rw-r--r--src/daemon/internal.h10
-rw-r--r--src/include/microhttpd.h11
-rw-r--r--src/testcurl/daemontest_get.c50
-rw-r--r--src/testcurl/daemontest_get_chunked.c43
-rw-r--r--src/testcurl/daemontest_iplimit.c99
-rw-r--r--src/testcurl/daemontest_large_put.c60
-rw-r--r--src/testcurl/daemontest_post.c53
-rw-r--r--src/testcurl/daemontest_post_loop.c65
-rw-r--r--src/testcurl/daemontest_postform.c55
-rw-r--r--src/testcurl/daemontest_process_headers.c50
-rw-r--r--src/testcurl/daemontest_put.c59
-rw-r--r--src/testcurl/daemontest_put_chunked.c59
13 files changed, 738 insertions, 7 deletions
diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c
index 3c90f5b4..18775c46 100644
--- a/src/daemon/daemon.c
+++ b/src/daemon/daemon.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of libmicrohttpd 2 This file is part of libmicrohttpd
3 (C) 2007, 2008 Daniel Pittman and Christian Grothoff 3 (C) 2007, 2008, 2009 Daniel Pittman and Christian Grothoff
4 4
5 This library is free software; you can redistribute it and/or 5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public 6 modify it under the terms of the GNU Lesser General Public
@@ -187,8 +187,8 @@ MHD_ip_limit_add(struct MHD_Daemon *daemon,
187 if (daemon->per_ip_connection_limit == 0) 187 if (daemon->per_ip_connection_limit == 0)
188 return MHD_YES; 188 return MHD_YES;
189 189
190 key = (struct MHD_IPCount*) malloc (sizeof(*key)); 190 key = malloc (sizeof(*key));
191 if (!key) 191 if (NULL == key)
192 return MHD_NO; 192 return MHD_NO;
193 193
194 /* Initialize key */ 194 /* Initialize key */
@@ -625,7 +625,7 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
625#endif 625#endif
626#endif 626#endif
627 connection = malloc (sizeof (struct MHD_Connection)); 627 connection = malloc (sizeof (struct MHD_Connection));
628 if (connection == NULL) 628 if (NULL == connection)
629 { 629 {
630#if HAVE_MESSAGES 630#if HAVE_MESSAGES
631 MHD_DLOG (daemon, "Error allocating memory: %s\n", STRERROR (errno)); 631 MHD_DLOG (daemon, "Error allocating memory: %s\n", STRERROR (errno));
@@ -1017,6 +1017,7 @@ MHD_start_daemon_va (unsigned int options,
1017 const struct sockaddr *servaddr = NULL; 1017 const struct sockaddr *servaddr = NULL;
1018 socklen_t addrlen; 1018 socklen_t addrlen;
1019 enum MHD_OPTION opt; 1019 enum MHD_OPTION opt;
1020 unsigned int i;
1020 1021
1021 if ((port == 0) || (dh == NULL)) 1022 if ((port == 0) || (dh == NULL))
1022 return NULL; 1023 return NULL;
@@ -1080,6 +1081,9 @@ MHD_start_daemon_va (unsigned int options,
1080 va_arg (ap, LogCallback); 1081 va_arg (ap, LogCallback);
1081 retVal->uri_log_callback_cls = va_arg (ap, void *); 1082 retVal->uri_log_callback_cls = va_arg (ap, void *);
1082 break; 1083 break;
1084 case MHD_OPTION_THREAD_POOL_SIZE:
1085 retVal->worker_pool_size = va_arg (ap, unsigned int);
1086 break;
1083#if HTTPS_SUPPORT 1087#if HTTPS_SUPPORT
1084 case MHD_OPTION_PROTOCOL_VERSION: 1088 case MHD_OPTION_PROTOCOL_VERSION:
1085 _set_priority (&retVal->priority_cache->protocol, 1089 _set_priority (&retVal->priority_cache->protocol,
@@ -1126,6 +1130,17 @@ MHD_start_daemon_va (unsigned int options,
1126 } 1130 }
1127 } 1131 }
1128 1132
1133 /* Thread pooling currently works only with internal select thread model */
1134 if ((0 == (options & MHD_USE_SELECT_INTERNALLY))
1135 && (retVal->worker_pool_size > 0))
1136 {
1137#if HAVE_MESSAGES
1138 FPRINTF (stderr,
1139 "MHD thread pooling only works with MHD_USE_SELECT_INTERNALLY\n");
1140#endif
1141 return NULL;
1142 }
1143
1129 if ((options & MHD_USE_IPv6) != 0) 1144 if ((options & MHD_USE_IPv6) != 0)
1130#if HAVE_INET6 1145#if HAVE_INET6
1131 socket_fd = SOCKET (PF_INET6, SOCK_STREAM, 0); 1146 socket_fd = SOCKET (PF_INET6, SOCK_STREAM, 0);
@@ -1235,7 +1250,8 @@ MHD_start_daemon_va (unsigned int options,
1235 } 1250 }
1236#endif 1251#endif
1237 if (((0 != (options & MHD_USE_THREAD_PER_CONNECTION)) || 1252 if (((0 != (options & MHD_USE_THREAD_PER_CONNECTION)) ||
1238 (0 != (options & MHD_USE_SELECT_INTERNALLY))) 1253 ((0 != (options & MHD_USE_SELECT_INTERNALLY))
1254 && (0 == retVal->worker_pool_size)))
1239 && (0 != 1255 && (0 !=
1240 pthread_create (&retVal->pid, NULL, &MHD_select_thread, retVal))) 1256 pthread_create (&retVal->pid, NULL, &MHD_select_thread, retVal)))
1241 { 1257 {
@@ -1248,6 +1264,87 @@ MHD_start_daemon_va (unsigned int options,
1248 CLOSE (socket_fd); 1264 CLOSE (socket_fd);
1249 return NULL; 1265 return NULL;
1250 } 1266 }
1267 else if (retVal->worker_pool_size > 0)
1268 {
1269 /* Coarse-grained count of connections per thread (note error
1270 * due to integer division). Also keep track of how many
1271 * connections are leftover after an equal split. */
1272 unsigned int conns_per_thread = retVal->max_connections
1273 / retVal->worker_pool_size;
1274 unsigned int leftover_conns = retVal->max_connections
1275 % retVal->worker_pool_size;
1276
1277 /* Allocate memory for pooled objects */
1278 retVal->worker_pool = malloc (sizeof (*retVal->worker_pool)
1279 * retVal->worker_pool_size);
1280
1281 /* Start the workers in the pool */
1282 for (i = 0; i < retVal->worker_pool_size; ++i)
1283 {
1284 /* Create copy of the Daemon object for each worker */
1285 struct MHD_Daemon *d = (struct MHD_Daemon*) malloc (sizeof (*d));
1286 if (!d)
1287 {
1288#if HAVE_MESSAGES
1289 MHD_DLOG (retVal,
1290 "Failed to copy daemon object: %d\n", STRERROR (errno));
1291#endif
1292 goto thread_failed;
1293 }
1294 memcpy (d, retVal, sizeof (*d));
1295
1296 /* Adjust pooling params for worker daemons; note that memcpy()
1297 * has already copied MHD_USE_SELECT_INTERNALLY thread model into
1298 * the worker threads. */
1299 d->master = retVal;
1300 d->worker_pool_size = 0;
1301 d->worker_pool = NULL;
1302
1303 /* Divide available connections evenly amongst the threads.
1304 * Thread indexes in [0, leftover_conns) each get one of the
1305 * leftover connections. */
1306 d->max_connections = conns_per_thread;
1307 if (i < leftover_conns)
1308 ++d->max_connections;
1309
1310 /* Spawn the worker thread */
1311 if (0 != pthread_create (&d->pid, NULL, &MHD_select_thread, d))
1312 {
1313#if HAVE_MESSAGES
1314 MHD_DLOG (retVal,
1315 "Failed to create pool thread: %d\n", STRERROR (errno));
1316#endif
1317 /* Free memory for this worker; cleanup below handles
1318 * all previously-created workers. */
1319 free (d);
1320 goto thread_failed;
1321 }
1322
1323 retVal->worker_pool[i] = d;
1324 continue;
1325
1326thread_failed:
1327 /* If no worker threads created, then shut down normally. Calling
1328 * MHD_stop_daemon (as we do below) doesn't work here since it
1329 * assumes a 0-sized thread pool means we had been in the default
1330 * MHD_USE_SELECT_INTERNALLY mode. */
1331 if (i == 0)
1332 {
1333 CLOSE (socket_fd);
1334 pthread_mutex_destroy (&retVal->per_ip_connection_mutex);
1335 free (retVal);
1336 return NULL;
1337 }
1338
1339 /* Shutdown worker threads we've already created. Pretend
1340 * as though we had fully initialized our daemon, but
1341 * with a smaller number of threads than had been
1342 * requested. */
1343 retVal->worker_pool_size = i - 1;
1344 MHD_stop_daemon (retVal);
1345 return NULL;
1346 }
1347 }
1251 return retVal; 1348 return retVal;
1252} 1349}
1253 1350
@@ -1281,20 +1378,42 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
1281{ 1378{
1282 void *unused; 1379 void *unused;
1283 int fd; 1380 int fd;
1381 unsigned int i;
1284 1382
1285 if (daemon == NULL) 1383 if (daemon == NULL)
1286 return; 1384 return;
1287 daemon->shutdown = MHD_YES; 1385 daemon->shutdown = MHD_YES;
1288 fd = daemon->socket_fd; 1386 fd = daemon->socket_fd;
1289 daemon->socket_fd = -1; 1387 daemon->socket_fd = -1;
1388
1389 /* Prepare workers for shutdown */
1390 for (i = 0; i < daemon->worker_pool_size; ++i)
1391 {
1392 daemon->worker_pool[i]->shutdown = MHD_YES;
1393 daemon->worker_pool[i]->socket_fd = -1;
1394 }
1395
1290#if DEBUG_CLOSE 1396#if DEBUG_CLOSE
1291#if HAVE_MESSAGES 1397#if HAVE_MESSAGES
1292 MHD_DLOG (daemon, "MHD shutdown, closing listen socket\n"); 1398 MHD_DLOG (daemon, "MHD shutdown, closing listen socket\n");
1293#endif 1399#endif
1294#endif 1400#endif
1295 CLOSE (fd); 1401 CLOSE (fd);
1402
1403 /* Signal workers to stop and clean them up */
1404 for (i = 0; i < daemon->worker_pool_size; ++i)
1405 pthread_kill (daemon->worker_pool[i]->pid, SIGALRM);
1406 for (i = 0; i < daemon->worker_pool_size; ++i)
1407 {
1408 pthread_join (daemon->worker_pool[i]->pid, &unused);
1409 MHD_close_connections (daemon->worker_pool[i]);
1410 free (daemon->worker_pool[i]);
1411 }
1412 free (daemon->worker_pool);
1413
1296 if ((0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || 1414 if ((0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ||
1297 (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY))) 1415 ((0 != (daemon->options & MHD_USE_SELECT_INTERNALLY))
1416 && (0 == daemon->worker_pool_size)))
1298 { 1417 {
1299 pthread_kill (daemon->pid, SIGALRM); 1418 pthread_kill (daemon->pid, SIGALRM);
1300 pthread_join (daemon->pid, &unused); 1419 pthread_join (daemon->pid, &unused);
diff --git a/src/daemon/internal.h b/src/daemon/internal.h
index d739c369..fcc1fd57 100644
--- a/src/daemon/internal.h
+++ b/src/daemon/internal.h
@@ -775,6 +775,16 @@ struct MHD_Daemon
775 * Pointer to master daemon (NULL if this is the master) 775 * Pointer to master daemon (NULL if this is the master)
776 */ 776 */
777 struct MHD_Daemon *master; 777 struct MHD_Daemon *master;
778
779 /**
780 * Worker daemons (one per thread)
781 */
782 struct MHD_Daemon **worker_pool;
783
784 /**
785 * Number of worker daemons
786 */
787 unsigned int worker_pool_size;
778}; 788};
779 789
780 790
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
index 8ac88a78..34ce1d98 100644
--- a/src/include/microhttpd.h
+++ b/src/include/microhttpd.h
@@ -429,8 +429,17 @@ enum MHD_OPTION
429 * if it was compiled without the "--enable-messages" 429 * if it was compiled without the "--enable-messages"
430 * flag being set. 430 * flag being set.
431 */ 431 */
432 MHD_OPTION_EXTERNAL_LOGGER = 13 432 MHD_OPTION_EXTERNAL_LOGGER = 13,
433 433
434 /**
435 * Number (unsigned int) of threads in thread pool. Enable
436 * thread pooling by setting this value to to something
437 * greater than 1. Currently, thread model must be
438 * MHD_USE_SELECT_INTERNALLY if thread pooling is enabled
439 * (MHD_start_daemon returns NULL for an unsupported thread
440 * model).
441 */
442 MHD_OPTION_THREAD_POOL_SIZE = 14,
434}; 443};
435 444
436/** 445/**
diff --git a/src/testcurl/daemontest_get.c b/src/testcurl/daemontest_get.c
index 94b15774..acf2bcc1 100644
--- a/src/testcurl/daemontest_get.c
+++ b/src/testcurl/daemontest_get.c
@@ -188,6 +188,55 @@ testMultithreadedGet ()
188 return 0; 188 return 0;
189} 189}
190 190
191static int
192testMultithreadedPoolGet ()
193{
194 struct MHD_Daemon *d;
195 CURL *c;
196 char buf[2048];
197 struct CBC cbc;
198 CURLcode errornum;
199
200 cbc.buf = buf;
201 cbc.size = 2048;
202 cbc.pos = 0;
203 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
204 1081, NULL, NULL, &ahc_echo, "GET",
205 MHD_OPTION_THREAD_POOL_SIZE, 4, MHD_OPTION_END);
206 if (d == NULL)
207 return 16;
208 c = curl_easy_init ();
209 curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1081/hello_world");
210 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
211 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
212 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
213 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
214 if (oneone)
215 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
216 else
217 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
218 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
219 // NOTE: use of CONNECTTIMEOUT without also
220 // setting NOSIGNAL results in really weird
221 // crashes on my system!
222 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
223 if (CURLE_OK != (errornum = curl_easy_perform (c)))
224 {
225 fprintf (stderr,
226 "curl_easy_perform failed: `%s'\n",
227 curl_easy_strerror (errornum));
228 curl_easy_cleanup (c);
229 MHD_stop_daemon (d);
230 return 32;
231 }
232 curl_easy_cleanup (c);
233 MHD_stop_daemon (d);
234 if (cbc.pos != strlen ("/hello_world"))
235 return 64;
236 if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
237 return 128;
238 return 0;
239}
191 240
192static int 241static int
193testExternalGet () 242testExternalGet ()
@@ -323,6 +372,7 @@ main (int argc, char *const *argv)
323 return 2; 372 return 2;
324 errorCount += testInternalGet (); 373 errorCount += testInternalGet ();
325 errorCount += testMultithreadedGet (); 374 errorCount += testMultithreadedGet ();
375 errorCount += testMultithreadedPoolGet ();
326 errorCount += testExternalGet (); 376 errorCount += testExternalGet ();
327 if (errorCount != 0) 377 if (errorCount != 0)
328 fprintf (stderr, "Error (code: %u)\n", errorCount); 378 fprintf (stderr, "Error (code: %u)\n", errorCount);
diff --git a/src/testcurl/daemontest_get_chunked.c b/src/testcurl/daemontest_get_chunked.c
index 794430e8..da11e90c 100644
--- a/src/testcurl/daemontest_get_chunked.c
+++ b/src/testcurl/daemontest_get_chunked.c
@@ -227,6 +227,48 @@ testMultithreadedGet ()
227 return validate (cbc, 64); 227 return validate (cbc, 64);
228} 228}
229 229
230static int
231testMultithreadedPoolGet ()
232{
233 struct MHD_Daemon *d;
234 CURL *c;
235 char buf[2048];
236 struct CBC cbc;
237 CURLcode errornum;
238
239 cbc.buf = buf;
240 cbc.size = 2048;
241 cbc.pos = 0;
242 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
243 1081, NULL, NULL, &ahc_echo, "GET",
244 MHD_OPTION_THREAD_POOL_SIZE, 4, MHD_OPTION_END);
245 if (d == NULL)
246 return 16;
247 c = curl_easy_init ();
248 curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1081/hello_world");
249 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
250 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
251 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
252 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
253 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
254 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
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, 1);
259 if (CURLE_OK != (errornum = curl_easy_perform (c)))
260 {
261 fprintf (stderr,
262 "curl_easy_perform failed: `%s'\n",
263 curl_easy_strerror (errornum));
264 curl_easy_cleanup (c);
265 MHD_stop_daemon (d);
266 return 32;
267 }
268 curl_easy_cleanup (c);
269 MHD_stop_daemon (d);
270 return validate (cbc, 64);
271}
230 272
231static int 273static int
232testExternalGet () 274testExternalGet ()
@@ -354,6 +396,7 @@ main (int argc, char *const *argv)
354 return 2; 396 return 2;
355 errorCount += testInternalGet (); 397 errorCount += testInternalGet ();
356 errorCount += testMultithreadedGet (); 398 errorCount += testMultithreadedGet ();
399 errorCount += testMultithreadedPoolGet ();
357 errorCount += testExternalGet (); 400 errorCount += testExternalGet ();
358 if (errorCount != 0) 401 if (errorCount != 0)
359 fprintf (stderr, "Error (code: %u)\n", errorCount); 402 fprintf (stderr, "Error (code: %u)\n", errorCount);
diff --git a/src/testcurl/daemontest_iplimit.c b/src/testcurl/daemontest_iplimit.c
index e8ec0e8d..f9b5aba5 100644
--- a/src/testcurl/daemontest_iplimit.c
+++ b/src/testcurl/daemontest_iplimit.c
@@ -90,6 +90,103 @@ ahc_echo (void *cls,
90} 90}
91 91
92static int 92static int
93testMultithreadedGet ()
94{
95 struct MHD_Daemon *d;
96 char buf[2048];
97 int k;
98
99 /* Test only valid for HTTP/1.1 (uses persistent connections) */
100 if (!oneone)
101 return 0;
102
103 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
104 1081, NULL, NULL, &ahc_echo, "GET",
105 MHD_OPTION_PER_IP_CONNECTION_LIMIT, 2,
106 MHD_OPTION_END);
107 if (d == NULL)
108 return 16;
109
110 for (k = 0; k < 3; ++k)
111 {
112 struct CBC cbc[3];
113 CURL *cenv[3];
114 int i;
115
116 for (i = 0; i < 3; ++i)
117 {
118 CURL *c;
119 CURLcode errornum;
120
121 cenv[i] = c = curl_easy_init ();
122 cbc[i].buf = buf;
123 cbc[i].size = 2048;
124 cbc[i].pos = 0;
125
126 curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1081/hello_world");
127 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
128 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc[i]);
129 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
130 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
131 curl_easy_setopt (c, CURLOPT_FORBID_REUSE, 0L);
132 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
133 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
134 // NOTE: use of CONNECTTIMEOUT without also
135 // setting NOSIGNAL results in really weird
136 // crashes on my system!
137 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
138
139 errornum = curl_easy_perform (c);
140 if (CURLE_OK != errornum && i < 2
141 || CURLE_OK == errornum && i == 2)
142 {
143 int j;
144
145 /* First 2 should succeed */
146 if (i < 2)
147 fprintf (stderr,
148 "curl_easy_perform failed: `%s'\n",
149 curl_easy_strerror (errornum));
150
151 /* Last request should have failed */
152 else
153 fprintf (stderr,
154 "No error on IP address over limit\n");
155
156 for (j = 0; j < i; ++j)
157 curl_easy_cleanup (cenv[j]);
158 MHD_stop_daemon (d);
159 return 32;
160 }
161 }
162
163 /* Cleanup the environments */
164 for (i = 0; i < 3; ++i)
165 curl_easy_cleanup (cenv[i]);
166
167 sleep(2);
168
169 for (i = 0; i < 2; ++i)
170 {
171 if (cbc[i].pos != strlen ("/hello_world"))
172 {
173 MHD_stop_daemon (d);
174 return 64;
175 }
176 if (0 != strncmp ("/hello_world", cbc[i].buf, strlen ("/hello_world")))
177 {
178 MHD_stop_daemon (d);
179 return 128;
180 }
181 }
182
183
184 }
185 MHD_stop_daemon (d);
186 return 0;
187}
188
189static int
93testMultithreadedPoolGet () 190testMultithreadedPoolGet ()
94{ 191{
95 struct MHD_Daemon *d; 192 struct MHD_Daemon *d;
@@ -103,6 +200,7 @@ testMultithreadedPoolGet ()
103 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG, 200 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
104 1081, NULL, NULL, &ahc_echo, "GET", 201 1081, NULL, NULL, &ahc_echo, "GET",
105 MHD_OPTION_PER_IP_CONNECTION_LIMIT, 2, 202 MHD_OPTION_PER_IP_CONNECTION_LIMIT, 2,
203 MHD_OPTION_THREAD_POOL_SIZE, 4,
106 MHD_OPTION_END); 204 MHD_OPTION_END);
107 if (d == NULL) 205 if (d == NULL)
108 return 16; 206 return 16;
@@ -194,6 +292,7 @@ main (int argc, char *const *argv)
194 oneone = NULL != strstr (argv[0], "11"); 292 oneone = NULL != strstr (argv[0], "11");
195 if (0 != curl_global_init (CURL_GLOBAL_WIN32)) 293 if (0 != curl_global_init (CURL_GLOBAL_WIN32))
196 return 2; 294 return 2;
295 errorCount += testMultithreadedGet ();
197 errorCount += testMultithreadedPoolGet (); 296 errorCount += testMultithreadedPoolGet ();
198 if (errorCount != 0) 297 if (errorCount != 0)
199 fprintf (stderr, "Error (code: %u)\n", errorCount); 298 fprintf (stderr, "Error (code: %u)\n", errorCount);
diff --git a/src/testcurl/daemontest_large_put.c b/src/testcurl/daemontest_large_put.c
index 069916a2..a454c5c5 100644
--- a/src/testcurl/daemontest_large_put.c
+++ b/src/testcurl/daemontest_large_put.c
@@ -245,6 +245,65 @@ testMultithreadedPut ()
245 return 0; 245 return 0;
246} 246}
247 247
248static int
249testMultithreadedPoolPut ()
250{
251 struct MHD_Daemon *d;
252 CURL *c;
253 struct CBC cbc;
254 unsigned int pos = 0;
255 int done_flag = 0;
256 CURLcode errornum;
257 char buf[2048];
258
259 cbc.buf = buf;
260 cbc.size = 2048;
261 cbc.pos = 0;
262 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
263 1081,
264 NULL, NULL, &ahc_echo, &done_flag,
265 MHD_OPTION_THREAD_POOL_SIZE, 4, MHD_OPTION_END);
266 if (d == NULL)
267 return 16;
268 c = curl_easy_init ();
269 curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1081/hello_world");
270 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
271 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
272 curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
273 curl_easy_setopt (c, CURLOPT_READDATA, &pos);
274 curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
275 curl_easy_setopt (c, CURLOPT_INFILESIZE, (long) PUT_SIZE);
276 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
277 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
278 if (oneone)
279 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
280 else
281 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
282 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
283 // NOTE: use of CONNECTTIMEOUT without also
284 // setting NOSIGNAL results in really weird
285 // crashes on my system!
286 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
287 if (CURLE_OK != (errornum = curl_easy_perform (c)))
288 {
289 fprintf (stderr,
290 "curl_easy_perform failed: `%s'\n",
291 curl_easy_strerror (errornum));
292 curl_easy_cleanup (c);
293 MHD_stop_daemon (d);
294 return 32;
295 }
296 curl_easy_cleanup (c);
297 MHD_stop_daemon (d);
298 if (cbc.pos != strlen ("/hello_world"))
299 {
300 fprintf (stderr, "Got invalid response `%.*s'\n", cbc.pos, cbc.buf);
301 return 64;
302 }
303 if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
304 return 128;
305 return 0;
306}
248 307
249static int 308static int
250testExternalPut () 309testExternalPut ()
@@ -394,6 +453,7 @@ main (int argc, char *const *argv)
394 memset (put_buffer, 1, PUT_SIZE); 453 memset (put_buffer, 1, PUT_SIZE);
395 errorCount += testInternalPut (); 454 errorCount += testInternalPut ();
396 errorCount += testMultithreadedPut (); 455 errorCount += testMultithreadedPut ();
456 errorCount += testMultithreadedPoolPut ();
397 errorCount += testExternalPut (); 457 errorCount += testExternalPut ();
398 free (put_buffer); 458 free (put_buffer);
399 if (errorCount != 0) 459 if (errorCount != 0)
diff --git a/src/testcurl/daemontest_post.c b/src/testcurl/daemontest_post.c
index 0ef2bbb7..715047fe 100644
--- a/src/testcurl/daemontest_post.c
+++ b/src/testcurl/daemontest_post.c
@@ -231,6 +231,58 @@ testMultithreadedPost ()
231 return 0; 231 return 0;
232} 232}
233 233
234static int
235testMultithreadedPoolPost ()
236{
237 struct MHD_Daemon *d;
238 CURL *c;
239 char buf[2048];
240 struct CBC cbc;
241 CURLcode errornum;
242
243 cbc.buf = buf;
244 cbc.size = 2048;
245 cbc.pos = 0;
246 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
247 1081, NULL, NULL, &ahc_echo, NULL,
248 MHD_OPTION_THREAD_POOL_SIZE, 4, MHD_OPTION_END);
249 if (d == NULL)
250 return 16;
251 c = curl_easy_init ();
252 curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1081/hello_world");
253 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
254 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
255 curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA);
256 curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, strlen (POST_DATA));
257 curl_easy_setopt (c, CURLOPT_POST, 1L);
258 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
259 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
260 if (oneone)
261 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
262 else
263 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
264 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
265 // NOTE: use of CONNECTTIMEOUT without also
266 // setting NOSIGNAL results in really weird
267 // crashes on my system!
268 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
269 if (CURLE_OK != (errornum = curl_easy_perform (c)))
270 {
271 fprintf (stderr,
272 "curl_easy_perform failed: `%s'\n",
273 curl_easy_strerror (errornum));
274 curl_easy_cleanup (c);
275 MHD_stop_daemon (d);
276 return 32;
277 }
278 curl_easy_cleanup (c);
279 MHD_stop_daemon (d);
280 if (cbc.pos != strlen ("/hello_world"))
281 return 64;
282 if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
283 return 128;
284 return 0;
285}
234 286
235static int 287static int
236testExternalPost () 288testExternalPost ()
@@ -369,6 +421,7 @@ main (int argc, char *const *argv)
369 return 2; 421 return 2;
370 errorCount += testInternalPost (); 422 errorCount += testInternalPost ();
371 errorCount += testMultithreadedPost (); 423 errorCount += testMultithreadedPost ();
424 errorCount += testMultithreadedPoolPost ();
372 errorCount += testExternalPost (); 425 errorCount += testExternalPost ();
373 if (errorCount != 0) 426 if (errorCount != 0)
374 fprintf (stderr, "Error (code: %u)\n", errorCount); 427 fprintf (stderr, "Error (code: %u)\n", errorCount);
diff --git a/src/testcurl/daemontest_post_loop.c b/src/testcurl/daemontest_post_loop.c
index 0c74f96a..b1e1ab3f 100644
--- a/src/testcurl/daemontest_post_loop.c
+++ b/src/testcurl/daemontest_post_loop.c
@@ -225,6 +225,70 @@ testMultithreadedPost ()
225 return 0; 225 return 0;
226} 226}
227 227
228static int
229testMultithreadedPoolPost ()
230{
231 struct MHD_Daemon *d;
232 CURL *c;
233 char buf[2048];
234 struct CBC cbc;
235 CURLcode errornum;
236 int i;
237 char url[1024];
238
239 cbc.buf = buf;
240 cbc.size = 2048;
241 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
242 1081, NULL, NULL, &ahc_echo, NULL,
243 MHD_OPTION_THREAD_POOL_SIZE, 4, MHD_OPTION_END);
244 if (d == NULL)
245 return 16;
246 for (i = 0; i < LOOPCOUNT; i++)
247 {
248 if (99 == i % 100)
249 fprintf (stderr, ".");
250 c = curl_easy_init ();
251 cbc.pos = 0;
252 buf[0] = '\0';
253 sprintf (url, "http://localhost:1081/hw%d", i);
254 curl_easy_setopt (c, CURLOPT_URL, url);
255 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
256 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
257 curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA);
258 curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, strlen (POST_DATA));
259 curl_easy_setopt (c, CURLOPT_POST, 1L);
260 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
261 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
262 if (oneone)
263 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
264 else
265 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
266 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
267 // NOTE: use of CONNECTTIMEOUT without also
268 // setting NOSIGNAL results in really weird
269 // crashes on my system!
270 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
271 if (CURLE_OK != (errornum = curl_easy_perform (c)))
272 {
273 fprintf (stderr,
274 "curl_easy_perform failed: `%s'\n",
275 curl_easy_strerror (errornum));
276 curl_easy_cleanup (c);
277 MHD_stop_daemon (d);
278 return 32;
279 }
280 curl_easy_cleanup (c);
281 if ((buf[0] != 'O') || (buf[1] != 'K'))
282 {
283 MHD_stop_daemon (d);
284 return 64;
285 }
286 }
287 MHD_stop_daemon (d);
288 if (LOOPCOUNT >= 99)
289 fprintf (stderr, "\n");
290 return 0;
291}
228 292
229static int 293static int
230testExternalPost () 294testExternalPost ()
@@ -379,6 +443,7 @@ main (int argc, char *const *argv)
379 return 2; 443 return 2;
380 errorCount += testInternalPost (); 444 errorCount += testInternalPost ();
381 errorCount += testMultithreadedPost (); 445 errorCount += testMultithreadedPost ();
446 errorCount += testMultithreadedPoolPost ();
382 errorCount += testExternalPost (); 447 errorCount += testExternalPost ();
383 if (errorCount != 0) 448 if (errorCount != 0)
384 fprintf (stderr, "Error (code: %u)\n", errorCount); 449 fprintf (stderr, "Error (code: %u)\n", errorCount);
diff --git a/src/testcurl/daemontest_postform.c b/src/testcurl/daemontest_postform.c
index 477713c3..a1e29f69 100644
--- a/src/testcurl/daemontest_postform.c
+++ b/src/testcurl/daemontest_postform.c
@@ -251,6 +251,60 @@ testMultithreadedPost ()
251 return 0; 251 return 0;
252} 252}
253 253
254static int
255testMultithreadedPoolPost ()
256{
257 struct MHD_Daemon *d;
258 CURL *c;
259 char buf[2048];
260 struct CBC cbc;
261 CURLcode errornum;
262 struct curl_httppost *pd;
263
264 cbc.buf = buf;
265 cbc.size = 2048;
266 cbc.pos = 0;
267 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
268 1081, NULL, NULL, &ahc_echo, NULL,
269 MHD_OPTION_THREAD_POOL_SIZE, 4, MHD_OPTION_END);
270 if (d == NULL)
271 return 16;
272 c = curl_easy_init ();
273 curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1081/hello_world");
274 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
275 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
276 pd = make_form ();
277 curl_easy_setopt (c, CURLOPT_HTTPPOST, pd);
278 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
279 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
280 if (oneone)
281 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
282 else
283 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
284 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 5L);
285 // NOTE: use of CONNECTTIMEOUT without also
286 // setting NOSIGNAL results in really weird
287 // crashes on my system!
288 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
289 if (CURLE_OK != (errornum = curl_easy_perform (c)))
290 {
291 fprintf (stderr,
292 "curl_easy_perform failed: `%s'\n",
293 curl_easy_strerror (errornum));
294 curl_easy_cleanup (c);
295 curl_formfree (pd);
296 MHD_stop_daemon (d);
297 return 32;
298 }
299 curl_easy_cleanup (c);
300 curl_formfree (pd);
301 MHD_stop_daemon (d);
302 if (cbc.pos != strlen ("/hello_world"))
303 return 64;
304 if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
305 return 128;
306 return 0;
307}
254 308
255static int 309static int
256testExternalPost () 310testExternalPost ()
@@ -394,6 +448,7 @@ main (int argc, char *const *argv)
394 return 2; 448 return 2;
395 errorCount += testInternalPost (); 449 errorCount += testInternalPost ();
396 errorCount += testMultithreadedPost (); 450 errorCount += testMultithreadedPost ();
451 errorCount += testMultithreadedPoolPost ();
397 errorCount += testExternalPost (); 452 errorCount += testExternalPost ();
398 if (errorCount != 0) 453 if (errorCount != 0)
399 fprintf (stderr, "Error (code: %u)\n", errorCount); 454 fprintf (stderr, "Error (code: %u)\n", errorCount);
diff --git a/src/testcurl/daemontest_process_headers.c b/src/testcurl/daemontest_process_headers.c
index e59699db..cd4bd68c 100644
--- a/src/testcurl/daemontest_process_headers.c
+++ b/src/testcurl/daemontest_process_headers.c
@@ -235,6 +235,55 @@ testMultithreadedGet ()
235 return 0; 235 return 0;
236} 236}
237 237
238static int
239testMultithreadedPoolGet ()
240{
241 struct MHD_Daemon *d;
242 CURL *c;
243 char buf[2048];
244 struct CBC cbc;
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 21080, NULL, NULL, &ahc_echo, "GET",
252 MHD_OPTION_THREAD_POOL_SIZE, 4, MHD_OPTION_END);
253 if (d == NULL)
254 return 16;
255 c = curl_easy_init ();
256 curl_easy_setopt (c, CURLOPT_URL, "http://localhost:21080/hello_world");
257 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
258 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
259 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
260 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
261 if (oneone)
262 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
263 else
264 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
265 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
266 /* NOTE: use of CONNECTTIMEOUT without also
267 setting NOSIGNAL results in really weird
268 crashes on my system! */
269 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
270 if (CURLE_OK != (errornum = curl_easy_perform (c)))
271 {
272 fprintf (stderr,
273 "curl_easy_perform failed: `%s'\n",
274 curl_easy_strerror (errornum));
275 curl_easy_cleanup (c);
276 MHD_stop_daemon (d);
277 return 32;
278 }
279 curl_easy_cleanup (c);
280 MHD_stop_daemon (d);
281 if (cbc.pos != strlen ("/hello_world"))
282 return 64;
283 if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
284 return 128;
285 return 0;
286}
238 287
239static int 288static int
240testExternalGet () 289testExternalGet ()
@@ -370,6 +419,7 @@ main (int argc, char *const *argv)
370 return 2; 419 return 2;
371 errorCount += testInternalGet (); 420 errorCount += testInternalGet ();
372 errorCount += testMultithreadedGet (); 421 errorCount += testMultithreadedGet ();
422 errorCount += testMultithreadedPoolGet ();
373 errorCount += testExternalGet (); 423 errorCount += testExternalGet ();
374 if (errorCount != 0) 424 if (errorCount != 0)
375 fprintf (stderr, "Error (code: %u)\n", errorCount); 425 fprintf (stderr, "Error (code: %u)\n", errorCount);
diff --git a/src/testcurl/daemontest_put.c b/src/testcurl/daemontest_put.c
index 753af4f2..76e96320 100644
--- a/src/testcurl/daemontest_put.c
+++ b/src/testcurl/daemontest_put.c
@@ -223,6 +223,64 @@ testMultithreadedPut ()
223 return 0; 223 return 0;
224} 224}
225 225
226static int
227testMultithreadedPoolPut ()
228{
229 struct MHD_Daemon *d;
230 CURL *c;
231 char buf[2048];
232 struct CBC cbc;
233 unsigned int pos = 0;
234 int done_flag = 0;
235 CURLcode errornum;
236
237 cbc.buf = buf;
238 cbc.size = 2048;
239 cbc.pos = 0;
240 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
241 1081,
242 NULL, NULL, &ahc_echo, &done_flag,
243 MHD_OPTION_THREAD_POOL_SIZE, 4, MHD_OPTION_END);
244 if (d == NULL)
245 return 16;
246 c = curl_easy_init ();
247 curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1081/hello_world");
248 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
249 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
250 curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
251 curl_easy_setopt (c, CURLOPT_READDATA, &pos);
252 curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
253 curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
254 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
255 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
256 if (oneone)
257 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
258 else
259 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
260 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
261 // NOTE: use of CONNECTTIMEOUT without also
262 // setting NOSIGNAL results in really weird
263 // crashes on my system!
264 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
265 if (CURLE_OK != (errornum = curl_easy_perform (c)))
266 {
267 fprintf (stderr,
268 "curl_easy_perform failed: `%s'\n",
269 curl_easy_strerror (errornum));
270 curl_easy_cleanup (c);
271 MHD_stop_daemon (d);
272 return 32;
273 }
274 curl_easy_cleanup (c);
275 MHD_stop_daemon (d);
276 if (cbc.pos != strlen ("/hello_world"))
277 return 64;
278 if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
279 return 128;
280
281 return 0;
282}
283
226 284
227static int 285static int
228testExternalPut () 286testExternalPut ()
@@ -365,6 +423,7 @@ main (int argc, char *const *argv)
365 return 2; 423 return 2;
366 errorCount += testInternalPut (); 424 errorCount += testInternalPut ();
367 errorCount += testMultithreadedPut (); 425 errorCount += testMultithreadedPut ();
426 errorCount += testMultithreadedPoolPut ();
368 errorCount += testExternalPut (); 427 errorCount += testExternalPut ();
369 if (errorCount != 0) 428 if (errorCount != 0)
370 fprintf (stderr, "Error (code: %u)\n", errorCount); 429 fprintf (stderr, "Error (code: %u)\n", errorCount);
diff --git a/src/testcurl/daemontest_put_chunked.c b/src/testcurl/daemontest_put_chunked.c
index 96c3f79c..3fa1f092 100644
--- a/src/testcurl/daemontest_put_chunked.c
+++ b/src/testcurl/daemontest_put_chunked.c
@@ -232,6 +232,64 @@ testMultithreadedPut ()
232 return 0; 232 return 0;
233} 233}
234 234
235static int
236testMultithreadedPoolPut ()
237{
238 struct MHD_Daemon *d;
239 CURL *c;
240 char buf[2048];
241 struct CBC cbc;
242 unsigned int pos = 0;
243 int done_flag = 0;
244 CURLcode errornum;
245
246 cbc.buf = buf;
247 cbc.size = 2048;
248 cbc.pos = 0;
249 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
250 11081,
251 NULL, NULL, &ahc_echo, &done_flag,
252 MHD_OPTION_THREAD_POOL_SIZE, 4, MHD_OPTION_END);
253 if (d == NULL)
254 return 16;
255 c = curl_easy_init ();
256 curl_easy_setopt (c, CURLOPT_URL, "http://localhost:11081/hello_world");
257 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
258 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
259 curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
260 curl_easy_setopt (c, CURLOPT_READDATA, &pos);
261 curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
262 /*
263 // by not giving the file size, we force chunking!
264 curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
265 */
266 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
267 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
268 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
269 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
270 // NOTE: use of CONNECTTIMEOUT without also
271 // setting NOSIGNAL results in really weird
272 // crashes on my system!
273 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
274 if (CURLE_OK != (errornum = curl_easy_perform (c)))
275 {
276 fprintf (stderr,
277 "curl_easy_perform failed: `%s'\n",
278 curl_easy_strerror (errornum));
279 curl_easy_cleanup (c);
280 MHD_stop_daemon (d);
281 return 32;
282 }
283 curl_easy_cleanup (c);
284 MHD_stop_daemon (d);
285 if (cbc.pos != strlen ("/hello_world"))
286 return 64;
287 if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
288 return 128;
289
290 return 0;
291}
292
235 293
236static int 294static int
237testExternalPut () 295testExternalPut ()
@@ -373,6 +431,7 @@ main (int argc, char *const *argv)
373 return 2; 431 return 2;
374 errorCount += testInternalPut (); 432 errorCount += testInternalPut ();
375 errorCount += testMultithreadedPut (); 433 errorCount += testMultithreadedPut ();
434 errorCount += testMultithreadedPoolPut ();
376 errorCount += testExternalPut (); 435 errorCount += testExternalPut ();
377 if (errorCount != 0) 436 if (errorCount != 0)
378 fprintf (stderr, "Error (code: %u)\n", errorCount); 437 fprintf (stderr, "Error (code: %u)\n", errorCount);