aboutsummaryrefslogtreecommitdiff
path: root/src/testcurl/test_get_response_cleanup.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/testcurl/test_get_response_cleanup.c')
-rw-r--r--src/testcurl/test_get_response_cleanup.c287
1 files changed, 287 insertions, 0 deletions
diff --git a/src/testcurl/test_get_response_cleanup.c b/src/testcurl/test_get_response_cleanup.c
new file mode 100644
index 00000000..e0d1a0dc
--- /dev/null
+++ b/src/testcurl/test_get_response_cleanup.c
@@ -0,0 +1,287 @@
1/* DO NOT CHANGE THIS LINE */
2/*
3 This file is part of libmicrohttpd
4 (C) 2007, 2009 Christian Grothoff
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., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
20*/
21
22/**
23 * @file daemontest_get_response_cleanup.c
24 * @brief Testcase for libmicrohttpd response cleanup
25 * @author Christian Grothoff
26 */
27
28#include "MHD_config.h"
29#include "platform.h"
30#include <microhttpd.h>
31#include <stdlib.h>
32#include <unistd.h>
33#include <string.h>
34#include <time.h>
35#include <sys/types.h>
36#include <sys/wait.h>
37#include <fcntl.h>
38
39#ifndef WINDOWS
40#include <sys/socket.h>
41#include <unistd.h>
42#endif
43
44#define TESTSTR "/* DO NOT CHANGE THIS LINE */"
45
46static int oneone;
47
48static int ok;
49
50
51static pid_t
52fork_curl (const char *url)
53{
54 pid_t ret;
55
56 ret = fork();
57 if (ret != 0)
58 return ret;
59 execlp ("curl", "curl", "-s", "-N", "-o", "/dev/null", "-GET", url, NULL);
60 fprintf (stderr,
61 "Failed to exec curl: %s\n",
62 strerror (errno));
63 _exit (-1);
64}
65
66static void
67kill_curl (pid_t pid)
68{
69 int status;
70
71 //fprintf (stderr, "Killing curl\n");
72 kill (pid, SIGTERM);
73 waitpid (pid, &status, 0);
74}
75
76
77static ssize_t
78push_callback (void *cls, uint64_t pos, char *buf, size_t max)
79{
80 if (max == 0)
81 return 0;
82 buf[0] = 'd';
83 return 1;
84}
85
86static void
87push_free_callback (void *cls)
88{
89 int *ok = cls;
90
91 //fprintf (stderr, "Cleanup callback called!\n");
92 *ok = 0;
93}
94
95
96static int
97ahc_echo (void *cls,
98 struct MHD_Connection *connection,
99 const char *url,
100 const char *method,
101 const char *version,
102 const char *upload_data, size_t *upload_data_size,
103 void **unused)
104{
105 static int ptr;
106 const char *me = cls;
107 struct MHD_Response *response;
108 int ret;
109
110 //fprintf (stderr, "In CB: %s!\n", method);
111 if (0 != strcmp (me, method))
112 return MHD_NO; /* unexpected method */
113 if (&ptr != *unused)
114 {
115 *unused = &ptr;
116 return MHD_YES;
117 }
118 *unused = NULL;
119 response = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN,
120 32 * 1024,
121 &push_callback,
122 &ok,
123 &push_free_callback);
124 ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
125 MHD_destroy_response (response);
126 if (ret == MHD_NO)
127 abort ();
128 return ret;
129}
130
131
132static int
133testInternalGet ()
134{
135 struct MHD_Daemon *d;
136 pid_t curl;
137
138 ok = 1;
139 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
140 11080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
141 if (d == NULL)
142 return 1;
143 curl = fork_curl ("http://127.0.0.1:11080/");
144 sleep (1);
145 kill_curl (curl);
146 sleep (1);
147 // fprintf (stderr, "Stopping daemon!\n");
148 MHD_stop_daemon (d);
149 if (ok != 0)
150 return 2;
151 return 0;
152}
153
154static int
155testMultithreadedGet ()
156{
157 struct MHD_Daemon *d;
158 pid_t curl;
159
160 d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG,
161 1081, NULL, NULL, &ahc_echo, "GET",
162 MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 2,
163 MHD_OPTION_END);
164 if (d == NULL)
165 return 16;
166 ok = 1;
167 //fprintf (stderr, "Forking cURL!\n");
168 curl = fork_curl ("http://127.0.0.1:1081/");
169 sleep (1);
170 kill_curl (curl);
171 sleep (1);
172 curl = fork_curl ("http://127.0.0.1:1081/");
173 sleep (1);
174 if (ok != 0)
175 {
176 kill_curl (curl);
177 MHD_stop_daemon (d);
178 return 64;
179 }
180 kill_curl (curl);
181 sleep (1);
182 //fprintf (stderr, "Stopping daemon!\n");
183 MHD_stop_daemon (d);
184 if (ok != 0)
185 return 32;
186
187 return 0;
188}
189
190static int
191testMultithreadedPoolGet ()
192{
193 struct MHD_Daemon *d;
194 pid_t curl;
195
196 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
197 1081, NULL, NULL, &ahc_echo, "GET",
198 MHD_OPTION_THREAD_POOL_SIZE, 4, MHD_OPTION_END);
199 if (d == NULL)
200 return 64;
201 ok = 1;
202 curl = fork_curl ("http://127.0.0.1:1081/");
203 sleep (1);
204 kill_curl (curl);
205 sleep (1);
206 //fprintf (stderr, "Stopping daemon!\n");
207 MHD_stop_daemon (d);
208 if (ok != 0)
209 return 128;
210 return 0;
211}
212
213static int
214testExternalGet ()
215{
216 struct MHD_Daemon *d;
217 fd_set rs;
218 fd_set ws;
219 fd_set es;
220 int max;
221 time_t start;
222 struct timeval tv;
223 pid_t curl;
224
225 d = MHD_start_daemon (MHD_USE_DEBUG,
226 1082, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
227 if (d == NULL)
228 return 256;
229 curl = fork_curl ("http://127.0.0.1:1082/");
230
231 start = time (NULL);
232 while ((time (NULL) - start < 2))
233 {
234 max = 0;
235 FD_ZERO (&rs);
236 FD_ZERO (&ws);
237 FD_ZERO (&es);
238 if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
239 {
240 MHD_stop_daemon (d);
241 return 4096;
242 }
243 tv.tv_sec = 0;
244 tv.tv_usec = 1000;
245 select (max + 1, &rs, &ws, &es, &tv);
246 MHD_run (d);
247 }
248 kill_curl (curl);
249 start = time (NULL);
250 while ((time (NULL) - start < 2))
251 {
252 max = 0;
253 FD_ZERO (&rs);
254 FD_ZERO (&ws);
255 FD_ZERO (&es);
256 if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
257 {
258 MHD_stop_daemon (d);
259 return 4096;
260 }
261 tv.tv_sec = 0;
262 tv.tv_usec = 1000;
263 select (max + 1, &rs, &ws, &es, &tv);
264 MHD_run (d);
265 }
266 // fprintf (stderr, "Stopping daemon!\n");
267 MHD_stop_daemon (d);
268 if (ok != 0)
269 return 1024;
270 return 0;
271}
272
273
274int
275main (int argc, char *const *argv)
276{
277 unsigned int errorCount = 0;
278
279 oneone = NULL != strstr (argv[0], "11");
280 errorCount += testInternalGet ();
281 errorCount += testMultithreadedGet ();
282 errorCount += testMultithreadedPoolGet ();
283 errorCount += testExternalGet ();
284 if (errorCount != 0)
285 fprintf (stderr, "Error (code: %u)\n", errorCount);
286 return errorCount != 0; /* 0 == pass */
287}