diff options
Diffstat (limited to 'src/daemon/daemon.c')
-rw-r--r-- | src/daemon/daemon.c | 747 |
1 files changed, 361 insertions, 386 deletions
diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c index 2fbd3abc..3b2ebab0 100644 --- a/src/daemon/daemon.c +++ b/src/daemon/daemon.c | |||
@@ -48,30 +48,28 @@ | |||
48 | * already exists | 48 | * already exists |
49 | */ | 49 | */ |
50 | int | 50 | int |
51 | MHD_register_handler(struct MHD_Daemon * daemon, | 51 | MHD_register_handler (struct MHD_Daemon *daemon, |
52 | const char * uri_prefix, | 52 | const char *uri_prefix, |
53 | MHD_AccessHandlerCallback dh, | 53 | MHD_AccessHandlerCallback dh, void *dh_cls) |
54 | void * dh_cls) { | 54 | { |
55 | struct MHD_Access_Handler * ah; | 55 | struct MHD_Access_Handler *ah; |
56 | 56 | ||
57 | if ( (daemon == NULL) || | 57 | if ((daemon == NULL) || (uri_prefix == NULL) || (dh == NULL)) |
58 | (uri_prefix == NULL) || | 58 | return MHD_NO; |
59 | (dh == NULL) ) | ||
60 | return MHD_NO; | ||
61 | ah = daemon->handlers; | 59 | ah = daemon->handlers; |
62 | while (ah != NULL) { | 60 | while (ah != NULL) |
63 | if (0 == strcmp(uri_prefix, | 61 | { |
64 | ah->uri_prefix)) | 62 | if (0 == strcmp (uri_prefix, ah->uri_prefix)) |
65 | return MHD_NO; | 63 | return MHD_NO; |
66 | ah = ah->next; | 64 | ah = ah->next; |
67 | } | 65 | } |
68 | ah = malloc(sizeof(struct MHD_Access_Handler)); | 66 | ah = malloc (sizeof (struct MHD_Access_Handler)); |
69 | ah->next = daemon->handlers; | 67 | ah->next = daemon->handlers; |
70 | ah->uri_prefix = strdup(uri_prefix); | 68 | ah->uri_prefix = strdup (uri_prefix); |
71 | ah->dh = dh; | 69 | ah->dh = dh; |
72 | ah->dh_cls = dh_cls; | 70 | ah->dh_cls = dh_cls; |
73 | daemon->handlers = ah; | 71 | daemon->handlers = ah; |
74 | return MHD_YES; | 72 | return MHD_YES; |
75 | } | 73 | } |
76 | 74 | ||
77 | 75 | ||
@@ -84,34 +82,33 @@ MHD_register_handler(struct MHD_Daemon * daemon, | |||
84 | * is not known for this daemon | 82 | * is not known for this daemon |
85 | */ | 83 | */ |
86 | int | 84 | int |
87 | MHD_unregister_handler(struct MHD_Daemon * daemon, | 85 | MHD_unregister_handler (struct MHD_Daemon *daemon, |
88 | const char * uri_prefix, | 86 | const char *uri_prefix, |
89 | MHD_AccessHandlerCallback dh, | 87 | MHD_AccessHandlerCallback dh, void *dh_cls) |
90 | void * dh_cls) { | 88 | { |
91 | struct MHD_Access_Handler * prev; | 89 | struct MHD_Access_Handler *prev; |
92 | struct MHD_Access_Handler * pos; | 90 | struct MHD_Access_Handler *pos; |
93 | 91 | ||
94 | if ( (daemon == NULL) || | 92 | if ((daemon == NULL) || (uri_prefix == NULL) || (dh == NULL)) |
95 | (uri_prefix == NULL) || | 93 | return MHD_NO; |
96 | (dh == NULL) ) | ||
97 | return MHD_NO; | ||
98 | pos = daemon->handlers; | 94 | pos = daemon->handlers; |
99 | prev = NULL; | 95 | prev = NULL; |
100 | while (pos != NULL) { | 96 | while (pos != NULL) |
101 | if ( (dh == pos->dh) && | 97 | { |
102 | (dh_cls == pos->dh_cls) && | 98 | if ((dh == pos->dh) && |
103 | (0 == strcmp(uri_prefix, | 99 | (dh_cls == pos->dh_cls) && |
104 | pos->uri_prefix)) ) { | 100 | (0 == strcmp (uri_prefix, pos->uri_prefix))) |
105 | if (prev == NULL) | 101 | { |
106 | daemon->handlers = pos->next; | 102 | if (prev == NULL) |
107 | else | 103 | daemon->handlers = pos->next; |
108 | prev->next = pos->next; | 104 | else |
109 | free(pos); | 105 | prev->next = pos->next; |
110 | return MHD_YES; | 106 | free (pos); |
107 | return MHD_YES; | ||
108 | } | ||
109 | prev = pos; | ||
110 | pos = pos->next; | ||
111 | } | 111 | } |
112 | prev = pos; | ||
113 | pos = pos->next; | ||
114 | } | ||
115 | return MHD_NO; | 112 | return MHD_NO; |
116 | } | 113 | } |
117 | 114 | ||
@@ -123,34 +120,32 @@ MHD_unregister_handler(struct MHD_Daemon * daemon, | |||
123 | * options for this call. | 120 | * options for this call. |
124 | */ | 121 | */ |
125 | int | 122 | int |
126 | MHD_get_fdset(struct MHD_Daemon * daemon, | 123 | MHD_get_fdset (struct MHD_Daemon *daemon, |
127 | fd_set * read_fd_set, | 124 | fd_set * read_fd_set, |
128 | fd_set * write_fd_set, | 125 | fd_set * write_fd_set, fd_set * except_fd_set, int *max_fd) |
129 | fd_set * except_fd_set, | 126 | { |
130 | int * max_fd) { | 127 | struct MHD_Connection *pos; |
131 | struct MHD_Connection * pos; | 128 | |
132 | 129 | if ((daemon == NULL) || | |
133 | if ( (daemon == NULL) || | 130 | (read_fd_set == NULL) || |
134 | (read_fd_set == NULL) || | 131 | (write_fd_set == NULL) || |
135 | (write_fd_set == NULL) || | 132 | (except_fd_set == NULL) || |
136 | (except_fd_set == NULL) || | 133 | (max_fd == NULL) || |
137 | (max_fd == NULL) || | 134 | ((daemon->options & MHD_USE_THREAD_PER_CONNECTION) != 0)) |
138 | ( (daemon->options & MHD_USE_THREAD_PER_CONNECTION) != 0) ) | 135 | return MHD_NO; |
139 | return MHD_NO; | 136 | FD_SET (daemon->socket_fd, read_fd_set); |
140 | FD_SET(daemon->socket_fd, | 137 | if ((*max_fd) < daemon->socket_fd) |
141 | read_fd_set); | ||
142 | if ( (*max_fd) < daemon->socket_fd) | ||
143 | *max_fd = daemon->socket_fd; | 138 | *max_fd = daemon->socket_fd; |
144 | pos = daemon->connections; | 139 | pos = daemon->connections; |
145 | while (pos != NULL) { | 140 | while (pos != NULL) |
146 | if (MHD_YES != MHD_connection_get_fdset(pos, | 141 | { |
147 | read_fd_set, | 142 | if (MHD_YES != MHD_connection_get_fdset (pos, |
148 | write_fd_set, | 143 | read_fd_set, |
149 | except_fd_set, | 144 | write_fd_set, |
150 | max_fd)) | 145 | except_fd_set, max_fd)) |
151 | return MHD_NO; | 146 | return MHD_NO; |
152 | pos = pos->next; | 147 | pos = pos->next; |
153 | } | 148 | } |
154 | return MHD_YES; | 149 | return MHD_YES; |
155 | } | 150 | } |
156 | 151 | ||
@@ -160,8 +155,9 @@ MHD_get_fdset(struct MHD_Daemon * daemon, | |||
160 | * connection. | 155 | * connection. |
161 | */ | 156 | */ |
162 | static void * | 157 | static void * |
163 | MHD_handle_connection(void * data) { | 158 | MHD_handle_connection (void *data) |
164 | struct MHD_Connection * con = data; | 159 | { |
160 | struct MHD_Connection *con = data; | ||
165 | int num_ready; | 161 | int num_ready; |
166 | fd_set rs; | 162 | fd_set rs; |
167 | fd_set ws; | 163 | fd_set ws; |
@@ -169,42 +165,35 @@ MHD_handle_connection(void * data) { | |||
169 | int max; | 165 | int max; |
170 | 166 | ||
171 | if (con == NULL) | 167 | if (con == NULL) |
172 | abort(); | 168 | abort (); |
173 | while ( (! con->daemon->shutdown) && | 169 | while ((!con->daemon->shutdown) && (con->socket_fd != -1)) |
174 | (con->socket_fd != -1) ) { | 170 | { |
175 | FD_ZERO(&rs); | 171 | FD_ZERO (&rs); |
176 | FD_ZERO(&ws); | 172 | FD_ZERO (&ws); |
177 | FD_ZERO(&es); | 173 | FD_ZERO (&es); |
178 | max = 0; | 174 | max = 0; |
179 | MHD_connection_get_fdset(con, | 175 | MHD_connection_get_fdset (con, &rs, &ws, &es, &max); |
180 | &rs, | 176 | num_ready = SELECT (max + 1, &rs, &ws, &es, NULL); |
181 | &ws, | 177 | if (num_ready <= 0) |
182 | &es, | 178 | { |
183 | &max); | 179 | if (errno == EINTR) |
184 | num_ready = SELECT(max + 1, | 180 | continue; |
185 | &rs, | 181 | break; |
186 | &ws, | 182 | } |
187 | &es, | 183 | if (((FD_ISSET (con->socket_fd, &rs)) && |
188 | NULL); | 184 | (MHD_YES != MHD_connection_handle_read (con))) || |
189 | if (num_ready <= 0) { | 185 | ((con->socket_fd != -1) && |
190 | if (errno == EINTR) | 186 | (FD_ISSET (con->socket_fd, &ws)) && |
191 | continue; | 187 | (MHD_YES != MHD_connection_handle_write (con)))) |
192 | break; | 188 | break; |
189 | if ((con->headersReceived == 1) && (con->response == NULL)) | ||
190 | MHD_call_connection_handler (con); | ||
191 | } | ||
192 | if (con->socket_fd != -1) | ||
193 | { | ||
194 | CLOSE (con->socket_fd); | ||
195 | con->socket_fd = -1; | ||
193 | } | 196 | } |
194 | if ( ( (FD_ISSET(con->socket_fd, &rs)) && | ||
195 | (MHD_YES != MHD_connection_handle_read(con)) ) || | ||
196 | ( (con->socket_fd != -1) && | ||
197 | (FD_ISSET(con->socket_fd, &ws)) && | ||
198 | (MHD_YES != MHD_connection_handle_write(con)) ) ) | ||
199 | break; | ||
200 | if ( (con->headersReceived == 1) && | ||
201 | (con->response == NULL) ) | ||
202 | MHD_call_connection_handler(con); | ||
203 | } | ||
204 | if (con->socket_fd != -1) { | ||
205 | CLOSE(con->socket_fd); | ||
206 | con->socket_fd = -1; | ||
207 | } | ||
208 | return NULL; | 197 | return NULL; |
209 | } | 198 | } |
210 | 199 | ||
@@ -215,77 +204,66 @@ MHD_handle_connection(void * data) { | |||
215 | * accept policy callback. | 204 | * accept policy callback. |
216 | */ | 205 | */ |
217 | static int | 206 | static int |
218 | MHD_accept_connection(struct MHD_Daemon * daemon) { | 207 | MHD_accept_connection (struct MHD_Daemon *daemon) |
219 | struct MHD_Connection * connection; | 208 | { |
209 | struct MHD_Connection *connection; | ||
220 | struct sockaddr_in6 addr6; | 210 | struct sockaddr_in6 addr6; |
221 | struct sockaddr * addr = (struct sockaddr*) &addr6; | 211 | struct sockaddr *addr = (struct sockaddr *) &addr6; |
222 | socklen_t addrlen; | 212 | socklen_t addrlen; |
223 | int s; | 213 | int s; |
224 | 214 | ||
225 | 215 | ||
226 | if (sizeof(struct sockaddr) > sizeof(struct sockaddr_in6)) | 216 | if (sizeof (struct sockaddr) > sizeof (struct sockaddr_in6)) |
227 | abort(); /* fatal, serious error */ | 217 | abort (); /* fatal, serious error */ |
228 | addrlen = sizeof(struct sockaddr_in6); | 218 | addrlen = sizeof (struct sockaddr_in6); |
229 | memset(addr, | 219 | memset (addr, 0, sizeof (struct sockaddr_in6)); |
230 | 0, | 220 | s = ACCEPT (daemon->socket_fd, addr, &addrlen); |
231 | sizeof(struct sockaddr_in6)); | 221 | if ((s < 0) || (addrlen <= 0)) |
232 | s = ACCEPT(daemon->socket_fd, | 222 | { |
233 | addr, | 223 | MHD_DLOG (daemon, "Error accepting connection: %s\n", STRERROR (errno)); |
234 | &addrlen); | 224 | if (s != -1) |
235 | if ( (s < 0) || | 225 | CLOSE (s); /* just in case */ |
236 | (addrlen <= 0) ) { | 226 | return MHD_NO; |
237 | MHD_DLOG(daemon, | 227 | } |
238 | "Error accepting connection: %s\n", | 228 | if (daemon->max_connections == 0) |
239 | STRERROR(errno)); | 229 | { |
240 | if (s != -1) | 230 | /* above connection limit - reject */ |
241 | CLOSE(s); /* just in case */ | 231 | CLOSE (s); |
242 | return MHD_NO; | 232 | return MHD_NO; |
243 | } | 233 | } |
244 | if (daemon->max_connections == 0) { | 234 | if ((daemon->apc != NULL) && |
245 | /* above connection limit - reject */ | 235 | (MHD_NO == daemon->apc (daemon->apc_cls, addr, addrlen))) |
246 | CLOSE(s); | 236 | { |
247 | return MHD_NO; | 237 | CLOSE (s); |
248 | } | 238 | return MHD_YES; |
249 | if ( (daemon->apc != NULL) && | 239 | } |
250 | (MHD_NO == daemon->apc(daemon->apc_cls, | 240 | connection = malloc (sizeof (struct MHD_Connection)); |
251 | addr, | 241 | memset (connection, 0, sizeof (struct MHD_Connection)); |
252 | addrlen)) ) { | ||
253 | CLOSE(s); | ||
254 | return MHD_YES; | ||
255 | } | ||
256 | connection = malloc(sizeof(struct MHD_Connection)); | ||
257 | memset(connection, | ||
258 | 0, | ||
259 | sizeof(struct MHD_Connection)); | ||
260 | connection->pool = NULL; | 242 | connection->pool = NULL; |
261 | connection->addr = malloc(addrlen); | 243 | connection->addr = malloc (addrlen); |
262 | if (connection->addr == NULL) { | 244 | if (connection->addr == NULL) |
263 | CLOSE(s); | 245 | { |
264 | free(connection); | 246 | CLOSE (s); |
265 | return MHD_NO; | 247 | free (connection); |
266 | } | 248 | return MHD_NO; |
267 | memcpy(connection->addr, | 249 | } |
268 | addr, | 250 | memcpy (connection->addr, addr, addrlen); |
269 | addrlen); | ||
270 | connection->addr_len = addrlen; | 251 | connection->addr_len = addrlen; |
271 | connection->socket_fd = s; | 252 | connection->socket_fd = s; |
272 | connection->daemon = daemon; | 253 | connection->daemon = daemon; |
273 | if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION) ) && | 254 | if ((0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && |
274 | (0 != pthread_create(&connection->pid, | 255 | (0 != pthread_create (&connection->pid, |
275 | NULL, | 256 | NULL, &MHD_handle_connection, connection))) |
276 | &MHD_handle_connection, | 257 | { |
277 | connection)) ) { | 258 | MHD_DLOG (daemon, "Failed to create a thread: %s\n", STRERROR (errno)); |
278 | MHD_DLOG(daemon, | 259 | CLOSE (s); |
279 | "Failed to create a thread: %s\n", | 260 | free (connection->addr); |
280 | STRERROR(errno)); | 261 | free (connection); |
281 | CLOSE(s); | 262 | return MHD_NO; |
282 | free(connection->addr); | 263 | } |
283 | free(connection); | ||
284 | return MHD_NO; | ||
285 | } | ||
286 | connection->next = daemon->connections; | 264 | connection->next = daemon->connections; |
287 | daemon->connections = connection; | 265 | daemon->connections = connection; |
288 | daemon->max_connections--; | 266 | daemon->max_connections--; |
289 | return MHD_YES; | 267 | return MHD_YES; |
290 | } | 268 | } |
291 | 269 | ||
@@ -301,43 +279,46 @@ MHD_accept_connection(struct MHD_Daemon * daemon) { | |||
301 | * the upload data buffer is full). | 279 | * the upload data buffer is full). |
302 | */ | 280 | */ |
303 | static void | 281 | static void |
304 | MHD_cleanup_connections(struct MHD_Daemon * daemon) { | 282 | MHD_cleanup_connections (struct MHD_Daemon *daemon) |
305 | struct MHD_Connection * pos; | 283 | { |
306 | struct MHD_Connection * prev; | 284 | struct MHD_Connection *pos; |
307 | void * unused; | 285 | struct MHD_Connection *prev; |
286 | void *unused; | ||
308 | 287 | ||
309 | pos = daemon->connections; | 288 | pos = daemon->connections; |
310 | prev = NULL; | 289 | prev = NULL; |
311 | while (pos != NULL) { | 290 | while (pos != NULL) |
312 | if (pos->socket_fd == -1) { | 291 | { |
313 | if (prev == NULL) | 292 | if (pos->socket_fd == -1) |
314 | daemon->connections = pos->next; | 293 | { |
315 | else | 294 | if (prev == NULL) |
316 | prev->next = pos->next; | 295 | daemon->connections = pos->next; |
317 | if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) { | 296 | else |
318 | pthread_kill(pos->pid, SIGALRM); | 297 | prev->next = pos->next; |
319 | pthread_join(pos->pid, &unused); | 298 | if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) |
320 | } | 299 | { |
321 | if (pos->response != NULL) | 300 | pthread_kill (pos->pid, SIGALRM); |
322 | MHD_destroy_response(pos->response); | 301 | pthread_join (pos->pid, &unused); |
323 | MHD_pool_destroy(pos->pool); | 302 | } |
324 | free(pos->addr); | 303 | if (pos->response != NULL) |
325 | free(pos); | 304 | MHD_destroy_response (pos->response); |
326 | daemon->max_connections++; | 305 | MHD_pool_destroy (pos->pool); |
327 | if (prev == NULL) | 306 | free (pos->addr); |
328 | pos = daemon->connections; | 307 | free (pos); |
329 | else | 308 | daemon->max_connections++; |
330 | pos = prev->next; | 309 | if (prev == NULL) |
331 | continue; | 310 | pos = daemon->connections; |
311 | else | ||
312 | pos = prev->next; | ||
313 | continue; | ||
314 | } | ||
315 | |||
316 | if ((pos->headersReceived == 1) && (pos->response == NULL)) | ||
317 | MHD_call_connection_handler (pos); | ||
318 | |||
319 | prev = pos; | ||
320 | pos = pos->next; | ||
332 | } | 321 | } |
333 | |||
334 | if ( (pos->headersReceived == 1) && | ||
335 | (pos->response == NULL) ) | ||
336 | MHD_call_connection_handler(pos); | ||
337 | |||
338 | prev = pos; | ||
339 | pos = pos->next; | ||
340 | } | ||
341 | } | 322 | } |
342 | 323 | ||
343 | 324 | ||
@@ -348,9 +329,9 @@ MHD_cleanup_connections(struct MHD_Daemon * daemon) { | |||
348 | * @return MHD_NO on serious errors, MHD_YES on success | 329 | * @return MHD_NO on serious errors, MHD_YES on success |
349 | */ | 330 | */ |
350 | static int | 331 | static int |
351 | MHD_select(struct MHD_Daemon * daemon, | 332 | MHD_select (struct MHD_Daemon *daemon, int may_block) |
352 | int may_block) { | 333 | { |
353 | struct MHD_Connection * pos; | 334 | struct MHD_Connection *pos; |
354 | int num_ready; | 335 | int num_ready; |
355 | fd_set rs; | 336 | fd_set rs; |
356 | fd_set ws; | 337 | fd_set ws; |
@@ -361,61 +342,58 @@ MHD_select(struct MHD_Daemon * daemon, | |||
361 | 342 | ||
362 | timeout.tv_sec = 0; | 343 | timeout.tv_sec = 0; |
363 | timeout.tv_usec = 0; | 344 | timeout.tv_usec = 0; |
364 | if(daemon == NULL) | 345 | if (daemon == NULL) |
365 | abort(); | 346 | abort (); |
366 | FD_ZERO(&rs); | 347 | FD_ZERO (&rs); |
367 | FD_ZERO(&ws); | 348 | FD_ZERO (&ws); |
368 | FD_ZERO(&es); | 349 | FD_ZERO (&es); |
369 | max = 0; | 350 | max = 0; |
370 | 351 | ||
371 | if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) { | 352 | if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) |
372 | /* single-threaded, go over everything */ | 353 | { |
373 | if (MHD_NO == MHD_get_fdset(daemon, | 354 | /* single-threaded, go over everything */ |
374 | &rs, | 355 | if (MHD_NO == MHD_get_fdset (daemon, &rs, &ws, &es, &max)) |
375 | &ws, | 356 | return MHD_NO; |
376 | &es, | 357 | } |
377 | &max)) | 358 | else |
359 | { | ||
360 | /* accept only, have one thread per connection */ | ||
361 | max = daemon->socket_fd; | ||
362 | FD_SET (daemon->socket_fd, &rs); | ||
363 | } | ||
364 | num_ready = SELECT (max + 1, | ||
365 | &rs, &ws, &es, may_block == MHD_NO ? &timeout : NULL); | ||
366 | if (num_ready < 0) | ||
367 | { | ||
368 | if (errno == EINTR) | ||
369 | return MHD_YES; | ||
370 | MHD_DLOG (daemon, "Select failed: %s\n", STRERROR (errno)); | ||
378 | return MHD_NO; | 371 | return MHD_NO; |
379 | } else { | 372 | } |
380 | /* accept only, have one thread per connection */ | ||
381 | max = daemon->socket_fd; | ||
382 | FD_SET(daemon->socket_fd, &rs); | ||
383 | } | ||
384 | num_ready = SELECT(max + 1, | ||
385 | &rs, | ||
386 | &ws, | ||
387 | &es, | ||
388 | may_block == MHD_NO ? &timeout : NULL); | ||
389 | if (num_ready < 0) { | ||
390 | if (errno == EINTR) | ||
391 | return MHD_YES; | ||
392 | MHD_DLOG(daemon, | ||
393 | "Select failed: %s\n", | ||
394 | STRERROR(errno)); | ||
395 | return MHD_NO; | ||
396 | } | ||
397 | ds = daemon->socket_fd; | 373 | ds = daemon->socket_fd; |
398 | if (ds == -1) | 374 | if (ds == -1) |
399 | return MHD_YES; | 375 | return MHD_YES; |
400 | if (FD_ISSET(ds, | 376 | if (FD_ISSET (ds, &rs)) |
401 | &rs)) | 377 | MHD_accept_connection (daemon); |
402 | MHD_accept_connection(daemon); | 378 | if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) |
403 | if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) { | 379 | { |
404 | /* do not have a thread per connection, process all connections now */ | 380 | /* do not have a thread per connection, process all connections now */ |
405 | pos = daemon->connections; | 381 | pos = daemon->connections; |
406 | while (pos != NULL) { | 382 | while (pos != NULL) |
407 | ds = pos->socket_fd; | 383 | { |
408 | if (ds == -1) { | 384 | ds = pos->socket_fd; |
409 | pos = pos->next; | 385 | if (ds == -1) |
410 | continue; | 386 | { |
411 | } | 387 | pos = pos->next; |
412 | if (FD_ISSET(ds, &rs)) | 388 | continue; |
413 | MHD_connection_handle_read(pos); | 389 | } |
414 | if (FD_ISSET(ds, &ws)) | 390 | if (FD_ISSET (ds, &rs)) |
415 | MHD_connection_handle_write(pos); | 391 | MHD_connection_handle_read (pos); |
416 | pos = pos->next; | 392 | if (FD_ISSET (ds, &ws)) |
393 | MHD_connection_handle_write (pos); | ||
394 | pos = pos->next; | ||
395 | } | ||
417 | } | 396 | } |
418 | } | ||
419 | return MHD_YES; | 397 | return MHD_YES; |
420 | } | 398 | } |
421 | 399 | ||
@@ -431,13 +409,14 @@ MHD_select(struct MHD_Daemon * daemon, | |||
431 | * options for this call. | 409 | * options for this call. |
432 | */ | 410 | */ |
433 | int | 411 | int |
434 | MHD_run(struct MHD_Daemon * daemon) { | 412 | MHD_run (struct MHD_Daemon *daemon) |
435 | if ( (daemon->shutdown != 0) || | 413 | { |
436 | (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || | 414 | if ((daemon->shutdown != 0) || |
437 | (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) ) | 415 | (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || |
416 | (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY))) | ||
438 | return MHD_NO; | 417 | return MHD_NO; |
439 | MHD_select(daemon, MHD_NO); | 418 | MHD_select (daemon, MHD_NO); |
440 | MHD_cleanup_connections(daemon); | 419 | MHD_cleanup_connections (daemon); |
441 | return MHD_YES; | 420 | return MHD_YES; |
442 | } | 421 | } |
443 | 422 | ||
@@ -447,12 +426,14 @@ MHD_run(struct MHD_Daemon * daemon) { | |||
447 | * is explicitly shut down. | 426 | * is explicitly shut down. |
448 | */ | 427 | */ |
449 | static void * | 428 | static void * |
450 | MHD_select_thread(void * cls) { | 429 | MHD_select_thread (void *cls) |
451 | struct MHD_Daemon * daemon = cls; | 430 | { |
452 | while (daemon->shutdown == 0) { | 431 | struct MHD_Daemon *daemon = cls; |
453 | MHD_select(daemon, MHD_YES); | 432 | while (daemon->shutdown == 0) |
454 | MHD_cleanup_connections(daemon); | 433 | { |
455 | } | 434 | MHD_select (daemon, MHD_YES); |
435 | MHD_cleanup_connections (daemon); | ||
436 | } | ||
456 | return NULL; | 437 | return NULL; |
457 | } | 438 | } |
458 | 439 | ||
@@ -469,88 +450,75 @@ MHD_select_thread(void * cls) { | |||
469 | * @return NULL on error, handle to daemon on success | 450 | * @return NULL on error, handle to daemon on success |
470 | */ | 451 | */ |
471 | struct MHD_Daemon * | 452 | struct MHD_Daemon * |
472 | MHD_start_daemon(unsigned int options, | 453 | MHD_start_daemon (unsigned int options, |
473 | unsigned short port, | 454 | unsigned short port, |
474 | MHD_AcceptPolicyCallback apc, | 455 | MHD_AcceptPolicyCallback apc, |
475 | void * apc_cls, | 456 | void *apc_cls, |
476 | MHD_AccessHandlerCallback dh, | 457 | MHD_AccessHandlerCallback dh, void *dh_cls, ...) |
477 | void * dh_cls, | 458 | { |
478 | ...) { | ||
479 | const int on = 1; | 459 | const int on = 1; |
480 | struct MHD_Daemon * retVal; | 460 | struct MHD_Daemon *retVal; |
481 | int socket_fd; | 461 | int socket_fd; |
482 | struct sockaddr_in servaddr4; | 462 | struct sockaddr_in servaddr4; |
483 | struct sockaddr_in6 servaddr6; | 463 | struct sockaddr_in6 servaddr6; |
484 | const struct sockaddr * servaddr; | 464 | const struct sockaddr *servaddr; |
485 | socklen_t addrlen; | 465 | socklen_t addrlen; |
486 | va_list ap; | 466 | va_list ap; |
487 | enum MHD_OPTION opt; | 467 | enum MHD_OPTION opt; |
488 | 468 | ||
489 | if ((options & MHD_USE_SSL) != 0) | 469 | if ((options & MHD_USE_SSL) != 0) |
490 | return NULL; | 470 | return NULL; |
491 | if ( (port == 0) || | 471 | if ((port == 0) || (dh == NULL)) |
492 | (dh == NULL) ) | ||
493 | return NULL; | 472 | return NULL; |
494 | if ((options & MHD_USE_IPv6) != 0) | 473 | if ((options & MHD_USE_IPv6) != 0) |
495 | socket_fd = SOCKET(PF_INET6, SOCK_STREAM, 0); | 474 | socket_fd = SOCKET (PF_INET6, SOCK_STREAM, 0); |
496 | else | 475 | else |
497 | socket_fd = SOCKET(PF_INET, SOCK_STREAM, 0); | 476 | socket_fd = SOCKET (PF_INET, SOCK_STREAM, 0); |
498 | if (socket_fd < 0) { | 477 | if (socket_fd < 0) |
499 | if ((options & MHD_USE_DEBUG) != 0) | 478 | { |
500 | fprintf(stderr, | 479 | if ((options & MHD_USE_DEBUG) != 0) |
501 | "Call to socket failed: %s\n", | 480 | fprintf (stderr, "Call to socket failed: %s\n", STRERROR (errno)); |
502 | STRERROR(errno)); | 481 | return NULL; |
503 | return NULL; | 482 | } |
504 | } | 483 | if ((SETSOCKOPT (socket_fd, |
505 | if ( (SETSOCKOPT(socket_fd, | 484 | SOL_SOCKET, |
506 | SOL_SOCKET, | 485 | SO_REUSEADDR, |
507 | SO_REUSEADDR, | 486 | &on, sizeof (on)) < 0) && (options & MHD_USE_DEBUG) != 0) |
508 | &on, | 487 | fprintf (stderr, "setsockopt failed: %s\n", STRERROR (errno)); |
509 | sizeof(on)) < 0) && | 488 | if ((options & MHD_USE_IPv6) != 0) |
510 | (options & MHD_USE_DEBUG) != 0) | 489 | { |
511 | fprintf(stderr, | 490 | memset (&servaddr6, 0, sizeof (struct sockaddr_in6)); |
512 | "setsockopt failed: %s\n", | 491 | servaddr6.sin6_family = AF_INET6; |
513 | STRERROR(errno)); | 492 | servaddr6.sin6_port = htons (port); |
514 | if ((options & MHD_USE_IPv6) != 0) { | 493 | servaddr = (struct sockaddr *) &servaddr6; |
515 | memset(&servaddr6, | 494 | addrlen = sizeof (struct sockaddr_in6); |
516 | 0, | 495 | } |
517 | sizeof(struct sockaddr_in6)); | 496 | else |
518 | servaddr6.sin6_family = AF_INET6; | 497 | { |
519 | servaddr6.sin6_port = htons(port); | 498 | memset (&servaddr4, 0, sizeof (struct sockaddr_in)); |
520 | servaddr = (struct sockaddr*) &servaddr6; | 499 | servaddr4.sin_family = AF_INET; |
521 | addrlen = sizeof(struct sockaddr_in6); | 500 | servaddr4.sin_port = htons (port); |
522 | } else { | 501 | servaddr = (struct sockaddr *) &servaddr4; |
523 | memset(&servaddr4, | 502 | addrlen = sizeof (struct sockaddr_in); |
524 | 0, | 503 | } |
525 | sizeof(struct sockaddr_in)); | 504 | if (BIND (socket_fd, servaddr, addrlen) < 0) |
526 | servaddr4.sin_family = AF_INET; | 505 | { |
527 | servaddr4.sin_port = htons(port); | 506 | if ((options & MHD_USE_DEBUG) != 0) |
528 | servaddr = (struct sockaddr*) &servaddr4; | 507 | fprintf (stderr, |
529 | addrlen = sizeof(struct sockaddr_in); | 508 | "Failed to bind to port %u: %s\n", port, STRERROR (errno)); |
530 | } | 509 | CLOSE (socket_fd); |
531 | if (BIND(socket_fd, | 510 | return NULL; |
532 | servaddr, | 511 | } |
533 | addrlen) < 0) { | 512 | if (LISTEN (socket_fd, 20) < 0) |
534 | if ( (options & MHD_USE_DEBUG) != 0) | 513 | { |
535 | fprintf(stderr, | 514 | if ((options & MHD_USE_DEBUG) != 0) |
536 | "Failed to bind to port %u: %s\n", | 515 | fprintf (stderr, |
537 | port, | 516 | "Failed to listen for connections: %s\n", STRERROR (errno)); |
538 | STRERROR(errno)); | 517 | CLOSE (socket_fd); |
539 | CLOSE(socket_fd); | 518 | return NULL; |
540 | return NULL; | 519 | } |
541 | } | 520 | retVal = malloc (sizeof (struct MHD_Daemon)); |
542 | if (LISTEN(socket_fd, 20) < 0) { | 521 | memset (retVal, 0, sizeof (struct MHD_Daemon)); |
543 | if ((options & MHD_USE_DEBUG) != 0) | ||
544 | fprintf(stderr, | ||
545 | "Failed to listen for connections: %s\n", | ||
546 | STRERROR(errno)); | ||
547 | CLOSE(socket_fd); | ||
548 | return NULL; | ||
549 | } | ||
550 | retVal = malloc(sizeof(struct MHD_Daemon)); | ||
551 | memset(retVal, | ||
552 | 0, | ||
553 | sizeof(struct MHD_Daemon)); | ||
554 | retVal->options = options; | 522 | retVal->options = options; |
555 | retVal->port = port; | 523 | retVal->port = port; |
556 | retVal->apc = apc; | 524 | retVal->apc = apc; |
@@ -562,35 +530,34 @@ MHD_start_daemon(unsigned int options, | |||
562 | retVal->default_handler.next = NULL; | 530 | retVal->default_handler.next = NULL; |
563 | retVal->max_connections = MHD_MAX_CONNECTIONS_DEFAULT; | 531 | retVal->max_connections = MHD_MAX_CONNECTIONS_DEFAULT; |
564 | retVal->pool_size = MHD_POOL_SIZE_DEFAULT; | 532 | retVal->pool_size = MHD_POOL_SIZE_DEFAULT; |
565 | va_start(ap, dh_cls); | 533 | va_start (ap, dh_cls); |
566 | while (MHD_OPTION_END != (opt = va_arg(ap, enum MHD_OPTION))) { | 534 | while (MHD_OPTION_END != (opt = va_arg (ap, enum MHD_OPTION))) |
567 | switch (opt) { | 535 | { |
568 | case MHD_OPTION_CONNECTION_MEMORY_LIMIT: | 536 | switch (opt) |
569 | retVal->pool_size = va_arg(ap, unsigned int); | 537 | { |
570 | break; | 538 | case MHD_OPTION_CONNECTION_MEMORY_LIMIT: |
571 | case MHD_OPTION_CONNECTION_LIMIT: | 539 | retVal->pool_size = va_arg (ap, unsigned int); |
572 | retVal->max_connections = va_arg(ap, unsigned int); | 540 | break; |
573 | break; | 541 | case MHD_OPTION_CONNECTION_LIMIT: |
574 | default: | 542 | retVal->max_connections = va_arg (ap, unsigned int); |
575 | fprintf(stderr, | 543 | break; |
576 | "Invalid MHD_OPTION argument! (Did you terminate the list with MHD_OPTION_END?)\n"); | 544 | default: |
577 | abort(); | 545 | fprintf (stderr, |
546 | "Invalid MHD_OPTION argument! (Did you terminate the list with MHD_OPTION_END?)\n"); | ||
547 | abort (); | ||
548 | } | ||
549 | } | ||
550 | va_end (ap); | ||
551 | if (((0 != (options & MHD_USE_THREAD_PER_CONNECTION)) || | ||
552 | (0 != (options & MHD_USE_SELECT_INTERNALLY))) && | ||
553 | (0 != pthread_create (&retVal->pid, NULL, &MHD_select_thread, retVal))) | ||
554 | { | ||
555 | MHD_DLOG (retVal, | ||
556 | "Failed to create listen thread: %s\n", STRERROR (errno)); | ||
557 | free (retVal); | ||
558 | CLOSE (socket_fd); | ||
559 | return NULL; | ||
578 | } | 560 | } |
579 | } | ||
580 | va_end(ap); | ||
581 | if ( ( (0 != (options & MHD_USE_THREAD_PER_CONNECTION)) || | ||
582 | (0 != (options & MHD_USE_SELECT_INTERNALLY)) ) && | ||
583 | (0 != pthread_create(&retVal->pid, | ||
584 | NULL, | ||
585 | &MHD_select_thread, | ||
586 | retVal)) ) { | ||
587 | MHD_DLOG(retVal, | ||
588 | "Failed to create listen thread: %s\n", | ||
589 | STRERROR(errno)); | ||
590 | free(retVal); | ||
591 | CLOSE(socket_fd); | ||
592 | return NULL; | ||
593 | } | ||
594 | return retVal; | 561 | return retVal; |
595 | } | 562 | } |
596 | 563 | ||
@@ -598,27 +565,31 @@ MHD_start_daemon(unsigned int options, | |||
598 | * Shutdown an http daemon. | 565 | * Shutdown an http daemon. |
599 | */ | 566 | */ |
600 | void | 567 | void |
601 | MHD_stop_daemon(struct MHD_Daemon * daemon) { | 568 | MHD_stop_daemon (struct MHD_Daemon *daemon) |
602 | void * unused; | 569 | { |
570 | void *unused; | ||
603 | 571 | ||
604 | if (daemon == NULL) | 572 | if (daemon == NULL) |
605 | return; | 573 | return; |
606 | daemon->shutdown = 1; | 574 | daemon->shutdown = 1; |
607 | CLOSE(daemon->socket_fd); | 575 | CLOSE (daemon->socket_fd); |
608 | daemon->socket_fd = -1; | 576 | daemon->socket_fd = -1; |
609 | if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || | 577 | if ((0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || |
610 | (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) ) { | 578 | (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY))) |
611 | pthread_kill(daemon->pid, SIGALRM); | 579 | { |
612 | pthread_join(daemon->pid, &unused); | 580 | pthread_kill (daemon->pid, SIGALRM); |
613 | } | 581 | pthread_join (daemon->pid, &unused); |
614 | while (daemon->connections != NULL) { | 582 | } |
615 | if (-1 != daemon->connections->socket_fd) { | 583 | while (daemon->connections != NULL) |
616 | CLOSE(daemon->connections->socket_fd); | 584 | { |
617 | daemon->connections->socket_fd = -1; | 585 | if (-1 != daemon->connections->socket_fd) |
586 | { | ||
587 | CLOSE (daemon->connections->socket_fd); | ||
588 | daemon->connections->socket_fd = -1; | ||
589 | } | ||
590 | MHD_cleanup_connections (daemon); | ||
618 | } | 591 | } |
619 | MHD_cleanup_connections(daemon); | 592 | free (daemon); |
620 | } | ||
621 | free(daemon); | ||
622 | } | 593 | } |
623 | 594 | ||
624 | #ifndef WINDOWS | 595 | #ifndef WINDOWS |
@@ -627,23 +598,27 @@ static struct sigaction sig; | |||
627 | 598 | ||
628 | static struct sigaction old; | 599 | static struct sigaction old; |
629 | 600 | ||
630 | static void sigalrmHandler(int sig) { | 601 | static void |
602 | sigalrmHandler (int sig) | ||
603 | { | ||
631 | } | 604 | } |
632 | 605 | ||
633 | /** | 606 | /** |
634 | * Initialize the signal handler for SIGALRM. | 607 | * Initialize the signal handler for SIGALRM. |
635 | */ | 608 | */ |
636 | void __attribute__ ((constructor)) MHD_pthread_handlers_ltdl_init() { | 609 | void __attribute__ ((constructor)) MHD_pthread_handlers_ltdl_init () |
610 | { | ||
637 | /* make sure SIGALRM does not kill us */ | 611 | /* make sure SIGALRM does not kill us */ |
638 | memset(&sig, 0, sizeof(struct sigaction)); | 612 | memset (&sig, 0, sizeof (struct sigaction)); |
639 | memset(&old, 0, sizeof(struct sigaction)); | 613 | memset (&old, 0, sizeof (struct sigaction)); |
640 | sig.sa_flags = SA_NODEFER; | 614 | sig.sa_flags = SA_NODEFER; |
641 | sig.sa_handler = &sigalrmHandler; | 615 | sig.sa_handler = &sigalrmHandler; |
642 | sigaction(SIGALRM, &sig, &old); | 616 | sigaction (SIGALRM, &sig, &old); |
643 | } | 617 | } |
644 | 618 | ||
645 | void __attribute__ ((destructor)) MHD_pthread_handlers_ltdl_fini() { | 619 | void __attribute__ ((destructor)) MHD_pthread_handlers_ltdl_fini () |
646 | sigaction(SIGALRM, &old, &sig); | 620 | { |
621 | sigaction (SIGALRM, &old, &sig); | ||
647 | } | 622 | } |
648 | 623 | ||
649 | #endif | 624 | #endif |