aboutsummaryrefslogtreecommitdiff
path: root/src/testcurl/daemontest_get_response_cleanup.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/testcurl/daemontest_get_response_cleanup.c')
-rw-r--r--src/testcurl/daemontest_get_response_cleanup.c282
1 files changed, 282 insertions, 0 deletions
diff --git a/src/testcurl/daemontest_get_response_cleanup.c b/src/testcurl/daemontest_get_response_cleanup.c
new file mode 100644
index 00000000..90550c45
--- /dev/null
+++ b/src/testcurl/daemontest_get_response_cleanup.c
@@ -0,0 +1,282 @@
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 _exit (-1);
61}
62
63static void
64kill_curl (pid_t pid)
65{
66 int status;
67
68 // fprintf (stderr, "Killing curl\n");
69 kill (pid, SIGTERM);
70 waitpid (pid, &status, 0);
71}
72
73
74static ssize_t
75push_callback (void *cls, uint64_t pos, char *buf, size_t max)
76{
77 if (max == 0)
78 return 0;
79 buf[0] = 'd';
80 return 1;
81}
82
83static void
84push_free_callback (void *cls)
85{
86 int *ok = cls;
87
88 // fprintf (stderr, "Cleanup callback called!\n");
89 *ok = 0;
90}
91
92
93static int
94ahc_echo (void *cls,
95 struct MHD_Connection *connection,
96 const char *url,
97 const char *method,
98 const char *version,
99 const char *upload_data, size_t *upload_data_size,
100 void **unused)
101{
102 static int ptr;
103 const char *me = cls;
104 struct MHD_Response *response;
105 int ret;
106
107 if (0 != strcmp (me, method))
108 return MHD_NO; /* unexpected method */
109 if (&ptr != *unused)
110 {
111 *unused = &ptr;
112 return MHD_YES;
113 }
114 *unused = NULL;
115 response = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN,
116 32 * 1024,
117 &push_callback,
118 &ok,
119 &push_free_callback);
120 ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
121 MHD_destroy_response (response);
122 if (ret == MHD_NO)
123 abort ();
124 return ret;
125}
126
127
128static int
129testInternalGet ()
130{
131 struct MHD_Daemon *d;
132 pid_t curl;
133
134 ok = 1;
135 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
136 11080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
137 if (d == NULL)
138 return 1;
139 curl = fork_curl ("http://localhost:11080/");
140 sleep (1);
141 kill_curl (curl);
142 sleep (1);
143 // fprintf (stderr, "Stopping daemon!\n");
144 MHD_stop_daemon (d);
145 if (ok != 0)
146 return 2;
147 return 0;
148}
149
150static int
151testMultithreadedGet ()
152{
153 struct MHD_Daemon *d;
154 pid_t curl;
155
156 d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG,
157 1081, NULL, NULL, &ahc_echo, "GET",
158 MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 2,
159 MHD_OPTION_END);
160 if (d == NULL)
161 return 16;
162 ok = 1;
163 curl = fork_curl ("http://localhost:1081/");
164 sleep (1);
165 kill_curl (curl);
166 sleep (1);
167 curl = fork_curl ("http://localhost:1081/");
168 sleep (1);
169 if (ok != 0)
170 {
171 kill_curl (curl);
172 MHD_stop_daemon (d);
173 return 64;
174 }
175 kill_curl (curl);
176 sleep (1);
177 // fprintf (stderr, "Stopping daemon!\n");
178 MHD_stop_daemon (d);
179 if (ok != 0)
180 return 32;
181
182 return 0;
183}
184
185static int
186testMultithreadedPoolGet ()
187{
188 struct MHD_Daemon *d;
189 pid_t curl;
190
191 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
192 1081, NULL, NULL, &ahc_echo, "GET",
193 MHD_OPTION_THREAD_POOL_SIZE, 4, MHD_OPTION_END);
194 if (d == NULL)
195 return 64;
196 ok = 1;
197 curl = fork_curl ("http://localhost:1081/");
198 sleep (1);
199 kill_curl (curl);
200 sleep (1);
201 // fprintf (stderr, "Stopping daemon!\n");
202 MHD_stop_daemon (d);
203 if (ok != 0)
204 return 128;
205 return 0;
206}
207
208static int
209testExternalGet ()
210{
211 struct MHD_Daemon *d;
212 fd_set rs;
213 fd_set ws;
214 fd_set es;
215 int max;
216 time_t start;
217 struct timeval tv;
218 pid_t curl;
219
220 d = MHD_start_daemon (MHD_USE_DEBUG,
221 1082, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
222 if (d == NULL)
223 return 256;
224 curl = fork_curl ("http://localhost:1082/");
225
226 start = time (NULL);
227 while ((time (NULL) - start < 2))
228 {
229 max = 0;
230 FD_ZERO (&rs);
231 FD_ZERO (&ws);
232 FD_ZERO (&es);
233 if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
234 {
235 MHD_stop_daemon (d);
236 return 4096;
237 }
238 tv.tv_sec = 0;
239 tv.tv_usec = 1000;
240 select (max + 1, &rs, &ws, &es, &tv);
241 MHD_run (d);
242 }
243 kill_curl (curl);
244 start = time (NULL);
245 while ((time (NULL) - start < 2))
246 {
247 max = 0;
248 FD_ZERO (&rs);
249 FD_ZERO (&ws);
250 FD_ZERO (&es);
251 if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
252 {
253 MHD_stop_daemon (d);
254 return 4096;
255 }
256 tv.tv_sec = 0;
257 tv.tv_usec = 1000;
258 select (max + 1, &rs, &ws, &es, &tv);
259 MHD_run (d);
260 }
261 // fprintf (stderr, "Stopping daemon!\n");
262 MHD_stop_daemon (d);
263 if (ok != 0)
264 return 1024;
265 return 0;
266}
267
268
269int
270main (int argc, char *const *argv)
271{
272 unsigned int errorCount = 0;
273
274 oneone = NULL != strstr (argv[0], "11");
275 errorCount += testInternalGet ();
276 errorCount += testMultithreadedGet ();
277 errorCount += testMultithreadedPoolGet ();
278 errorCount += testExternalGet ();
279 if (errorCount != 0)
280 fprintf (stderr, "Error (code: %u)\n", errorCount);
281 return errorCount != 0; /* 0 == pass */
282}