diff options
Diffstat (limited to 'src/microhttpd/daemon.c')
-rw-r--r-- | src/microhttpd/daemon.c | 7140 |
1 files changed, 3608 insertions, 3532 deletions
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c index fb4abd5d..97e0ec30 100644 --- a/src/microhttpd/daemon.c +++ b/src/microhttpd/daemon.c | |||
@@ -115,7 +115,7 @@ close_all_connections (struct MHD_Daemon *daemon); | |||
115 | */ | 115 | */ |
116 | static int | 116 | static int |
117 | MHD_epoll (struct MHD_Daemon *daemon, | 117 | MHD_epoll (struct MHD_Daemon *daemon, |
118 | int may_block); | 118 | int may_block); |
119 | 119 | ||
120 | #endif /* EPOLL_SUPPORT */ | 120 | #endif /* EPOLL_SUPPORT */ |
121 | 121 | ||
@@ -130,21 +130,21 @@ MHD_epoll (struct MHD_Daemon *daemon, | |||
130 | */ | 130 | */ |
131 | static void | 131 | static void |
132 | mhd_panic_std (void *cls, | 132 | mhd_panic_std (void *cls, |
133 | const char *file, | 133 | const char *file, |
134 | unsigned int line, | 134 | unsigned int line, |
135 | const char *reason) | 135 | const char *reason) |
136 | { | 136 | { |
137 | (void)cls; /* Mute compiler warning. */ | 137 | (void) cls; /* Mute compiler warning. */ |
138 | #ifdef HAVE_MESSAGES | 138 | #ifdef HAVE_MESSAGES |
139 | fprintf (stderr, | 139 | fprintf (stderr, |
140 | _("Fatal error in GNU libmicrohttpd %s:%u: %s\n"), | 140 | _ ("Fatal error in GNU libmicrohttpd %s:%u: %s\n"), |
141 | file, | 141 | file, |
142 | line, | 142 | line, |
143 | reason); | 143 | reason); |
144 | #else /* ! HAVE_MESSAGES */ | 144 | #else /* ! HAVE_MESSAGES */ |
145 | (void)file; /* Mute compiler warning. */ | 145 | (void) file; /* Mute compiler warning. */ |
146 | (void)line; /* Mute compiler warning. */ | 146 | (void) line; /* Mute compiler warning. */ |
147 | (void)reason; /* Mute compiler warning. */ | 147 | (void) reason; /* Mute compiler warning. */ |
148 | #endif | 148 | #endif |
149 | abort (); | 149 | abort (); |
150 | } | 150 | } |
@@ -164,7 +164,7 @@ void *mhd_panic_cls = NULL; | |||
164 | * Globally initialise library. | 164 | * Globally initialise library. |
165 | */ | 165 | */ |
166 | void | 166 | void |
167 | MHD_init(void); | 167 | MHD_init (void); |
168 | 168 | ||
169 | 169 | ||
170 | #if defined(MHD_WINSOCK_SOCKETS) | 170 | #if defined(MHD_WINSOCK_SOCKETS) |
@@ -179,7 +179,7 @@ static int mhd_winsock_inited_ = 0; | |||
179 | * Do nothing - global initialisation is | 179 | * Do nothing - global initialisation is |
180 | * performed by library constructor. | 180 | * performed by library constructor. |
181 | */ | 181 | */ |
182 | #define MHD_check_global_init_() (void)0 | 182 | #define MHD_check_global_init_() (void) 0 |
183 | #else /* ! _AUTOINIT_FUNCS_ARE_SUPPORTED */ | 183 | #else /* ! _AUTOINIT_FUNCS_ARE_SUPPORTED */ |
184 | /** | 184 | /** |
185 | * Track global initialisation | 185 | * Track global initialisation |
@@ -191,7 +191,7 @@ volatile int global_init_count = 0; | |||
191 | /** | 191 | /** |
192 | * Global initialisation mutex | 192 | * Global initialisation mutex |
193 | */ | 193 | */ |
194 | MHD_MUTEX_STATIC_DEFN_INIT_(global_init_mutex_); | 194 | MHD_MUTEX_STATIC_DEFN_INIT_ (global_init_mutex_); |
195 | #endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */ | 195 | #endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */ |
196 | #endif | 196 | #endif |
197 | 197 | ||
@@ -205,14 +205,14 @@ MHD_check_global_init_ (void) | |||
205 | { | 205 | { |
206 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 206 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
207 | #ifdef MHD_MUTEX_STATIC_DEFN_INIT_ | 207 | #ifdef MHD_MUTEX_STATIC_DEFN_INIT_ |
208 | MHD_mutex_lock_chk_(&global_init_mutex_); | 208 | MHD_mutex_lock_chk_ (&global_init_mutex_); |
209 | #endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */ | 209 | #endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */ |
210 | #endif | 210 | #endif |
211 | if (0 == global_init_count++) | 211 | if (0 == global_init_count++) |
212 | MHD_init (); | 212 | MHD_init (); |
213 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 213 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
214 | #ifdef MHD_MUTEX_STATIC_DEFN_INIT_ | 214 | #ifdef MHD_MUTEX_STATIC_DEFN_INIT_ |
215 | MHD_mutex_unlock_chk_(&global_init_mutex_); | 215 | MHD_mutex_unlock_chk_ (&global_init_mutex_); |
216 | #endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */ | 216 | #endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */ |
217 | #endif | 217 | #endif |
218 | } | 218 | } |
@@ -227,9 +227,9 @@ MHD_default_logger_ (void *cls, | |||
227 | const char *fm, | 227 | const char *fm, |
228 | va_list ap) | 228 | va_list ap) |
229 | { | 229 | { |
230 | vfprintf ((FILE*)cls, fm, ap); | 230 | vfprintf ((FILE*) cls, fm, ap); |
231 | #ifdef _DEBUG | 231 | #ifdef _DEBUG |
232 | fflush ((FILE*)cls); | 232 | fflush ((FILE*) cls); |
233 | #endif /* _DEBUG */ | 233 | #endif /* _DEBUG */ |
234 | } | 234 | } |
235 | 235 | ||
@@ -308,7 +308,7 @@ static void | |||
308 | MHD_ip_count_lock (struct MHD_Daemon *daemon) | 308 | MHD_ip_count_lock (struct MHD_Daemon *daemon) |
309 | { | 309 | { |
310 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 310 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
311 | MHD_mutex_lock_chk_(&daemon->per_ip_connection_mutex); | 311 | MHD_mutex_lock_chk_ (&daemon->per_ip_connection_mutex); |
312 | #else | 312 | #else |
313 | (void) daemon; | 313 | (void) daemon; |
314 | #endif | 314 | #endif |
@@ -324,7 +324,7 @@ static void | |||
324 | MHD_ip_count_unlock (struct MHD_Daemon *daemon) | 324 | MHD_ip_count_unlock (struct MHD_Daemon *daemon) |
325 | { | 325 | { |
326 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 326 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
327 | MHD_mutex_unlock_chk_(&daemon->per_ip_connection_mutex); | 327 | MHD_mutex_unlock_chk_ (&daemon->per_ip_connection_mutex); |
328 | #else | 328 | #else |
329 | (void) daemon; | 329 | (void) daemon; |
330 | #endif | 330 | #endif |
@@ -361,37 +361,37 @@ MHD_ip_addr_compare (const void *a1, | |||
361 | */ | 361 | */ |
362 | static int | 362 | static int |
363 | MHD_ip_addr_to_key (const struct sockaddr *addr, | 363 | MHD_ip_addr_to_key (const struct sockaddr *addr, |
364 | socklen_t addrlen, | 364 | socklen_t addrlen, |
365 | struct MHD_IPCount *key) | 365 | struct MHD_IPCount *key) |
366 | { | 366 | { |
367 | memset(key, | 367 | memset (key, |
368 | 0, | 368 | 0, |
369 | sizeof(*key)); | 369 | sizeof(*key)); |
370 | 370 | ||
371 | /* IPv4 addresses */ | 371 | /* IPv4 addresses */ |
372 | if (sizeof (struct sockaddr_in) == addrlen) | 372 | if (sizeof (struct sockaddr_in) == addrlen) |
373 | { | 373 | { |
374 | const struct sockaddr_in *addr4 = (const struct sockaddr_in*) addr; | 374 | const struct sockaddr_in *addr4 = (const struct sockaddr_in*) addr; |
375 | 375 | ||
376 | key->family = AF_INET; | 376 | key->family = AF_INET; |
377 | memcpy (&key->addr.ipv4, | 377 | memcpy (&key->addr.ipv4, |
378 | &addr4->sin_addr, | 378 | &addr4->sin_addr, |
379 | sizeof(addr4->sin_addr)); | 379 | sizeof(addr4->sin_addr)); |
380 | return MHD_YES; | 380 | return MHD_YES; |
381 | } | 381 | } |
382 | 382 | ||
383 | #if HAVE_INET6 | 383 | #if HAVE_INET6 |
384 | /* IPv6 addresses */ | 384 | /* IPv6 addresses */ |
385 | if (sizeof (struct sockaddr_in6) == addrlen) | 385 | if (sizeof (struct sockaddr_in6) == addrlen) |
386 | { | 386 | { |
387 | const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*) addr; | 387 | const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*) addr; |
388 | 388 | ||
389 | key->family = AF_INET6; | 389 | key->family = AF_INET6; |
390 | memcpy (&key->addr.ipv6, | 390 | memcpy (&key->addr.ipv6, |
391 | &addr6->sin6_addr, | 391 | &addr6->sin6_addr, |
392 | sizeof(addr6->sin6_addr)); | 392 | sizeof(addr6->sin6_addr)); |
393 | return MHD_YES; | 393 | return MHD_YES; |
394 | } | 394 | } |
395 | #endif | 395 | #endif |
396 | 396 | ||
397 | /* Some other address */ | 397 | /* Some other address */ |
@@ -412,8 +412,8 @@ MHD_ip_addr_to_key (const struct sockaddr *addr, | |||
412 | */ | 412 | */ |
413 | static int | 413 | static int |
414 | MHD_ip_limit_add (struct MHD_Daemon *daemon, | 414 | MHD_ip_limit_add (struct MHD_Daemon *daemon, |
415 | const struct sockaddr *addr, | 415 | const struct sockaddr *addr, |
416 | socklen_t addrlen) | 416 | socklen_t addrlen) |
417 | { | 417 | { |
418 | struct MHD_IPCount *key; | 418 | struct MHD_IPCount *key; |
419 | void **nodep; | 419 | void **nodep; |
@@ -432,30 +432,30 @@ MHD_ip_limit_add (struct MHD_Daemon *daemon, | |||
432 | if (MHD_NO == MHD_ip_addr_to_key (addr, | 432 | if (MHD_NO == MHD_ip_addr_to_key (addr, |
433 | addrlen, | 433 | addrlen, |
434 | key)) | 434 | key)) |
435 | { | 435 | { |
436 | /* Allow unhandled address types through */ | 436 | /* Allow unhandled address types through */ |
437 | free (key); | 437 | free (key); |
438 | return MHD_YES; | 438 | return MHD_YES; |
439 | } | 439 | } |
440 | MHD_ip_count_lock (daemon); | 440 | MHD_ip_count_lock (daemon); |
441 | 441 | ||
442 | /* Search for the IP address */ | 442 | /* Search for the IP address */ |
443 | if (NULL == (nodep = tsearch (key, | 443 | if (NULL == (nodep = tsearch (key, |
444 | &daemon->per_ip_connection_count, | 444 | &daemon->per_ip_connection_count, |
445 | &MHD_ip_addr_compare))) | 445 | &MHD_ip_addr_compare))) |
446 | { | 446 | { |
447 | #ifdef HAVE_MESSAGES | 447 | #ifdef HAVE_MESSAGES |
448 | MHD_DLOG (daemon, | 448 | MHD_DLOG (daemon, |
449 | _("Failed to add IP connection count node\n")); | 449 | _ ("Failed to add IP connection count node\n")); |
450 | #endif | 450 | #endif |
451 | MHD_ip_count_unlock (daemon); | 451 | MHD_ip_count_unlock (daemon); |
452 | free (key); | 452 | free (key); |
453 | return MHD_NO; | 453 | return MHD_NO; |
454 | } | 454 | } |
455 | node = *nodep; | 455 | node = *nodep; |
456 | /* If we got an existing node back, free the one we created */ | 456 | /* If we got an existing node back, free the one we created */ |
457 | if (node != key) | 457 | if (node != key) |
458 | free(key); | 458 | free (key); |
459 | key = (struct MHD_IPCount *) node; | 459 | key = (struct MHD_IPCount *) node; |
460 | /* Test if there is room for another connection; if so, | 460 | /* Test if there is room for another connection; if so, |
461 | * increment count */ | 461 | * increment count */ |
@@ -478,8 +478,8 @@ MHD_ip_limit_add (struct MHD_Daemon *daemon, | |||
478 | */ | 478 | */ |
479 | static void | 479 | static void |
480 | MHD_ip_limit_del (struct MHD_Daemon *daemon, | 480 | MHD_ip_limit_del (struct MHD_Daemon *daemon, |
481 | const struct sockaddr *addr, | 481 | const struct sockaddr *addr, |
482 | socklen_t addrlen) | 482 | socklen_t addrlen) |
483 | { | 483 | { |
484 | struct MHD_IPCount search_key; | 484 | struct MHD_IPCount search_key; |
485 | struct MHD_IPCount *found_key; | 485 | struct MHD_IPCount *found_key; |
@@ -499,27 +499,27 @@ MHD_ip_limit_del (struct MHD_Daemon *daemon, | |||
499 | 499 | ||
500 | /* Search for the IP address */ | 500 | /* Search for the IP address */ |
501 | if (NULL == (nodep = tfind (&search_key, | 501 | if (NULL == (nodep = tfind (&search_key, |
502 | &daemon->per_ip_connection_count, | 502 | &daemon->per_ip_connection_count, |
503 | &MHD_ip_addr_compare))) | 503 | &MHD_ip_addr_compare))) |
504 | { | 504 | { |
505 | /* Something's wrong if we couldn't find an IP address | 505 | /* Something's wrong if we couldn't find an IP address |
506 | * that was previously added */ | 506 | * that was previously added */ |
507 | MHD_PANIC (_("Failed to find previously-added IP address\n")); | 507 | MHD_PANIC (_ ("Failed to find previously-added IP address\n")); |
508 | } | 508 | } |
509 | found_key = (struct MHD_IPCount *) *nodep; | 509 | found_key = (struct MHD_IPCount *) *nodep; |
510 | /* Validate existing count for IP address */ | 510 | /* Validate existing count for IP address */ |
511 | if (0 == found_key->count) | 511 | if (0 == found_key->count) |
512 | { | 512 | { |
513 | MHD_PANIC (_("Previously-added IP address had counter of zero\n")); | 513 | MHD_PANIC (_ ("Previously-added IP address had counter of zero\n")); |
514 | } | 514 | } |
515 | /* Remove the node entirely if count reduces to 0 */ | 515 | /* Remove the node entirely if count reduces to 0 */ |
516 | if (0 == --found_key->count) | 516 | if (0 == --found_key->count) |
517 | { | 517 | { |
518 | tdelete (found_key, | 518 | tdelete (found_key, |
519 | &daemon->per_ip_connection_count, | 519 | &daemon->per_ip_connection_count, |
520 | &MHD_ip_addr_compare); | 520 | &MHD_ip_addr_compare); |
521 | free (found_key); | 521 | free (found_key); |
522 | } | 522 | } |
523 | 523 | ||
524 | MHD_ip_count_unlock (daemon); | 524 | MHD_ip_count_unlock (daemon); |
525 | } | 525 | } |
@@ -541,103 +541,104 @@ MHD_init_daemon_certificate (struct MHD_Daemon *daemon) | |||
541 | 541 | ||
542 | #if GNUTLS_VERSION_MAJOR >= 3 | 542 | #if GNUTLS_VERSION_MAJOR >= 3 |
543 | if (NULL != daemon->cert_callback) | 543 | if (NULL != daemon->cert_callback) |
544 | { | 544 | { |
545 | gnutls_certificate_set_retrieve_function2 (daemon->x509_cred, | 545 | gnutls_certificate_set_retrieve_function2 (daemon->x509_cred, |
546 | daemon->cert_callback); | 546 | daemon->cert_callback); |
547 | } | 547 | } |
548 | #endif | 548 | #endif |
549 | #if GNUTLS_VERSION_NUMBER >= 0x030603 | 549 | #if GNUTLS_VERSION_NUMBER >= 0x030603 |
550 | else if (NULL != daemon->cert_callback2) | 550 | else if (NULL != daemon->cert_callback2) |
551 | { | 551 | { |
552 | gnutls_certificate_set_retrieve_function3 (daemon->x509_cred, | 552 | gnutls_certificate_set_retrieve_function3 (daemon->x509_cred, |
553 | daemon->cert_callback2); | 553 | daemon->cert_callback2); |
554 | } | 554 | } |
555 | #endif | 555 | #endif |
556 | 556 | ||
557 | if (NULL != daemon->https_mem_trust) | 557 | if (NULL != daemon->https_mem_trust) |
558 | { | ||
559 | size_t paramlen; | ||
560 | paramlen = strlen (daemon->https_mem_trust); | ||
561 | if (UINT_MAX < paramlen) | ||
558 | { | 562 | { |
559 | size_t paramlen; | ||
560 | paramlen = strlen (daemon->https_mem_trust); | ||
561 | if (UINT_MAX < paramlen) | ||
562 | { | ||
563 | #ifdef HAVE_MESSAGES | 563 | #ifdef HAVE_MESSAGES |
564 | MHD_DLOG(daemon, | 564 | MHD_DLOG (daemon, |
565 | "Too long trust certificate\n"); | 565 | "Too long trust certificate\n"); |
566 | #endif | 566 | #endif |
567 | return -1; | 567 | return -1; |
568 | } | 568 | } |
569 | cert.data = (unsigned char *) daemon->https_mem_trust; | 569 | cert.data = (unsigned char *) daemon->https_mem_trust; |
570 | cert.size = (unsigned int) paramlen; | 570 | cert.size = (unsigned int) paramlen; |
571 | if (gnutls_certificate_set_x509_trust_mem (daemon->x509_cred, | 571 | if (gnutls_certificate_set_x509_trust_mem (daemon->x509_cred, |
572 | &cert, | 572 | &cert, |
573 | GNUTLS_X509_FMT_PEM) < 0) | 573 | GNUTLS_X509_FMT_PEM) < 0) |
574 | { | 574 | { |
575 | #ifdef HAVE_MESSAGES | 575 | #ifdef HAVE_MESSAGES |
576 | MHD_DLOG(daemon, | 576 | MHD_DLOG (daemon, |
577 | "Bad trust certificate format\n"); | 577 | "Bad trust certificate format\n"); |
578 | #endif | 578 | #endif |
579 | return -1; | 579 | return -1; |
580 | } | ||
581 | } | 580 | } |
581 | } | ||
582 | 582 | ||
583 | if (daemon->have_dhparams) | 583 | if (daemon->have_dhparams) |
584 | { | 584 | { |
585 | gnutls_certificate_set_dh_params (daemon->x509_cred, | 585 | gnutls_certificate_set_dh_params (daemon->x509_cred, |
586 | daemon->https_mem_dhparams); | 586 | daemon->https_mem_dhparams); |
587 | } | 587 | } |
588 | /* certificate & key loaded from memory */ | 588 | /* certificate & key loaded from memory */ |
589 | if ( (NULL != daemon->https_mem_cert) && | 589 | if ( (NULL != daemon->https_mem_cert) && |
590 | (NULL != daemon->https_mem_key) ) | 590 | (NULL != daemon->https_mem_key) ) |
591 | { | 591 | { |
592 | size_t param1len; | 592 | size_t param1len; |
593 | size_t param2len; | 593 | size_t param2len; |
594 | 594 | ||
595 | param1len = strlen (daemon->https_mem_key); | 595 | param1len = strlen (daemon->https_mem_key); |
596 | param2len = strlen (daemon->https_mem_cert); | 596 | param2len = strlen (daemon->https_mem_cert); |
597 | if ( (UINT_MAX < param1len) || | 597 | if ( (UINT_MAX < param1len) || |
598 | (UINT_MAX < param2len) ) | 598 | (UINT_MAX < param2len) ) |
599 | { | 599 | { |
600 | #ifdef HAVE_MESSAGES | 600 | #ifdef HAVE_MESSAGES |
601 | MHD_DLOG(daemon, | 601 | MHD_DLOG (daemon, |
602 | "Too long key or certificate\n"); | 602 | "Too long key or certificate\n"); |
603 | #endif | 603 | #endif |
604 | return -1; | 604 | return -1; |
605 | } | 605 | } |
606 | key.data = (unsigned char *) daemon->https_mem_key; | 606 | key.data = (unsigned char *) daemon->https_mem_key; |
607 | key.size = (unsigned int)param1len; | 607 | key.size = (unsigned int) param1len; |
608 | cert.data = (unsigned char *) daemon->https_mem_cert; | 608 | cert.data = (unsigned char *) daemon->https_mem_cert; |
609 | cert.size = (unsigned int)param2len; | 609 | cert.size = (unsigned int) param2len; |
610 | 610 | ||
611 | if (NULL != daemon->https_key_password) { | 611 | if (NULL != daemon->https_key_password) |
612 | { | ||
612 | #if GNUTLS_VERSION_NUMBER >= 0x030111 | 613 | #if GNUTLS_VERSION_NUMBER >= 0x030111 |
613 | ret = gnutls_certificate_set_x509_key_mem2 (daemon->x509_cred, | 614 | ret = gnutls_certificate_set_x509_key_mem2 (daemon->x509_cred, |
614 | &cert, | 615 | &cert, |
615 | &key, | 616 | &key, |
616 | GNUTLS_X509_FMT_PEM, | 617 | GNUTLS_X509_FMT_PEM, |
617 | daemon->https_key_password, | 618 | daemon->https_key_password, |
618 | 0); | 619 | 0); |
619 | #else | 620 | #else |
620 | #ifdef HAVE_MESSAGES | 621 | #ifdef HAVE_MESSAGES |
621 | MHD_DLOG (daemon, | 622 | MHD_DLOG (daemon, |
622 | _("Failed to setup x509 certificate/key: pre 3.X.X version " \ | 623 | _ ("Failed to setup x509 certificate/key: pre 3.X.X version " \ |
623 | "of GnuTLS does not support setting key password")); | 624 | "of GnuTLS does not support setting key password")); |
624 | #endif | 625 | #endif |
625 | return -1; | 626 | return -1; |
626 | #endif | 627 | #endif |
627 | } | 628 | } |
628 | else | 629 | else |
629 | ret = gnutls_certificate_set_x509_key_mem (daemon->x509_cred, | 630 | ret = gnutls_certificate_set_x509_key_mem (daemon->x509_cred, |
630 | &cert, | 631 | &cert, |
631 | &key, | 632 | &key, |
632 | GNUTLS_X509_FMT_PEM); | 633 | GNUTLS_X509_FMT_PEM); |
633 | #ifdef HAVE_MESSAGES | 634 | #ifdef HAVE_MESSAGES |
634 | if (0 != ret) | 635 | if (0 != ret) |
635 | MHD_DLOG (daemon, | 636 | MHD_DLOG (daemon, |
636 | "GnuTLS failed to setup x509 certificate/key: %s\n", | 637 | "GnuTLS failed to setup x509 certificate/key: %s\n", |
637 | gnutls_strerror (ret)); | 638 | gnutls_strerror (ret)); |
638 | #endif | 639 | #endif |
639 | return ret; | 640 | return ret; |
640 | } | 641 | } |
641 | #if GNUTLS_VERSION_MAJOR >= 3 | 642 | #if GNUTLS_VERSION_MAJOR >= 3 |
642 | if (NULL != daemon->cert_callback) | 643 | if (NULL != daemon->cert_callback) |
643 | return 0; | 644 | return 0; |
@@ -663,25 +664,25 @@ static int | |||
663 | MHD_TLS_init (struct MHD_Daemon *daemon) | 664 | MHD_TLS_init (struct MHD_Daemon *daemon) |
664 | { | 665 | { |
665 | switch (daemon->cred_type) | 666 | switch (daemon->cred_type) |
666 | { | 667 | { |
667 | case GNUTLS_CRD_CERTIFICATE: | 668 | case GNUTLS_CRD_CERTIFICATE: |
668 | if (0 != | 669 | if (0 != |
669 | gnutls_certificate_allocate_credentials (&daemon->x509_cred)) | 670 | gnutls_certificate_allocate_credentials (&daemon->x509_cred)) |
670 | return GNUTLS_E_MEMORY_ERROR; | 671 | return GNUTLS_E_MEMORY_ERROR; |
671 | return MHD_init_daemon_certificate (daemon); | 672 | return MHD_init_daemon_certificate (daemon); |
672 | case GNUTLS_CRD_PSK: | 673 | case GNUTLS_CRD_PSK: |
673 | if (0 != | 674 | if (0 != |
674 | gnutls_psk_allocate_server_credentials (&daemon->psk_cred)) | 675 | gnutls_psk_allocate_server_credentials (&daemon->psk_cred)) |
675 | return GNUTLS_E_MEMORY_ERROR; | 676 | return GNUTLS_E_MEMORY_ERROR; |
676 | return 0; | 677 | return 0; |
677 | default: | 678 | default: |
678 | #ifdef HAVE_MESSAGES | 679 | #ifdef HAVE_MESSAGES |
679 | MHD_DLOG (daemon, | 680 | MHD_DLOG (daemon, |
680 | _("Error: invalid credentials type %d specified.\n"), | 681 | _ ("Error: invalid credentials type %d specified.\n"), |
681 | daemon->cred_type); | 682 | daemon->cred_type); |
682 | #endif | 683 | #endif |
683 | return -1; | 684 | return -1; |
684 | } | 685 | } |
685 | } | 686 | } |
686 | #endif /* HTTPS_SUPPORT */ | 687 | #endif /* HTTPS_SUPPORT */ |
687 | 688 | ||
@@ -761,55 +762,55 @@ urh_to_fdset (struct MHD_UpgradeResponseHandle *urh, | |||
761 | /* Do not add to 'es' only if socket is closed | 762 | /* Do not add to 'es' only if socket is closed |
762 | * or not used anymore. */ | 763 | * or not used anymore. */ |
763 | if (MHD_INVALID_SOCKET != conn_sckt) | 764 | if (MHD_INVALID_SOCKET != conn_sckt) |
764 | { | 765 | { |
765 | if ( (urh->in_buffer_used < urh->in_buffer_size) && | 766 | if ( (urh->in_buffer_used < urh->in_buffer_size) && |
766 | (! MHD_add_to_fd_set_ (conn_sckt, | 767 | (! MHD_add_to_fd_set_ (conn_sckt, |
767 | rs, | 768 | rs, |
768 | max_fd, | 769 | max_fd, |
769 | fd_setsize)) ) | 770 | fd_setsize)) ) |
770 | res = false; | 771 | res = false; |
771 | if ( (0 != urh->out_buffer_used) && | 772 | if ( (0 != urh->out_buffer_used) && |
772 | (! MHD_add_to_fd_set_ (conn_sckt, | 773 | (! MHD_add_to_fd_set_ (conn_sckt, |
773 | ws, | 774 | ws, |
774 | max_fd, | 775 | max_fd, |
775 | fd_setsize)) ) | 776 | fd_setsize)) ) |
776 | res = false; | 777 | res = false; |
777 | /* Do not monitor again for errors if error was detected before as | 778 | /* Do not monitor again for errors if error was detected before as |
778 | * error state is remembered. */ | 779 | * error state is remembered. */ |
779 | if ((0 == (urh->app.celi & MHD_EPOLL_STATE_ERROR)) && | 780 | if ((0 == (urh->app.celi & MHD_EPOLL_STATE_ERROR)) && |
780 | ((0 != urh->in_buffer_size) || | 781 | ((0 != urh->in_buffer_size) || |
781 | (0 != urh->out_buffer_size) || | 782 | (0 != urh->out_buffer_size) || |
782 | (0 != urh->out_buffer_used))) | 783 | (0 != urh->out_buffer_used))) |
783 | MHD_add_to_fd_set_ (conn_sckt, | 784 | MHD_add_to_fd_set_ (conn_sckt, |
784 | es, | 785 | es, |
785 | max_fd, | 786 | max_fd, |
786 | fd_setsize); | 787 | fd_setsize); |
787 | } | 788 | } |
788 | if (MHD_INVALID_SOCKET != mhd_sckt) | 789 | if (MHD_INVALID_SOCKET != mhd_sckt) |
789 | { | 790 | { |
790 | if ( (urh->out_buffer_used < urh->out_buffer_size) && | 791 | if ( (urh->out_buffer_used < urh->out_buffer_size) && |
791 | (! MHD_add_to_fd_set_ (mhd_sckt, | 792 | (! MHD_add_to_fd_set_ (mhd_sckt, |
792 | rs, | 793 | rs, |
793 | max_fd, | 794 | max_fd, |
794 | fd_setsize)) ) | 795 | fd_setsize)) ) |
795 | res = false; | 796 | res = false; |
796 | if ( (0 != urh->in_buffer_used) && | 797 | if ( (0 != urh->in_buffer_used) && |
797 | (! MHD_add_to_fd_set_ (mhd_sckt, | 798 | (! MHD_add_to_fd_set_ (mhd_sckt, |
798 | ws, | 799 | ws, |
799 | max_fd, | 800 | max_fd, |
800 | fd_setsize)) ) | 801 | fd_setsize)) ) |
801 | res = false; | 802 | res = false; |
802 | /* Do not monitor again for errors if error was detected before as | 803 | /* Do not monitor again for errors if error was detected before as |
803 | * error state is remembered. */ | 804 | * error state is remembered. */ |
804 | if ((0 == (urh->mhd.celi & MHD_EPOLL_STATE_ERROR)) && | 805 | if ((0 == (urh->mhd.celi & MHD_EPOLL_STATE_ERROR)) && |
805 | ((0 != urh->out_buffer_size) || | 806 | ((0 != urh->out_buffer_size) || |
806 | (0 != urh->in_buffer_size) || | 807 | (0 != urh->in_buffer_size) || |
807 | (0 != urh->in_buffer_used))) | 808 | (0 != urh->in_buffer_used))) |
808 | MHD_add_to_fd_set_ (mhd_sckt, | 809 | MHD_add_to_fd_set_ (mhd_sckt, |
809 | es, | 810 | es, |
810 | max_fd, | 811 | max_fd, |
811 | fd_setsize); | 812 | fd_setsize); |
812 | } | 813 | } |
813 | 814 | ||
814 | return res; | 815 | return res; |
815 | } | 816 | } |
@@ -838,23 +839,23 @@ urh_from_fdset (struct MHD_UpgradeResponseHandle *urh, | |||
838 | urh->mhd.celi &= (~MHD_EPOLL_STATE_READ_READY & ~MHD_EPOLL_STATE_WRITE_READY); | 839 | urh->mhd.celi &= (~MHD_EPOLL_STATE_READ_READY & ~MHD_EPOLL_STATE_WRITE_READY); |
839 | 840 | ||
840 | if (MHD_INVALID_SOCKET != conn_sckt) | 841 | if (MHD_INVALID_SOCKET != conn_sckt) |
841 | { | 842 | { |
842 | if (FD_ISSET (conn_sckt, rs)) | 843 | if (FD_ISSET (conn_sckt, rs)) |
843 | urh->app.celi |= MHD_EPOLL_STATE_READ_READY; | 844 | urh->app.celi |= MHD_EPOLL_STATE_READ_READY; |
844 | if (FD_ISSET (conn_sckt, ws)) | 845 | if (FD_ISSET (conn_sckt, ws)) |
845 | urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY; | 846 | urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY; |
846 | if (FD_ISSET (conn_sckt, es)) | 847 | if (FD_ISSET (conn_sckt, es)) |
847 | urh->app.celi |= MHD_EPOLL_STATE_ERROR; | 848 | urh->app.celi |= MHD_EPOLL_STATE_ERROR; |
848 | } | 849 | } |
849 | if ((MHD_INVALID_SOCKET != mhd_sckt)) | 850 | if ((MHD_INVALID_SOCKET != mhd_sckt)) |
850 | { | 851 | { |
851 | if (FD_ISSET (mhd_sckt, rs)) | 852 | if (FD_ISSET (mhd_sckt, rs)) |
852 | urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY; | 853 | urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY; |
853 | if (FD_ISSET (mhd_sckt, ws)) | 854 | if (FD_ISSET (mhd_sckt, ws)) |
854 | urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY; | 855 | urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY; |
855 | if (FD_ISSET (mhd_sckt, es)) | 856 | if (FD_ISSET (mhd_sckt, es)) |
856 | urh->mhd.celi |= MHD_EPOLL_STATE_ERROR; | 857 | urh->mhd.celi |= MHD_EPOLL_STATE_ERROR; |
857 | } | 858 | } |
858 | } | 859 | } |
859 | 860 | ||
860 | #ifdef HAVE_POLL | 861 | #ifdef HAVE_POLL |
@@ -869,7 +870,7 @@ urh_from_fdset (struct MHD_UpgradeResponseHandle *urh, | |||
869 | */ | 870 | */ |
870 | static void | 871 | static void |
871 | urh_update_pollfd (struct MHD_UpgradeResponseHandle *urh, | 872 | urh_update_pollfd (struct MHD_UpgradeResponseHandle *urh, |
872 | struct pollfd p[2]) | 873 | struct pollfd p[2]) |
873 | { | 874 | { |
874 | p[0].events = 0; | 875 | p[0].events = 0; |
875 | p[1].events = 0; | 876 | p[1].events = 0; |
@@ -910,12 +911,12 @@ urh_update_pollfd (struct MHD_UpgradeResponseHandle *urh, | |||
910 | */ | 911 | */ |
911 | static void | 912 | static void |
912 | urh_to_pollfd (struct MHD_UpgradeResponseHandle *urh, | 913 | urh_to_pollfd (struct MHD_UpgradeResponseHandle *urh, |
913 | struct pollfd p[2]) | 914 | struct pollfd p[2]) |
914 | { | 915 | { |
915 | p[0].fd = urh->connection->socket_fd; | 916 | p[0].fd = urh->connection->socket_fd; |
916 | p[1].fd = urh->mhd.socket; | 917 | p[1].fd = urh->mhd.socket; |
917 | urh_update_pollfd (urh, | 918 | urh_update_pollfd (urh, |
918 | p); | 919 | p); |
919 | } | 920 | } |
920 | 921 | ||
921 | 922 | ||
@@ -926,7 +927,7 @@ urh_to_pollfd (struct MHD_UpgradeResponseHandle *urh, | |||
926 | */ | 927 | */ |
927 | static void | 928 | static void |
928 | urh_from_pollfd (struct MHD_UpgradeResponseHandle *urh, | 929 | urh_from_pollfd (struct MHD_UpgradeResponseHandle *urh, |
929 | struct pollfd p[2]) | 930 | struct pollfd p[2]) |
930 | { | 931 | { |
931 | /* Reset read/write ready, preserve error state. */ | 932 | /* Reset read/write ready, preserve error state. */ |
932 | urh->app.celi &= (~MHD_EPOLL_STATE_READ_READY & ~MHD_EPOLL_STATE_WRITE_READY); | 933 | urh->app.celi &= (~MHD_EPOLL_STATE_READ_READY & ~MHD_EPOLL_STATE_WRITE_READY); |
@@ -998,85 +999,85 @@ internal_get_fdset2 (struct MHD_Daemon *daemon, | |||
998 | * or INFO_WRITE sockets will not fit 'except_fd_set'. */ | 999 | * or INFO_WRITE sockets will not fit 'except_fd_set'. */ |
999 | /* Start from oldest connections. Make sense for W32 FDSETs. */ | 1000 | /* Start from oldest connections. Make sense for W32 FDSETs. */ |
1000 | for (pos = daemon->connections_tail; NULL != pos; pos = posn) | 1001 | for (pos = daemon->connections_tail; NULL != pos; pos = posn) |
1001 | { | 1002 | { |
1002 | posn = pos->prev; | 1003 | posn = pos->prev; |
1003 | 1004 | ||
1004 | switch (pos->event_loop_info) | 1005 | switch (pos->event_loop_info) |
1005 | { | 1006 | { |
1006 | case MHD_EVENT_LOOP_INFO_READ: | 1007 | case MHD_EVENT_LOOP_INFO_READ: |
1007 | if (! MHD_add_to_fd_set_ (pos->socket_fd, | 1008 | if (! MHD_add_to_fd_set_ (pos->socket_fd, |
1008 | read_fd_set, | 1009 | read_fd_set, |
1009 | max_fd, | 1010 | max_fd, |
1010 | fd_setsize)) | 1011 | fd_setsize)) |
1011 | result = MHD_NO; | 1012 | result = MHD_NO; |
1012 | #ifdef MHD_POSIX_SOCKETS | 1013 | #ifdef MHD_POSIX_SOCKETS |
1013 | MHD_add_to_fd_set_ (pos->socket_fd, | 1014 | MHD_add_to_fd_set_ (pos->socket_fd, |
1014 | except_fd_set, | 1015 | except_fd_set, |
1015 | max_fd, | 1016 | max_fd, |
1016 | fd_setsize); | 1017 | fd_setsize); |
1017 | #endif /* MHD_POSIX_SOCKETS */ | 1018 | #endif /* MHD_POSIX_SOCKETS */ |
1018 | break; | 1019 | break; |
1019 | case MHD_EVENT_LOOP_INFO_WRITE: | 1020 | case MHD_EVENT_LOOP_INFO_WRITE: |
1020 | if (! MHD_add_to_fd_set_ (pos->socket_fd, | 1021 | if (! MHD_add_to_fd_set_ (pos->socket_fd, |
1021 | write_fd_set, | 1022 | write_fd_set, |
1022 | max_fd, | 1023 | max_fd, |
1023 | fd_setsize)) | 1024 | fd_setsize)) |
1024 | result = MHD_NO; | 1025 | result = MHD_NO; |
1025 | #ifdef MHD_POSIX_SOCKETS | 1026 | #ifdef MHD_POSIX_SOCKETS |
1026 | MHD_add_to_fd_set_ (pos->socket_fd, | 1027 | MHD_add_to_fd_set_ (pos->socket_fd, |
1027 | except_fd_set, | 1028 | except_fd_set, |
1028 | max_fd, | 1029 | max_fd, |
1029 | fd_setsize); | 1030 | fd_setsize); |
1030 | #endif /* MHD_POSIX_SOCKETS */ | 1031 | #endif /* MHD_POSIX_SOCKETS */ |
1031 | break; | 1032 | break; |
1032 | case MHD_EVENT_LOOP_INFO_BLOCK: | 1033 | case MHD_EVENT_LOOP_INFO_BLOCK: |
1033 | if ( (NULL == except_fd_set) || | 1034 | if ( (NULL == except_fd_set) || |
1034 | ! MHD_add_to_fd_set_ (pos->socket_fd, | 1035 | ! MHD_add_to_fd_set_ (pos->socket_fd, |
1035 | except_fd_set, | 1036 | except_fd_set, |
1036 | max_fd, | 1037 | max_fd, |
1037 | fd_setsize)) | 1038 | fd_setsize)) |
1038 | result = MHD_NO; | 1039 | result = MHD_NO; |
1039 | break; | 1040 | break; |
1040 | case MHD_EVENT_LOOP_INFO_CLEANUP: | 1041 | case MHD_EVENT_LOOP_INFO_CLEANUP: |
1041 | /* this should never happen */ | 1042 | /* this should never happen */ |
1042 | break; | 1043 | break; |
1043 | } | ||
1044 | } | 1044 | } |
1045 | } | ||
1045 | #ifdef MHD_WINSOCK_SOCKETS | 1046 | #ifdef MHD_WINSOCK_SOCKETS |
1046 | /* W32 use limited array for fd_set so add INFO_READ/INFO_WRITE sockets | 1047 | /* W32 use limited array for fd_set so add INFO_READ/INFO_WRITE sockets |
1047 | * only after INFO_BLOCK sockets to ensure that INFO_BLOCK sockets will | 1048 | * only after INFO_BLOCK sockets to ensure that INFO_BLOCK sockets will |
1048 | * not be pushed out. */ | 1049 | * not be pushed out. */ |
1049 | for (pos = daemon->connections_tail; NULL != pos; pos = posn) | 1050 | for (pos = daemon->connections_tail; NULL != pos; pos = posn) |
1050 | { | 1051 | { |
1051 | posn = pos->prev; | 1052 | posn = pos->prev; |
1052 | MHD_add_to_fd_set_ (pos->socket_fd, | 1053 | MHD_add_to_fd_set_ (pos->socket_fd, |
1053 | except_fd_set, | 1054 | except_fd_set, |
1054 | max_fd, | 1055 | max_fd, |
1055 | fd_setsize); | 1056 | fd_setsize); |
1056 | } | 1057 | } |
1057 | #endif /* MHD_WINSOCK_SOCKETS */ | 1058 | #endif /* MHD_WINSOCK_SOCKETS */ |
1058 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) | 1059 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) |
1059 | { | 1060 | { |
1060 | struct MHD_UpgradeResponseHandle *urh; | 1061 | struct MHD_UpgradeResponseHandle *urh; |
1061 | 1062 | ||
1062 | for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev) | 1063 | for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev) |
1063 | { | 1064 | { |
1064 | if (MHD_NO == | 1065 | if (MHD_NO == |
1065 | urh_to_fdset (urh, | 1066 | urh_to_fdset (urh, |
1066 | read_fd_set, | 1067 | read_fd_set, |
1067 | write_fd_set, | 1068 | write_fd_set, |
1068 | except_fd_set, | 1069 | except_fd_set, |
1069 | max_fd, | 1070 | max_fd, |
1070 | fd_setsize)) | 1071 | fd_setsize)) |
1071 | result = MHD_NO; | 1072 | result = MHD_NO; |
1072 | } | 1073 | } |
1073 | } | 1074 | } |
1074 | #endif | 1075 | #endif |
1075 | #if DEBUG_CONNECT | 1076 | #if DEBUG_CONNECT |
1076 | #ifdef HAVE_MESSAGES | 1077 | #ifdef HAVE_MESSAGES |
1077 | if (NULL != max_fd) | 1078 | if (NULL != max_fd) |
1078 | MHD_DLOG (daemon, | 1079 | MHD_DLOG (daemon, |
1079 | _("Maximum socket in select set: %d\n"), | 1080 | _ ("Maximum socket in select set: %d\n"), |
1080 | *max_fd); | 1081 | *max_fd); |
1081 | #endif | 1082 | #endif |
1082 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ | 1083 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ |
@@ -1118,11 +1119,11 @@ internal_get_fdset2 (struct MHD_Daemon *daemon, | |||
1118 | */ | 1119 | */ |
1119 | int | 1120 | int |
1120 | MHD_get_fdset2 (struct MHD_Daemon *daemon, | 1121 | MHD_get_fdset2 (struct MHD_Daemon *daemon, |
1121 | fd_set *read_fd_set, | 1122 | fd_set *read_fd_set, |
1122 | fd_set *write_fd_set, | 1123 | fd_set *write_fd_set, |
1123 | fd_set *except_fd_set, | 1124 | fd_set *except_fd_set, |
1124 | MHD_socket *max_fd, | 1125 | MHD_socket *max_fd, |
1125 | unsigned int fd_setsize) | 1126 | unsigned int fd_setsize) |
1126 | { | 1127 | { |
1127 | fd_set es; | 1128 | fd_set es; |
1128 | 1129 | ||
@@ -1134,38 +1135,38 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon, | |||
1134 | return MHD_NO; | 1135 | return MHD_NO; |
1135 | 1136 | ||
1136 | if (NULL == except_fd_set) | 1137 | if (NULL == except_fd_set) |
1137 | { /* Workaround to maintain backward compatibility. */ | 1138 | { /* Workaround to maintain backward compatibility. */ |
1138 | #ifdef HAVE_MESSAGES | 1139 | #ifdef HAVE_MESSAGES |
1139 | MHD_DLOG (daemon, | 1140 | MHD_DLOG (daemon, |
1140 | _("MHD_get_fdset2() called with except_fd_set " | 1141 | _ ("MHD_get_fdset2() called with except_fd_set " |
1141 | "set to NULL. Such behavior is unsupported.\n")); | 1142 | "set to NULL. Such behavior is unsupported.\n")); |
1142 | #endif | 1143 | #endif |
1143 | FD_ZERO (&es); | 1144 | FD_ZERO (&es); |
1144 | except_fd_set = &es; | 1145 | except_fd_set = &es; |
1145 | } | 1146 | } |
1146 | 1147 | ||
1147 | #ifdef EPOLL_SUPPORT | 1148 | #ifdef EPOLL_SUPPORT |
1148 | if (0 != (daemon->options & MHD_USE_EPOLL)) | 1149 | if (0 != (daemon->options & MHD_USE_EPOLL)) |
1149 | { | 1150 | { |
1150 | if (daemon->shutdown) | 1151 | if (daemon->shutdown) |
1151 | return MHD_NO; | 1152 | return MHD_NO; |
1152 | 1153 | ||
1153 | /* we're in epoll mode, use the epoll FD as a stand-in for | 1154 | /* we're in epoll mode, use the epoll FD as a stand-in for |
1154 | the entire event set */ | 1155 | the entire event set */ |
1155 | 1156 | ||
1156 | return MHD_add_to_fd_set_ (daemon->epoll_fd, | 1157 | return MHD_add_to_fd_set_ (daemon->epoll_fd, |
1157 | read_fd_set, | 1158 | read_fd_set, |
1158 | max_fd, | 1159 | max_fd, |
1159 | fd_setsize) ? MHD_YES : MHD_NO; | 1160 | fd_setsize) ? MHD_YES : MHD_NO; |
1160 | } | 1161 | } |
1161 | #endif | 1162 | #endif |
1162 | 1163 | ||
1163 | return internal_get_fdset2 (daemon, | 1164 | return internal_get_fdset2 (daemon, |
1164 | read_fd_set, | 1165 | read_fd_set, |
1165 | write_fd_set, | 1166 | write_fd_set, |
1166 | except_fd_set, | 1167 | except_fd_set, |
1167 | max_fd, | 1168 | max_fd, |
1168 | fd_setsize); | 1169 | fd_setsize); |
1169 | } | 1170 | } |
1170 | 1171 | ||
1171 | 1172 | ||
@@ -1197,37 +1198,37 @@ call_handlers (struct MHD_Connection *con, | |||
1197 | if (con->tls_read_ready) | 1198 | if (con->tls_read_ready) |
1198 | read_ready = true; | 1199 | read_ready = true; |
1199 | #endif /* HTTPS_SUPPORT */ | 1200 | #endif /* HTTPS_SUPPORT */ |
1200 | if (!force_close) | 1201 | if (! force_close) |
1202 | { | ||
1203 | if ( (MHD_EVENT_LOOP_INFO_READ == con->event_loop_info) && | ||
1204 | read_ready) | ||
1201 | { | 1205 | { |
1202 | if ( (MHD_EVENT_LOOP_INFO_READ == con->event_loop_info) && | 1206 | MHD_connection_handle_read (con); |
1203 | read_ready) | 1207 | ret = MHD_connection_handle_idle (con); |
1204 | { | 1208 | states_info_processed = true; |
1205 | MHD_connection_handle_read (con); | ||
1206 | ret = MHD_connection_handle_idle (con); | ||
1207 | states_info_processed = true; | ||
1208 | } | ||
1209 | /* No need to check value of 'ret' here as closed connection | ||
1210 | * cannot be in MHD_EVENT_LOOP_INFO_WRITE state. */ | ||
1211 | if ( (MHD_EVENT_LOOP_INFO_WRITE == con->event_loop_info) && | ||
1212 | write_ready) | ||
1213 | { | ||
1214 | MHD_connection_handle_write (con); | ||
1215 | ret = MHD_connection_handle_idle (con); | ||
1216 | states_info_processed = true; | ||
1217 | } | ||
1218 | } | 1209 | } |
1219 | else | 1210 | /* No need to check value of 'ret' here as closed connection |
1211 | * cannot be in MHD_EVENT_LOOP_INFO_WRITE state. */ | ||
1212 | if ( (MHD_EVENT_LOOP_INFO_WRITE == con->event_loop_info) && | ||
1213 | write_ready) | ||
1220 | { | 1214 | { |
1221 | MHD_connection_close_ (con, | 1215 | MHD_connection_handle_write (con); |
1222 | MHD_REQUEST_TERMINATED_WITH_ERROR); | 1216 | ret = MHD_connection_handle_idle (con); |
1223 | return MHD_connection_handle_idle (con); | 1217 | states_info_processed = true; |
1224 | } | 1218 | } |
1219 | } | ||
1220 | else | ||
1221 | { | ||
1222 | MHD_connection_close_ (con, | ||
1223 | MHD_REQUEST_TERMINATED_WITH_ERROR); | ||
1224 | return MHD_connection_handle_idle (con); | ||
1225 | } | ||
1225 | 1226 | ||
1226 | if (!states_info_processed) | 1227 | if (! states_info_processed) |
1227 | { /* Connection is not read or write ready, but external conditions | 1228 | { /* Connection is not read or write ready, but external conditions |
1228 | * may be changed and need to be processed. */ | 1229 | * may be changed and need to be processed. */ |
1229 | ret = MHD_connection_handle_idle (con); | 1230 | ret = MHD_connection_handle_idle (con); |
1230 | } | 1231 | } |
1231 | /* Fast track for fast connections. */ | 1232 | /* Fast track for fast connections. */ |
1232 | /* If full request was read by single read_handler() invocation | 1233 | /* If full request was read by single read_handler() invocation |
1233 | and headers were completely prepared by single MHD_connection_handle_idle() | 1234 | and headers were completely prepared by single MHD_connection_handle_idle() |
@@ -1239,23 +1240,23 @@ call_handlers (struct MHD_Connection *con, | |||
1239 | /* No need to check 'ret' as connection is always in | 1240 | /* No need to check 'ret' as connection is always in |
1240 | * MHD_CONNECTION_CLOSED state if 'ret' is equal 'MHD_NO'. */ | 1241 | * MHD_CONNECTION_CLOSED state if 'ret' is equal 'MHD_NO'. */ |
1241 | else if (on_fasttrack && con->sk_nonblck) | 1242 | else if (on_fasttrack && con->sk_nonblck) |
1243 | { | ||
1244 | if (MHD_CONNECTION_HEADERS_SENDING == con->state) | ||
1242 | { | 1245 | { |
1243 | if (MHD_CONNECTION_HEADERS_SENDING == con->state) | 1246 | MHD_connection_handle_write (con); |
1244 | { | 1247 | /* Always call 'MHD_connection_handle_idle()' after each read/write. */ |
1245 | MHD_connection_handle_write (con); | 1248 | ret = MHD_connection_handle_idle (con); |
1246 | /* Always call 'MHD_connection_handle_idle()' after each read/write. */ | ||
1247 | ret = MHD_connection_handle_idle (con); | ||
1248 | } | ||
1249 | /* If all headers were sent by single write_handler() and | ||
1250 | * response body is prepared by single MHD_connection_handle_idle() | ||
1251 | * call - continue. */ | ||
1252 | if ((MHD_CONNECTION_NORMAL_BODY_READY == con->state) || | ||
1253 | (MHD_CONNECTION_CHUNKED_BODY_READY == con->state)) | ||
1254 | { | ||
1255 | MHD_connection_handle_write (con); | ||
1256 | ret = MHD_connection_handle_idle (con); | ||
1257 | } | ||
1258 | } | 1249 | } |
1250 | /* If all headers were sent by single write_handler() and | ||
1251 | * response body is prepared by single MHD_connection_handle_idle() | ||
1252 | * call - continue. */ | ||
1253 | if ((MHD_CONNECTION_NORMAL_BODY_READY == con->state) || | ||
1254 | (MHD_CONNECTION_CHUNKED_BODY_READY == con->state)) | ||
1255 | { | ||
1256 | MHD_connection_handle_write (con); | ||
1257 | ret = MHD_connection_handle_idle (con); | ||
1258 | } | ||
1259 | } | ||
1259 | 1260 | ||
1260 | /* All connection's data and states are processed for this turn. | 1261 | /* All connection's data and states are processed for this turn. |
1261 | * If connection already has more data to be processed - use | 1262 | * If connection already has more data to be processed - use |
@@ -1267,15 +1268,15 @@ call_handlers (struct MHD_Connection *con, | |||
1267 | * without space in read buffer will be marked as 'info block'. */ | 1268 | * without space in read buffer will be marked as 'info block'. */ |
1268 | if ( (! con->daemon->data_already_pending) && | 1269 | if ( (! con->daemon->data_already_pending) && |
1269 | (0 == (con->daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ) | 1270 | (0 == (con->daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ) |
1270 | { | 1271 | { |
1271 | if (MHD_EVENT_LOOP_INFO_BLOCK == con->event_loop_info) | 1272 | if (MHD_EVENT_LOOP_INFO_BLOCK == con->event_loop_info) |
1272 | con->daemon->data_already_pending = true; | 1273 | con->daemon->data_already_pending = true; |
1273 | #ifdef HTTPS_SUPPORT | 1274 | #ifdef HTTPS_SUPPORT |
1274 | else if ( (con->tls_read_ready) && | 1275 | else if ( (con->tls_read_ready) && |
1275 | (MHD_EVENT_LOOP_INFO_READ == con->event_loop_info) ) | 1276 | (MHD_EVENT_LOOP_INFO_READ == con->event_loop_info) ) |
1276 | con->daemon->data_already_pending = true; | 1277 | con->daemon->data_already_pending = true; |
1277 | #endif /* HTTPS_SUPPORT */ | 1278 | #endif /* HTTPS_SUPPORT */ |
1278 | } | 1279 | } |
1279 | return ret; | 1280 | return ret; |
1280 | } | 1281 | } |
1281 | 1282 | ||
@@ -1330,55 +1331,58 @@ process_urh (struct MHD_UpgradeResponseHandle *urh) | |||
1330 | * pointers to 'connection' and 'daemon' are not changed | 1331 | * pointers to 'connection' and 'daemon' are not changed |
1331 | * during this processing, so no need to chain dereference | 1332 | * during this processing, so no need to chain dereference |
1332 | * each time. */ | 1333 | * each time. */ |
1333 | struct MHD_Connection * const connection = urh->connection; | 1334 | struct MHD_Connection *const connection = urh->connection; |
1334 | struct MHD_Daemon * const daemon = connection->daemon; | 1335 | struct MHD_Daemon *const daemon = connection->daemon; |
1335 | /* Prevent data races: use same value of 'was_closed' throughout | 1336 | /* Prevent data races: use same value of 'was_closed' throughout |
1336 | * this function. If 'was_closed' changed externally in the middle | 1337 | * this function. If 'was_closed' changed externally in the middle |
1337 | * of processing - it will be processed on next iteration. */ | 1338 | * of processing - it will be processed on next iteration. */ |
1338 | bool was_closed; | 1339 | bool was_closed; |
1339 | if (daemon->shutdown) | 1340 | if (daemon->shutdown) |
1340 | { | 1341 | { |
1341 | /* Daemon shutting down, application will not receive any more data. */ | 1342 | /* Daemon shutting down, application will not receive any more data. */ |
1342 | #ifdef HAVE_MESSAGES | 1343 | #ifdef HAVE_MESSAGES |
1343 | if (! urh->was_closed) | 1344 | if (! urh->was_closed) |
1344 | { | 1345 | { |
1345 | MHD_DLOG (daemon, | 1346 | MHD_DLOG (daemon, |
1346 | _("Initiated daemon shutdown while \"upgraded\" connection was not closed.\n")); | 1347 | _ ( |
1347 | } | 1348 | "Initiated daemon shutdown while \"upgraded\" connection was not closed.\n")); |
1348 | #endif | ||
1349 | urh->was_closed = true; | ||
1350 | } | 1349 | } |
1350 | #endif | ||
1351 | urh->was_closed = true; | ||
1352 | } | ||
1351 | was_closed = urh->was_closed; | 1353 | was_closed = urh->was_closed; |
1352 | if (was_closed) | 1354 | if (was_closed) |
1355 | { | ||
1356 | /* Application was closed connections: no more data | ||
1357 | * can be forwarded to application socket. */ | ||
1358 | if (0 < urh->in_buffer_used) | ||
1353 | { | 1359 | { |
1354 | /* Application was closed connections: no more data | ||
1355 | * can be forwarded to application socket. */ | ||
1356 | if (0 < urh->in_buffer_used) | ||
1357 | { | ||
1358 | #ifdef HAVE_MESSAGES | 1360 | #ifdef HAVE_MESSAGES |
1359 | MHD_DLOG (daemon, | 1361 | MHD_DLOG (daemon, |
1360 | _("Failed to forward to application " MHD_UNSIGNED_LONG_LONG_PRINTF \ | 1362 | _ ( |
1361 | " bytes of data received from remote side: application shut down socket\n"), | 1363 | "Failed to forward to application " |
1362 | (MHD_UNSIGNED_LONG_LONG) urh->in_buffer_used); | 1364 | MHD_UNSIGNED_LONG_LONG_PRINTF \ |
1363 | #endif | 1365 | " bytes of data received from remote side: application shut down socket\n"), |
1364 | 1366 | (MHD_UNSIGNED_LONG_LONG) urh->in_buffer_used); | |
1365 | } | 1367 | #endif |
1366 | /* If application signaled MHD about socket closure then | 1368 | |
1367 | * check for any pending data even if socket is not marked | 1369 | } |
1368 | * as 'ready' (signal may arrive after poll()/select()). | 1370 | /* If application signaled MHD about socket closure then |
1369 | * Socketpair for forwarding is always in non-blocking mode | 1371 | * check for any pending data even if socket is not marked |
1370 | * so no risk that recv() will block the thread. */ | 1372 | * as 'ready' (signal may arrive after poll()/select()). |
1371 | if (0 != urh->out_buffer_size) | 1373 | * Socketpair for forwarding is always in non-blocking mode |
1372 | urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY; | 1374 | * so no risk that recv() will block the thread. */ |
1373 | /* Discard any data received form remote. */ | 1375 | if (0 != urh->out_buffer_size) |
1374 | urh->in_buffer_used = 0; | 1376 | urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY; |
1375 | /* Do not try to push data to application. */ | 1377 | /* Discard any data received form remote. */ |
1376 | urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | 1378 | urh->in_buffer_used = 0; |
1377 | /* Reading from remote client is not required anymore. */ | 1379 | /* Do not try to push data to application. */ |
1378 | urh->in_buffer_size = 0; | 1380 | urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY; |
1379 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; | 1381 | /* Reading from remote client is not required anymore. */ |
1380 | connection->tls_read_ready = false; | 1382 | urh->in_buffer_size = 0; |
1381 | } | 1383 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; |
1384 | connection->tls_read_ready = false; | ||
1385 | } | ||
1382 | 1386 | ||
1383 | /* On some platforms (W32, possibly Darwin) failed send() (send() will always | 1387 | /* On some platforms (W32, possibly Darwin) failed send() (send() will always |
1384 | * fail after remote disconnect was detected) may discard data in system | 1388 | * fail after remote disconnect was detected) may discard data in system |
@@ -1399,237 +1403,241 @@ process_urh (struct MHD_UpgradeResponseHandle *urh) | |||
1399 | if ( ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->app.celi)) || | 1403 | if ( ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->app.celi)) || |
1400 | (connection->tls_read_ready) ) && | 1404 | (connection->tls_read_ready) ) && |
1401 | (urh->in_buffer_used < urh->in_buffer_size) ) | 1405 | (urh->in_buffer_used < urh->in_buffer_size) ) |
1402 | { | 1406 | { |
1403 | ssize_t res; | 1407 | ssize_t res; |
1404 | size_t buf_size; | 1408 | size_t buf_size; |
1405 | 1409 | ||
1406 | buf_size = urh->in_buffer_size - urh->in_buffer_used; | 1410 | buf_size = urh->in_buffer_size - urh->in_buffer_used; |
1407 | if (buf_size > SSIZE_MAX) | 1411 | if (buf_size > SSIZE_MAX) |
1408 | buf_size = SSIZE_MAX; | 1412 | buf_size = SSIZE_MAX; |
1409 | 1413 | ||
1410 | connection->tls_read_ready = false; | 1414 | connection->tls_read_ready = false; |
1411 | res = gnutls_record_recv (connection->tls_session, | 1415 | res = gnutls_record_recv (connection->tls_session, |
1412 | &urh->in_buffer[urh->in_buffer_used], | 1416 | &urh->in_buffer[urh->in_buffer_used], |
1413 | buf_size); | 1417 | buf_size); |
1414 | if (0 >= res) | 1418 | if (0 >= res) |
1415 | { | 1419 | { |
1416 | if (GNUTLS_E_INTERRUPTED != res) | 1420 | if (GNUTLS_E_INTERRUPTED != res) |
1417 | { | 1421 | { |
1418 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; | 1422 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; |
1419 | if (GNUTLS_E_AGAIN != res) | 1423 | if (GNUTLS_E_AGAIN != res) |
1420 | { | ||
1421 | /* Unrecoverable error on socket was detected or | ||
1422 | * socket was disconnected/shut down. */ | ||
1423 | /* Stop trying to read from this TLS socket. */ | ||
1424 | urh->in_buffer_size = 0; | ||
1425 | } | ||
1426 | } | ||
1427 | } | ||
1428 | else /* 0 < res */ | ||
1429 | { | ||
1430 | urh->in_buffer_used += res; | ||
1431 | if (buf_size > (size_t)res) | ||
1432 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; | ||
1433 | else if (0 < gnutls_record_check_pending (connection->tls_session)) | ||
1434 | connection->tls_read_ready = true; | ||
1435 | } | ||
1436 | if (MHD_EPOLL_STATE_ERROR == | ||
1437 | ((MHD_EPOLL_STATE_ERROR | MHD_EPOLL_STATE_READ_READY) & urh->app.celi)) | ||
1438 | { | 1424 | { |
1439 | /* Unrecoverable error on socket was detected and all | 1425 | /* Unrecoverable error on socket was detected or |
1440 | * pending data was read from system buffers. */ | 1426 | * socket was disconnected/shut down. */ |
1441 | /* Stop trying to read from this TLS socket. */ | 1427 | /* Stop trying to read from this TLS socket. */ |
1442 | urh->in_buffer_size = 0; | 1428 | urh->in_buffer_size = 0; |
1443 | } | 1429 | } |
1430 | } | ||
1431 | } | ||
1432 | else /* 0 < res */ | ||
1433 | { | ||
1434 | urh->in_buffer_used += res; | ||
1435 | if (buf_size > (size_t) res) | ||
1436 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; | ||
1437 | else if (0 < gnutls_record_check_pending (connection->tls_session)) | ||
1438 | connection->tls_read_ready = true; | ||
1439 | } | ||
1440 | if (MHD_EPOLL_STATE_ERROR == | ||
1441 | ((MHD_EPOLL_STATE_ERROR | MHD_EPOLL_STATE_READ_READY) & urh->app.celi)) | ||
1442 | { | ||
1443 | /* Unrecoverable error on socket was detected and all | ||
1444 | * pending data was read from system buffers. */ | ||
1445 | /* Stop trying to read from this TLS socket. */ | ||
1446 | urh->in_buffer_size = 0; | ||
1444 | } | 1447 | } |
1448 | } | ||
1445 | 1449 | ||
1446 | /* | 1450 | /* |
1447 | * handle reading from application | 1451 | * handle reading from application |
1448 | */ | 1452 | */ |
1449 | if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) && | 1453 | if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) && |
1450 | (urh->out_buffer_used < urh->out_buffer_size) ) | 1454 | (urh->out_buffer_used < urh->out_buffer_size) ) |
1451 | { | 1455 | { |
1452 | ssize_t res; | 1456 | ssize_t res; |
1453 | size_t buf_size; | 1457 | size_t buf_size; |
1454 | 1458 | ||
1455 | buf_size = urh->out_buffer_size - urh->out_buffer_used; | 1459 | buf_size = urh->out_buffer_size - urh->out_buffer_used; |
1456 | if (buf_size > MHD_SCKT_SEND_MAX_SIZE_) | 1460 | if (buf_size > MHD_SCKT_SEND_MAX_SIZE_) |
1457 | buf_size = MHD_SCKT_SEND_MAX_SIZE_; | 1461 | buf_size = MHD_SCKT_SEND_MAX_SIZE_; |
1458 | 1462 | ||
1459 | res = MHD_recv_ (urh->mhd.socket, | 1463 | res = MHD_recv_ (urh->mhd.socket, |
1460 | &urh->out_buffer[urh->out_buffer_used], | 1464 | &urh->out_buffer[urh->out_buffer_used], |
1461 | buf_size); | 1465 | buf_size); |
1462 | if (0 >= res) | 1466 | if (0 >= res) |
1463 | { | 1467 | { |
1464 | const int err = MHD_socket_get_error_ (); | 1468 | const int err = MHD_socket_get_error_ (); |
1465 | if ((0 == res) || | 1469 | if ((0 == res) || |
1466 | ((! MHD_SCKT_ERR_IS_EINTR_ (err)) && | 1470 | ((! MHD_SCKT_ERR_IS_EINTR_ (err)) && |
1467 | (! MHD_SCKT_ERR_IS_LOW_RESOURCES_(err)))) | 1471 | (! MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err)))) |
1468 | { | 1472 | { |
1469 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; | 1473 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; |
1470 | if ((0 == res) || | 1474 | if ((0 == res) || |
1471 | (was_closed) || | 1475 | (was_closed) || |
1472 | (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) || | 1476 | (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) || |
1473 | (! MHD_SCKT_ERR_IS_EAGAIN_ (err))) | 1477 | (! MHD_SCKT_ERR_IS_EAGAIN_ (err))) |
1474 | { | ||
1475 | /* Socket disconnect/shutdown was detected; | ||
1476 | * Application signaled about closure of 'upgraded' socket; | ||
1477 | * or persistent / unrecoverable error. */ | ||
1478 | /* Do not try to pull more data from application. */ | ||
1479 | urh->out_buffer_size = 0; | ||
1480 | } | ||
1481 | } | ||
1482 | } | ||
1483 | else /* 0 < res */ | ||
1484 | { | ||
1485 | urh->out_buffer_used += res; | ||
1486 | if (buf_size > (size_t)res) | ||
1487 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; | ||
1488 | } | ||
1489 | if ( (0 == (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) && | ||
1490 | ( (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) || | ||
1491 | (was_closed) ) ) | ||
1492 | { | 1478 | { |
1493 | /* Unrecoverable error on socket was detected and all | 1479 | /* Socket disconnect/shutdown was detected; |
1494 | * pending data was read from system buffers. */ | 1480 | * Application signaled about closure of 'upgraded' socket; |
1481 | * or persistent / unrecoverable error. */ | ||
1495 | /* Do not try to pull more data from application. */ | 1482 | /* Do not try to pull more data from application. */ |
1496 | urh->out_buffer_size = 0; | 1483 | urh->out_buffer_size = 0; |
1497 | } | 1484 | } |
1485 | } | ||
1486 | } | ||
1487 | else /* 0 < res */ | ||
1488 | { | ||
1489 | urh->out_buffer_used += res; | ||
1490 | if (buf_size > (size_t) res) | ||
1491 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; | ||
1492 | } | ||
1493 | if ( (0 == (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) && | ||
1494 | ( (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) || | ||
1495 | (was_closed) ) ) | ||
1496 | { | ||
1497 | /* Unrecoverable error on socket was detected and all | ||
1498 | * pending data was read from system buffers. */ | ||
1499 | /* Do not try to pull more data from application. */ | ||
1500 | urh->out_buffer_size = 0; | ||
1498 | } | 1501 | } |
1502 | } | ||
1499 | 1503 | ||
1500 | /* | 1504 | /* |
1501 | * handle writing to remote HTTPS client | 1505 | * handle writing to remote HTTPS client |
1502 | */ | 1506 | */ |
1503 | if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) && | 1507 | if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) && |
1504 | (urh->out_buffer_used > 0) ) | 1508 | (urh->out_buffer_used > 0) ) |
1505 | { | 1509 | { |
1506 | ssize_t res; | 1510 | ssize_t res; |
1507 | size_t data_size; | 1511 | size_t data_size; |
1508 | 1512 | ||
1509 | data_size = urh->out_buffer_used; | 1513 | data_size = urh->out_buffer_used; |
1510 | if (data_size > SSIZE_MAX) | 1514 | if (data_size > SSIZE_MAX) |
1511 | data_size = SSIZE_MAX; | 1515 | data_size = SSIZE_MAX; |
1512 | 1516 | ||
1513 | res = gnutls_record_send (connection->tls_session, | 1517 | res = gnutls_record_send (connection->tls_session, |
1514 | urh->out_buffer, | 1518 | urh->out_buffer, |
1515 | data_size); | 1519 | data_size); |
1516 | if (0 >= res) | 1520 | if (0 >= res) |
1517 | { | 1521 | { |
1518 | if (GNUTLS_E_INTERRUPTED != res) | 1522 | if (GNUTLS_E_INTERRUPTED != res) |
1519 | { | 1523 | { |
1520 | urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | 1524 | urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY; |
1521 | if (GNUTLS_E_AGAIN != res) | 1525 | if (GNUTLS_E_AGAIN != res) |
1522 | { | ||
1523 | /* TLS connection shut down or | ||
1524 | * persistent / unrecoverable error. */ | ||
1525 | #ifdef HAVE_MESSAGES | ||
1526 | MHD_DLOG (daemon, | ||
1527 | _("Failed to forward to remote client " MHD_UNSIGNED_LONG_LONG_PRINTF \ | ||
1528 | " bytes of data received from application: %s\n"), | ||
1529 | (MHD_UNSIGNED_LONG_LONG) urh->out_buffer_used, | ||
1530 | gnutls_strerror(res)); | ||
1531 | #endif | ||
1532 | /* Discard any data unsent to remote. */ | ||
1533 | urh->out_buffer_used = 0; | ||
1534 | /* Do not try to pull more data from application. */ | ||
1535 | urh->out_buffer_size = 0; | ||
1536 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; | ||
1537 | } | ||
1538 | } | ||
1539 | } | ||
1540 | else /* 0 < res */ | ||
1541 | { | ||
1542 | const size_t next_out_buffer_used = urh->out_buffer_used - res; | ||
1543 | if (0 != next_out_buffer_used) | ||
1544 | { | ||
1545 | memmove (urh->out_buffer, | ||
1546 | &urh->out_buffer[res], | ||
1547 | next_out_buffer_used); | ||
1548 | if (data_size > (size_t)res) | ||
1549 | urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
1550 | } | ||
1551 | urh->out_buffer_used = next_out_buffer_used; | ||
1552 | } | ||
1553 | if ( (0 == urh->out_buffer_used) && | ||
1554 | (0 != (MHD_EPOLL_STATE_ERROR & urh->app.celi)) ) | ||
1555 | { | 1526 | { |
1556 | /* Unrecoverable error on socket was detected and all | 1527 | /* TLS connection shut down or |
1557 | * pending data was sent to remote. */ | 1528 | * persistent / unrecoverable error. */ |
1558 | /* Do not try to send to remote anymore. */ | 1529 | #ifdef HAVE_MESSAGES |
1559 | urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | 1530 | MHD_DLOG (daemon, |
1531 | _ ( | ||
1532 | "Failed to forward to remote client " | ||
1533 | MHD_UNSIGNED_LONG_LONG_PRINTF \ | ||
1534 | " bytes of data received from application: %s\n"), | ||
1535 | (MHD_UNSIGNED_LONG_LONG) urh->out_buffer_used, | ||
1536 | gnutls_strerror (res)); | ||
1537 | #endif | ||
1538 | /* Discard any data unsent to remote. */ | ||
1539 | urh->out_buffer_used = 0; | ||
1560 | /* Do not try to pull more data from application. */ | 1540 | /* Do not try to pull more data from application. */ |
1561 | urh->out_buffer_size = 0; | 1541 | urh->out_buffer_size = 0; |
1562 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; | 1542 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; |
1563 | } | 1543 | } |
1544 | } | ||
1564 | } | 1545 | } |
1546 | else /* 0 < res */ | ||
1547 | { | ||
1548 | const size_t next_out_buffer_used = urh->out_buffer_used - res; | ||
1549 | if (0 != next_out_buffer_used) | ||
1550 | { | ||
1551 | memmove (urh->out_buffer, | ||
1552 | &urh->out_buffer[res], | ||
1553 | next_out_buffer_used); | ||
1554 | if (data_size > (size_t) res) | ||
1555 | urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
1556 | } | ||
1557 | urh->out_buffer_used = next_out_buffer_used; | ||
1558 | } | ||
1559 | if ( (0 == urh->out_buffer_used) && | ||
1560 | (0 != (MHD_EPOLL_STATE_ERROR & urh->app.celi)) ) | ||
1561 | { | ||
1562 | /* Unrecoverable error on socket was detected and all | ||
1563 | * pending data was sent to remote. */ | ||
1564 | /* Do not try to send to remote anymore. */ | ||
1565 | urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
1566 | /* Do not try to pull more data from application. */ | ||
1567 | urh->out_buffer_size = 0; | ||
1568 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; | ||
1569 | } | ||
1570 | } | ||
1565 | 1571 | ||
1566 | /* | 1572 | /* |
1567 | * handle writing to application | 1573 | * handle writing to application |
1568 | */ | 1574 | */ |
1569 | if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) && | 1575 | if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) && |
1570 | (urh->in_buffer_used > 0) ) | 1576 | (urh->in_buffer_used > 0) ) |
1571 | { | 1577 | { |
1572 | ssize_t res; | 1578 | ssize_t res; |
1573 | size_t data_size; | 1579 | size_t data_size; |
1574 | 1580 | ||
1575 | data_size = urh->in_buffer_used; | 1581 | data_size = urh->in_buffer_used; |
1576 | if (data_size > MHD_SCKT_SEND_MAX_SIZE_) | 1582 | if (data_size > MHD_SCKT_SEND_MAX_SIZE_) |
1577 | data_size = MHD_SCKT_SEND_MAX_SIZE_; | 1583 | data_size = MHD_SCKT_SEND_MAX_SIZE_; |
1578 | 1584 | ||
1579 | res = MHD_send_ (urh->mhd.socket, | 1585 | res = MHD_send_ (urh->mhd.socket, |
1580 | urh->in_buffer, | 1586 | urh->in_buffer, |
1581 | data_size); | 1587 | data_size); |
1582 | if (0 >= res) | 1588 | if (0 >= res) |
1583 | { | 1589 | { |
1584 | const int err = MHD_socket_get_error_ (); | 1590 | const int err = MHD_socket_get_error_ (); |
1585 | if ( (! MHD_SCKT_ERR_IS_EINTR_ (err)) && | 1591 | if ( (! MHD_SCKT_ERR_IS_EINTR_ (err)) && |
1586 | (! MHD_SCKT_ERR_IS_LOW_RESOURCES_(err)) ) | 1592 | (! MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err)) ) |
1587 | { | 1593 | { |
1588 | urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | 1594 | urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY; |
1589 | if (! MHD_SCKT_ERR_IS_EAGAIN_ (err)) | 1595 | if (! MHD_SCKT_ERR_IS_EAGAIN_ (err)) |
1590 | { | ||
1591 | /* Socketpair connection shut down or | ||
1592 | * persistent / unrecoverable error. */ | ||
1593 | #ifdef HAVE_MESSAGES | ||
1594 | MHD_DLOG (daemon, | ||
1595 | _("Failed to forward to application " MHD_UNSIGNED_LONG_LONG_PRINTF \ | ||
1596 | " bytes of data received from remote side: %s\n"), | ||
1597 | (MHD_UNSIGNED_LONG_LONG) urh->in_buffer_used, | ||
1598 | MHD_socket_strerr_ (err)); | ||
1599 | #endif | ||
1600 | /* Discard any data received form remote. */ | ||
1601 | urh->in_buffer_used = 0; | ||
1602 | /* Reading from remote client is not required anymore. */ | ||
1603 | urh->in_buffer_size = 0; | ||
1604 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; | ||
1605 | connection->tls_read_ready = false; | ||
1606 | } | ||
1607 | } | ||
1608 | } | ||
1609 | else /* 0 < res */ | ||
1610 | { | ||
1611 | const size_t next_in_buffer_used = urh->in_buffer_used - res; | ||
1612 | if (0 != next_in_buffer_used) | ||
1613 | { | ||
1614 | memmove (urh->in_buffer, | ||
1615 | &urh->in_buffer[res], | ||
1616 | next_in_buffer_used); | ||
1617 | if (data_size > (size_t)res) | ||
1618 | urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
1619 | } | ||
1620 | urh->in_buffer_used = next_in_buffer_used; | ||
1621 | } | ||
1622 | if ( (0 == urh->in_buffer_used) && | ||
1623 | (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) ) | ||
1624 | { | 1596 | { |
1625 | /* Do not try to push data to application. */ | 1597 | /* Socketpair connection shut down or |
1626 | urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | 1598 | * persistent / unrecoverable error. */ |
1599 | #ifdef HAVE_MESSAGES | ||
1600 | MHD_DLOG (daemon, | ||
1601 | _ ( | ||
1602 | "Failed to forward to application " | ||
1603 | MHD_UNSIGNED_LONG_LONG_PRINTF \ | ||
1604 | " bytes of data received from remote side: %s\n"), | ||
1605 | (MHD_UNSIGNED_LONG_LONG) urh->in_buffer_used, | ||
1606 | MHD_socket_strerr_ (err)); | ||
1607 | #endif | ||
1608 | /* Discard any data received form remote. */ | ||
1609 | urh->in_buffer_used = 0; | ||
1627 | /* Reading from remote client is not required anymore. */ | 1610 | /* Reading from remote client is not required anymore. */ |
1628 | urh->in_buffer_size = 0; | 1611 | urh->in_buffer_size = 0; |
1629 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; | 1612 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; |
1630 | connection->tls_read_ready = false; | 1613 | connection->tls_read_ready = false; |
1631 | } | 1614 | } |
1615 | } | ||
1616 | } | ||
1617 | else /* 0 < res */ | ||
1618 | { | ||
1619 | const size_t next_in_buffer_used = urh->in_buffer_used - res; | ||
1620 | if (0 != next_in_buffer_used) | ||
1621 | { | ||
1622 | memmove (urh->in_buffer, | ||
1623 | &urh->in_buffer[res], | ||
1624 | next_in_buffer_used); | ||
1625 | if (data_size > (size_t) res) | ||
1626 | urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
1627 | } | ||
1628 | urh->in_buffer_used = next_in_buffer_used; | ||
1629 | } | ||
1630 | if ( (0 == urh->in_buffer_used) && | ||
1631 | (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) ) | ||
1632 | { | ||
1633 | /* Do not try to push data to application. */ | ||
1634 | urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
1635 | /* Reading from remote client is not required anymore. */ | ||
1636 | urh->in_buffer_size = 0; | ||
1637 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; | ||
1638 | connection->tls_read_ready = false; | ||
1632 | } | 1639 | } |
1640 | } | ||
1633 | 1641 | ||
1634 | /* Check whether data is present in TLS buffers | 1642 | /* Check whether data is present in TLS buffers |
1635 | * and incoming forward buffer have some space. */ | 1643 | * and incoming forward buffer have some space. */ |
@@ -1641,23 +1649,25 @@ process_urh (struct MHD_UpgradeResponseHandle *urh) | |||
1641 | if ( (daemon->shutdown) && | 1649 | if ( (daemon->shutdown) && |
1642 | ( (0 != urh->out_buffer_size) || | 1650 | ( (0 != urh->out_buffer_size) || |
1643 | (0 != urh->out_buffer_used) ) ) | 1651 | (0 != urh->out_buffer_used) ) ) |
1644 | { | 1652 | { |
1645 | /* Daemon shutting down, discard any remaining forward data. */ | 1653 | /* Daemon shutting down, discard any remaining forward data. */ |
1646 | #ifdef HAVE_MESSAGES | 1654 | #ifdef HAVE_MESSAGES |
1647 | if (0 < urh->out_buffer_used) | 1655 | if (0 < urh->out_buffer_used) |
1648 | MHD_DLOG (daemon, | 1656 | MHD_DLOG (daemon, |
1649 | _("Failed to forward to remote client " MHD_UNSIGNED_LONG_LONG_PRINTF \ | 1657 | _ ( |
1650 | " bytes of data received from application: daemon shut down\n"), | 1658 | "Failed to forward to remote client " |
1651 | (MHD_UNSIGNED_LONG_LONG) urh->out_buffer_used); | 1659 | MHD_UNSIGNED_LONG_LONG_PRINTF \ |
1652 | #endif | 1660 | " bytes of data received from application: daemon shut down\n"), |
1653 | /* Discard any data unsent to remote. */ | 1661 | (MHD_UNSIGNED_LONG_LONG) urh->out_buffer_used); |
1654 | urh->out_buffer_used = 0; | 1662 | #endif |
1655 | /* Do not try to sent to remote anymore. */ | 1663 | /* Discard any data unsent to remote. */ |
1656 | urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | 1664 | urh->out_buffer_used = 0; |
1657 | /* Do not try to pull more data from application. */ | 1665 | /* Do not try to sent to remote anymore. */ |
1658 | urh->out_buffer_size = 0; | 1666 | urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY; |
1659 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; | 1667 | /* Do not try to pull more data from application. */ |
1660 | } | 1668 | urh->out_buffer_size = 0; |
1669 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; | ||
1670 | } | ||
1661 | } | 1671 | } |
1662 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ | 1672 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ |
1663 | 1673 | ||
@@ -1682,128 +1692,128 @@ thread_main_connection_upgrade (struct MHD_Connection *con) | |||
1682 | until the application tells us that it is done | 1692 | until the application tells us that it is done |
1683 | with the socket; */ | 1693 | with the socket; */ |
1684 | if ( (0 != (daemon->options & MHD_USE_TLS)) && | 1694 | if ( (0 != (daemon->options & MHD_USE_TLS)) && |
1685 | (0 == (daemon->options & MHD_USE_POLL))) | 1695 | (0 == (daemon->options & MHD_USE_POLL))) |
1686 | { | 1696 | { |
1687 | while ( (0 != urh->in_buffer_size) || | 1697 | while ( (0 != urh->in_buffer_size) || |
1688 | (0 != urh->out_buffer_size) || | 1698 | (0 != urh->out_buffer_size) || |
1689 | (0 != urh->in_buffer_used) || | 1699 | (0 != urh->in_buffer_used) || |
1690 | (0 != urh->out_buffer_used) ) | 1700 | (0 != urh->out_buffer_used) ) |
1691 | { | 1701 | { |
1692 | /* use select */ | 1702 | /* use select */ |
1693 | fd_set rs; | 1703 | fd_set rs; |
1694 | fd_set ws; | 1704 | fd_set ws; |
1695 | fd_set es; | 1705 | fd_set es; |
1696 | MHD_socket max_fd; | 1706 | MHD_socket max_fd; |
1697 | int num_ready; | 1707 | int num_ready; |
1698 | bool result; | 1708 | bool result; |
1699 | 1709 | ||
1700 | FD_ZERO (&rs); | 1710 | FD_ZERO (&rs); |
1701 | FD_ZERO (&ws); | 1711 | FD_ZERO (&ws); |
1702 | FD_ZERO (&es); | 1712 | FD_ZERO (&es); |
1703 | max_fd = MHD_INVALID_SOCKET; | 1713 | max_fd = MHD_INVALID_SOCKET; |
1704 | result = urh_to_fdset (urh, | 1714 | result = urh_to_fdset (urh, |
1705 | &rs, | 1715 | &rs, |
1706 | &ws, | 1716 | &ws, |
1707 | &es, | 1717 | &es, |
1708 | &max_fd, | 1718 | &max_fd, |
1709 | FD_SETSIZE); | 1719 | FD_SETSIZE); |
1710 | if (! result) | 1720 | if (! result) |
1711 | { | 1721 | { |
1712 | #ifdef HAVE_MESSAGES | 1722 | #ifdef HAVE_MESSAGES |
1713 | MHD_DLOG (con->daemon, | 1723 | MHD_DLOG (con->daemon, |
1714 | _("Error preparing select\n")); | 1724 | _ ("Error preparing select\n")); |
1715 | #endif | 1725 | #endif |
1716 | break; | 1726 | break; |
1717 | } | 1727 | } |
1718 | /* FIXME: does this check really needed? */ | 1728 | /* FIXME: does this check really needed? */ |
1719 | if (MHD_INVALID_SOCKET != max_fd) | 1729 | if (MHD_INVALID_SOCKET != max_fd) |
1720 | { | 1730 | { |
1721 | struct timeval* tvp; | 1731 | struct timeval*tvp; |
1722 | struct timeval tv; | 1732 | struct timeval tv; |
1723 | if ( (con->tls_read_ready) && | 1733 | if ( (con->tls_read_ready) && |
1724 | (urh->in_buffer_used < urh->in_buffer_size)) | 1734 | (urh->in_buffer_used < urh->in_buffer_size)) |
1725 | { /* No need to wait if incoming data is already pending in TLS buffers. */ | 1735 | { /* No need to wait if incoming data is already pending in TLS buffers. */ |
1726 | tv.tv_sec = 0; | 1736 | tv.tv_sec = 0; |
1727 | tv.tv_usec = 0; | 1737 | tv.tv_usec = 0; |
1728 | tvp = &tv; | 1738 | tvp = &tv; |
1729 | } | ||
1730 | else | ||
1731 | tvp = NULL; | ||
1732 | num_ready = MHD_SYS_select_ (max_fd + 1, | ||
1733 | &rs, | ||
1734 | &ws, | ||
1735 | &es, | ||
1736 | tvp); | ||
1737 | } | ||
1738 | else | ||
1739 | num_ready = 0; | ||
1740 | if (num_ready < 0) | ||
1741 | { | ||
1742 | const int err = MHD_socket_get_error_(); | ||
1743 | |||
1744 | if (MHD_SCKT_ERR_IS_EINTR_(err)) | ||
1745 | continue; | ||
1746 | #ifdef HAVE_MESSAGES | ||
1747 | MHD_DLOG (con->daemon, | ||
1748 | _("Error during select (%d): `%s'\n"), | ||
1749 | err, | ||
1750 | MHD_socket_strerr_ (err)); | ||
1751 | #endif | ||
1752 | break; | ||
1753 | } | ||
1754 | urh_from_fdset (urh, | ||
1755 | &rs, | ||
1756 | &ws, | ||
1757 | &es); | ||
1758 | process_urh (urh); | ||
1759 | } | 1739 | } |
1740 | else | ||
1741 | tvp = NULL; | ||
1742 | num_ready = MHD_SYS_select_ (max_fd + 1, | ||
1743 | &rs, | ||
1744 | &ws, | ||
1745 | &es, | ||
1746 | tvp); | ||
1747 | } | ||
1748 | else | ||
1749 | num_ready = 0; | ||
1750 | if (num_ready < 0) | ||
1751 | { | ||
1752 | const int err = MHD_socket_get_error_ (); | ||
1753 | |||
1754 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) | ||
1755 | continue; | ||
1756 | #ifdef HAVE_MESSAGES | ||
1757 | MHD_DLOG (con->daemon, | ||
1758 | _ ("Error during select (%d): `%s'\n"), | ||
1759 | err, | ||
1760 | MHD_socket_strerr_ (err)); | ||
1761 | #endif | ||
1762 | break; | ||
1763 | } | ||
1764 | urh_from_fdset (urh, | ||
1765 | &rs, | ||
1766 | &ws, | ||
1767 | &es); | ||
1768 | process_urh (urh); | ||
1760 | } | 1769 | } |
1770 | } | ||
1761 | #ifdef HAVE_POLL | 1771 | #ifdef HAVE_POLL |
1762 | else if (0 != (daemon->options & MHD_USE_TLS)) | 1772 | else if (0 != (daemon->options & MHD_USE_TLS)) |
1763 | { | 1773 | { |
1764 | /* use poll() */ | 1774 | /* use poll() */ |
1765 | struct pollfd p[2]; | 1775 | struct pollfd p[2]; |
1766 | memset (p, | 1776 | memset (p, |
1767 | 0, | 1777 | 0, |
1768 | sizeof (p)); | 1778 | sizeof (p)); |
1769 | p[0].fd = urh->connection->socket_fd; | 1779 | p[0].fd = urh->connection->socket_fd; |
1770 | p[1].fd = urh->mhd.socket; | 1780 | p[1].fd = urh->mhd.socket; |
1781 | |||
1782 | while ( (0 != urh->in_buffer_size) || | ||
1783 | (0 != urh->out_buffer_size) || | ||
1784 | (0 != urh->in_buffer_used) || | ||
1785 | (0 != urh->out_buffer_used) ) | ||
1786 | { | ||
1787 | int timeout; | ||
1788 | |||
1789 | urh_update_pollfd (urh, p); | ||
1790 | |||
1791 | if ( (con->tls_read_ready) && | ||
1792 | (urh->in_buffer_used < urh->in_buffer_size)) | ||
1793 | timeout = 0; /* No need to wait if incoming data is already pending in TLS buffers. */ | ||
1794 | else | ||
1795 | timeout = -1; | ||
1771 | 1796 | ||
1772 | while ( (0 != urh->in_buffer_size) || | 1797 | if (MHD_sys_poll_ (p, |
1773 | (0 != urh->out_buffer_size) || | 1798 | 2, |
1774 | (0 != urh->in_buffer_used) || | 1799 | timeout) < 0) |
1775 | (0 != urh->out_buffer_used) ) | 1800 | { |
1776 | { | 1801 | const int err = MHD_socket_get_error_ (); |
1777 | int timeout; | 1802 | |
1778 | 1803 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) | |
1779 | urh_update_pollfd(urh, p); | 1804 | continue; |
1780 | 1805 | #ifdef HAVE_MESSAGES | |
1781 | if ( (con->tls_read_ready) && | 1806 | MHD_DLOG (con->daemon, |
1782 | (urh->in_buffer_used < urh->in_buffer_size)) | 1807 | _ ("Error during poll: `%s'\n"), |
1783 | timeout = 0; /* No need to wait if incoming data is already pending in TLS buffers. */ | 1808 | MHD_socket_strerr_ (err)); |
1784 | else | 1809 | #endif |
1785 | timeout = -1; | 1810 | break; |
1786 | 1811 | } | |
1787 | if (MHD_sys_poll_ (p, | 1812 | urh_from_pollfd (urh, |
1788 | 2, | 1813 | p); |
1789 | timeout) < 0) | 1814 | process_urh (urh); |
1790 | { | ||
1791 | const int err = MHD_socket_get_error_ (); | ||
1792 | |||
1793 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) | ||
1794 | continue; | ||
1795 | #ifdef HAVE_MESSAGES | ||
1796 | MHD_DLOG (con->daemon, | ||
1797 | _("Error during poll: `%s'\n"), | ||
1798 | MHD_socket_strerr_ (err)); | ||
1799 | #endif | ||
1800 | break; | ||
1801 | } | ||
1802 | urh_from_pollfd (urh, | ||
1803 | p); | ||
1804 | process_urh (urh); | ||
1805 | } | ||
1806 | } | 1815 | } |
1816 | } | ||
1807 | /* end POLL */ | 1817 | /* end POLL */ |
1808 | #endif | 1818 | #endif |
1809 | /* end HTTPS */ | 1819 | /* end HTTPS */ |
@@ -1854,346 +1864,348 @@ thread_main_handle_connection (void *data) | |||
1854 | const bool use_poll = 0; | 1864 | const bool use_poll = 0; |
1855 | #endif /* ! HAVE_POLL */ | 1865 | #endif /* ! HAVE_POLL */ |
1856 | bool was_suspended = false; | 1866 | bool was_suspended = false; |
1857 | MHD_thread_init_(&(con->pid)); | 1867 | MHD_thread_init_ (&(con->pid)); |
1858 | 1868 | ||
1859 | while ( (! daemon->shutdown) && | 1869 | while ( (! daemon->shutdown) && |
1860 | (MHD_CONNECTION_CLOSED != con->state) ) | 1870 | (MHD_CONNECTION_CLOSED != con->state) ) |
1861 | { | 1871 | { |
1862 | const time_t timeout = daemon->connection_timeout; | 1872 | const time_t timeout = daemon->connection_timeout; |
1863 | #ifdef UPGRADE_SUPPORT | 1873 | #ifdef UPGRADE_SUPPORT |
1864 | struct MHD_UpgradeResponseHandle * const urh = con->urh; | 1874 | struct MHD_UpgradeResponseHandle *const urh = con->urh; |
1865 | #else /* ! UPGRADE_SUPPORT */ | 1875 | #else /* ! UPGRADE_SUPPORT */ |
1866 | static const void * const urh = NULL; | 1876 | static const void *const urh = NULL; |
1867 | #endif /* ! UPGRADE_SUPPORT */ | 1877 | #endif /* ! UPGRADE_SUPPORT */ |
1868 | 1878 | ||
1869 | if ( (con->suspended) && | 1879 | if ( (con->suspended) && |
1870 | (NULL == urh) ) | 1880 | (NULL == urh) ) |
1881 | { | ||
1882 | /* Connection was suspended, wait for resume. */ | ||
1883 | was_suspended = true; | ||
1884 | if (! use_poll) | ||
1885 | { | ||
1886 | FD_ZERO (&rs); | ||
1887 | if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc), | ||
1888 | &rs, | ||
1889 | NULL, | ||
1890 | FD_SETSIZE)) | ||
1871 | { | 1891 | { |
1872 | /* Connection was suspended, wait for resume. */ | ||
1873 | was_suspended = true; | ||
1874 | if (! use_poll) | ||
1875 | { | ||
1876 | FD_ZERO (&rs); | ||
1877 | if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc), | ||
1878 | &rs, | ||
1879 | NULL, | ||
1880 | FD_SETSIZE)) | ||
1881 | { | ||
1882 | #ifdef HAVE_MESSAGES | 1892 | #ifdef HAVE_MESSAGES |
1883 | MHD_DLOG (con->daemon, | 1893 | MHD_DLOG (con->daemon, |
1884 | _("Failed to add FD to fd_set\n")); | 1894 | _ ("Failed to add FD to fd_set\n")); |
1885 | #endif | 1895 | #endif |
1886 | goto exit; | 1896 | goto exit; |
1887 | } | 1897 | } |
1888 | if (0 > MHD_SYS_select_ (MHD_itc_r_fd_ (daemon->itc) + 1, | 1898 | if (0 > MHD_SYS_select_ (MHD_itc_r_fd_ (daemon->itc) + 1, |
1889 | &rs, | 1899 | &rs, |
1890 | NULL, | 1900 | NULL, |
1891 | NULL, | 1901 | NULL, |
1892 | NULL)) | 1902 | NULL)) |
1893 | { | 1903 | { |
1894 | const int err = MHD_socket_get_error_(); | 1904 | const int err = MHD_socket_get_error_ (); |
1895 | |||
1896 | if (MHD_SCKT_ERR_IS_EINTR_(err)) | ||
1897 | continue; | ||
1898 | #ifdef HAVE_MESSAGES | ||
1899 | MHD_DLOG (con->daemon, | ||
1900 | _("Error during select (%d): `%s'\n"), | ||
1901 | err, | ||
1902 | MHD_socket_strerr_ (err)); | ||
1903 | #endif | ||
1904 | break; | ||
1905 | } | ||
1906 | } | ||
1907 | #ifdef HAVE_POLL | ||
1908 | else /* use_poll */ | ||
1909 | { | ||
1910 | p[0].events = POLLIN; | ||
1911 | p[0].fd = MHD_itc_r_fd_ (daemon->itc); | ||
1912 | p[0].revents = 0; | ||
1913 | if (0 > MHD_sys_poll_ (p, | ||
1914 | 1, | ||
1915 | -1)) | ||
1916 | { | ||
1917 | if (MHD_SCKT_LAST_ERR_IS_(MHD_SCKT_EINTR_)) | ||
1918 | continue; | ||
1919 | #ifdef HAVE_MESSAGES | ||
1920 | MHD_DLOG (con->daemon, | ||
1921 | _("Error during poll: `%s'\n"), | ||
1922 | MHD_socket_last_strerr_ ()); | ||
1923 | #endif | ||
1924 | break; | ||
1925 | } | ||
1926 | } | ||
1927 | #endif /* HAVE_POLL */ | ||
1928 | MHD_itc_clear_ (daemon->itc); | ||
1929 | continue; /* Check again for resume. */ | ||
1930 | } /* End of "suspended" branch. */ | ||
1931 | 1905 | ||
1932 | if (was_suspended) | 1906 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) |
1907 | continue; | ||
1908 | #ifdef HAVE_MESSAGES | ||
1909 | MHD_DLOG (con->daemon, | ||
1910 | _ ("Error during select (%d): `%s'\n"), | ||
1911 | err, | ||
1912 | MHD_socket_strerr_ (err)); | ||
1913 | #endif | ||
1914 | break; | ||
1915 | } | ||
1916 | } | ||
1917 | #ifdef HAVE_POLL | ||
1918 | else /* use_poll */ | ||
1919 | { | ||
1920 | p[0].events = POLLIN; | ||
1921 | p[0].fd = MHD_itc_r_fd_ (daemon->itc); | ||
1922 | p[0].revents = 0; | ||
1923 | if (0 > MHD_sys_poll_ (p, | ||
1924 | 1, | ||
1925 | -1)) | ||
1933 | { | 1926 | { |
1934 | MHD_update_last_activity_ (con); /* Reset timeout timer. */ | 1927 | if (MHD_SCKT_LAST_ERR_IS_ (MHD_SCKT_EINTR_)) |
1935 | /* Process response queued during suspend and update states. */ | 1928 | continue; |
1936 | MHD_connection_handle_idle (con); | 1929 | #ifdef HAVE_MESSAGES |
1937 | was_suspended = false; | 1930 | MHD_DLOG (con->daemon, |
1931 | _ ("Error during poll: `%s'\n"), | ||
1932 | MHD_socket_last_strerr_ ()); | ||
1933 | #endif | ||
1934 | break; | ||
1938 | } | 1935 | } |
1936 | } | ||
1937 | #endif /* HAVE_POLL */ | ||
1938 | MHD_itc_clear_ (daemon->itc); | ||
1939 | continue; /* Check again for resume. */ | ||
1940 | } /* End of "suspended" branch. */ | ||
1939 | 1941 | ||
1940 | tvp = NULL; | 1942 | if (was_suspended) |
1943 | { | ||
1944 | MHD_update_last_activity_ (con); /* Reset timeout timer. */ | ||
1945 | /* Process response queued during suspend and update states. */ | ||
1946 | MHD_connection_handle_idle (con); | ||
1947 | was_suspended = false; | ||
1948 | } | ||
1941 | 1949 | ||
1942 | if ( (MHD_EVENT_LOOP_INFO_BLOCK == con->event_loop_info) | 1950 | tvp = NULL; |
1951 | |||
1952 | if ( (MHD_EVENT_LOOP_INFO_BLOCK == con->event_loop_info) | ||
1943 | #ifdef HTTPS_SUPPORT | 1953 | #ifdef HTTPS_SUPPORT |
1944 | || ( (con->tls_read_ready) && | 1954 | || ( (con->tls_read_ready) && |
1945 | (MHD_EVENT_LOOP_INFO_READ == con->event_loop_info) ) | 1955 | (MHD_EVENT_LOOP_INFO_READ == con->event_loop_info) ) |
1946 | #endif /* HTTPS_SUPPORT */ | 1956 | #endif /* HTTPS_SUPPORT */ |
1947 | ) | 1957 | ) |
1948 | { | 1958 | { |
1949 | /* do not block: more data may be inside of TLS buffers waiting or | 1959 | /* do not block: more data may be inside of TLS buffers waiting or |
1950 | * application must provide response data */ | 1960 | * application must provide response data */ |
1951 | tv.tv_sec = 0; | 1961 | tv.tv_sec = 0; |
1952 | tv.tv_usec = 0; | 1962 | tv.tv_usec = 0; |
1953 | tvp = &tv; | 1963 | tvp = &tv; |
1954 | } | 1964 | } |
1955 | if ( (NULL == tvp) && | 1965 | if ( (NULL == tvp) && |
1956 | (timeout > 0) ) | 1966 | (timeout > 0) ) |
1957 | { | 1967 | { |
1958 | now = MHD_monotonic_sec_counter(); | 1968 | now = MHD_monotonic_sec_counter (); |
1959 | if (now - con->last_activity > timeout) | 1969 | if (now - con->last_activity > timeout) |
1960 | tv.tv_sec = 0; | 1970 | tv.tv_sec = 0; |
1961 | else | 1971 | else |
1962 | { | 1972 | { |
1963 | const time_t seconds_left = timeout - (now - con->last_activity); | 1973 | const time_t seconds_left = timeout - (now - con->last_activity); |
1964 | #if !defined(_WIN32) || defined(__CYGWIN__) | 1974 | #if ! defined(_WIN32) || defined(__CYGWIN__) |
1965 | tv.tv_sec = seconds_left; | 1975 | tv.tv_sec = seconds_left; |
1966 | #else /* _WIN32 && !__CYGWIN__ */ | 1976 | #else /* _WIN32 && !__CYGWIN__ */ |
1967 | if (seconds_left > TIMEVAL_TV_SEC_MAX) | 1977 | if (seconds_left > TIMEVAL_TV_SEC_MAX) |
1968 | tv.tv_sec = TIMEVAL_TV_SEC_MAX; | 1978 | tv.tv_sec = TIMEVAL_TV_SEC_MAX; |
1969 | else | 1979 | else |
1970 | tv.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) seconds_left; | 1980 | tv.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) seconds_left; |
1971 | #endif /* _WIN32 && ! __CYGWIN__ */ | 1981 | #endif /* _WIN32 && ! __CYGWIN__ */ |
1972 | } | 1982 | } |
1973 | tv.tv_usec = 0; | 1983 | tv.tv_usec = 0; |
1974 | tvp = &tv; | 1984 | tvp = &tv; |
1975 | } | 1985 | } |
1976 | if (! use_poll) | 1986 | if (! use_poll) |
1977 | { | 1987 | { |
1978 | /* use select */ | 1988 | /* use select */ |
1979 | bool err_state = false; | 1989 | bool err_state = false; |
1980 | 1990 | ||
1981 | FD_ZERO (&rs); | 1991 | FD_ZERO (&rs); |
1982 | FD_ZERO (&ws); | 1992 | FD_ZERO (&ws); |
1983 | FD_ZERO (&es); | 1993 | FD_ZERO (&es); |
1984 | maxsock = MHD_INVALID_SOCKET; | 1994 | maxsock = MHD_INVALID_SOCKET; |
1985 | switch (con->event_loop_info) | 1995 | switch (con->event_loop_info) |
1986 | { | 1996 | { |
1987 | case MHD_EVENT_LOOP_INFO_READ: | 1997 | case MHD_EVENT_LOOP_INFO_READ: |
1988 | if (! MHD_add_to_fd_set_ (con->socket_fd, | 1998 | if (! MHD_add_to_fd_set_ (con->socket_fd, |
1989 | &rs, | 1999 | &rs, |
1990 | &maxsock, | 2000 | &maxsock, |
1991 | FD_SETSIZE)) | 2001 | FD_SETSIZE)) |
1992 | err_state = true; | 2002 | err_state = true; |
1993 | break; | 2003 | break; |
1994 | case MHD_EVENT_LOOP_INFO_WRITE: | 2004 | case MHD_EVENT_LOOP_INFO_WRITE: |
1995 | if (! MHD_add_to_fd_set_ (con->socket_fd, | 2005 | if (! MHD_add_to_fd_set_ (con->socket_fd, |
1996 | &ws, | 2006 | &ws, |
1997 | &maxsock, | 2007 | &maxsock, |
1998 | FD_SETSIZE)) | 2008 | FD_SETSIZE)) |
1999 | err_state = true; | 2009 | err_state = true; |
2000 | break; | 2010 | break; |
2001 | case MHD_EVENT_LOOP_INFO_BLOCK: | 2011 | case MHD_EVENT_LOOP_INFO_BLOCK: |
2002 | if (! MHD_add_to_fd_set_ (con->socket_fd, | 2012 | if (! MHD_add_to_fd_set_ (con->socket_fd, |
2003 | &es, | 2013 | &es, |
2004 | &maxsock, | 2014 | &maxsock, |
2005 | FD_SETSIZE)) | 2015 | FD_SETSIZE)) |
2006 | err_state = true; | 2016 | err_state = true; |
2007 | break; | 2017 | break; |
2008 | case MHD_EVENT_LOOP_INFO_CLEANUP: | 2018 | case MHD_EVENT_LOOP_INFO_CLEANUP: |
2009 | /* how did we get here!? */ | 2019 | /* how did we get here!? */ |
2010 | goto exit; | 2020 | goto exit; |
2011 | } | 2021 | } |
2012 | #if WINDOWS | 2022 | #if WINDOWS |
2013 | if (MHD_ITC_IS_VALID_(daemon->itc) ) | 2023 | if (MHD_ITC_IS_VALID_ (daemon->itc) ) |
2014 | { | 2024 | { |
2015 | if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc), | 2025 | if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc), |
2016 | &rs, | 2026 | &rs, |
2017 | &maxsock, | 2027 | &maxsock, |
2018 | FD_SETSIZE)) | 2028 | FD_SETSIZE)) |
2019 | err_state = 1; | 2029 | err_state = 1; |
2020 | } | 2030 | } |
2021 | #endif | 2031 | #endif |
2022 | if (err_state) | 2032 | if (err_state) |
2023 | { | 2033 | { |
2024 | #ifdef HAVE_MESSAGES | 2034 | #ifdef HAVE_MESSAGES |
2025 | MHD_DLOG (con->daemon, | 2035 | MHD_DLOG (con->daemon, |
2026 | _("Failed to add FD to fd_set\n")); | 2036 | _ ("Failed to add FD to fd_set\n")); |
2027 | #endif | 2037 | #endif |
2028 | goto exit; | 2038 | goto exit; |
2029 | } | 2039 | } |
2030 | 2040 | ||
2031 | num_ready = MHD_SYS_select_ (maxsock + 1, | 2041 | num_ready = MHD_SYS_select_ (maxsock + 1, |
2032 | &rs, | 2042 | &rs, |
2033 | &ws, | 2043 | &ws, |
2034 | &es, | 2044 | &es, |
2035 | tvp); | 2045 | tvp); |
2036 | if (num_ready < 0) | 2046 | if (num_ready < 0) |
2037 | { | 2047 | { |
2038 | const int err = MHD_socket_get_error_(); | 2048 | const int err = MHD_socket_get_error_ (); |
2039 | 2049 | ||
2040 | if (MHD_SCKT_ERR_IS_EINTR_(err)) | 2050 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) |
2041 | continue; | 2051 | continue; |
2042 | #ifdef HAVE_MESSAGES | 2052 | #ifdef HAVE_MESSAGES |
2043 | MHD_DLOG (con->daemon, | 2053 | MHD_DLOG (con->daemon, |
2044 | _("Error during select (%d): `%s'\n"), | 2054 | _ ("Error during select (%d): `%s'\n"), |
2045 | err, | 2055 | err, |
2046 | MHD_socket_strerr_ (err)); | 2056 | MHD_socket_strerr_ (err)); |
2047 | #endif | 2057 | #endif |
2048 | break; | 2058 | break; |
2049 | } | 2059 | } |
2050 | #if WINDOWS | 2060 | #if WINDOWS |
2051 | /* Clear ITC before other processing so additional | 2061 | /* Clear ITC before other processing so additional |
2052 | * signals will trigger select() again */ | 2062 | * signals will trigger select() again */ |
2053 | if ( (MHD_ITC_IS_VALID_(daemon->itc)) && | 2063 | if ( (MHD_ITC_IS_VALID_ (daemon->itc)) && |
2054 | (FD_ISSET (MHD_itc_r_fd_ (daemon->itc), | 2064 | (FD_ISSET (MHD_itc_r_fd_ (daemon->itc), |
2055 | &rs)) ) | 2065 | &rs)) ) |
2056 | MHD_itc_clear_ (daemon->itc); | 2066 | MHD_itc_clear_ (daemon->itc); |
2057 | #endif | 2067 | #endif |
2058 | if (MHD_NO == | 2068 | if (MHD_NO == |
2059 | call_handlers (con, | 2069 | call_handlers (con, |
2060 | FD_ISSET (con->socket_fd, | 2070 | FD_ISSET (con->socket_fd, |
2061 | &rs), | 2071 | &rs), |
2062 | FD_ISSET (con->socket_fd, | 2072 | FD_ISSET (con->socket_fd, |
2063 | &ws), | 2073 | &ws), |
2064 | FD_ISSET (con->socket_fd, | 2074 | FD_ISSET (con->socket_fd, |
2065 | &es)) ) | 2075 | &es)) ) |
2066 | goto exit; | 2076 | goto exit; |
2067 | } | 2077 | } |
2068 | #ifdef HAVE_POLL | 2078 | #ifdef HAVE_POLL |
2069 | else | 2079 | else |
2070 | { | 2080 | { |
2071 | /* use poll */ | 2081 | /* use poll */ |
2072 | memset (&p, | 2082 | memset (&p, |
2073 | 0, | 2083 | 0, |
2074 | sizeof (p)); | 2084 | sizeof (p)); |
2075 | p[0].fd = con->socket_fd; | 2085 | p[0].fd = con->socket_fd; |
2076 | switch (con->event_loop_info) | 2086 | switch (con->event_loop_info) |
2077 | { | 2087 | { |
2078 | case MHD_EVENT_LOOP_INFO_READ: | 2088 | case MHD_EVENT_LOOP_INFO_READ: |
2079 | p[0].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC; | 2089 | p[0].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC; |
2080 | break; | 2090 | break; |
2081 | case MHD_EVENT_LOOP_INFO_WRITE: | 2091 | case MHD_EVENT_LOOP_INFO_WRITE: |
2082 | p[0].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC; | 2092 | p[0].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC; |
2083 | break; | 2093 | break; |
2084 | case MHD_EVENT_LOOP_INFO_BLOCK: | 2094 | case MHD_EVENT_LOOP_INFO_BLOCK: |
2085 | p[0].events |= MHD_POLL_EVENTS_ERR_DISC; | 2095 | p[0].events |= MHD_POLL_EVENTS_ERR_DISC; |
2086 | break; | 2096 | break; |
2087 | case MHD_EVENT_LOOP_INFO_CLEANUP: | 2097 | case MHD_EVENT_LOOP_INFO_CLEANUP: |
2088 | /* how did we get here!? */ | 2098 | /* how did we get here!? */ |
2089 | goto exit; | 2099 | goto exit; |
2090 | } | 2100 | } |
2091 | #if WINDOWS | 2101 | #if WINDOWS |
2092 | extra_slot = 0; | 2102 | extra_slot = 0; |
2093 | if (MHD_ITC_IS_VALID_(daemon->itc)) | 2103 | if (MHD_ITC_IS_VALID_ (daemon->itc)) |
2094 | { | 2104 | { |
2095 | p[1].events |= POLLIN; | 2105 | p[1].events |= POLLIN; |
2096 | p[1].fd = MHD_itc_r_fd_ (daemon->itc); | 2106 | p[1].fd = MHD_itc_r_fd_ (daemon->itc); |
2097 | p[1].revents = 0; | 2107 | p[1].revents = 0; |
2098 | extra_slot = 1; | 2108 | extra_slot = 1; |
2099 | } | 2109 | } |
2100 | #endif | 2110 | #endif |
2101 | if (MHD_sys_poll_ (p, | 2111 | if (MHD_sys_poll_ (p, |
2102 | #if WINDOWS | 2112 | #if WINDOWS |
2103 | 1 + extra_slot, | 2113 | 1 + extra_slot, |
2104 | #else | 2114 | #else |
2105 | 1, | 2115 | 1, |
2106 | #endif | 2116 | #endif |
2107 | (NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0) | 2117 | (NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0) |
2108 | { | 2118 | { |
2109 | if (MHD_SCKT_LAST_ERR_IS_(MHD_SCKT_EINTR_)) | 2119 | if (MHD_SCKT_LAST_ERR_IS_ (MHD_SCKT_EINTR_)) |
2110 | continue; | 2120 | continue; |
2111 | #ifdef HAVE_MESSAGES | 2121 | #ifdef HAVE_MESSAGES |
2112 | MHD_DLOG (con->daemon, | 2122 | MHD_DLOG (con->daemon, |
2113 | _("Error during poll: `%s'\n"), | 2123 | _ ("Error during poll: `%s'\n"), |
2114 | MHD_socket_last_strerr_ ()); | 2124 | MHD_socket_last_strerr_ ()); |
2115 | #endif | 2125 | #endif |
2116 | break; | 2126 | break; |
2117 | } | 2127 | } |
2118 | #if WINDOWS | 2128 | #if WINDOWS |
2119 | /* Clear ITC before other processing so additional | 2129 | /* Clear ITC before other processing so additional |
2120 | * signals will trigger poll() again */ | 2130 | * signals will trigger poll() again */ |
2121 | if ( (MHD_ITC_IS_VALID_(daemon->itc)) && | 2131 | if ( (MHD_ITC_IS_VALID_ (daemon->itc)) && |
2122 | (0 != (p[1].revents & (POLLERR | POLLHUP | POLLIN))) ) | 2132 | (0 != (p[1].revents & (POLLERR | POLLHUP | POLLIN))) ) |
2123 | MHD_itc_clear_ (daemon->itc); | 2133 | MHD_itc_clear_ (daemon->itc); |
2124 | #endif | 2134 | #endif |
2125 | if (MHD_NO == | 2135 | if (MHD_NO == |
2126 | call_handlers (con, | 2136 | call_handlers (con, |
2127 | 0 != (p[0].revents & POLLIN), | 2137 | (0 != (p[0].revents & POLLIN)), |
2128 | 0 != (p[0].revents & POLLOUT), | 2138 | (0 != (p[0].revents & POLLOUT)), |
2129 | 0 != (p[0].revents & (POLLERR | MHD_POLL_REVENTS_ERR_DISC)))) | 2139 | (0 != (p[0].revents & (POLLERR |
2130 | goto exit; | 2140 | | MHD_POLL_REVENTS_ERR_DISC))) )) |
2131 | } | 2141 | goto exit; |
2142 | } | ||
2132 | #endif | 2143 | #endif |
2133 | #ifdef UPGRADE_SUPPORT | 2144 | #ifdef UPGRADE_SUPPORT |
2134 | if (MHD_CONNECTION_UPGRADE == con->state) | 2145 | if (MHD_CONNECTION_UPGRADE == con->state) |
2135 | { | 2146 | { |
2136 | /* Normal HTTP processing is finished, | 2147 | /* Normal HTTP processing is finished, |
2137 | * notify application. */ | 2148 | * notify application. */ |
2138 | if ( (NULL != daemon->notify_completed) && | 2149 | if ( (NULL != daemon->notify_completed) && |
2139 | (con->client_aware) ) | 2150 | (con->client_aware) ) |
2140 | daemon->notify_completed (daemon->notify_completed_cls, | 2151 | daemon->notify_completed (daemon->notify_completed_cls, |
2141 | con, | 2152 | con, |
2142 | &con->client_context, | 2153 | &con->client_context, |
2143 | MHD_REQUEST_TERMINATED_COMPLETED_OK); | 2154 | MHD_REQUEST_TERMINATED_COMPLETED_OK); |
2144 | con->client_aware = false; | 2155 | con->client_aware = false; |
2145 | 2156 | ||
2146 | thread_main_connection_upgrade (con); | 2157 | thread_main_connection_upgrade (con); |
2147 | /* MHD_connection_finish_forward_() was called by thread_main_connection_upgrade(). */ | 2158 | /* MHD_connection_finish_forward_() was called by thread_main_connection_upgrade(). */ |
2148 | 2159 | ||
2149 | /* "Upgraded" data will not be used in this thread from this point. */ | 2160 | /* "Upgraded" data will not be used in this thread from this point. */ |
2150 | con->urh->clean_ready = true; | 2161 | con->urh->clean_ready = true; |
2151 | /* If 'urh->was_closed' set to true, connection will be | 2162 | /* If 'urh->was_closed' set to true, connection will be |
2152 | * moved immediately to cleanup list. Otherwise connection | 2163 | * moved immediately to cleanup list. Otherwise connection |
2153 | * will stay in suspended list until 'urh' will be marked | 2164 | * will stay in suspended list until 'urh' will be marked |
2154 | * with 'was_closed' by application. */ | 2165 | * with 'was_closed' by application. */ |
2155 | MHD_resume_connection(con); | 2166 | MHD_resume_connection (con); |
2156 | 2167 | ||
2157 | /* skip usual clean up */ | 2168 | /* skip usual clean up */ |
2158 | return (MHD_THRD_RTRN_TYPE_) 0; | 2169 | return (MHD_THRD_RTRN_TYPE_) 0; |
2159 | } | ||
2160 | #endif /* UPGRADE_SUPPORT */ | ||
2161 | } | 2170 | } |
2171 | #endif /* UPGRADE_SUPPORT */ | ||
2172 | } | ||
2162 | #if DEBUG_CLOSE | 2173 | #if DEBUG_CLOSE |
2163 | #ifdef HAVE_MESSAGES | 2174 | #ifdef HAVE_MESSAGES |
2164 | MHD_DLOG (con->daemon, | 2175 | MHD_DLOG (con->daemon, |
2165 | _("Processing thread terminating. Closing connection\n")); | 2176 | _ ("Processing thread terminating. Closing connection\n")); |
2166 | #endif | 2177 | #endif |
2167 | #endif | 2178 | #endif |
2168 | if (MHD_CONNECTION_CLOSED != con->state) | 2179 | if (MHD_CONNECTION_CLOSED != con->state) |
2169 | MHD_connection_close_ (con, | 2180 | MHD_connection_close_ (con, |
2170 | (daemon->shutdown) ? | 2181 | (daemon->shutdown) ? |
2171 | MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN: | 2182 | MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN : |
2172 | MHD_REQUEST_TERMINATED_WITH_ERROR); | 2183 | MHD_REQUEST_TERMINATED_WITH_ERROR); |
2173 | MHD_connection_handle_idle (con); | 2184 | MHD_connection_handle_idle (con); |
2174 | exit: | 2185 | exit: |
2175 | if (NULL != con->response) | 2186 | if (NULL != con->response) |
2176 | { | 2187 | { |
2177 | MHD_destroy_response (con->response); | 2188 | MHD_destroy_response (con->response); |
2178 | con->response = NULL; | 2189 | con->response = NULL; |
2179 | } | 2190 | } |
2180 | 2191 | ||
2181 | if (MHD_INVALID_SOCKET != con->socket_fd) | 2192 | if (MHD_INVALID_SOCKET != con->socket_fd) |
2182 | { | 2193 | { |
2183 | shutdown (con->socket_fd, | 2194 | shutdown (con->socket_fd, |
2184 | SHUT_WR); | 2195 | SHUT_WR); |
2185 | /* 'socket_fd' can be used in other thread to signal shutdown. | 2196 | /* 'socket_fd' can be used in other thread to signal shutdown. |
2186 | * To avoid data races, do not close socket here. Daemon will | 2197 | * To avoid data races, do not close socket here. Daemon will |
2187 | * use more connections only after cleanup anyway. */ | 2198 | * use more connections only after cleanup anyway. */ |
2188 | } | 2199 | } |
2189 | if ( (MHD_ITC_IS_VALID_(daemon->itc)) && | 2200 | if ( (MHD_ITC_IS_VALID_ (daemon->itc)) && |
2190 | (! MHD_itc_activate_ (daemon->itc, "t")) ) | 2201 | (! MHD_itc_activate_ (daemon->itc, "t")) ) |
2191 | { | 2202 | { |
2192 | #ifdef HAVE_MESSAGES | 2203 | #ifdef HAVE_MESSAGES |
2193 | MHD_DLOG (daemon, | 2204 | MHD_DLOG (daemon, |
2194 | _("Failed to signal thread termination via inter-thread communication channel.")); | 2205 | _ ( |
2206 | "Failed to signal thread termination via inter-thread communication channel.")); | ||
2195 | #endif | 2207 | #endif |
2196 | } | 2208 | } |
2197 | return (MHD_THRD_RTRN_TYPE_) 0; | 2209 | return (MHD_THRD_RTRN_TYPE_) 0; |
2198 | } | 2210 | } |
2199 | #endif | 2211 | #endif |
@@ -2210,8 +2222,8 @@ static void | |||
2210 | MHD_cleanup_connections (struct MHD_Daemon *daemon); | 2222 | MHD_cleanup_connections (struct MHD_Daemon *daemon); |
2211 | 2223 | ||
2212 | #if defined(HTTPS_SUPPORT) | 2224 | #if defined(HTTPS_SUPPORT) |
2213 | #if !defined(MHD_WINSOCK_SOCKETS) && !defined(MHD_socket_nosignal_) && \ | 2225 | #if ! defined(MHD_WINSOCK_SOCKETS) && ! defined(MHD_socket_nosignal_) && \ |
2214 | (GNUTLS_VERSION_NUMBER+0 < 0x030402) && defined(MSG_NOSIGNAL) | 2226 | (GNUTLS_VERSION_NUMBER + 0 < 0x030402) && defined(MSG_NOSIGNAL) |
2215 | /** | 2227 | /** |
2216 | * Older version of GnuTLS do not support suppressing of SIGPIPE signal. | 2228 | * Older version of GnuTLS do not support suppressing of SIGPIPE signal. |
2217 | * Use push function replacement with suppressing SIGPIPE signal where necessary | 2229 | * Use push function replacement with suppressing SIGPIPE signal where necessary |
@@ -2226,15 +2238,15 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon); | |||
2226 | * for TLS library. | 2238 | * for TLS library. |
2227 | */ | 2239 | */ |
2228 | static ssize_t | 2240 | static ssize_t |
2229 | MHD_tls_push_func_(gnutls_transport_ptr_t trnsp, | 2241 | MHD_tls_push_func_ (gnutls_transport_ptr_t trnsp, |
2230 | const void *data, | 2242 | const void *data, |
2231 | size_t data_size) | 2243 | size_t data_size) |
2232 | { | 2244 | { |
2233 | #if (MHD_SCKT_SEND_MAX_SIZE_ < SSIZE_MAX) || (0 == SSIZE_MAX) | 2245 | #if (MHD_SCKT_SEND_MAX_SIZE_ < SSIZE_MAX) || (0 == SSIZE_MAX) |
2234 | if (data_size > MHD_SCKT_SEND_MAX_SIZE_) | 2246 | if (data_size > MHD_SCKT_SEND_MAX_SIZE_) |
2235 | data_size = MHD_SCKT_SEND_MAX_SIZE_; | 2247 | data_size = MHD_SCKT_SEND_MAX_SIZE_; |
2236 | #endif /* (MHD_SCKT_SEND_MAX_SIZE_ < SSIZE_MAX) || (0 == SSIZE_MAX) */ | 2248 | #endif /* (MHD_SCKT_SEND_MAX_SIZE_ < SSIZE_MAX) || (0 == SSIZE_MAX) */ |
2237 | return MHD_send_ ((MHD_socket)(intptr_t)(trnsp), data, data_size); | 2249 | return MHD_send_ ((MHD_socket) (intptr_t) (trnsp), data, data_size); |
2238 | } | 2250 | } |
2239 | #endif /* MHD_TLSLIB_DONT_SUPPRESS_SIGPIPE */ | 2251 | #endif /* MHD_TLSLIB_DONT_SUPPRESS_SIGPIPE */ |
2240 | 2252 | ||
@@ -2249,8 +2261,8 @@ MHD_tls_push_func_(gnutls_transport_ptr_t trnsp, | |||
2249 | */ | 2261 | */ |
2250 | static int | 2262 | static int |
2251 | psk_gnutls_adapter (gnutls_session_t session, | 2263 | psk_gnutls_adapter (gnutls_session_t session, |
2252 | const char *username, | 2264 | const char *username, |
2253 | gnutls_datum_t *key) | 2265 | gnutls_datum_t *key) |
2254 | { | 2266 | { |
2255 | struct MHD_Connection *connection; | 2267 | struct MHD_Connection *connection; |
2256 | struct MHD_Daemon *daemon; | 2268 | struct MHD_Daemon *daemon; |
@@ -2262,7 +2274,7 @@ psk_gnutls_adapter (gnutls_session_t session, | |||
2262 | { | 2274 | { |
2263 | #ifdef HAVE_MESSAGES | 2275 | #ifdef HAVE_MESSAGES |
2264 | /* Cannot use our logger, we don't even have "daemon" */ | 2276 | /* Cannot use our logger, we don't even have "daemon" */ |
2265 | MHD_PANIC (_("Internal server error. This should be impossible.\n")); | 2277 | MHD_PANIC (_ ("Internal server error. This should be impossible.\n")); |
2266 | #endif | 2278 | #endif |
2267 | return -1; | 2279 | return -1; |
2268 | } | 2280 | } |
@@ -2272,46 +2284,47 @@ psk_gnutls_adapter (gnutls_session_t session, | |||
2272 | { | 2284 | { |
2273 | #ifdef HAVE_MESSAGES | 2285 | #ifdef HAVE_MESSAGES |
2274 | MHD_DLOG (daemon, | 2286 | MHD_DLOG (daemon, |
2275 | _("PSK not supported by this server.\n")); | 2287 | _ ("PSK not supported by this server.\n")); |
2276 | #endif | 2288 | #endif |
2277 | return -1; | 2289 | return -1; |
2278 | } | 2290 | } |
2279 | if (0 != daemon->cred_callback (daemon->cred_callback_cls, | 2291 | if (0 != daemon->cred_callback (daemon->cred_callback_cls, |
2280 | connection, | 2292 | connection, |
2281 | username, | 2293 | username, |
2282 | &app_psk, | 2294 | &app_psk, |
2283 | &app_psk_size)) | 2295 | &app_psk_size)) |
2284 | return -1; | 2296 | return -1; |
2285 | if (NULL == (key->data = gnutls_malloc (app_psk_size))) | 2297 | if (NULL == (key->data = gnutls_malloc (app_psk_size))) |
2286 | { | 2298 | { |
2287 | #ifdef HAVE_MESSAGES | 2299 | #ifdef HAVE_MESSAGES |
2288 | MHD_DLOG (daemon, | 2300 | MHD_DLOG (daemon, |
2289 | _("PSK authentication failed: gnutls_malloc failed to allocate memory\n")); | 2301 | _ ( |
2302 | "PSK authentication failed: gnutls_malloc failed to allocate memory\n")); | ||
2290 | #endif | 2303 | #endif |
2291 | free (app_psk); | 2304 | free (app_psk); |
2292 | return -1; | 2305 | return -1; |
2293 | } | 2306 | } |
2294 | if (UINT_MAX < app_psk_size) | 2307 | if (UINT_MAX < app_psk_size) |
2295 | { | 2308 | { |
2296 | #ifdef HAVE_MESSAGES | 2309 | #ifdef HAVE_MESSAGES |
2297 | MHD_DLOG (daemon, | 2310 | MHD_DLOG (daemon, |
2298 | _("PSK authentication failed: PSK too long\n")); | 2311 | _ ("PSK authentication failed: PSK too long\n")); |
2299 | #endif | 2312 | #endif |
2300 | free (app_psk); | 2313 | free (app_psk); |
2301 | return -1; | 2314 | return -1; |
2302 | } | 2315 | } |
2303 | key->size = (unsigned int)app_psk_size; | 2316 | key->size = (unsigned int) app_psk_size; |
2304 | memcpy (key->data, | 2317 | memcpy (key->data, |
2305 | app_psk, | 2318 | app_psk, |
2306 | app_psk_size); | 2319 | app_psk_size); |
2307 | free (app_psk); | 2320 | free (app_psk); |
2308 | return 0; | 2321 | return 0; |
2309 | #else | 2322 | #else |
2310 | #ifdef HAVE_MESSAGES | 2323 | #ifdef HAVE_MESSAGES |
2311 | MHD_DLOG (daemon, | 2324 | MHD_DLOG (daemon, |
2312 | _("PSK not supported by this server.\n")); | 2325 | _ ("PSK not supported by this server.\n")); |
2313 | #endif | 2326 | #endif |
2314 | return -1; | 2327 | return -1; |
2315 | #endif | 2328 | #endif |
2316 | } | 2329 | } |
2317 | #endif /* HTTPS_SUPPORT */ | 2330 | #endif /* HTTPS_SUPPORT */ |
@@ -2360,71 +2373,71 @@ internal_add_connection (struct MHD_Daemon *daemon, | |||
2360 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 2373 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
2361 | mhd_assert ((NULL == daemon->worker_pool) || (external_add)); | 2374 | mhd_assert ((NULL == daemon->worker_pool) || (external_add)); |
2362 | if ((external_add) && (NULL != daemon->worker_pool)) | 2375 | if ((external_add) && (NULL != daemon->worker_pool)) |
2363 | { | 2376 | { |
2364 | /* have a pool, try to find a pool with capacity; we use the | 2377 | /* have a pool, try to find a pool with capacity; we use the |
2365 | socket as the initial offset into the pool for load | 2378 | socket as the initial offset into the pool for load |
2366 | balancing */ | 2379 | balancing */ |
2367 | for (i = 0; i < daemon->worker_pool_size; ++i) | 2380 | for (i = 0; i < daemon->worker_pool_size; ++i) |
2368 | { | 2381 | { |
2369 | struct MHD_Daemon * const worker = | 2382 | struct MHD_Daemon *const worker = |
2370 | &daemon->worker_pool[(i + client_socket) % daemon->worker_pool_size]; | 2383 | &daemon->worker_pool[(i + client_socket) % daemon->worker_pool_size]; |
2371 | if (worker->connections < worker->connection_limit) | 2384 | if (worker->connections < worker->connection_limit) |
2372 | return internal_add_connection (worker, | 2385 | return internal_add_connection (worker, |
2373 | client_socket, | 2386 | client_socket, |
2374 | addr, | 2387 | addr, |
2375 | addrlen, | 2388 | addrlen, |
2376 | true, | 2389 | true, |
2377 | non_blck); | 2390 | non_blck); |
2378 | } | 2391 | } |
2379 | /* all pools are at their connection limit, must refuse */ | 2392 | /* all pools are at their connection limit, must refuse */ |
2380 | MHD_socket_close_chk_ (client_socket); | 2393 | MHD_socket_close_chk_ (client_socket); |
2381 | #if ENFILE | 2394 | #if ENFILE |
2382 | errno = ENFILE; | 2395 | errno = ENFILE; |
2383 | #endif | 2396 | #endif |
2384 | return MHD_NO; | 2397 | return MHD_NO; |
2385 | } | 2398 | } |
2386 | #endif | 2399 | #endif |
2387 | 2400 | ||
2388 | if ( (! MHD_SCKT_FD_FITS_FDSET_(client_socket, | 2401 | if ( (! MHD_SCKT_FD_FITS_FDSET_ (client_socket, |
2389 | NULL)) && | 2402 | NULL)) && |
2390 | (0 == (daemon->options & (MHD_USE_POLL | MHD_USE_EPOLL))) ) | 2403 | (0 == (daemon->options & (MHD_USE_POLL | MHD_USE_EPOLL))) ) |
2391 | { | 2404 | { |
2392 | #ifdef HAVE_MESSAGES | 2405 | #ifdef HAVE_MESSAGES |
2393 | MHD_DLOG (daemon, | 2406 | MHD_DLOG (daemon, |
2394 | _("Socket descriptor larger than FD_SETSIZE: %d > %d\n"), | 2407 | _ ("Socket descriptor larger than FD_SETSIZE: %d > %d\n"), |
2395 | (int) client_socket, | 2408 | (int) client_socket, |
2396 | (int) FD_SETSIZE); | 2409 | (int) FD_SETSIZE); |
2397 | #endif | 2410 | #endif |
2398 | MHD_socket_close_chk_ (client_socket); | 2411 | MHD_socket_close_chk_ (client_socket); |
2399 | #if EINVAL | 2412 | #if EINVAL |
2400 | errno = EINVAL; | 2413 | errno = EINVAL; |
2401 | #endif | 2414 | #endif |
2402 | return MHD_NO; | 2415 | return MHD_NO; |
2403 | } | 2416 | } |
2404 | 2417 | ||
2405 | #ifdef MHD_socket_nosignal_ | 2418 | #ifdef MHD_socket_nosignal_ |
2406 | if (! MHD_socket_nosignal_ (client_socket)) | 2419 | if (! MHD_socket_nosignal_ (client_socket)) |
2407 | { | 2420 | { |
2408 | #ifdef HAVE_MESSAGES | 2421 | #ifdef HAVE_MESSAGES |
2409 | MHD_DLOG (daemon, | 2422 | MHD_DLOG (daemon, |
2410 | _("Failed to set SO_NOSIGPIPE on accepted socket: %s\n"), | 2423 | _ ("Failed to set SO_NOSIGPIPE on accepted socket: %s\n"), |
2411 | MHD_socket_last_strerr_()); | 2424 | MHD_socket_last_strerr_ ()); |
2412 | #endif | 2425 | #endif |
2413 | #ifndef MSG_NOSIGNAL | 2426 | #ifndef MSG_NOSIGNAL |
2414 | /* Cannot use socket as it can produce SIGPIPE. */ | 2427 | /* Cannot use socket as it can produce SIGPIPE. */ |
2415 | #ifdef ENOTSOCK | 2428 | #ifdef ENOTSOCK |
2416 | errno = ENOTSOCK; | 2429 | errno = ENOTSOCK; |
2417 | #endif /* ENOTSOCK */ | 2430 | #endif /* ENOTSOCK */ |
2418 | return MHD_NO; | 2431 | return MHD_NO; |
2419 | #endif /* ! MSG_NOSIGNAL */ | 2432 | #endif /* ! MSG_NOSIGNAL */ |
2420 | } | 2433 | } |
2421 | #endif /* MHD_socket_nosignal_ */ | 2434 | #endif /* MHD_socket_nosignal_ */ |
2422 | 2435 | ||
2423 | 2436 | ||
2424 | #ifdef HAVE_MESSAGES | 2437 | #ifdef HAVE_MESSAGES |
2425 | #if DEBUG_CONNECT | 2438 | #if DEBUG_CONNECT |
2426 | MHD_DLOG (daemon, | 2439 | MHD_DLOG (daemon, |
2427 | _("Accepted connection on socket %d\n"), | 2440 | _ ("Accepted connection on socket %d\n"), |
2428 | client_socket); | 2441 | client_socket); |
2429 | #endif | 2442 | #endif |
2430 | #endif | 2443 | #endif |
@@ -2432,93 +2445,94 @@ internal_add_connection (struct MHD_Daemon *daemon, | |||
2432 | (MHD_NO == MHD_ip_limit_add (daemon, | 2445 | (MHD_NO == MHD_ip_limit_add (daemon, |
2433 | addr, | 2446 | addr, |
2434 | addrlen)) ) | 2447 | addrlen)) ) |
2435 | { | 2448 | { |
2436 | /* above connection limit - reject */ | 2449 | /* above connection limit - reject */ |
2437 | #ifdef HAVE_MESSAGES | 2450 | #ifdef HAVE_MESSAGES |
2438 | MHD_DLOG (daemon, | 2451 | MHD_DLOG (daemon, |
2439 | _("Server reached connection limit. Closing inbound connection.\n")); | 2452 | _ ( |
2453 | "Server reached connection limit. Closing inbound connection.\n")); | ||
2440 | #endif | 2454 | #endif |
2441 | MHD_socket_close_chk_ (client_socket); | 2455 | MHD_socket_close_chk_ (client_socket); |
2442 | #if ENFILE | 2456 | #if ENFILE |
2443 | errno = ENFILE; | 2457 | errno = ENFILE; |
2444 | #endif | 2458 | #endif |
2445 | return MHD_NO; | 2459 | return MHD_NO; |
2446 | } | 2460 | } |
2447 | 2461 | ||
2448 | /* apply connection acceptance policy if present */ | 2462 | /* apply connection acceptance policy if present */ |
2449 | if ( (NULL != daemon->apc) && | 2463 | if ( (NULL != daemon->apc) && |
2450 | (MHD_NO == daemon->apc (daemon->apc_cls, | 2464 | (MHD_NO == daemon->apc (daemon->apc_cls, |
2451 | addr, | 2465 | addr, |
2452 | addrlen)) ) | 2466 | addrlen)) ) |
2453 | { | 2467 | { |
2454 | #if DEBUG_CLOSE | 2468 | #if DEBUG_CLOSE |
2455 | #ifdef HAVE_MESSAGES | 2469 | #ifdef HAVE_MESSAGES |
2456 | MHD_DLOG (daemon, | 2470 | MHD_DLOG (daemon, |
2457 | _("Connection rejected by application. Closing connection.\n")); | 2471 | _ ("Connection rejected by application. Closing connection.\n")); |
2458 | #endif | 2472 | #endif |
2459 | #endif | 2473 | #endif |
2460 | MHD_socket_close_chk_ (client_socket); | 2474 | MHD_socket_close_chk_ (client_socket); |
2461 | MHD_ip_limit_del (daemon, | 2475 | MHD_ip_limit_del (daemon, |
2462 | addr, | 2476 | addr, |
2463 | addrlen); | 2477 | addrlen); |
2464 | #if EACCESS | 2478 | #if EACCESS |
2465 | errno = EACCESS; | 2479 | errno = EACCESS; |
2466 | #endif | 2480 | #endif |
2467 | return MHD_NO; | 2481 | return MHD_NO; |
2468 | } | 2482 | } |
2469 | 2483 | ||
2470 | if (NULL == (connection = MHD_calloc_ (1, sizeof (struct MHD_Connection)))) | 2484 | if (NULL == (connection = MHD_calloc_ (1, sizeof (struct MHD_Connection)))) |
2471 | { | 2485 | { |
2472 | eno = errno; | 2486 | eno = errno; |
2473 | #ifdef HAVE_MESSAGES | 2487 | #ifdef HAVE_MESSAGES |
2474 | MHD_DLOG (daemon, | 2488 | MHD_DLOG (daemon, |
2475 | "Error allocating memory: %s\n", | 2489 | "Error allocating memory: %s\n", |
2476 | MHD_strerror_ (errno)); | 2490 | MHD_strerror_ (errno)); |
2477 | #endif | 2491 | #endif |
2478 | MHD_socket_close_chk_ (client_socket); | 2492 | MHD_socket_close_chk_ (client_socket); |
2479 | MHD_ip_limit_del (daemon, | 2493 | MHD_ip_limit_del (daemon, |
2480 | addr, | 2494 | addr, |
2481 | addrlen); | 2495 | addrlen); |
2482 | errno = eno; | 2496 | errno = eno; |
2483 | return MHD_NO; | 2497 | return MHD_NO; |
2484 | } | 2498 | } |
2485 | connection->pool = MHD_pool_create (daemon->pool_size); | 2499 | connection->pool = MHD_pool_create (daemon->pool_size); |
2486 | if (NULL == connection->pool) | 2500 | if (NULL == connection->pool) |
2487 | { | 2501 | { |
2488 | #ifdef HAVE_MESSAGES | 2502 | #ifdef HAVE_MESSAGES |
2489 | MHD_DLOG (daemon, | 2503 | MHD_DLOG (daemon, |
2490 | _("Error allocating memory: %s\n"), | 2504 | _ ("Error allocating memory: %s\n"), |
2491 | MHD_strerror_ (errno)); | 2505 | MHD_strerror_ (errno)); |
2492 | #endif | 2506 | #endif |
2493 | MHD_socket_close_chk_ (client_socket); | 2507 | MHD_socket_close_chk_ (client_socket); |
2494 | MHD_ip_limit_del (daemon, | 2508 | MHD_ip_limit_del (daemon, |
2495 | addr, | 2509 | addr, |
2496 | addrlen); | 2510 | addrlen); |
2497 | free (connection); | 2511 | free (connection); |
2498 | #if ENOMEM | 2512 | #if ENOMEM |
2499 | errno = ENOMEM; | 2513 | errno = ENOMEM; |
2500 | #endif | 2514 | #endif |
2501 | return MHD_NO; | 2515 | return MHD_NO; |
2502 | } | 2516 | } |
2503 | 2517 | ||
2504 | connection->connection_timeout = daemon->connection_timeout; | 2518 | connection->connection_timeout = daemon->connection_timeout; |
2505 | if (NULL == (connection->addr = malloc (addrlen))) | 2519 | if (NULL == (connection->addr = malloc (addrlen))) |
2506 | { | 2520 | { |
2507 | eno = errno; | 2521 | eno = errno; |
2508 | #ifdef HAVE_MESSAGES | 2522 | #ifdef HAVE_MESSAGES |
2509 | MHD_DLOG (daemon, | 2523 | MHD_DLOG (daemon, |
2510 | _("Error allocating memory: %s\n"), | 2524 | _ ("Error allocating memory: %s\n"), |
2511 | MHD_strerror_ (errno)); | 2525 | MHD_strerror_ (errno)); |
2512 | #endif | 2526 | #endif |
2513 | MHD_socket_close_chk_ (client_socket); | 2527 | MHD_socket_close_chk_ (client_socket); |
2514 | MHD_ip_limit_del (daemon, | 2528 | MHD_ip_limit_del (daemon, |
2515 | addr, | 2529 | addr, |
2516 | addrlen); | 2530 | addrlen); |
2517 | MHD_pool_destroy (connection->pool); | 2531 | MHD_pool_destroy (connection->pool); |
2518 | free (connection); | 2532 | free (connection); |
2519 | errno = eno; | 2533 | errno = eno; |
2520 | return MHD_NO; | 2534 | return MHD_NO; |
2521 | } | 2535 | } |
2522 | memcpy (connection->addr, | 2536 | memcpy (connection->addr, |
2523 | addr, | 2537 | addr, |
2524 | addrlen); | 2538 | addrlen); |
@@ -2526,125 +2540,127 @@ internal_add_connection (struct MHD_Daemon *daemon, | |||
2526 | connection->socket_fd = client_socket; | 2540 | connection->socket_fd = client_socket; |
2527 | connection->sk_nonblck = non_blck; | 2541 | connection->sk_nonblck = non_blck; |
2528 | connection->daemon = daemon; | 2542 | connection->daemon = daemon; |
2529 | connection->last_activity = MHD_monotonic_sec_counter(); | 2543 | connection->last_activity = MHD_monotonic_sec_counter (); |
2530 | 2544 | ||
2531 | if (0 == (daemon->options & MHD_USE_TLS)) | 2545 | if (0 == (daemon->options & MHD_USE_TLS)) |
2532 | { | 2546 | { |
2533 | /* set default connection handlers */ | 2547 | /* set default connection handlers */ |
2534 | MHD_set_http_callbacks_ (connection); | 2548 | MHD_set_http_callbacks_ (connection); |
2535 | } | 2549 | } |
2536 | else | 2550 | else |
2537 | { | 2551 | { |
2538 | #ifdef HTTPS_SUPPORT | 2552 | #ifdef HTTPS_SUPPORT |
2539 | #if (GNUTLS_VERSION_NUMBER+0 >= 0x030500) | 2553 | #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030500) |
2540 | gnutls_init_flags_t | 2554 | gnutls_init_flags_t |
2541 | #else | 2555 | #else |
2542 | unsigned int | 2556 | unsigned int |
2543 | #endif | 2557 | #endif |
2544 | flags; | 2558 | flags; |
2545 | 2559 | ||
2546 | flags = GNUTLS_SERVER; | 2560 | flags = GNUTLS_SERVER; |
2547 | #if (GNUTLS_VERSION_NUMBER+0 >= 0x030402) | 2561 | #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030402) |
2548 | flags |= GNUTLS_NO_SIGNAL; | 2562 | flags |= GNUTLS_NO_SIGNAL; |
2549 | #endif /* GNUTLS_VERSION_NUMBER >= 0x030402 */ | 2563 | #endif /* GNUTLS_VERSION_NUMBER >= 0x030402 */ |
2550 | #if GNUTLS_VERSION_MAJOR >= 3 | 2564 | #if GNUTLS_VERSION_MAJOR >= 3 |
2551 | flags |= GNUTLS_NONBLOCK; | 2565 | flags |= GNUTLS_NONBLOCK; |
2552 | #endif /* GNUTLS_VERSION_MAJOR >= 3*/ | 2566 | #endif /* GNUTLS_VERSION_MAJOR >= 3*/ |
2553 | #if (GNUTLS_VERSION_NUMBER+0 >= 0x030603) | 2567 | #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030603) |
2554 | if (0 != (daemon->options & MHD_USE_POST_HANDSHAKE_AUTH_SUPPORT)) | 2568 | if (0 != (daemon->options & MHD_USE_POST_HANDSHAKE_AUTH_SUPPORT)) |
2555 | flags |= GNUTLS_POST_HANDSHAKE_AUTH; | 2569 | flags |= GNUTLS_POST_HANDSHAKE_AUTH; |
2556 | #endif | 2570 | #endif |
2557 | #if (GNUTLS_VERSION_NUMBER+0 >= 0x030605) | 2571 | #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030605) |
2558 | if (0 != (daemon->options & MHD_USE_INSECURE_TLS_EARLY_DATA)) | 2572 | if (0 != (daemon->options & MHD_USE_INSECURE_TLS_EARLY_DATA)) |
2559 | flags |= GNUTLS_ENABLE_EARLY_DATA; | 2573 | flags |= GNUTLS_ENABLE_EARLY_DATA; |
2560 | #endif | 2574 | #endif |
2561 | connection->tls_state = MHD_TLS_CONN_INIT; | 2575 | connection->tls_state = MHD_TLS_CONN_INIT; |
2562 | MHD_set_https_callbacks (connection); | 2576 | MHD_set_https_callbacks (connection); |
2563 | gnutls_init (&connection->tls_session, | 2577 | gnutls_init (&connection->tls_session, |
2564 | flags); | 2578 | flags); |
2565 | gnutls_priority_set (connection->tls_session, | 2579 | gnutls_priority_set (connection->tls_session, |
2566 | daemon->priority_cache); | 2580 | daemon->priority_cache); |
2567 | gnutls_session_set_ptr (connection->tls_session, | 2581 | gnutls_session_set_ptr (connection->tls_session, |
2568 | connection); | 2582 | connection); |
2569 | switch (daemon->cred_type) | 2583 | switch (daemon->cred_type) |
2570 | { | 2584 | { |
2571 | /* set needed credentials for certificate authentication. */ | 2585 | /* set needed credentials for certificate authentication. */ |
2572 | case GNUTLS_CRD_CERTIFICATE: | 2586 | case GNUTLS_CRD_CERTIFICATE: |
2573 | gnutls_credentials_set (connection->tls_session, | 2587 | gnutls_credentials_set (connection->tls_session, |
2574 | GNUTLS_CRD_CERTIFICATE, | 2588 | GNUTLS_CRD_CERTIFICATE, |
2575 | daemon->x509_cred); | 2589 | daemon->x509_cred); |
2576 | break; | 2590 | break; |
2577 | case GNUTLS_CRD_PSK: | 2591 | case GNUTLS_CRD_PSK: |
2578 | gnutls_credentials_set (connection->tls_session, | 2592 | gnutls_credentials_set (connection->tls_session, |
2579 | GNUTLS_CRD_PSK, | 2593 | GNUTLS_CRD_PSK, |
2580 | daemon->psk_cred); | 2594 | daemon->psk_cred); |
2581 | gnutls_psk_set_server_credentials_function (daemon->psk_cred, | 2595 | gnutls_psk_set_server_credentials_function (daemon->psk_cred, |
2582 | &psk_gnutls_adapter); | 2596 | &psk_gnutls_adapter); |
2583 | break; | 2597 | break; |
2584 | default: | 2598 | default: |
2585 | #ifdef HAVE_MESSAGES | 2599 | #ifdef HAVE_MESSAGES |
2586 | MHD_DLOG (connection->daemon, | 2600 | MHD_DLOG (connection->daemon, |
2587 | _("Failed to setup TLS credentials: unknown credential type %d\n"), | 2601 | _ ( |
2588 | daemon->cred_type); | 2602 | "Failed to setup TLS credentials: unknown credential type %d\n"), |
2589 | #endif | 2603 | daemon->cred_type); |
2590 | MHD_socket_close_chk_ (client_socket); | 2604 | #endif |
2591 | MHD_ip_limit_del (daemon, | 2605 | MHD_socket_close_chk_ (client_socket); |
2592 | addr, | 2606 | MHD_ip_limit_del (daemon, |
2593 | addrlen); | 2607 | addr, |
2594 | free (connection->addr); | 2608 | addrlen); |
2595 | free (connection); | 2609 | free (connection->addr); |
2596 | MHD_PANIC (_("Unknown credential type")); | 2610 | free (connection); |
2611 | MHD_PANIC (_ ("Unknown credential type")); | ||
2597 | #if EINVAL | 2612 | #if EINVAL |
2598 | errno = EINVAL; | 2613 | errno = EINVAL; |
2599 | #endif | 2614 | #endif |
2600 | return MHD_NO; | 2615 | return MHD_NO; |
2601 | } | 2616 | } |
2602 | #if (GNUTLS_VERSION_NUMBER+0 >= 0x030109) && !defined(_WIN64) | 2617 | #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030109) && ! defined(_WIN64) |
2603 | gnutls_transport_set_int (connection->tls_session, | 2618 | gnutls_transport_set_int (connection->tls_session, |
2604 | (int)(client_socket)); | 2619 | (int) (client_socket)); |
2605 | #else /* GnuTLS before 3.1.9 or Win x64 */ | 2620 | #else /* GnuTLS before 3.1.9 or Win x64 */ |
2606 | gnutls_transport_set_ptr (connection->tls_session, | 2621 | gnutls_transport_set_ptr (connection->tls_session, |
2607 | (gnutls_transport_ptr_t)(intptr_t)(client_socket)); | 2622 | (gnutls_transport_ptr_t) (intptr_t) (client_socket)); |
2608 | #endif /* GnuTLS before 3.1.9 */ | 2623 | #endif /* GnuTLS before 3.1.9 */ |
2609 | #ifdef MHD_TLSLIB_NEED_PUSH_FUNC | 2624 | #ifdef MHD_TLSLIB_NEED_PUSH_FUNC |
2610 | gnutls_transport_set_push_function (connection->tls_session, | 2625 | gnutls_transport_set_push_function (connection->tls_session, |
2611 | MHD_tls_push_func_); | 2626 | MHD_tls_push_func_); |
2612 | #endif /* MHD_TLSLIB_NEED_PUSH_FUNC */ | 2627 | #endif /* MHD_TLSLIB_NEED_PUSH_FUNC */ |
2613 | if (daemon->https_mem_trust) | 2628 | if (daemon->https_mem_trust) |
2614 | gnutls_certificate_server_set_request (connection->tls_session, | 2629 | gnutls_certificate_server_set_request (connection->tls_session, |
2615 | GNUTLS_CERT_REQUEST); | 2630 | GNUTLS_CERT_REQUEST); |
2616 | #else /* ! HTTPS_SUPPORT */ | 2631 | #else /* ! HTTPS_SUPPORT */ |
2617 | eno = EINVAL; | 2632 | eno = EINVAL; |
2618 | goto cleanup; | 2633 | goto cleanup; |
2619 | #endif /* ! HTTPS_SUPPORT */ | 2634 | #endif /* ! HTTPS_SUPPORT */ |
2620 | } | 2635 | } |
2621 | 2636 | ||
2622 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 2637 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
2623 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 2638 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
2624 | #endif | 2639 | #endif |
2625 | /* Firm check under lock. */ | 2640 | /* Firm check under lock. */ |
2626 | if (daemon->connections >= daemon->connection_limit) | 2641 | if (daemon->connections >= daemon->connection_limit) |
2627 | { | 2642 | { |
2628 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 2643 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
2629 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 2644 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
2630 | #endif | 2645 | #endif |
2631 | /* above connection limit - reject */ | 2646 | /* above connection limit - reject */ |
2632 | #ifdef HAVE_MESSAGES | 2647 | #ifdef HAVE_MESSAGES |
2633 | MHD_DLOG (daemon, | 2648 | MHD_DLOG (daemon, |
2634 | _("Server reached connection limit. Closing inbound connection.\n")); | 2649 | _ ( |
2650 | "Server reached connection limit. Closing inbound connection.\n")); | ||
2635 | #endif | 2651 | #endif |
2636 | #if ENFILE | 2652 | #if ENFILE |
2637 | eno = ENFILE; | 2653 | eno = ENFILE; |
2638 | #endif | 2654 | #endif |
2639 | goto cleanup; | 2655 | goto cleanup; |
2640 | } | 2656 | } |
2641 | daemon->connections++; | 2657 | daemon->connections++; |
2642 | if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) | 2658 | if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) |
2643 | { | 2659 | { |
2644 | XDLL_insert (daemon->normal_timeout_head, | 2660 | XDLL_insert (daemon->normal_timeout_head, |
2645 | daemon->normal_timeout_tail, | 2661 | daemon->normal_timeout_tail, |
2646 | connection); | 2662 | connection); |
2647 | } | 2663 | } |
2648 | DLL_insert (daemon->connections_head, | 2664 | DLL_insert (daemon->connections_head, |
2649 | daemon->connections_tail, | 2665 | daemon->connections_tail, |
2650 | connection); | 2666 | connection); |
@@ -2659,80 +2675,82 @@ internal_add_connection (struct MHD_Daemon *daemon, | |||
2659 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 2675 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
2660 | /* attempt to create handler thread */ | 2676 | /* attempt to create handler thread */ |
2661 | if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) | 2677 | if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) |
2678 | { | ||
2679 | if (! MHD_create_named_thread_ (&connection->pid, | ||
2680 | "MHD-connection", | ||
2681 | daemon->thread_stack_size, | ||
2682 | &thread_main_handle_connection, | ||
2683 | connection)) | ||
2662 | { | 2684 | { |
2663 | if (! MHD_create_named_thread_ (&connection->pid, | 2685 | eno = errno; |
2664 | "MHD-connection", | ||
2665 | daemon->thread_stack_size, | ||
2666 | &thread_main_handle_connection, | ||
2667 | connection)) | ||
2668 | { | ||
2669 | eno = errno; | ||
2670 | #ifdef HAVE_MESSAGES | 2686 | #ifdef HAVE_MESSAGES |
2671 | MHD_DLOG (daemon, | 2687 | MHD_DLOG (daemon, |
2672 | "Failed to create a thread: %s\n", | 2688 | "Failed to create a thread: %s\n", |
2673 | MHD_strerror_ (eno)); | 2689 | MHD_strerror_ (eno)); |
2674 | #endif | 2690 | #endif |
2675 | goto cleanup; | 2691 | goto cleanup; |
2676 | } | ||
2677 | } | 2692 | } |
2693 | } | ||
2678 | else | 2694 | else |
2679 | connection->pid = daemon->pid; | 2695 | connection->pid = daemon->pid; |
2680 | #endif | 2696 | #endif |
2681 | #ifdef EPOLL_SUPPORT | 2697 | #ifdef EPOLL_SUPPORT |
2682 | if (0 != (daemon->options & MHD_USE_EPOLL)) | 2698 | if (0 != (daemon->options & MHD_USE_EPOLL)) |
2683 | { | 2699 | { |
2684 | if ((0 == (daemon->options & MHD_USE_TURBO)) || (external_add)) | 2700 | if ((0 == (daemon->options & MHD_USE_TURBO)) || (external_add)) |
2685 | { /* Do not manipulate EReady DL-list in 'external_add' mode. */ | 2701 | { /* Do not manipulate EReady DL-list in 'external_add' mode. */ |
2686 | struct epoll_event event; | 2702 | struct epoll_event event; |
2687 | 2703 | ||
2688 | event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET; | 2704 | event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET; |
2689 | event.data.ptr = connection; | 2705 | event.data.ptr = connection; |
2690 | if (0 != epoll_ctl (daemon->epoll_fd, | 2706 | if (0 != epoll_ctl (daemon->epoll_fd, |
2691 | EPOLL_CTL_ADD, | 2707 | EPOLL_CTL_ADD, |
2692 | client_socket, | 2708 | client_socket, |
2693 | &event)) | 2709 | &event)) |
2694 | { | 2710 | { |
2695 | eno = errno; | 2711 | eno = errno; |
2696 | #ifdef HAVE_MESSAGES | 2712 | #ifdef HAVE_MESSAGES |
2697 | MHD_DLOG (daemon, | 2713 | MHD_DLOG (daemon, |
2698 | _("Call to epoll_ctl failed: %s\n"), | 2714 | _ ("Call to epoll_ctl failed: %s\n"), |
2699 | MHD_socket_last_strerr_ ()); | 2715 | MHD_socket_last_strerr_ ()); |
2700 | #endif | 2716 | #endif |
2701 | goto cleanup; | 2717 | goto cleanup; |
2702 | } | 2718 | } |
2703 | connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET; | 2719 | connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET; |
2704 | } | 2720 | } |
2705 | else | 2721 | else |
2706 | { | 2722 | { |
2707 | connection->epoll_state |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY | 2723 | connection->epoll_state |= MHD_EPOLL_STATE_READ_READY |
2708 | | MHD_EPOLL_STATE_IN_EREADY_EDLL; | 2724 | | MHD_EPOLL_STATE_WRITE_READY |
2709 | EDLL_insert (daemon->eready_head, | 2725 | | MHD_EPOLL_STATE_IN_EREADY_EDLL; |
2726 | EDLL_insert (daemon->eready_head, | ||
2710 | daemon->eready_tail, | 2727 | daemon->eready_tail, |
2711 | connection); | 2728 | connection); |
2712 | } | ||
2713 | } | 2729 | } |
2730 | } | ||
2714 | else /* This 'else' is combined with next 'if'. */ | 2731 | else /* This 'else' is combined with next 'if'. */ |
2715 | #endif | 2732 | #endif |
2716 | if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && | 2733 | if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && |
2717 | (external_add) && | 2734 | (external_add) && |
2718 | (MHD_ITC_IS_VALID_(daemon->itc)) && | 2735 | (MHD_ITC_IS_VALID_ (daemon->itc)) && |
2719 | (! MHD_itc_activate_ (daemon->itc, "n")) ) | 2736 | (! MHD_itc_activate_ (daemon->itc, "n")) ) |
2720 | { | 2737 | { |
2721 | #ifdef HAVE_MESSAGES | 2738 | #ifdef HAVE_MESSAGES |
2722 | MHD_DLOG (daemon, | 2739 | MHD_DLOG (daemon, |
2723 | _("Failed to signal new connection via inter-thread communication channel.")); | 2740 | _ ( |
2741 | "Failed to signal new connection via inter-thread communication channel.")); | ||
2724 | #endif | 2742 | #endif |
2725 | } | 2743 | } |
2726 | return MHD_YES; | 2744 | return MHD_YES; |
2727 | cleanup: | 2745 | cleanup: |
2728 | if (NULL != daemon->notify_connection) | 2746 | if (NULL != daemon->notify_connection) |
2729 | daemon->notify_connection (daemon->notify_connection_cls, | 2747 | daemon->notify_connection (daemon->notify_connection_cls, |
2730 | connection, | 2748 | connection, |
2731 | &connection->socket_context, | 2749 | &connection->socket_context, |
2732 | MHD_CONNECTION_NOTIFY_CLOSED); | 2750 | MHD_CONNECTION_NOTIFY_CLOSED); |
2733 | #ifdef HTTPS_SUPPORT | 2751 | #ifdef HTTPS_SUPPORT |
2734 | if (NULL != connection->tls_session) | 2752 | if (NULL != connection->tls_session) |
2735 | gnutls_deinit (connection->tls_session); | 2753 | gnutls_deinit (connection->tls_session); |
2736 | #endif /* HTTPS_SUPPORT */ | 2754 | #endif /* HTTPS_SUPPORT */ |
2737 | MHD_socket_close_chk_ (client_socket); | 2755 | MHD_socket_close_chk_ (client_socket); |
2738 | MHD_ip_limit_del (daemon, | 2756 | MHD_ip_limit_del (daemon, |
@@ -2742,14 +2760,14 @@ internal_add_connection (struct MHD_Daemon *daemon, | |||
2742 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 2760 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
2743 | #endif | 2761 | #endif |
2744 | if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) | 2762 | if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) |
2745 | { | 2763 | { |
2746 | XDLL_remove (daemon->normal_timeout_head, | 2764 | XDLL_remove (daemon->normal_timeout_head, |
2747 | daemon->normal_timeout_tail, | 2765 | daemon->normal_timeout_tail, |
2748 | connection); | 2766 | connection); |
2749 | } | 2767 | } |
2750 | DLL_remove (daemon->connections_head, | 2768 | DLL_remove (daemon->connections_head, |
2751 | daemon->connections_tail, | 2769 | daemon->connections_tail, |
2752 | connection); | 2770 | connection); |
2753 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 2771 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
2754 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 2772 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
2755 | #endif | 2773 | #endif |
@@ -2782,25 +2800,25 @@ internal_suspend_connection_ (struct MHD_Connection *connection) | |||
2782 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 2800 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
2783 | #endif | 2801 | #endif |
2784 | if (connection->resuming) | 2802 | if (connection->resuming) |
2785 | { | 2803 | { |
2786 | /* suspending again while we didn't even complete resuming yet */ | 2804 | /* suspending again while we didn't even complete resuming yet */ |
2787 | connection->resuming = false; | 2805 | connection->resuming = false; |
2788 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 2806 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
2789 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 2807 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
2790 | #endif | 2808 | #endif |
2791 | return; | 2809 | return; |
2792 | } | 2810 | } |
2793 | if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) | 2811 | if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) |
2794 | { | 2812 | { |
2795 | if (connection->connection_timeout == daemon->connection_timeout) | 2813 | if (connection->connection_timeout == daemon->connection_timeout) |
2796 | XDLL_remove (daemon->normal_timeout_head, | 2814 | XDLL_remove (daemon->normal_timeout_head, |
2797 | daemon->normal_timeout_tail, | 2815 | daemon->normal_timeout_tail, |
2798 | connection); | 2816 | connection); |
2799 | else | 2817 | else |
2800 | XDLL_remove (daemon->manual_timeout_head, | 2818 | XDLL_remove (daemon->manual_timeout_head, |
2801 | daemon->manual_timeout_tail, | 2819 | daemon->manual_timeout_tail, |
2802 | connection); | 2820 | connection); |
2803 | } | 2821 | } |
2804 | DLL_remove (daemon->connections_head, | 2822 | DLL_remove (daemon->connections_head, |
2805 | daemon->connections_tail, | 2823 | daemon->connections_tail, |
2806 | connection); | 2824 | connection); |
@@ -2811,25 +2829,25 @@ internal_suspend_connection_ (struct MHD_Connection *connection) | |||
2811 | connection->suspended = true; | 2829 | connection->suspended = true; |
2812 | #ifdef EPOLL_SUPPORT | 2830 | #ifdef EPOLL_SUPPORT |
2813 | if (0 != (daemon->options & MHD_USE_EPOLL)) | 2831 | if (0 != (daemon->options & MHD_USE_EPOLL)) |
2832 | { | ||
2833 | if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) | ||
2814 | { | 2834 | { |
2815 | if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) | 2835 | EDLL_remove (daemon->eready_head, |
2816 | { | 2836 | daemon->eready_tail, |
2817 | EDLL_remove (daemon->eready_head, | 2837 | connection); |
2818 | daemon->eready_tail, | 2838 | connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL; |
2819 | connection); | 2839 | } |
2820 | connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL; | 2840 | if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) |
2821 | } | 2841 | { |
2822 | if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) | 2842 | if (0 != epoll_ctl (daemon->epoll_fd, |
2823 | { | 2843 | EPOLL_CTL_DEL, |
2824 | if (0 != epoll_ctl (daemon->epoll_fd, | 2844 | connection->socket_fd, |
2825 | EPOLL_CTL_DEL, | 2845 | NULL)) |
2826 | connection->socket_fd, | 2846 | MHD_PANIC (_ ("Failed to remove FD from epoll set\n")); |
2827 | NULL)) | 2847 | connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET; |
2828 | MHD_PANIC (_("Failed to remove FD from epoll set\n")); | ||
2829 | connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET; | ||
2830 | } | ||
2831 | connection->epoll_state |= MHD_EPOLL_STATE_SUSPENDED; | ||
2832 | } | 2848 | } |
2849 | connection->epoll_state |= MHD_EPOLL_STATE_SUSPENDED; | ||
2850 | } | ||
2833 | #endif | 2851 | #endif |
2834 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 2852 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
2835 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 2853 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
@@ -2871,19 +2889,21 @@ internal_suspend_connection_ (struct MHD_Connection *connection) | |||
2871 | void | 2889 | void |
2872 | MHD_suspend_connection (struct MHD_Connection *connection) | 2890 | MHD_suspend_connection (struct MHD_Connection *connection) |
2873 | { | 2891 | { |
2874 | struct MHD_Daemon * const daemon = connection->daemon; | 2892 | struct MHD_Daemon *const daemon = connection->daemon; |
2875 | 2893 | ||
2876 | if (0 == (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) | 2894 | if (0 == (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) |
2877 | MHD_PANIC (_("Cannot suspend connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n")); | 2895 | MHD_PANIC (_ ( |
2896 | "Cannot suspend connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n")); | ||
2878 | #ifdef UPGRADE_SUPPORT | 2897 | #ifdef UPGRADE_SUPPORT |
2879 | if (NULL != connection->urh) | 2898 | if (NULL != connection->urh) |
2880 | { | 2899 | { |
2881 | #ifdef HAVE_MESSAGES | 2900 | #ifdef HAVE_MESSAGES |
2882 | MHD_DLOG (daemon, | 2901 | MHD_DLOG (daemon, |
2883 | _("Error: connection scheduled for \"upgrade\" cannot be suspended")); | 2902 | _ ( |
2903 | "Error: connection scheduled for \"upgrade\" cannot be suspended")); | ||
2884 | #endif /* HAVE_MESSAGES */ | 2904 | #endif /* HAVE_MESSAGES */ |
2885 | return; | 2905 | return; |
2886 | } | 2906 | } |
2887 | #endif /* UPGRADE_SUPPORT */ | 2907 | #endif /* UPGRADE_SUPPORT */ |
2888 | internal_suspend_connection_ (connection); | 2908 | internal_suspend_connection_ (connection); |
2889 | } | 2909 | } |
@@ -2903,7 +2923,8 @@ MHD_resume_connection (struct MHD_Connection *connection) | |||
2903 | struct MHD_Daemon *daemon = connection->daemon; | 2923 | struct MHD_Daemon *daemon = connection->daemon; |
2904 | 2924 | ||
2905 | if (0 == (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) | 2925 | if (0 == (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) |
2906 | MHD_PANIC (_("Cannot resume connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n")); | 2926 | MHD_PANIC (_ ( |
2927 | "Cannot resume connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n")); | ||
2907 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 2928 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
2908 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 2929 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
2909 | #endif | 2930 | #endif |
@@ -2912,14 +2933,15 @@ MHD_resume_connection (struct MHD_Connection *connection) | |||
2912 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 2933 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
2913 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 2934 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
2914 | #endif | 2935 | #endif |
2915 | if ( (MHD_ITC_IS_VALID_(daemon->itc)) && | 2936 | if ( (MHD_ITC_IS_VALID_ (daemon->itc)) && |
2916 | (! MHD_itc_activate_ (daemon->itc, "r")) ) | 2937 | (! MHD_itc_activate_ (daemon->itc, "r")) ) |
2917 | { | 2938 | { |
2918 | #ifdef HAVE_MESSAGES | 2939 | #ifdef HAVE_MESSAGES |
2919 | MHD_DLOG (daemon, | 2940 | MHD_DLOG (daemon, |
2920 | _("Failed to signal resume via inter-thread communication channel.")); | 2941 | _ ( |
2942 | "Failed to signal resume via inter-thread communication channel.")); | ||
2921 | #endif | 2943 | #endif |
2922 | } | 2944 | } |
2923 | } | 2945 | } |
2924 | 2946 | ||
2925 | 2947 | ||
@@ -2938,7 +2960,8 @@ resume_suspended_connections (struct MHD_Daemon *daemon) | |||
2938 | struct MHD_Connection *pos; | 2960 | struct MHD_Connection *pos; |
2939 | struct MHD_Connection *prev = NULL; | 2961 | struct MHD_Connection *prev = NULL; |
2940 | int ret; | 2962 | int ret; |
2941 | const bool used_thr_p_c = (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)); | 2963 | const bool used_thr_p_c = (0 != (daemon->options |
2964 | & MHD_USE_THREAD_PER_CONNECTION)); | ||
2942 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 2965 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
2943 | mhd_assert (NULL == daemon->worker_pool); | 2966 | mhd_assert (NULL == daemon->worker_pool); |
2944 | #endif | 2967 | #endif |
@@ -2947,112 +2970,114 @@ resume_suspended_connections (struct MHD_Daemon *daemon) | |||
2947 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 2970 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
2948 | #endif | 2971 | #endif |
2949 | if (daemon->resuming) | 2972 | if (daemon->resuming) |
2950 | { | 2973 | { |
2951 | prev = daemon->suspended_connections_tail; | 2974 | prev = daemon->suspended_connections_tail; |
2952 | /* During shutdown check for resuming is forced. */ | 2975 | /* During shutdown check for resuming is forced. */ |
2953 | mhd_assert((NULL != prev) || (daemon->shutdown)); | 2976 | mhd_assert ((NULL != prev) || (daemon->shutdown)); |
2954 | } | 2977 | } |
2955 | 2978 | ||
2956 | daemon->resuming = false; | 2979 | daemon->resuming = false; |
2957 | 2980 | ||
2958 | while (NULL != (pos = prev)) | 2981 | while (NULL != (pos = prev)) |
2959 | { | 2982 | { |
2960 | #ifdef UPGRADE_SUPPORT | 2983 | #ifdef UPGRADE_SUPPORT |
2961 | struct MHD_UpgradeResponseHandle * const urh = pos->urh; | 2984 | struct MHD_UpgradeResponseHandle *const urh = pos->urh; |
2962 | #else /* ! UPGRADE_SUPPORT */ | 2985 | #else /* ! UPGRADE_SUPPORT */ |
2963 | static const void * const urh = NULL; | 2986 | static const void *const urh = NULL; |
2964 | #endif /* ! UPGRADE_SUPPORT */ | 2987 | #endif /* ! UPGRADE_SUPPORT */ |
2965 | prev = pos->prev; | 2988 | prev = pos->prev; |
2966 | if ( (! pos->resuming) | 2989 | if ( (! pos->resuming) |
2967 | #ifdef UPGRADE_SUPPORT | 2990 | #ifdef UPGRADE_SUPPORT |
2968 | || ( (NULL != urh) && | 2991 | || ( (NULL != urh) && |
2969 | ( (! urh->was_closed) || | 2992 | ( (! urh->was_closed) || |
2970 | (! urh->clean_ready) ) ) | 2993 | (! urh->clean_ready) ) ) |
2971 | #endif /* UPGRADE_SUPPORT */ | 2994 | #endif /* UPGRADE_SUPPORT */ |
2972 | ) | 2995 | ) |
2973 | continue; | 2996 | continue; |
2974 | ret = MHD_YES; | 2997 | ret = MHD_YES; |
2975 | mhd_assert (pos->suspended); | 2998 | mhd_assert (pos->suspended); |
2976 | DLL_remove (daemon->suspended_connections_head, | 2999 | DLL_remove (daemon->suspended_connections_head, |
2977 | daemon->suspended_connections_tail, | 3000 | daemon->suspended_connections_tail, |
3001 | pos); | ||
3002 | pos->suspended = false; | ||
3003 | if (NULL == urh) | ||
3004 | { | ||
3005 | DLL_insert (daemon->connections_head, | ||
3006 | daemon->connections_tail, | ||
2978 | pos); | 3007 | pos); |
2979 | pos->suspended = false; | 3008 | if (! used_thr_p_c) |
2980 | if (NULL == urh) | 3009 | { |
2981 | { | 3010 | /* Reset timeout timer on resume. */ |
2982 | DLL_insert (daemon->connections_head, | 3011 | if (0 != pos->connection_timeout) |
2983 | daemon->connections_tail, | 3012 | pos->last_activity = MHD_monotonic_sec_counter (); |
2984 | pos); | 3013 | |
2985 | if (! used_thr_p_c) | 3014 | if (pos->connection_timeout == daemon->connection_timeout) |
2986 | { | 3015 | XDLL_insert (daemon->normal_timeout_head, |
2987 | /* Reset timeout timer on resume. */ | 3016 | daemon->normal_timeout_tail, |
2988 | if (0 != pos->connection_timeout) | 3017 | pos); |
2989 | pos->last_activity = MHD_monotonic_sec_counter(); | 3018 | else |
2990 | 3019 | XDLL_insert (daemon->manual_timeout_head, | |
2991 | if (pos->connection_timeout == daemon->connection_timeout) | 3020 | daemon->manual_timeout_tail, |
2992 | XDLL_insert (daemon->normal_timeout_head, | 3021 | pos); |
2993 | daemon->normal_timeout_tail, | 3022 | } |
2994 | pos); | ||
2995 | else | ||
2996 | XDLL_insert (daemon->manual_timeout_head, | ||
2997 | daemon->manual_timeout_tail, | ||
2998 | pos); | ||
2999 | } | ||
3000 | #ifdef EPOLL_SUPPORT | 3023 | #ifdef EPOLL_SUPPORT |
3001 | if (0 != (daemon->options & MHD_USE_EPOLL)) | 3024 | if (0 != (daemon->options & MHD_USE_EPOLL)) |
3002 | { | 3025 | { |
3003 | if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) | 3026 | if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) |
3004 | MHD_PANIC ("Resumed connection was already in EREADY set\n"); | 3027 | MHD_PANIC ("Resumed connection was already in EREADY set\n"); |
3005 | /* we always mark resumed connections as ready, as we | 3028 | /* we always mark resumed connections as ready, as we |
3006 | might have missed the edge poll event during suspension */ | 3029 | might have missed the edge poll event during suspension */ |
3007 | EDLL_insert (daemon->eready_head, | 3030 | EDLL_insert (daemon->eready_head, |
3008 | daemon->eready_tail, | 3031 | daemon->eready_tail, |
3009 | pos); | 3032 | pos); |
3010 | pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL | \ | 3033 | pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL \ |
3011 | MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY; | 3034 | | MHD_EPOLL_STATE_READ_READY |
3012 | pos->epoll_state &= ~MHD_EPOLL_STATE_SUSPENDED; | 3035 | | MHD_EPOLL_STATE_WRITE_READY; |
3013 | } | 3036 | pos->epoll_state &= ~MHD_EPOLL_STATE_SUSPENDED; |
3037 | } | ||
3014 | #endif | 3038 | #endif |
3015 | } | 3039 | } |
3016 | #ifdef UPGRADE_SUPPORT | 3040 | #ifdef UPGRADE_SUPPORT |
3017 | else | 3041 | else |
3018 | { | 3042 | { |
3019 | /* Data forwarding was finished (for TLS connections) AND | 3043 | /* Data forwarding was finished (for TLS connections) AND |
3020 | * application was closed upgraded connection. | 3044 | * application was closed upgraded connection. |
3021 | * Insert connection into cleanup list. */ | 3045 | * Insert connection into cleanup list. */ |
3022 | 3046 | ||
3023 | if ( (NULL != daemon->notify_completed) && | 3047 | if ( (NULL != daemon->notify_completed) && |
3024 | (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && | 3048 | (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && |
3025 | (pos->client_aware) ) | 3049 | (pos->client_aware) ) |
3026 | { | 3050 | { |
3027 | daemon->notify_completed (daemon->notify_completed_cls, | 3051 | daemon->notify_completed (daemon->notify_completed_cls, |
3028 | pos, | 3052 | pos, |
3029 | &pos->client_context, | 3053 | &pos->client_context, |
3030 | MHD_REQUEST_TERMINATED_COMPLETED_OK); | 3054 | MHD_REQUEST_TERMINATED_COMPLETED_OK); |
3031 | pos->client_aware = false; | 3055 | pos->client_aware = false; |
3032 | } | 3056 | } |
3033 | DLL_insert (daemon->cleanup_head, | 3057 | DLL_insert (daemon->cleanup_head, |
3034 | daemon->cleanup_tail, | 3058 | daemon->cleanup_tail, |
3035 | pos); | 3059 | pos); |
3036 | 3060 | ||
3037 | } | ||
3038 | #endif /* UPGRADE_SUPPORT */ | ||
3039 | pos->resuming = false; | ||
3040 | } | 3061 | } |
3062 | #endif /* UPGRADE_SUPPORT */ | ||
3063 | pos->resuming = false; | ||
3064 | } | ||
3041 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 3065 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
3042 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 3066 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
3043 | #endif | 3067 | #endif |
3044 | if ( (used_thr_p_c) && | 3068 | if ( (used_thr_p_c) && |
3045 | (MHD_NO != ret) ) | 3069 | (MHD_NO != ret) ) |
3046 | { /* Wake up suspended connections. */ | 3070 | { /* Wake up suspended connections. */ |
3047 | if (! MHD_itc_activate_(daemon->itc, | 3071 | if (! MHD_itc_activate_ (daemon->itc, |
3048 | "w")) | 3072 | "w")) |
3049 | { | 3073 | { |
3050 | #ifdef HAVE_MESSAGES | 3074 | #ifdef HAVE_MESSAGES |
3051 | MHD_DLOG (daemon, | 3075 | MHD_DLOG (daemon, |
3052 | _("Failed to signal resume of connection via inter-thread communication channel.")); | 3076 | _ ( |
3077 | "Failed to signal resume of connection via inter-thread communication channel.")); | ||
3053 | #endif | 3078 | #endif |
3054 | } | ||
3055 | } | 3079 | } |
3080 | } | ||
3056 | return ret; | 3081 | return ret; |
3057 | } | 3082 | } |
3058 | 3083 | ||
@@ -3093,34 +3118,34 @@ MHD_add_connection (struct MHD_Daemon *daemon, | |||
3093 | bool sk_nonbl; | 3118 | bool sk_nonbl; |
3094 | 3119 | ||
3095 | if (! MHD_socket_nonblocking_ (client_socket)) | 3120 | if (! MHD_socket_nonblocking_ (client_socket)) |
3096 | { | 3121 | { |
3097 | #ifdef HAVE_MESSAGES | 3122 | #ifdef HAVE_MESSAGES |
3098 | MHD_DLOG (daemon, | 3123 | MHD_DLOG (daemon, |
3099 | _("Failed to set nonblocking mode on new client socket: %s\n"), | 3124 | _ ("Failed to set nonblocking mode on new client socket: %s\n"), |
3100 | MHD_socket_last_strerr_()); | 3125 | MHD_socket_last_strerr_ ()); |
3101 | #endif | 3126 | #endif |
3102 | sk_nonbl = 0; | 3127 | sk_nonbl = 0; |
3103 | } | 3128 | } |
3104 | else | 3129 | else |
3105 | sk_nonbl = !0; | 3130 | sk_nonbl = ! 0; |
3106 | 3131 | ||
3107 | if ( (0 != (daemon->options & MHD_USE_TURBO)) && | 3132 | if ( (0 != (daemon->options & MHD_USE_TURBO)) && |
3108 | (! MHD_socket_noninheritable_ (client_socket)) ) | 3133 | (! MHD_socket_noninheritable_ (client_socket)) ) |
3109 | { | 3134 | { |
3110 | #ifdef HAVE_MESSAGES | 3135 | #ifdef HAVE_MESSAGES |
3111 | MHD_DLOG (daemon, | 3136 | MHD_DLOG (daemon, |
3112 | _("Failed to set noninheritable mode on new client socket.\n")); | 3137 | _ ("Failed to set noninheritable mode on new client socket.\n")); |
3113 | #endif | 3138 | #endif |
3114 | } | 3139 | } |
3115 | 3140 | ||
3116 | if ( (0 == (daemon->options & MHD_USE_TURBO)) && | 3141 | if ( (0 == (daemon->options & MHD_USE_TURBO)) && |
3117 | (! MHD_socket_buffering_reset_ (client_socket)) ) | 3142 | (! MHD_socket_buffering_reset_ (client_socket)) ) |
3118 | { | 3143 | { |
3119 | #ifdef HAVE_MESSAGES | 3144 | #ifdef HAVE_MESSAGES |
3120 | MHD_DLOG (daemon, | 3145 | MHD_DLOG (daemon, |
3121 | _("Failed to reset buffering mode on new client socket.\n")); | 3146 | _ ("Failed to reset buffering mode on new client socket.\n")); |
3122 | #endif | 3147 | #endif |
3123 | } | 3148 | } |
3124 | return internal_add_connection (daemon, | 3149 | return internal_add_connection (daemon, |
3125 | client_socket, | 3150 | client_socket, |
3126 | addr, | 3151 | addr, |
@@ -3179,94 +3204,98 @@ MHD_accept_connection (struct MHD_Daemon *daemon) | |||
3179 | #endif /* ! USE_ACCEPT4 */ | 3204 | #endif /* ! USE_ACCEPT4 */ |
3180 | if ( (MHD_INVALID_SOCKET == s) || | 3205 | if ( (MHD_INVALID_SOCKET == s) || |
3181 | (addrlen <= 0) ) | 3206 | (addrlen <= 0) ) |
3182 | { | 3207 | { |
3183 | const int err = MHD_socket_get_error_ (); | 3208 | const int err = MHD_socket_get_error_ (); |
3184 | 3209 | ||
3185 | /* This could be a common occurance with multiple worker threads */ | 3210 | /* This could be a common occurance with multiple worker threads */ |
3186 | if (MHD_SCKT_ERR_IS_ (err, | 3211 | if (MHD_SCKT_ERR_IS_ (err, |
3187 | MHD_SCKT_EINVAL_)) | 3212 | MHD_SCKT_EINVAL_)) |
3188 | return MHD_NO; /* can happen during shutdown */ | 3213 | return MHD_NO; /* can happen during shutdown */ |
3189 | if (MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err)) | 3214 | if (MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_ (err)) |
3190 | return MHD_NO; /* do not print error if client just disconnected early */ | 3215 | return MHD_NO; /* do not print error if client just disconnected early */ |
3216 | #ifdef HAVE_MESSAGES | ||
3217 | if (! MHD_SCKT_ERR_IS_EAGAIN_ (err) ) | ||
3218 | MHD_DLOG (daemon, | ||
3219 | _ ("Error accepting connection: %s\n"), | ||
3220 | MHD_socket_strerr_ (err)); | ||
3221 | #endif | ||
3222 | if (MHD_INVALID_SOCKET != s) | ||
3223 | { | ||
3224 | MHD_socket_close_chk_ (s); | ||
3225 | } | ||
3226 | if ( MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err) ) | ||
3227 | { | ||
3228 | /* system/process out of resources */ | ||
3229 | if (0 == daemon->connections) | ||
3230 | { | ||
3191 | #ifdef HAVE_MESSAGES | 3231 | #ifdef HAVE_MESSAGES |
3192 | if (! MHD_SCKT_ERR_IS_EAGAIN_ (err) ) | 3232 | /* Not setting 'at_limit' flag, as there is no way it |
3233 | would ever be cleared. Instead trying to produce | ||
3234 | bit fat ugly warning. */ | ||
3193 | MHD_DLOG (daemon, | 3235 | MHD_DLOG (daemon, |
3194 | _("Error accepting connection: %s\n"), | 3236 | _ ( |
3195 | MHD_socket_strerr_(err)); | 3237 | "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")); |
3196 | #endif | 3238 | #endif |
3197 | if (MHD_INVALID_SOCKET != s) | 3239 | } |
3198 | { | 3240 | else |
3199 | MHD_socket_close_chk_ (s); | 3241 | { |
3200 | } | ||
3201 | if ( MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err) ) | ||
3202 | { | ||
3203 | /* system/process out of resources */ | ||
3204 | if (0 == daemon->connections) | ||
3205 | { | ||
3206 | #ifdef HAVE_MESSAGES | ||
3207 | /* Not setting 'at_limit' flag, as there is no way it | ||
3208 | would ever be cleared. Instead trying to produce | ||
3209 | bit fat ugly warning. */ | ||
3210 | MHD_DLOG (daemon, | ||
3211 | _("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")); | ||
3212 | #endif | ||
3213 | } | ||
3214 | else | ||
3215 | { | ||
3216 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 3242 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
3217 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 3243 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
3218 | #endif | 3244 | #endif |
3219 | daemon->at_limit = true; | 3245 | daemon->at_limit = true; |
3220 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 3246 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
3221 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 3247 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
3222 | #endif | 3248 | #endif |
3223 | #ifdef HAVE_MESSAGES | 3249 | #ifdef HAVE_MESSAGES |
3224 | MHD_DLOG (daemon, | 3250 | MHD_DLOG (daemon, |
3225 | _("Hit process or system resource limit at %u connections, temporarily suspending accept(). Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n"), | 3251 | _ ( |
3226 | (unsigned int) daemon->connections); | 3252 | "Hit process or system resource limit at %u connections, temporarily suspending accept(). Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n"), |
3253 | (unsigned int) daemon->connections); | ||
3227 | #endif | 3254 | #endif |
3228 | } | 3255 | } |
3229 | } | ||
3230 | return MHD_NO; | ||
3231 | } | 3256 | } |
3257 | return MHD_NO; | ||
3258 | } | ||
3232 | #if defined(MHD_TCP_CORK_NOPUSH) || defined(HAVE_MSG_MORE) | 3259 | #if defined(MHD_TCP_CORK_NOPUSH) || defined(HAVE_MSG_MORE) |
3233 | /* We will use TCP_CORK or TCP_NOPUSH or MSG_MORE to control | 3260 | /* We will use TCP_CORK or TCP_NOPUSH or MSG_MORE to control |
3234 | transmission, disable Nagle's algorithm (always) */ | 3261 | transmission, disable Nagle's algorithm (always) */ |
3235 | if (0 != MHD_socket_set_nodelay_ (s, | 3262 | if (0 != MHD_socket_set_nodelay_ (s, |
3236 | true)) | 3263 | true)) |
3237 | { | 3264 | { |
3238 | #ifdef HAVE_MESSAGES | 3265 | #ifdef HAVE_MESSAGES |
3239 | MHD_DLOG (daemon, | 3266 | MHD_DLOG (daemon, |
3240 | _("Failed to disable TCP Nagle on socket: %s\n"), | 3267 | _ ("Failed to disable TCP Nagle on socket: %s\n"), |
3241 | MHD_socket_last_strerr_()); | 3268 | MHD_socket_last_strerr_ ()); |
3242 | } | 3269 | } |
3243 | #endif | 3270 | #endif |
3244 | #endif | 3271 | #endif |
3245 | #if !defined(USE_ACCEPT4) || !defined(HAVE_SOCK_NONBLOCK) | 3272 | #if ! defined(USE_ACCEPT4) || ! defined(HAVE_SOCK_NONBLOCK) |
3246 | if (! MHD_socket_nonblocking_ (s)) | 3273 | if (! MHD_socket_nonblocking_ (s)) |
3247 | { | 3274 | { |
3248 | #ifdef HAVE_MESSAGES | 3275 | #ifdef HAVE_MESSAGES |
3249 | MHD_DLOG (daemon, | 3276 | MHD_DLOG (daemon, |
3250 | _("Failed to set nonblocking mode on incoming connection socket: %s\n"), | 3277 | _ ( |
3251 | MHD_socket_last_strerr_()); | 3278 | "Failed to set nonblocking mode on incoming connection socket: %s\n"), |
3279 | MHD_socket_last_strerr_ ()); | ||
3252 | #endif | 3280 | #endif |
3253 | } | 3281 | } |
3254 | else | 3282 | else |
3255 | sk_nonbl = !0; | 3283 | sk_nonbl = ! 0; |
3256 | #endif /* !USE_ACCEPT4 || !HAVE_SOCK_NONBLOCK */ | 3284 | #endif /* !USE_ACCEPT4 || !HAVE_SOCK_NONBLOCK */ |
3257 | #if !defined(USE_ACCEPT4) || !defined(SOCK_CLOEXEC) | 3285 | #if ! defined(USE_ACCEPT4) || ! defined(SOCK_CLOEXEC) |
3258 | if (! MHD_socket_noninheritable_ (s)) | 3286 | if (! MHD_socket_noninheritable_ (s)) |
3259 | { | 3287 | { |
3260 | #ifdef HAVE_MESSAGES | 3288 | #ifdef HAVE_MESSAGES |
3261 | MHD_DLOG (daemon, | 3289 | MHD_DLOG (daemon, |
3262 | _("Failed to set noninheritable mode on incoming connection socket.\n")); | 3290 | _ ( |
3291 | "Failed to set noninheritable mode on incoming connection socket.\n")); | ||
3263 | #endif | 3292 | #endif |
3264 | } | 3293 | } |
3265 | #endif /* !USE_ACCEPT4 || !SOCK_CLOEXEC */ | 3294 | #endif /* !USE_ACCEPT4 || !SOCK_CLOEXEC */ |
3266 | #ifdef HAVE_MESSAGES | 3295 | #ifdef HAVE_MESSAGES |
3267 | #if DEBUG_CONNECT | 3296 | #if DEBUG_CONNECT |
3268 | MHD_DLOG (daemon, | 3297 | MHD_DLOG (daemon, |
3269 | _("Accepted connection on socket %d\n"), | 3298 | _ ("Accepted connection on socket %d\n"), |
3270 | s); | 3299 | s); |
3271 | #endif | 3300 | #endif |
3272 | #endif | 3301 | #endif |
@@ -3298,80 +3327,80 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon) | |||
3298 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 3327 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
3299 | #endif | 3328 | #endif |
3300 | while (NULL != (pos = daemon->cleanup_tail)) | 3329 | while (NULL != (pos = daemon->cleanup_tail)) |
3301 | { | 3330 | { |
3302 | DLL_remove (daemon->cleanup_head, | 3331 | DLL_remove (daemon->cleanup_head, |
3303 | daemon->cleanup_tail, | 3332 | daemon->cleanup_tail, |
3304 | pos); | 3333 | pos); |
3305 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 3334 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
3306 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 3335 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
3307 | if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && | 3336 | if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && |
3308 | (! pos->thread_joined) && | 3337 | (! pos->thread_joined) && |
3309 | (! MHD_join_thread_ (pos->pid.handle)) ) | 3338 | (! MHD_join_thread_ (pos->pid.handle)) ) |
3310 | MHD_PANIC (_("Failed to join a thread\n")); | 3339 | MHD_PANIC (_ ("Failed to join a thread\n")); |
3311 | #endif | 3340 | #endif |
3312 | #ifdef UPGRADE_SUPPORT | 3341 | #ifdef UPGRADE_SUPPORT |
3313 | cleanup_upgraded_connection (pos); | 3342 | cleanup_upgraded_connection (pos); |
3314 | #endif /* UPGRADE_SUPPORT */ | 3343 | #endif /* UPGRADE_SUPPORT */ |
3315 | MHD_pool_destroy (pos->pool); | 3344 | MHD_pool_destroy (pos->pool); |
3316 | #ifdef HTTPS_SUPPORT | 3345 | #ifdef HTTPS_SUPPORT |
3317 | if (NULL != pos->tls_session) | 3346 | if (NULL != pos->tls_session) |
3318 | gnutls_deinit (pos->tls_session); | 3347 | gnutls_deinit (pos->tls_session); |
3319 | #endif /* HTTPS_SUPPORT */ | 3348 | #endif /* HTTPS_SUPPORT */ |
3320 | 3349 | ||
3321 | /* clean up the connection */ | 3350 | /* clean up the connection */ |
3322 | if (NULL != daemon->notify_connection) | 3351 | if (NULL != daemon->notify_connection) |
3323 | daemon->notify_connection (daemon->notify_connection_cls, | 3352 | daemon->notify_connection (daemon->notify_connection_cls, |
3324 | pos, | 3353 | pos, |
3325 | &pos->socket_context, | 3354 | &pos->socket_context, |
3326 | MHD_CONNECTION_NOTIFY_CLOSED); | 3355 | MHD_CONNECTION_NOTIFY_CLOSED); |
3327 | MHD_ip_limit_del (daemon, | 3356 | MHD_ip_limit_del (daemon, |
3328 | pos->addr, | 3357 | pos->addr, |
3329 | pos->addr_len); | 3358 | pos->addr_len); |
3330 | #ifdef EPOLL_SUPPORT | 3359 | #ifdef EPOLL_SUPPORT |
3331 | if (0 != (daemon->options & MHD_USE_EPOLL)) | 3360 | if (0 != (daemon->options & MHD_USE_EPOLL)) |
3332 | { | 3361 | { |
3333 | if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) | 3362 | if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) |
3334 | { | 3363 | { |
3335 | EDLL_remove (daemon->eready_head, | 3364 | EDLL_remove (daemon->eready_head, |
3336 | daemon->eready_tail, | 3365 | daemon->eready_tail, |
3337 | pos); | 3366 | pos); |
3338 | pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL; | 3367 | pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL; |
3339 | } | 3368 | } |
3340 | if ( (-1 != daemon->epoll_fd) && | 3369 | if ( (-1 != daemon->epoll_fd) && |
3341 | (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) ) | 3370 | (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) ) |
3342 | { | 3371 | { |
3343 | /* epoll documentation suggests that closing a FD | 3372 | /* epoll documentation suggests that closing a FD |
3344 | automatically removes it from the epoll set; however, | 3373 | automatically removes it from the epoll set; however, |
3345 | this is not true as if we fail to do manually remove it, | 3374 | this is not true as if we fail to do manually remove it, |
3346 | we are still seeing an event for this fd in epoll, | 3375 | we are still seeing an event for this fd in epoll, |
3347 | causing grief (use-after-free...) --- at least on my | 3376 | causing grief (use-after-free...) --- at least on my |
3348 | system. */ | 3377 | system. */ |
3349 | if (0 != epoll_ctl (daemon->epoll_fd, | 3378 | if (0 != epoll_ctl (daemon->epoll_fd, |
3350 | EPOLL_CTL_DEL, | 3379 | EPOLL_CTL_DEL, |
3351 | pos->socket_fd, | 3380 | pos->socket_fd, |
3352 | NULL)) | 3381 | NULL)) |
3353 | MHD_PANIC (_("Failed to remove FD from epoll set\n")); | 3382 | MHD_PANIC (_ ("Failed to remove FD from epoll set\n")); |
3354 | pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET; | 3383 | pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET; |
3355 | } | 3384 | } |
3356 | } | 3385 | } |
3357 | #endif | 3386 | #endif |
3358 | if (NULL != pos->response) | 3387 | if (NULL != pos->response) |
3359 | { | 3388 | { |
3360 | MHD_destroy_response (pos->response); | 3389 | MHD_destroy_response (pos->response); |
3361 | pos->response = NULL; | 3390 | pos->response = NULL; |
3362 | } | 3391 | } |
3363 | if (MHD_INVALID_SOCKET != pos->socket_fd) | 3392 | if (MHD_INVALID_SOCKET != pos->socket_fd) |
3364 | MHD_socket_close_chk_ (pos->socket_fd); | 3393 | MHD_socket_close_chk_ (pos->socket_fd); |
3365 | if (NULL != pos->addr) | 3394 | if (NULL != pos->addr) |
3366 | free (pos->addr); | 3395 | free (pos->addr); |
3367 | free (pos); | 3396 | free (pos); |
3368 | 3397 | ||
3369 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 3398 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
3370 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 3399 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
3371 | #endif | 3400 | #endif |
3372 | daemon->connections--; | 3401 | daemon->connections--; |
3373 | daemon->at_limit = false; | 3402 | daemon->at_limit = false; |
3374 | } | 3403 | } |
3375 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 3404 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
3376 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 3405 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
3377 | #endif | 3406 | #endif |
@@ -3408,71 +3437,71 @@ MHD_get_timeout (struct MHD_Daemon *daemon, | |||
3408 | bool have_timeout; | 3437 | bool have_timeout; |
3409 | 3438 | ||
3410 | if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) | 3439 | if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) |
3411 | { | 3440 | { |
3412 | #ifdef HAVE_MESSAGES | 3441 | #ifdef HAVE_MESSAGES |
3413 | MHD_DLOG (daemon, | 3442 | MHD_DLOG (daemon, |
3414 | _("Illegal call to MHD_get_timeout\n")); | 3443 | _ ("Illegal call to MHD_get_timeout\n")); |
3415 | #endif | 3444 | #endif |
3416 | return MHD_NO; | 3445 | return MHD_NO; |
3417 | } | 3446 | } |
3418 | 3447 | ||
3419 | if (daemon->data_already_pending) | 3448 | if (daemon->data_already_pending) |
3420 | { | 3449 | { |
3421 | /* Some data already waiting to be processed. */ | 3450 | /* Some data already waiting to be processed. */ |
3422 | *timeout = 0; | 3451 | *timeout = 0; |
3423 | return MHD_YES; | 3452 | return MHD_YES; |
3424 | } | 3453 | } |
3425 | 3454 | ||
3426 | #ifdef EPOLL_SUPPORT | 3455 | #ifdef EPOLL_SUPPORT |
3427 | if ( (0 != (daemon->options & MHD_USE_EPOLL)) && | 3456 | if ( (0 != (daemon->options & MHD_USE_EPOLL)) && |
3428 | ((NULL != daemon->eready_head) | 3457 | ((NULL != daemon->eready_head) |
3429 | #if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT) | 3458 | #if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT) |
3430 | || (NULL != daemon->eready_urh_head) | 3459 | || (NULL != daemon->eready_urh_head) |
3431 | #endif /* UPGRADE_SUPPORT && HTTPS_SUPPORT */ | 3460 | #endif /* UPGRADE_SUPPORT && HTTPS_SUPPORT */ |
3432 | ) ) | 3461 | ) ) |
3433 | { | 3462 | { |
3434 | /* Some connection(s) already have some data pending. */ | 3463 | /* Some connection(s) already have some data pending. */ |
3435 | *timeout = 0; | 3464 | *timeout = 0; |
3436 | return MHD_YES; | 3465 | return MHD_YES; |
3437 | } | 3466 | } |
3438 | #endif /* EPOLL_SUPPORT */ | 3467 | #endif /* EPOLL_SUPPORT */ |
3439 | 3468 | ||
3440 | have_timeout = false; | 3469 | have_timeout = false; |
3441 | earliest_deadline = 0; /* avoid compiler warnings */ | 3470 | earliest_deadline = 0; /* avoid compiler warnings */ |
3442 | for (pos = daemon->manual_timeout_tail; NULL != pos; pos = pos->prevX) | 3471 | for (pos = daemon->manual_timeout_tail; NULL != pos; pos = pos->prevX) |
3472 | { | ||
3473 | if (0 != pos->connection_timeout) | ||
3443 | { | 3474 | { |
3444 | if (0 != pos->connection_timeout) | 3475 | if ( (! have_timeout) || |
3445 | { | 3476 | (earliest_deadline - pos->last_activity > pos->connection_timeout) ) |
3446 | if ( (! have_timeout) || | 3477 | earliest_deadline = pos->last_activity + pos->connection_timeout; |
3447 | (earliest_deadline - pos->last_activity > pos->connection_timeout) ) | 3478 | have_timeout = true; |
3448 | earliest_deadline = pos->last_activity + pos->connection_timeout; | ||
3449 | have_timeout = true; | ||
3450 | } | ||
3451 | } | 3479 | } |
3480 | } | ||
3452 | /* normal timeouts are sorted, so we only need to look at the 'tail' (oldest) */ | 3481 | /* normal timeouts are sorted, so we only need to look at the 'tail' (oldest) */ |
3453 | pos = daemon->normal_timeout_tail; | 3482 | pos = daemon->normal_timeout_tail; |
3454 | if ( (NULL != pos) && | 3483 | if ( (NULL != pos) && |
3455 | (0 != pos->connection_timeout) ) | 3484 | (0 != pos->connection_timeout) ) |
3456 | { | 3485 | { |
3457 | if ( (! have_timeout) || | 3486 | if ( (! have_timeout) || |
3458 | (earliest_deadline - pos->connection_timeout > pos->last_activity) ) | 3487 | (earliest_deadline - pos->connection_timeout > pos->last_activity) ) |
3459 | earliest_deadline = pos->last_activity + pos->connection_timeout; | 3488 | earliest_deadline = pos->last_activity + pos->connection_timeout; |
3460 | have_timeout = true; | 3489 | have_timeout = true; |
3461 | } | 3490 | } |
3462 | 3491 | ||
3463 | if (! have_timeout) | 3492 | if (! have_timeout) |
3464 | return MHD_NO; | 3493 | return MHD_NO; |
3465 | now = MHD_monotonic_sec_counter(); | 3494 | now = MHD_monotonic_sec_counter (); |
3466 | if (earliest_deadline < now) | 3495 | if (earliest_deadline < now) |
3467 | *timeout = 0; | 3496 | *timeout = 0; |
3468 | else | 3497 | else |
3469 | { | 3498 | { |
3470 | const time_t second_left = earliest_deadline - now; | 3499 | const time_t second_left = earliest_deadline - now; |
3471 | 3500 | ||
3472 | if (((unsigned long long)second_left) > ULLONG_MAX / 1000) | 3501 | if (((unsigned long long) second_left) > ULLONG_MAX / 1000) |
3473 | *timeout = ULLONG_MAX; | 3502 | *timeout = ULLONG_MAX; |
3474 | else | 3503 | else |
3475 | *timeout = 1000LLU * (unsigned long long) second_left; | 3504 | *timeout = 1000LLU * (unsigned long long) second_left; |
3476 | } | 3505 | } |
3477 | return MHD_YES; | 3506 | return MHD_YES; |
3478 | } | 3507 | } |
@@ -3508,7 +3537,7 @@ internal_run_from_select (struct MHD_Daemon *daemon, | |||
3508 | /* Clear ITC to avoid spinning select */ | 3537 | /* Clear ITC to avoid spinning select */ |
3509 | /* Do it before any other processing so new signals | 3538 | /* Do it before any other processing so new signals |
3510 | will trigger select again and will be processed */ | 3539 | will trigger select again and will be processed */ |
3511 | if ( (MHD_ITC_IS_VALID_(daemon->itc)) && | 3540 | if ( (MHD_ITC_IS_VALID_ (daemon->itc)) && |
3512 | (FD_ISSET (MHD_itc_r_fd_ (daemon->itc), | 3541 | (FD_ISSET (MHD_itc_r_fd_ (daemon->itc), |
3513 | read_fd_set)) ) | 3542 | read_fd_set)) ) |
3514 | MHD_itc_clear_ (daemon->itc); | 3543 | MHD_itc_clear_ (daemon->itc); |
@@ -3521,49 +3550,49 @@ internal_run_from_select (struct MHD_Daemon *daemon, | |||
3521 | (void) MHD_accept_connection (daemon); | 3550 | (void) MHD_accept_connection (daemon); |
3522 | 3551 | ||
3523 | if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) | 3552 | if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) |
3553 | { | ||
3554 | /* do not have a thread per connection, process all connections now */ | ||
3555 | prev = daemon->connections_tail; | ||
3556 | while (NULL != (pos = prev)) | ||
3524 | { | 3557 | { |
3525 | /* do not have a thread per connection, process all connections now */ | 3558 | prev = pos->prev; |
3526 | prev = daemon->connections_tail; | 3559 | ds = pos->socket_fd; |
3527 | while (NULL != (pos = prev)) | 3560 | if (MHD_INVALID_SOCKET == ds) |
3528 | { | 3561 | continue; |
3529 | prev = pos->prev; | 3562 | call_handlers (pos, |
3530 | ds = pos->socket_fd; | 3563 | FD_ISSET (ds, |
3531 | if (MHD_INVALID_SOCKET == ds) | 3564 | read_fd_set), |
3532 | continue; | 3565 | FD_ISSET (ds, |
3533 | call_handlers (pos, | 3566 | write_fd_set), |
3534 | FD_ISSET (ds, | 3567 | FD_ISSET (ds, |
3535 | read_fd_set), | 3568 | except_fd_set)); |
3536 | FD_ISSET (ds, | ||
3537 | write_fd_set), | ||
3538 | FD_ISSET (ds, | ||
3539 | except_fd_set)); | ||
3540 | } | ||
3541 | } | 3569 | } |
3570 | } | ||
3542 | 3571 | ||
3543 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) | 3572 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) |
3544 | /* handle upgraded HTTPS connections */ | 3573 | /* handle upgraded HTTPS connections */ |
3545 | for (urh = daemon->urh_tail; NULL != urh; urh = urhn) | 3574 | for (urh = daemon->urh_tail; NULL != urh; urh = urhn) |
3575 | { | ||
3576 | urhn = urh->prev; | ||
3577 | /* update urh state based on select() output */ | ||
3578 | urh_from_fdset (urh, | ||