aboutsummaryrefslogtreecommitdiff
path: root/src/lib/connection_add.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/connection_add.c')
-rw-r--r--src/lib/connection_add.c1204
1 files changed, 607 insertions, 597 deletions
diff --git a/src/lib/connection_add.c b/src/lib/connection_add.c
index cd933d06..aaf04712 100644
--- a/src/lib/connection_add.c
+++ b/src/lib/connection_add.c
@@ -53,14 +53,14 @@ thread_main_connection_upgrade (struct MHD_Connection *con)
53 with the socket; */ 53 with the socket; */
54 if ( (NULL != daemon->tls_api) && 54 if ( (NULL != daemon->tls_api) &&
55 (MHD_ELS_POLL != daemon->event_loop_syscall) ) 55 (MHD_ELS_POLL != daemon->event_loop_syscall) )
56 { 56 {
57 MHD_daemon_upgrade_connection_with_select_ (con); 57 MHD_daemon_upgrade_connection_with_select_ (con);
58 } 58 }
59#ifdef HAVE_POLL 59#ifdef HAVE_POLL
60 else if (NULL != daemon->tls_api) 60 else if (NULL != daemon->tls_api)
61 { 61 {
62 MHD_daemon_upgrade_connection_with_poll_ (con); 62 MHD_daemon_upgrade_connection_with_poll_ (con);
63 } 63 }
64#endif 64#endif
65 /* end HTTPS */ 65 /* end HTTPS */
66#endif /* HTTPS_SUPPORT */ 66#endif /* HTTPS_SUPPORT */
@@ -111,342 +111,344 @@ thread_main_handle_connection (void *data)
111#endif /* ! HAVE_POLL */ 111#endif /* ! HAVE_POLL */
112 bool was_suspended = false; 112 bool was_suspended = false;
113 113
114 MHD_thread_init_(&con->pid); 114 MHD_thread_init_ (&con->pid);
115 115
116 while ( (! daemon->shutdown) && 116 while ( (! daemon->shutdown) &&
117 (MHD_REQUEST_CLOSED != con->request.state) ) 117 (MHD_REQUEST_CLOSED != con->request.state) )
118 { 118 {
119 const time_t timeout = daemon->connection_default_timeout; 119 const time_t timeout = daemon->connection_default_timeout;
120#ifdef UPGRADE_SUPPORT 120#ifdef UPGRADE_SUPPORT
121 struct MHD_UpgradeResponseHandle * const urh = con->request.urh; 121 struct MHD_UpgradeResponseHandle *const urh = con->request.urh;
122#else /* ! UPGRADE_SUPPORT */ 122#else /* ! UPGRADE_SUPPORT */
123 static const void * const urh = NULL; 123 static const void *const urh = NULL;
124#endif /* ! UPGRADE_SUPPORT */ 124#endif /* ! UPGRADE_SUPPORT */
125 125
126 if ( (con->suspended) && 126 if ( (con->suspended) &&
127 (NULL == urh) ) 127 (NULL == urh) )
128 {
129 /* Connection was suspended, wait for resume. */
130 was_suspended = true;
131 if (! use_poll)
132 {
133 FD_ZERO (&rs);
134 if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
135 &rs,
136 NULL,
137 FD_SETSIZE))
128 { 138 {
129 /* Connection was suspended, wait for resume. */
130 was_suspended = true;
131 if (! use_poll)
132 {
133 FD_ZERO (&rs);
134 if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
135 &rs,
136 NULL,
137 FD_SETSIZE))
138 {
139 #ifdef HAVE_MESSAGES 139 #ifdef HAVE_MESSAGES
140 MHD_DLOG (con->daemon, 140 MHD_DLOG (con->daemon,
141 MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE, 141 MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE,
142 _("Failed to add FD to fd_set\n")); 142 _ ("Failed to add FD to fd_set\n"));
143 #endif 143 #endif
144 goto exit; 144 goto exit;
145 } 145 }
146 if (0 > MHD_SYS_select_ (MHD_itc_r_fd_ (daemon->itc) + 1, 146 if (0 > MHD_SYS_select_ (MHD_itc_r_fd_ (daemon->itc) + 1,
147 &rs, 147 &rs,
148 NULL, 148 NULL,
149 NULL, 149 NULL,
150 NULL)) 150 NULL))
151 { 151 {
152 const int err = MHD_socket_get_error_(); 152 const int err = MHD_socket_get_error_ ();
153 153
154 if (MHD_SCKT_ERR_IS_EINTR_(err)) 154 if (MHD_SCKT_ERR_IS_EINTR_ (err))
155 continue; 155 continue;
156#ifdef HAVE_MESSAGES 156#ifdef HAVE_MESSAGES
157 MHD_DLOG (con->daemon, 157 MHD_DLOG (con->daemon,
158 MHD_SC_UNEXPECTED_SELECT_ERROR, 158 MHD_SC_UNEXPECTED_SELECT_ERROR,
159 _("Error during select (%d): `%s'\n"), 159 _ ("Error during select (%d): `%s'\n"),
160 err, 160 err,
161 MHD_socket_strerr_ (err)); 161 MHD_socket_strerr_ (err));
162#endif 162#endif
163 break; 163 break;
164 } 164 }
165 } 165 }
166#ifdef HAVE_POLL 166#ifdef HAVE_POLL
167 else /* use_poll */ 167 else /* use_poll */
168 { 168 {
169 p[0].events = POLLIN; 169 p[0].events = POLLIN;
170 p[0].fd = MHD_itc_r_fd_ (daemon->itc); 170 p[0].fd = MHD_itc_r_fd_ (daemon->itc);
171 p[0].revents = 0; 171 p[0].revents = 0;
172 if (0 > MHD_sys_poll_ (p, 172 if (0 > MHD_sys_poll_ (p,
173 1, 173 1,
174 -1)) 174 -1))
175 { 175 {
176 if (MHD_SCKT_LAST_ERR_IS_(MHD_SCKT_EINTR_)) 176 if (MHD_SCKT_LAST_ERR_IS_ (MHD_SCKT_EINTR_))
177 continue; 177 continue;
178#ifdef HAVE_MESSAGES 178#ifdef HAVE_MESSAGES
179 MHD_DLOG (con->daemon, 179 MHD_DLOG (con->daemon,
180 MHD_SC_UNEXPECTED_POLL_ERROR, 180 MHD_SC_UNEXPECTED_POLL_ERROR,
181 _("Error during poll: `%s'\n"), 181 _ ("Error during poll: `%s'\n"),
182 MHD_socket_last_strerr_ ()); 182 MHD_socket_last_strerr_ ());
183#endif 183#endif
184 break; 184 break;
185 } 185 }
186 } 186 }
187#endif /* HAVE_POLL */ 187#endif /* HAVE_POLL */
188 MHD_itc_clear_ (daemon->itc); 188 MHD_itc_clear_ (daemon->itc);
189 continue; /* Check again for resume. */ 189 continue; /* Check again for resume. */
190 } /* End of "suspended" branch. */ 190 } /* End of "suspended" branch. */
191 191
192 if (was_suspended) 192 if (was_suspended)
193 { 193 {
194 MHD_connection_update_last_activity_ (con); /* Reset timeout timer. */ 194 MHD_connection_update_last_activity_ (con); /* Reset timeout timer. */
195 /* Process response queued during suspend and update states. */ 195 /* Process response queued during suspend and update states. */
196 MHD_request_handle_idle_ (&con->request); 196 MHD_request_handle_idle_ (&con->request);
197 was_suspended = false; 197 was_suspended = false;
198 } 198 }
199 199
200 tvp = NULL; 200 tvp = NULL;
201 201
202 if ( (MHD_EVENT_LOOP_INFO_BLOCK == con->request.event_loop_info) 202 if ( (MHD_EVENT_LOOP_INFO_BLOCK == con->request.event_loop_info)
203#ifdef HTTPS_SUPPORT 203#ifdef HTTPS_SUPPORT
204 || ( (con->tls_read_ready) && 204 || ( (con->tls_read_ready) &&
205 (MHD_EVENT_LOOP_INFO_READ == con->request.event_loop_info) ) 205 (MHD_EVENT_LOOP_INFO_READ == con->request.event_loop_info) )
206#endif /* HTTPS_SUPPORT */ 206#endif /* HTTPS_SUPPORT */
207 ) 207 )
208 { 208 {
209 /* do not block: more data may be inside of TLS buffers waiting or 209 /* do not block: more data may be inside of TLS buffers waiting or
210 * application must provide response data */ 210 * application must provide response data */
211 tv.tv_sec = 0; 211 tv.tv_sec = 0;
212 tv.tv_usec = 0; 212 tv.tv_usec = 0;
213 tvp = &tv; 213 tvp = &tv;
214 } 214 }
215 if ( (NULL == tvp) && 215 if ( (NULL == tvp) &&
216 (timeout > 0) ) 216 (timeout > 0) )
217 { 217 {
218 now = MHD_monotonic_sec_counter(); 218 now = MHD_monotonic_sec_counter ();
219 if (now - con->last_activity > timeout) 219 if (now - con->last_activity > timeout)
220 tv.tv_sec = 0; 220 tv.tv_sec = 0;
221 else 221 else
222 { 222 {
223 const time_t seconds_left = timeout - (now - con->last_activity); 223 const time_t seconds_left = timeout - (now - con->last_activity);
224#if !defined(_WIN32) || defined(__CYGWIN__) 224#if ! defined(_WIN32) || defined(__CYGWIN__)
225 tv.tv_sec = seconds_left; 225 tv.tv_sec = seconds_left;
226#else /* _WIN32 && !__CYGWIN__ */ 226#else /* _WIN32 && !__CYGWIN__ */
227 if (seconds_left > TIMEVAL_TV_SEC_MAX) 227 if (seconds_left > TIMEVAL_TV_SEC_MAX)
228 tv.tv_sec = TIMEVAL_TV_SEC_MAX; 228 tv.tv_sec = TIMEVAL_TV_SEC_MAX;
229 else 229 else
230 tv.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) seconds_left; 230 tv.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) seconds_left;
231#endif /* _WIN32 && ! __CYGWIN__ */ 231#endif /* _WIN32 && ! __CYGWIN__ */
232 } 232 }
233 tv.tv_usec = 0; 233 tv.tv_usec = 0;
234 tvp = &tv; 234 tvp = &tv;
235 } 235 }
236 if (! use_poll) 236 if (! use_poll)
237 { 237 {
238 /* use select */ 238 /* use select */
239 bool err_state = false; 239 bool err_state = false;
240 240
241 FD_ZERO (&rs); 241 FD_ZERO (&rs);
242 FD_ZERO (&ws); 242 FD_ZERO (&ws);
243 FD_ZERO (&es); 243 FD_ZERO (&es);
244 maxsock = MHD_INVALID_SOCKET; 244 maxsock = MHD_INVALID_SOCKET;
245 switch (con->request.event_loop_info) 245 switch (con->request.event_loop_info)
246 { 246 {
247 case MHD_EVENT_LOOP_INFO_READ: 247 case MHD_EVENT_LOOP_INFO_READ:
248 if (! MHD_add_to_fd_set_ (con->socket_fd, 248 if (! MHD_add_to_fd_set_ (con->socket_fd,
249 &rs, 249 &rs,
250 &maxsock, 250 &maxsock,
251 FD_SETSIZE)) 251 FD_SETSIZE))
252 err_state = true; 252 err_state = true;
253 break; 253 break;
254 case MHD_EVENT_LOOP_INFO_WRITE: 254 case MHD_EVENT_LOOP_INFO_WRITE:
255 if (! MHD_add_to_fd_set_ (con->socket_fd, 255 if (! MHD_add_to_fd_set_ (con->socket_fd,
256 &ws, 256 &ws,
257 &maxsock, 257 &maxsock,
258 FD_SETSIZE)) 258 FD_SETSIZE))
259 err_state = true; 259 err_state = true;
260 break; 260 break;
261 case MHD_EVENT_LOOP_INFO_BLOCK: 261 case MHD_EVENT_LOOP_INFO_BLOCK:
262 if (! MHD_add_to_fd_set_ (con->socket_fd, 262 if (! MHD_add_to_fd_set_ (con->socket_fd,
263 &es, 263 &es,
264 &maxsock, 264 &maxsock,
265 FD_SETSIZE)) 265 FD_SETSIZE))
266 err_state = true; 266 err_state = true;
267 break; 267 break;
268 case MHD_EVENT_LOOP_INFO_CLEANUP: 268 case MHD_EVENT_LOOP_INFO_CLEANUP:
269 /* how did we get here!? */ 269 /* how did we get here!? */
270 goto exit; 270 goto exit;
271 } 271 }
272#if WINDOWS 272#if WINDOWS
273 if (MHD_ITC_IS_VALID_(daemon->itc) ) 273 if (MHD_ITC_IS_VALID_ (daemon->itc) )
274 { 274 {
275 if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc), 275 if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
276 &rs, 276 &rs,
277 &maxsock, 277 &maxsock,
278 FD_SETSIZE)) 278 FD_SETSIZE))
279 err_state = 1; 279 err_state = 1;
280 } 280 }
281#endif 281#endif
282 if (err_state) 282 if (err_state)
283 { 283 {
284#ifdef HAVE_MESSAGES 284#ifdef HAVE_MESSAGES
285 MHD_DLOG (con->daemon, 285 MHD_DLOG (con->daemon,
286 MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE, 286 MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE,
287 _("Failed to add FD to fd_set\n")); 287 _ ("Failed to add FD to fd_set\n"));
288#endif 288#endif
289 goto exit; 289 goto exit;
290 } 290 }
291 291
292 num_ready = MHD_SYS_select_ (maxsock + 1, 292 num_ready = MHD_SYS_select_ (maxsock + 1,
293 &rs, 293 &rs,
294 &ws, 294 &ws,
295 &es, 295 &es,
296 tvp); 296 tvp);
297 if (num_ready < 0) 297 if (num_ready < 0)
298 { 298 {
299 const int err = MHD_socket_get_error_(); 299 const int err = MHD_socket_get_error_ ();
300 300
301 if (MHD_SCKT_ERR_IS_EINTR_(err)) 301 if (MHD_SCKT_ERR_IS_EINTR_ (err))
302 continue; 302 continue;
303#ifdef HAVE_MESSAGES 303#ifdef HAVE_MESSAGES
304 MHD_DLOG (con->daemon, 304 MHD_DLOG (con->daemon,
305 MHD_SC_UNEXPECTED_SELECT_ERROR, 305 MHD_SC_UNEXPECTED_SELECT_ERROR,
306 _("Error during select (%d): `%s'\n"), 306 _ ("Error during select (%d): `%s'\n"),
307 err, 307 err,
308 MHD_socket_strerr_ (err)); 308 MHD_socket_strerr_ (err));
309#endif 309#endif
310 break; 310 break;
311 } 311 }
312#if WINDOWS 312#if WINDOWS
313 /* Clear ITC before other processing so additional 313 /* Clear ITC before other processing so additional
314 * signals will trigger select() again */ 314 * signals will trigger select() again */
315 if ( (MHD_ITC_IS_VALID_(daemon->itc)) && 315 if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
316 (FD_ISSET (MHD_itc_r_fd_ (daemon->itc), 316 (FD_ISSET (MHD_itc_r_fd_ (daemon->itc),
317 &rs)) ) 317 &rs)) )
318 MHD_itc_clear_ (daemon->itc); 318 MHD_itc_clear_ (daemon->itc);
319#endif 319#endif
320 if (MHD_NO == 320 if (MHD_NO ==
321 MHD_connection_call_handlers_ (con, 321 MHD_connection_call_handlers_ (con,
322 FD_ISSET (con->socket_fd, 322 FD_ISSET (con->socket_fd,
323 &rs), 323 &rs),
324 FD_ISSET (con->socket_fd, 324 FD_ISSET (con->socket_fd,
325 &ws), 325 &ws),
326 FD_ISSET (con->socket_fd, 326 FD_ISSET (con->socket_fd,
327 &es)) ) 327 &es)) )
328 goto exit; 328 goto exit;
329 } 329 }
330#ifdef HAVE_POLL 330#ifdef HAVE_POLL
331 else 331 else
332 { 332 {
333 /* use poll */ 333 /* use poll */
334 memset (&p, 334 memset (&p,
335 0, 335 0,
336 sizeof (p)); 336 sizeof (p));
337 p[0].fd = con->socket_fd; 337 p[0].fd = con->socket_fd;
338 switch (con->request.event_loop_info) 338 switch (con->request.event_loop_info)
339 { 339 {
340 case MHD_EVENT_LOOP_INFO_READ: 340 case MHD_EVENT_LOOP_INFO_READ:
341 p[0].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC; 341 p[0].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
342 break; 342 break;
343 case MHD_EVENT_LOOP_INFO_WRITE: 343 case MHD_EVENT_LOOP_INFO_WRITE:
344 p[0].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC; 344 p[0].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
345 break; 345 break;
346 case MHD_EVENT_LOOP_INFO_BLOCK: 346 case MHD_EVENT_LOOP_INFO_BLOCK:
347 p[0].events |= MHD_POLL_EVENTS_ERR_DISC; 347 p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
348 break; 348 break;
349 case MHD_EVENT_LOOP_INFO_CLEANUP: 349 case MHD_EVENT_LOOP_INFO_CLEANUP:
350 /* how did we get here!? */ 350 /* how did we get here!? */
351 goto exit; 351 goto exit;
352 } 352 }
353#if WINDOWS 353#if WINDOWS
354 extra_slot = 0; 354 extra_slot = 0;
355 if (MHD_ITC_IS_VALID_(daemon->itc)) 355 if (MHD_ITC_IS_VALID_ (daemon->itc))
356 { 356 {
357 p[1].events |= POLLIN; 357 p[1].events |= POLLIN;
358 p[1].fd = MHD_itc_r_fd_ (daemon->itc); 358 p[1].fd = MHD_itc_r_fd_ (daemon->itc);
359 p[1].revents = 0; 359 p[1].revents = 0;
360 extra_slot = 1; 360 extra_slot = 1;
361 } 361 }
362#endif 362#endif
363 if (MHD_sys_poll_ (p, 363 if (MHD_sys_poll_ (p,
364#if WINDOWS 364#if WINDOWS
365 1 + extra_slot, 365 1 + extra_slot,
366#else 366#else
367 1, 367 1,
368#endif 368#endif
369 (NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0) 369 (NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0)
370 { 370 {
371 if (MHD_SCKT_LAST_ERR_IS_(MHD_SCKT_EINTR_)) 371 if (MHD_SCKT_LAST_ERR_IS_ (MHD_SCKT_EINTR_))
372 continue; 372 continue;
373#ifdef HAVE_MESSAGES 373#ifdef HAVE_MESSAGES
374 MHD_DLOG (con->daemon, 374 MHD_DLOG (con->daemon,
375 MHD_SC_UNEXPECTED_POLL_ERROR, 375 MHD_SC_UNEXPECTED_POLL_ERROR,
376 _("Error during poll: `%s'\n"), 376 _ ("Error during poll: `%s'\n"),
377 MHD_socket_last_strerr_ ()); 377 MHD_socket_last_strerr_ ());
378#endif 378#endif
379 break; 379 break;
380 } 380 }
381#if WINDOWS 381#if WINDOWS
382 /* Clear ITC before other processing so additional 382 /* Clear ITC before other processing so additional
383 * signals will trigger poll() again */ 383 * signals will trigger poll() again */
384 if ( (MHD_ITC_IS_VALID_(daemon->itc)) && 384 if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
385 (0 != (p[1].revents & (POLLERR | POLLHUP | POLLIN))) ) 385 (0 != (p[1].revents & (POLLERR | POLLHUP | POLLIN))) )
386 MHD_itc_clear_ (daemon->itc); 386 MHD_itc_clear_ (daemon->itc);
387#endif 387#endif
388 if (MHD_NO == 388 if (MHD_NO ==
389 MHD_connection_call_handlers_ (con, 389 MHD_connection_call_handlers_ (con,
390 0 != (p[0].revents & POLLIN), 390 (0 != (p[0].revents & POLLIN)),
391 0 != (p[0].revents & POLLOUT), 391 (0 != (p[0].revents & POLLOUT)),
392 0 != (p[0].revents & (POLLERR | MHD_POLL_REVENTS_ERR_DISC)))) 392 (0 != (p[0].revents & (POLLERR
393 goto exit; 393 |
394 } 394 MHD_POLL_REVENTS_ERR_DISC))) ))
395 goto exit;
396 }
395#endif 397#endif
396#ifdef UPGRADE_SUPPORT 398#ifdef UPGRADE_SUPPORT
397 if (MHD_REQUEST_UPGRADE == con->request.state) 399 if (MHD_REQUEST_UPGRADE == con->request.state)
398 { 400 {
399 /* Normal HTTP processing is finished, 401 /* Normal HTTP processing is finished,
400 * notify application. */ 402 * notify application. */
401 if (NULL != con->request.response->termination_cb) 403 if (NULL != con->request.response->termination_cb)
402 con->request.response->termination_cb 404 con->request.response->termination_cb
403 (con->request.response->termination_cb_cls, 405 (con->request.response->termination_cb_cls,
404 MHD_REQUEST_TERMINATED_COMPLETED_OK, 406 MHD_REQUEST_TERMINATED_COMPLETED_OK,
405 con->request.client_context); 407 con->request.client_context);
406 thread_main_connection_upgrade (con); 408 thread_main_connection_upgrade (con);
407 /* MHD_connection_finish_forward_() was called by thread_main_connection_upgrade(). */ 409 /* MHD_connection_finish_forward_() was called by thread_main_connection_upgrade(). */
408 410
409 /* "Upgraded" data will not be used in this thread from this point. */ 411 /* "Upgraded" data will not be used in this thread from this point. */
410 con->request.urh->clean_ready = true; 412 con->request.urh->clean_ready = true;
411 /* If 'urh->was_closed' set to true, connection will be 413 /* If 'urh->was_closed' set to true, connection will be
412 * moved immediately to cleanup list. Otherwise connection 414 * moved immediately to cleanup list. Otherwise connection
413 * will stay in suspended list until 'urh' will be marked 415 * will stay in suspended list until 'urh' will be marked
414 * with 'was_closed' by application. */ 416 * with 'was_closed' by application. */
415 MHD_request_resume (&con->request); 417 MHD_request_resume (&con->request);
416 418
417 /* skip usual clean up */ 419 /* skip usual clean up */
418 return (MHD_THRD_RTRN_TYPE_) 0; 420 return (MHD_THRD_RTRN_TYPE_) 0;
419 }
420#endif /* UPGRADE_SUPPORT */
421 } 421 }
422#endif /* UPGRADE_SUPPORT */
423 }
422#if DEBUG_CLOSE 424#if DEBUG_CLOSE
423#ifdef HAVE_MESSAGES 425#ifdef HAVE_MESSAGES
424 MHD_DLOG (con->daemon, 426 MHD_DLOG (con->daemon,
425 MHD_SC_THREAD_TERMINATING, 427 MHD_SC_THREAD_TERMINATING,
426 _("Processing thread terminating. Closing connection\n")); 428 _ ("Processing thread terminating. Closing connection\n"));
427#endif 429#endif
428#endif 430#endif
429 if (MHD_REQUEST_CLOSED != con->request.state) 431 if (MHD_REQUEST_CLOSED != con->request.state)
430 MHD_connection_close_ (con, 432 MHD_connection_close_ (con,
431 (daemon->shutdown) ? 433 (daemon->shutdown) ?
432 MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN: 434 MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN :
433 MHD_REQUEST_TERMINATED_WITH_ERROR); 435 MHD_REQUEST_TERMINATED_WITH_ERROR);
434 MHD_request_handle_idle_ (&con->request); 436 MHD_request_handle_idle_ (&con->request);
435exit: 437exit:
436 if (NULL != con->request.response) 438 if (NULL != con->request.response)
437 { 439 {
438 MHD_response_queue_for_destroy (con->request.response); 440 MHD_response_queue_for_destroy (con->request.response);
439 con->request.response = NULL; 441 con->request.response = NULL;
440 } 442 }
441 443
442 if (MHD_INVALID_SOCKET != con->socket_fd) 444 if (MHD_INVALID_SOCKET != con->socket_fd)
443 { 445 {
444 shutdown (con->socket_fd, 446 shutdown (con->socket_fd,
445 SHUT_WR); 447 SHUT_WR);
446 /* 'socket_fd' can be used in other thread to signal shutdown. 448 /* 'socket_fd' can be used in other thread to signal shutdown.
447 * To avoid data races, do not close socket here. Daemon will 449 * To avoid data races, do not close socket here. Daemon will
448 * use more connections only after cleanup anyway. */ 450 * use more connections only after cleanup anyway. */
449 } 451 }
450 return (MHD_THRD_RTRN_TYPE_) 0; 452 return (MHD_THRD_RTRN_TYPE_) 0;
451} 453}
452 454
@@ -469,9 +471,9 @@ recv_param_adapter (struct MHD_Connection *connection,
469 471
470 if ( (MHD_INVALID_SOCKET == connection->socket_fd) || 472 if ( (MHD_INVALID_SOCKET == connection->socket_fd) ||
471 (MHD_REQUEST_CLOSED == connection->request.state) ) 473 (MHD_REQUEST_CLOSED == connection->request.state) )
472 { 474 {
473 return MHD_ERR_NOTCONN_; 475 return MHD_ERR_NOTCONN_;
474 } 476 }
475 if (i > MHD_SCKT_SEND_MAX_SIZE_) 477 if (i > MHD_SCKT_SEND_MAX_SIZE_)
476 i = MHD_SCKT_SEND_MAX_SIZE_; /* return value limit */ 478 i = MHD_SCKT_SEND_MAX_SIZE_; /* return value limit */
477 479
@@ -479,25 +481,25 @@ recv_param_adapter (struct MHD_Connection *connection,
479 other, 481 other,
480 i); 482 i);
481 if (0 > ret) 483 if (0 > ret)
484 {
485 const int err = MHD_socket_get_error_ ();
486 if (MHD_SCKT_ERR_IS_EAGAIN_ (err))
482 { 487 {
483 const int err = MHD_socket_get_error_ ();
484 if (MHD_SCKT_ERR_IS_EAGAIN_ (err))
485 {
486#ifdef EPOLL_SUPPORT 488#ifdef EPOLL_SUPPORT
487 /* Got EAGAIN --- no longer read-ready */ 489 /* Got EAGAIN --- no longer read-ready */
488 connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY; 490 connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY;
489#endif /* EPOLL_SUPPORT */ 491#endif /* EPOLL_SUPPORT */
490 return MHD_ERR_AGAIN_; 492 return MHD_ERR_AGAIN_;
491 }
492 if (MHD_SCKT_ERR_IS_EINTR_ (err))
493 return MHD_ERR_AGAIN_;
494 if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_ECONNRESET_))
495 return MHD_ERR_CONNRESET_;
496 /* Treat any other error as hard error. */
497 return MHD_ERR_NOTCONN_;
498 } 493 }
494 if (MHD_SCKT_ERR_IS_EINTR_ (err))
495 return MHD_ERR_AGAIN_;
496 if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_ECONNRESET_))
497 return MHD_ERR_CONNRESET_;
498 /* Treat any other error as hard error. */
499 return MHD_ERR_NOTCONN_;
500 }
499#ifdef EPOLL_SUPPORT 501#ifdef EPOLL_SUPPORT
500 else if (i > (size_t)ret) 502 else if (i > (size_t) ret)
501 connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY; 503 connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY;
502#endif /* EPOLL_SUPPORT */ 504#endif /* EPOLL_SUPPORT */
503 return ret; 505 return ret;
@@ -522,9 +524,9 @@ send_param_adapter (struct MHD_Connection *connection,
522 524
523 if ( (MHD_INVALID_SOCKET == connection->socket_fd) || 525 if ( (MHD_INVALID_SOCKET == connection->socket_fd) ||
524 (MHD_REQUEST_CLOSED == connection->request.state) ) 526 (MHD_REQUEST_CLOSED == connection->request.state) )
525 { 527 {
526 return MHD_ERR_NOTCONN_; 528 return MHD_ERR_NOTCONN_;
527 } 529 }
528 if (i > MHD_SCKT_SEND_MAX_SIZE_) 530 if (i > MHD_SCKT_SEND_MAX_SIZE_)
529 i = MHD_SCKT_SEND_MAX_SIZE_; /* return value limit */ 531 i = MHD_SCKT_SEND_MAX_SIZE_; /* return value limit */
530 532
@@ -532,26 +534,26 @@ send_param_adapter (struct MHD_Connection *connection,
532 other, 534 other,
533 i); 535 i);
534 if (0 > ret) 536 if (0 > ret)
535 { 537 {
536 const int err = MHD_socket_get_error_(); 538 const int err = MHD_socket_get_error_ ();
537 539
538 if (MHD_SCKT_ERR_IS_EAGAIN_(err)) 540 if (MHD_SCKT_ERR_IS_EAGAIN_ (err))
539 { 541 {
540#ifdef EPOLL_SUPPORT 542#ifdef EPOLL_SUPPORT
541 /* EAGAIN --- no longer write-ready */ 543 /* EAGAIN --- no longer write-ready */
542 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; 544 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
543#endif /* EPOLL_SUPPORT */ 545#endif /* EPOLL_SUPPORT */
544 return MHD_ERR_AGAIN_; 546 return MHD_ERR_AGAIN_;
545 }
546 if (MHD_SCKT_ERR_IS_EINTR_ (err))
547 return MHD_ERR_AGAIN_;
548 if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_ECONNRESET_))
549 return MHD_ERR_CONNRESET_;
550 /* Treat any other error as hard error. */
551 return MHD_ERR_NOTCONN_;
552 } 547 }
548 if (MHD_SCKT_ERR_IS_EINTR_ (err))
549 return MHD_ERR_AGAIN_;
550 if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_ECONNRESET_))
551 return MHD_ERR_CONNRESET_;
552 /* Treat any other error as hard error. */
553 return MHD_ERR_NOTCONN_;
554 }
553#ifdef EPOLL_SUPPORT 555#ifdef EPOLL_SUPPORT
554 else if (i > (size_t)ret) 556 else if (i > (size_t) ret)
555 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; 557 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
556#endif /* EPOLL_SUPPORT */ 558#endif /* EPOLL_SUPPORT */
557 return ret; 559 return ret;
@@ -582,11 +584,11 @@ send_param_adapter (struct MHD_Connection *connection,
582 */ 584 */
583static enum MHD_StatusCode 585static enum MHD_StatusCode
584internal_add_connection (struct MHD_Daemon *daemon, 586internal_add_connection (struct MHD_Daemon *daemon,
585 MHD_socket client_socket, 587 MHD_socket client_socket,
586 const struct sockaddr *addr, 588 const struct sockaddr *addr,
587 socklen_t addrlen, 589 socklen_t addrlen,
588 bool external_add, 590 bool external_add,
589 bool non_blck) 591 bool non_blck)
590{ 592{
591 enum MHD_StatusCode sc; 593 enum MHD_StatusCode sc;
592 struct MHD_Connection *connection; 594 struct MHD_Connection *connection;
@@ -594,78 +596,78 @@ internal_add_connection (struct MHD_Daemon *daemon,
594 596
595 /* Direct add to master daemon could happen only with "external" add mode. */ 597 /* Direct add to master daemon could happen only with "external" add mode. */
596 mhd_assert ( (NULL == daemon->worker_pool) || 598 mhd_assert ( (NULL == daemon->worker_pool) ||
597 (external_add) ); 599 (external_add) );
598 if ( (external_add) && 600 if ( (external_add) &&
599 (NULL != daemon->worker_pool) ) 601 (NULL != daemon->worker_pool) )
600 { 602 {
601 unsigned int i; 603 unsigned int i;
602 604
603 /* have a pool, try to find a pool with capacity; we use the 605 /* have a pool, try to find a pool with capacity; we use the
604 socket as the initial offset into the pool for load 606 socket as the initial offset into the pool for load
605 balancing */ 607 balancing */
606 for (i = 0; i < daemon->worker_pool_size; ++i) 608 for (i = 0; i < daemon->worker_pool_size; ++i)
607 { 609 {
608 struct MHD_Daemon * const worker = 610 struct MHD_Daemon *const worker =
609 &daemon->worker_pool[(i + client_socket) % daemon->worker_pool_size]; 611 &daemon->worker_pool[(i + client_socket) % daemon->worker_pool_size];
610 if (worker->connections < worker->global_connection_limit) 612 if (worker->connections < worker->global_connection_limit)
611 return internal_add_connection (worker, 613 return internal_add_connection (worker,
612 client_socket, 614 client_socket,
613 addr, 615 addr,
614 addrlen, 616 addrlen,
615 true, 617 true,
616 non_blck); 618 non_blck);
617 } 619 }
618 /* all pools are at their connection limit, must refuse */ 620 /* all pools are at their connection limit, must refuse */
619 MHD_socket_close_chk_ (client_socket); 621 MHD_socket_close_chk_ (client_socket);
620#if ENFILE 622#if ENFILE
621 errno = ENFILE; 623 errno = ENFILE;
622#endif 624#endif
623 return MHD_SC_LIMIT_CONNECTIONS_REACHED; 625 return MHD_SC_LIMIT_CONNECTIONS_REACHED;
624 } 626 }
625 627
626 if ( (! MHD_SCKT_FD_FITS_FDSET_(client_socket, 628 if ( (! MHD_SCKT_FD_FITS_FDSET_ (client_socket,
627 NULL)) && 629 NULL)) &&
628 (MHD_ELS_SELECT == daemon->event_loop_syscall) ) 630 (MHD_ELS_SELECT == daemon->event_loop_syscall) )
629 { 631 {
630#ifdef HAVE_MESSAGES 632#ifdef HAVE_MESSAGES
631 MHD_DLOG (daemon, 633 MHD_DLOG (daemon,
632 MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE, 634 MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE,
633 _("Socket descriptor larger than FD_SETSIZE: %d > %d\n"), 635 _ ("Socket descriptor larger than FD_SETSIZE: %d > %d\n"),
634 (int) client_socket, 636 (int) client_socket,
635 (int) FD_SETSIZE); 637 (int) FD_SETSIZE);
636#endif 638#endif
637 MHD_socket_close_chk_ (client_socket); 639 MHD_socket_close_chk_ (client_socket);
638#if EINVAL 640#if EINVAL
639 errno = EINVAL; 641 errno = EINVAL;
640#endif 642#endif
641 return MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE; 643 return MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE;
642 } 644 }
643 645
644#ifdef MHD_socket_nosignal_ 646#ifdef MHD_socket_nosignal_
645 if (! MHD_socket_nosignal_ (client_socket)) 647 if (! MHD_socket_nosignal_ (client_socket))
646 { 648 {
647#ifdef HAVE_MESSAGES 649#ifdef HAVE_MESSAGES
648 MHD_DLOG (daemon, 650 MHD_DLOG (daemon,
649 MHD_SC_ACCEPT_CONFIGURE_NOSIGPIPE_FAILED, 651 MHD_SC_ACCEPT_CONFIGURE_NOSIGPIPE_FAILED,
650 _("Failed to set SO_NOSIGPIPE on accepted socket: %s\n"), 652 _ ("Failed to set SO_NOSIGPIPE on accepted socket: %s\n"),
651 MHD_socket_last_strerr_()); 653 MHD_socket_last_strerr_ ());
652#endif 654#endif
653#ifndef MSG_NOSIGNAL 655#ifndef MSG_NOSIGNAL
654 /* Cannot use socket as it can produce SIGPIPE. */ 656 /* Cannot use socket as it can produce SIGPIPE. */
655#ifdef ENOTSOCK 657#ifdef ENOTSOCK
656 errno = ENOTSOCK; 658 errno = ENOTSOCK;
657#endif /* ENOTSOCK */ 659#endif /* ENOTSOCK */
658 return MHD_SC_ACCEPT_CONFIGURE_NOSIGPIPE_FAILED; 660 return MHD_SC_ACCEPT_CONFIGURE_NOSIGPIPE_FAILED;
659#endif /* ! MSG_NOSIGNAL */ 661#endif /* ! MSG_NOSIGNAL */
660 } 662 }
661#endif /* MHD_socket_nosignal_ */ 663#endif /* MHD_socket_nosignal_ */
662 664
663 665
664#ifdef HAVE_MESSAGES 666#ifdef HAVE_MESSAGES
665#if DEBUG_CONNECT 667#if DEBUG_CONNECT
666 MHD_DLOG (daemon, 668 MHD_DLOG (daemon,
667 MHD_SC_CONNECTION_ACCEPTED, 669 MHD_SC_CONNECTION_ACCEPTED,
668 _("Accepted connection on socket %d\n"), 670 _ ("Accepted connection on socket %d\n"),
669 client_socket); 671 client_socket);
670#endif 672#endif
671#endif 673#endif
@@ -673,82 +675,83 @@ internal_add_connection (struct MHD_Daemon *daemon,
673 (MHD_NO == MHD_ip_limit_add (daemon, 675 (MHD_NO == MHD_ip_limit_add (daemon,
674 addr, 676 addr,
675 addrlen)) ) 677 addrlen)) )
676 { 678 {
677 /* above connection limit - reject */ 679 /* above connection limit - reject */
678#ifdef HAVE_MESSAGES 680#ifdef HAVE_MESSAGES
679 MHD_DLOG (daemon, 681 MHD_DLOG (daemon,
680 MHD_SC_LIMIT_CONNECTIONS_REACHED, 682 MHD_SC_LIMIT_CONNECTIONS_REACHED,
681 _("Server reached connection limit. Closing inbound connection.\n")); 683 _ (
684 "Server reached connection limit. Closing inbound connection.\n"));
682#endif 685#endif
683 MHD_socket_close_chk_ (client_socket); 686 MHD_socket_close_chk_ (client_socket);
684#if ENFILE 687#if ENFILE
685 errno = ENFILE; 688 errno = ENFILE;
686#endif 689#endif
687 return MHD_SC_LIMIT_CONNECTIONS_REACHED; 690 return MHD_SC_LIMIT_CONNECTIONS_REACHED;
688 } 691 }
689 692
690 /* apply connection acceptance policy if present */ 693 /* apply connection acceptance policy if present */
691 if ( (NULL != daemon->accept_policy_cb) && 694 if ( (NULL != daemon->accept_policy_cb) &&
692 (MHD_NO == 695 (MHD_NO ==
693 daemon->accept_policy_cb (daemon->accept_policy_cb_cls, 696 daemon->accept_policy_cb (daemon->accept_policy_cb_cls,
694 addr, 697 addr,
695 addrlen)) ) 698 addrlen)) )
696 { 699 {
697#if DEBUG_CLOSE 700#if DEBUG_CLOSE
698#ifdef HAVE_MESSAGES 701#ifdef HAVE_MESSAGES
699 MHD_DLOG (daemon, 702 MHD_DLOG (daemon,
700 MHD_SC_ACCEPT_POLICY_REJECTED, 703 MHD_SC_ACCEPT_POLICY_REJECTED,
701 _("Connection rejected by application. Closing connection.\n")); 704 _ ("Connection rejected by application. Closing connection.\n"));
702#endif 705#endif
703#endif 706#endif
704 MHD_socket_close_chk_ (client_socket); 707 MHD_socket_close_chk_ (client_socket);
705 MHD_ip_limit_del (daemon, 708 MHD_ip_limit_del (daemon,
706 addr, 709 addr,
707 addrlen); 710 addrlen);
708#if EACCESS 711#if EACCESS
709 errno = EACCESS; 712 errno = EACCESS;
710#endif 713#endif
711 return MHD_SC_ACCEPT_POLICY_REJECTED; 714 return MHD_SC_ACCEPT_POLICY_REJECTED;
712 } 715 }
713 716
714 if (NULL == 717 if (NULL ==
715 (connection = MHD_calloc_ (1, 718 (connection = MHD_calloc_ (1,
716 sizeof (struct MHD_Connection)))) 719 sizeof (struct MHD_Connection))))
717 { 720 {
718 eno = errno; 721 eno = errno;
719#ifdef HAVE_MESSAGES 722#ifdef HAVE_MESSAGES
720 MHD_DLOG (daemon, 723 MHD_DLOG (daemon,
721 MHD_SC_CONNECTION_MALLOC_FAILURE, 724 MHD_SC_CONNECTION_MALLOC_FAILURE,
722 "Error allocating memory: %s\n", 725 "Error allocating memory: %s\n",
723 MHD_strerror_ (errno)); 726 MHD_strerror_ (errno));
724#endif 727#endif
725 MHD_socket_close_chk_ (client_socket); 728 MHD_socket_close_chk_ (client_socket);
726 MHD_ip_limit_del (daemon, 729 MHD_ip_limit_del (daemon,
727 addr, 730 addr,
728 addrlen); 731 addrlen);
729 errno = eno; 732 errno = eno;
730 return MHD_SC_CONNECTION_MALLOC_FAILURE; 733 return MHD_SC_CONNECTION_MALLOC_FAILURE;
731 } 734 }
732 connection->pool 735 connection->pool
733 = MHD_pool_create (daemon->connection_memory_limit_b); 736 = MHD_pool_create (daemon->connection_memory_limit_b);
734 if (NULL == connection->pool) 737 if (NULL == connection->pool)
735 { 738 {
736#ifdef HAVE_MESSAGES 739#ifdef HAVE_MESSAGES
737 MHD_DLOG (daemon, 740 MHD_DLOG (daemon,
738 MHD_SC_POOL_MALLOC_FAILURE, 741 MHD_SC_POOL_MALLOC_FAILURE,
739 _("Error allocating memory: %s\n"), 742 _ ("Error allocating memory: %s\n"),
740 MHD_strerror_ (errno)); 743 MHD_strerror_ (errno));
741#endif 744#endif
742 MHD_socket_close_chk_ (client_socket); 745 MHD_socket_close_chk_ (client_socket);
743 MHD_ip_limit_del (daemon, 746 MHD_ip_limit_del (daemon,
744 addr, 747 addr,
745 addrlen); 748 addrlen);
746 free (connection); 749 free (connection);
747#if ENOMEM 750#if ENOMEM
748 errno = ENOMEM; 751 errno = ENOMEM;
749#endif 752#endif
750 return MHD_SC_POOL_MALLOC_FAILURE; 753 return MHD_SC_POOL_MALLOC_FAILURE;
751 } 754 }
752 755
753 connection->connection_timeout = daemon->connection_default_timeout; 756 connection->connection_timeout = daemon->connection_default_timeout;
754 memcpy (&connection->addr, 757 memcpy (&connection->addr,
@@ -758,148 +761,151 @@ internal_add_connection (struct MHD_Daemon *daemon,
758 connection->socket_fd = client_socket; 761 connection->socket_fd = client_socket;
759 connection->sk_nonblck = non_blck; 762 connection->sk_nonblck = non_blck;
760 connection->daemon = daemon; 763 connection->daemon = daemon;
761 connection->last_activity = MHD_monotonic_sec_counter(); 764 connection->last_activity = MHD_monotonic_sec_counter ();
762 765
763#ifdef HTTPS_SUPPORT 766#ifdef HTTPS_SUPPORT
764 if (NULL != daemon->tls_api) 767 if (NULL != daemon->tls_api)
768 {
769 connection->tls_cs
770 = daemon->tls_api->setup_connection (daemon->tls_api->cls,
771 NULL /* FIXME */);
772 if (NULL == connection->tls_cs)
765 { 773 {
766 connection->tls_cs 774 eno = EINVAL;
767 = daemon->tls_api->setup_connection (daemon->tls_api->cls, 775 sc = -1; // FIXME!
768 NULL /* FIXME */); 776 goto cleanup;
769 if (NULL == connection->tls_cs)
770 {
771 eno = EINVAL;
772 sc = -1; // FIXME!
773 goto cleanup;
774 }
775 } 777 }
778 }
776 else 779 else
777#endif /* ! HTTPS_SUPPORT */ 780#endif /* ! HTTPS_SUPPORT */
778 { 781 {
779 /* set default connection handlers */ 782 /* set default connection handlers */
780 connection->recv_cls = &recv_param_adapter; 783 connection->recv_cls = &recv_param_adapter;
781 connection->send_cls = &send_param_adapter; 784 connection->send_cls = &send_param_adapter;
782 } 785 }
783 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 786 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
784 /* Firm check under lock. */ 787 /* Firm check under lock. */
785 if (daemon->connections >= daemon->global_connection_limit) 788 if (daemon->connections >= daemon->global_connection_limit)
786 { 789 {
787 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 790 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
788 /* above connection limit - reject */ 791 /* above connection limit - reject */
789#ifdef HAVE_MESSAGES 792#ifdef HAVE_MESSAGES
790 MHD_DLOG (daemon, 793 MHD_DLOG (daemon,
791 MHD_SC_LIMIT_CONNECTIONS_REACHED, 794 MHD_SC_LIMIT_CONNECTIONS_REACHED,
792 _("Server reached connection limit. Closing inbound connection.\n")); 795 _ (
796 "Server reached connection limit. Closing inbound connection.\n"));
793#endif 797#endif
794#if ENFILE 798#if ENFILE
795 eno = ENFILE; 799 eno = ENFILE;
796#endif 800#endif
797 sc = MHD_SC_LIMIT_CONNECTIONS_REACHED; 801 sc = MHD_SC_LIMIT_CONNECTIONS_REACHED;
798 goto cleanup; 802 goto cleanup;
799 } 803 }
800 daemon->connections++; 804 daemon->connections++;
801 if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) 805 if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode)
802 { 806 {
803 XDLL_insert (daemon->normal_timeout_head, 807 XDLL_insert (daemon->normal_timeout_head,
804 daemon->normal_timeout_tail, 808 daemon->normal_timeout_tail,
805 connection); 809 connection);
806 } 810 }
807 DLL_insert (daemon->connections_head, 811 DLL_insert (daemon->connections_head,
808 daemon->connections_tail, 812 daemon->connections_tail,
809 connection); 813 connection);
810 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 814 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
811 815
812 if (NULL != daemon->notify_connection_cb) 816 if (NULL != daemon->notify_connection_cb)
813 daemon->notify_connection_cb (daemon->notify_connection_cb_cls, 817 daemon->notify_connection_cb (daemon->notify_connection_cb_cls,
814 connection, 818 connection,
815 MHD_CONNECTION_NOTIFY_STARTED); 819 MHD_CONNECTION_NOTIFY_STARTED);
816 820
817 /* attempt to create handler thread */ 821 /* attempt to create handler thread */
818 if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) 822 if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode)
823 {
824 if (! MHD_create_named_thread_ (&connection->pid,
825 "MHD-connection",
826 daemon->thread_stack_limit_b,
827 &thread_main_handle_connection,
828 connection))
819 { 829 {
820 if (! MHD_create_named_thread_ (&connection->pid, 830 eno = errno;
821 "MHD-connection",
822 daemon->thread_stack_limit_b,
823 &thread_main_handle_connection,
824 connection))
825 {
826 eno = errno;
827#ifdef HAVE_MESSAGES 831#ifdef HAVE_MESSAGES
828 MHD_DLOG (daemon, 832 MHD_DLOG (daemon,
829 MHD_SC_THREAD_LAUNCH_FAILURE, 833 MHD_SC_THREAD_LAUNCH_FAILURE,
830 "Failed to create a thread: %s\n", 834 "Failed to create a thread: %s\n",
831 MHD_strerror_ (eno)); 835 MHD_strerror_ (eno));
832#endif 836#endif
833 sc = MHD_SC_THREAD_LAUNCH_FAILURE; 837 sc = MHD_SC_THREAD_LAUNCH_FAILURE;
834 goto cleanup; 838 goto cleanup;
835 }
836 } 839 }
840 }
837 else 841 else
838 { 842 {
839 connection->pid = daemon->pid; 843 connection->pid = daemon->pid;
840 } 844 }
841#ifdef EPOLL_SUPPORT 845#ifdef EPOLL_SUPPORT
842 if (MHD_ELS_EPOLL == daemon->event_loop_syscall) 846 if (MHD_ELS_EPOLL == daemon->event_loop_syscall)
843 { 847 {
844 if ( (! daemon->enable_turbo) || 848 if ( (! daemon->enable_turbo) ||
845 (external_add)) 849 (external_add))
846 { /* Do not manipulate EReady DL-list in 'external_add' mode. */ 850 { /* Do not manipulate EReady DL-list in 'external_add' mode. */
847 struct epoll_event event; 851 struct epoll_event event;
848 852
849 event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET; 853 event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
850 event.data.ptr = connection; 854 event.data.ptr = connection;
851 if (0 != epoll_ctl (daemon->epoll_fd, 855 if (0 != epoll_ctl (daemon->epoll_fd,
852 EPOLL_CTL_ADD, 856 EPOLL_CTL_ADD,
853 client_socket, 857 client_socket,
854 &event)) 858 &event))
855 { 859 {
856 eno = errno; 860 eno = errno;
857#ifdef HAVE_MESSAGES 861#ifdef HAVE_MESSAGES
858 MHD_DLOG (daemon, 862 MHD_DLOG (daemon,
859 MHD_SC_EPOLL_CTL_ADD_FAILED, 863 MHD_SC_EPOLL_CTL_ADD_FAILED,
860 _("Call to epoll_ctl failed: %s\n"), 864 _ ("Call to epoll_ctl failed: %s\n"),
861 MHD_socket_last_strerr_ ()); 865 MHD_socket_last_strerr_ ());
862#endif 866#endif
863 sc = MHD_SC_EPOLL_CTL_ADD_FAILED; 867 sc = MHD_SC_EPOLL_CTL_ADD_FAILED;
864 goto cleanup; 868 goto cleanup;
865 } 869 }
866 connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET; 870 connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET;
867 } 871 }
868 else 872 else
869 { 873 {
870 connection->epoll_state |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY 874 connection->epoll_state |= MHD_EPOLL_STATE_READ_READY
871 | MHD_EPOLL_STATE_IN_EREADY_EDLL; 875 | MHD_EPOLL_STATE_WRITE_READY
872 EDLL_insert (daemon->eready_head, 876 | MHD_EPOLL_STATE_IN_EREADY_EDLL;
873 daemon->eready_tail, 877 EDLL_insert (daemon->eready_head,
874 connection); 878 daemon->eready_tail,
875 } 879 connection);
876 } 880 }
881 }
877 else /* This 'else' is combined with next 'if'. */ 882 else /* This 'else' is combined with next 'if'. */
878#endif 883#endif
879 if ( (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) && 884 if ( (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) &&
880 (external_add) && 885 (external_add) &&
881 (MHD_ITC_IS_VALID_(daemon->itc)) && 886 (MHD_ITC_IS_VALID_ (daemon->itc)) &&
882 (! MHD_itc_activate_ (daemon->itc, 887 (! MHD_itc_activate_ (daemon->itc,
883 "n")) ) 888 "n")) )
884 { 889 {
885#ifdef HAVE_MESSAGES 890#ifdef HAVE_MESSAGES
886 MHD_DLOG (daemon, 891 MHD_DLOG (daemon,
887 MHD_SC_ITC_USE_FAILED, 892 MHD_SC_ITC_USE_FAILED,
888 _("Failed to signal new connection via inter-thread communication channel (not necessarily fatal, continuing anyway).")); 893 _ (
894 "Failed to signal new connection via inter-thread communication channel (not necessarily fatal, continuing anyway)."));
889#endif 895#endif
890 } 896 }
891 return MHD_SC_OK; 897 return MHD_SC_OK;
892 898
893 cleanup: 899cleanup:
894 if (NULL != daemon->notify_connection_cb) 900 if (NULL != daemon->notify_connection_cb)
895 daemon->notify_connection_cb (daemon->notify_connection_cb_cls, 901 daemon->notify_connection_cb (daemon->notify_connection_cb_cls,
896 connection, 902 connection,
897 MHD_CONNECTION_NOTIFY_CLOSED); 903 MHD_CONNECTION_NOTIFY_CLOSED);
898#ifdef HTTPS_SUPPORT 904#ifdef HTTPS_SUPPORT
899 if ( (NULL != daemon->tls_api) && 905 if ( (NULL != daemon->tls_api) &&
900 (NULL != connection->tls_cs) ) 906 (NULL != connection->tls_cs) )
901 daemon->tls_api->teardown_connection (daemon->tls_api->cls, 907 daemon->tls_api->teardown_connection (daemon->tls_api->cls,
902 connection->tls_cs); 908 connection->tls_cs);
903#endif /* HTTPS_SUPPORT */ 909#endif /* HTTPS_SUPPORT */
904 MHD_socket_close_chk_ (client_socket); 910 MHD_socket_close_chk_ (client_socket);
905 MHD_ip_limit_del (daemon, 911 MHD_ip_limit_del (daemon,
@@ -907,14 +913,14 @@ internal_add_connection (struct MHD_Daemon *daemon,
907 addrlen); 913 addrlen);
908 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 914 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
909 if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) 915 if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode)
910 { 916 {
911 XDLL_remove (daemon->normal_timeout_head, 917 XDLL_remove (daemon->normal_timeout_head,
912 daemon->normal_timeout_tail, 918 daemon->normal_timeout_tail,
913 connection); 919 connection);
914 } 920 }
915 DLL_remove (daemon->connections_head, 921 DLL_remove (daemon->connections_head,
916 daemon->connections_tail, 922 daemon->connections_tail,
917 connection); 923 connection);
918 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 924 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
919 MHD_pool_destroy (connection->pool); 925 MHD_pool_destroy (connection->pool);
920 free (connection); 926 free (connection);
@@ -954,42 +960,42 @@ internal_add_connection (struct MHD_Daemon *daemon,
954 */ 960 */
955enum MHD_StatusCode 961enum MHD_StatusCode
956MHD_daemon_add_connection (struct MHD_Daemon *daemon, 962MHD_daemon_add_connection (struct MHD_Daemon *daemon,
957 MHD_socket client_socket, 963 MHD_socket client_socket,
958 const struct sockaddr *addr, 964 const struct sockaddr *addr,
959 socklen_t addrlen) 965 socklen_t addrlen)
960{ 966{
961 bool sk_nonbl; 967 bool sk_nonbl;
962 968
963 if (! MHD_socket_nonblocking_ (client_socket)) 969 if (! MHD_socket_nonblocking_ (client_socket))
964 { 970 {
965#ifdef HAVE_MESSAGES 971#ifdef HAVE_MESSAGES
966 MHD_DLOG (daemon, 972 MHD_DLOG (daemon,
967 MHD_SC_ACCEPT_CONFIGURE_NONBLOCKING_FAILED, 973 MHD_SC_ACCEPT_CONFIGURE_NONBLOCKING_FAILED,
968 _("Failed to set nonblocking mode on new client socket: %s\n"), 974 _ ("Failed to set nonblocking mode on new client socket: %s\n"),
969 MHD_socket_last_strerr_()); 975 MHD_socket_last_strerr_ ());
970#endif 976#endif
971 sk_nonbl = false; 977 sk_nonbl = false;
972 } 978 }
973 else 979 else
974 { 980 {
975 sk_nonbl = true; 981 sk_nonbl = true;
976 } 982 }
977 983
978 if ( (daemon->enable_turbo) && 984 if ( (daemon->enable_turbo) &&
979 (! MHD_socket_noninheritable_ (client_socket)) ) 985 (! MHD_socket_noninheritable_ (client_socket)) )
980 { 986 {
981#ifdef HAVE_MESSAGES 987#ifdef HAVE_MESSAGES
982 MHD_DLOG (daemon, 988 MHD_DLOG (daemon,
983 MHD_SC_ACCEPT_CONFIGURE_NOINHERIT_FAILED, 989 MHD_SC_ACCEPT_CONFIGURE_NOINHERIT_FAILED,
984 _("Failed to set noninheritable mode on new client socket.\n")); 990 _ ("Failed to set noninheritable mode on new client socket.\n"));
985#endif 991#endif
986 } 992 }
987 return internal_add_connection (daemon, 993 return internal_add_connection (daemon,
988 client_socket, 994 client_socket,
989 addr, 995 addr,
990 addrlen, 996 addrlen,
991 true, 997 true,
992 sk_nonbl); 998 sk_nonbl);
993} 999}
994 1000
995 1001
@@ -1033,94 +1039,98 @@ MHD_accept_connection_ (struct MHD_Daemon *daemon)
1033#endif /* ! USE_ACCEPT4 */ 1039#endif /* ! USE_ACCEPT4 */
1034 if ( (MHD_INVALID_SOCKET == s) || 1040 if ( (MHD_INVALID_SOCKET == s) ||
1035 (addrlen <= 0) ) 1041 (addrlen <= 0) )
1036 { 1042 {
1037 const int err = MHD_socket_get_error_ (); 1043 const int err = MHD_socket_get_error_ ();
1038 1044
1039 /* This could be a common occurance with multiple worker threads */ 1045 /* This could be a common occurance with multiple worker threads */
1040 if (MHD_SCKT_ERR_IS_ (err, 1046 if (MHD_SCKT_ERR_IS_ (err,
1041 MHD_SCKT_EINVAL_)) 1047 MHD_SCKT_EINVAL_))
1042 return MHD_SC_DAEMON_ALREADY_SHUTDOWN; /* can happen during shutdown, let's hope this is the cause... */ 1048 return MHD_SC_DAEMON_ALREADY_SHUTDOWN; /* can happen during shutdown, let's hope this is the cause... */
1043 if (MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err)) 1049 if (MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_ (err))
1044 return MHD_SC_ACCEPT_FAST_DISCONNECT; /* do not print error if client just disconnected early */ 1050 return MHD_SC_ACCEPT_FAST_DISCONNECT; /* do not print error if client just disconnected early */
1045 if (MHD_SCKT_ERR_IS_EAGAIN_ (err) ) 1051 if (MHD_SCKT_ERR_IS_EAGAIN_ (err) )
1046 return MHD_SC_ACCEPT_FAILED_EAGAIN; 1052 return MHD_SC_ACCEPT_FAILED_EAGAIN;
1047 if (MHD_INVALID_SOCKET != s) 1053 if (MHD_INVALID_SOCKET != s)
1048 { 1054 {
1049 MHD_socket_close_chk_ (s); 1055 MHD_socket_close_chk_ (s);
1050 } 1056 }
1051 if ( MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err) ) 1057 if ( MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err) )
1052 { 1058 {
1053 /* system/process out of resources */ 1059 /* system/process out of resources */
1054 if (0 == daemon->connections) 1060 if (0 == daemon->connections)
1055 { 1061 {
1056#ifdef HAVE_MESSAGES 1062#ifdef HAVE_MESSAGES
1057 /* Not setting 'at_limit' flag, as there is no way it 1063 /* Not setting 'at_limit' flag, as there is no way it
1058 would ever be cleared. Instead trying to produce 1064 would ever be cleared. Instead trying to produce
1059 bit fat ugly warning. */ 1065 bit fat ugly warning. */
1060 MHD_DLOG (daemon, 1066 MHD_DLOG (daemon,
1061 MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED_INSTANTLY, 1067 MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED_INSTANTLY,
1062 _("Hit process or system resource limit at FIRST connection. This is really bad as there is no sane way to proceed. Will try busy waiting for system resources to become magically available.\n")); 1068 _ (
1069 "Hit process or system resource limit at FIRST connection. This is really bad as there is no sane way to proceed. Will try busy waiting for system resources to become magically available.\n"));
1063#endif 1070#endif
1064 return MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED_INSTANTLY; 1071 return MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED_INSTANTLY;
1065 } 1072 }
1066 else 1073 else
1067 { 1074 {
1068 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 1075 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
1069 daemon->at_limit = true; 1076 daemon->at_limit = true;
1070 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 1077 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
1071#ifdef HAVE_MESSAGES 1078#ifdef HAVE_MESSAGES
1072 MHD_DLOG (daemon, 1079 MHD_DLOG (daemon,
1073 MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED, 1080 MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED,
1074 _("Hit process or system resource limit at %u connections, temporarily suspending accept(). Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n"), 1081 _ (
1075 (unsigned int) daemon->connections); 1082 "Hit process or system resource limit at %u connections, temporarily suspending accept(). Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n"),
1083 (unsigned int) daemon->connections);
1076#endif 1084#endif
1077 return MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED; 1085 return MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED;
1078 } 1086 }
1079 } 1087 }
1080#ifdef HAVE_MESSAGES 1088#ifdef HAVE_MESSAGES
1081 MHD_DLOG (daemon, 1089 MHD_DLOG (daemon,
1082 MHD_SC_ACCEPT_FAILED_UNEXPECTEDLY, 1090 MHD_SC_ACCEPT_FAILED_UNEXPECTEDLY,
1083 _("Error accepting connection: %s\n"), 1091 _ ("Error accepting connection: %s\n"),
1084 MHD_socket_strerr_(err)); 1092 MHD_socket_strerr_ (err));
1085#endif 1093#endif
1086 return MHD_SC_ACCEPT_FAILED_UNEXPECTEDLY; 1094 return MHD_SC_ACCEPT_FAILED_UNEXPECTEDLY;
1087 } 1095 }
1088#if !defined(USE_ACCEPT4) || !defined(HAVE_SOCK_NONBLOCK) 1096#if ! defined(USE_ACCEPT4) || ! defined(HAVE_SOCK_NONBLOCK)
1089 if (! MHD_socket_nonblocking_ (s)) 1097 if (! MHD_socket_nonblocking_ (s))
1090 { 1098 {
1091#ifdef HAVE_MESSAGES 1099#ifdef HAVE_MESSAGES
1092 MHD_DLOG (daemon, 1100 MHD_DLOG (daemon,
1093 MHD_SC_ACCEPT_CONFIGURE_NONBLOCKING_FAILED, 1101 MHD_SC_ACCEPT_CONFIGURE_NONBLOCKING_FAILED,
1094 _("Failed to set nonblocking mode on incoming connection socket: %s\n"), 1102 _ (
1095 MHD_socket_last_strerr_()); 1103 "Failed to set nonblocking mode on incoming connection socket: %s\n"),
1104 MHD_socket_last_strerr_ ());
1096#endif 1105#endif
1097 } 1106 }
1098 else 1107 else
1099 sk_nonbl = true; 1108 sk_nonbl = true;
1100#endif /* !USE_ACCEPT4 || !HAVE_SOCK_NONBLOCK */ 1109#endif /* !USE_ACCEPT4 || !HAVE_SOCK_NONBLOCK */
1101#if !defined(USE_ACCEPT4) || !defined(SOCK_CLOEXEC) 1110#if ! defined(USE_ACCEPT4) || ! defined(SOCK_CLOEXEC)
1102 if (! MHD_socket_noninheritable_ (s)) 1111 if (! MHD_socket_noninheritable_ (s))
1103 { 1112 {
1104#ifdef HAVE_MESSAGES 1113#ifdef HAVE_MESSAGES
1105 MHD_DLOG (daemon, 1114 MHD_DLOG (daemon,
1106 MHD_SC_ACCEPT_CONFIGURE_NOINHERIT_FAILED, 1115 MHD_SC_ACCEPT_CONFIGURE_NOINHERIT_FAILED,
1107 _("Failed to set noninheritable mode on incoming connection socket.\n")); 1116 _ (
1117 "Failed to set noninheritable mode on incoming connection socket.\n"));
1108#endif 1118#endif
1109 } 1119 }
1110#endif /* !USE_ACCEPT4 || !SOCK_CLOEXEC */ 1120#endif /* !USE_ACCEPT4 || !SOCK_CLOEXEC */
1111#ifdef HAVE_MESSAGES 1121#ifdef HAVE_MESSAGES
1112#if DEBUG_CONNECT 1122#if DEBUG_CONNECT
1113 MHD_DLOG (daemon, 1123 MHD_DLOG (daemon,
1114 MHD_SC_CONNECTION_ACCEPTED, 1124 MHD_SC_CONNECTION_ACCEPTED,
1115 _("Accepted connection on socket %d\n"), 1125 _ ("Accepted connection on socket %d\n"),
1116 s); 1126 s);
1117#endif 1127#endif
1118#endif 1128#endif
1119 return internal_add_connection (daemon, 1129 return internal_add_connection (daemon,
1120 s, 1130 s,
1121 addr, 1131 addr,
1122 addrlen, 1132 addrlen,
1123 false, 1133 false,
1124 sk_nonbl); 1134 sk_nonbl);
1125} 1135}
1126 1136