aboutsummaryrefslogtreecommitdiff
path: root/src/microhttpd/response.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/microhttpd/response.c')
-rw-r--r--src/microhttpd/response.c611
1 files changed, 307 insertions, 304 deletions
diff --git a/src/microhttpd/response.c b/src/microhttpd/response.c
index 65ea7b09..112a622a 100644
--- a/src/microhttpd/response.c
+++ b/src/microhttpd/response.c
@@ -101,17 +101,17 @@ add_response_entry (struct MHD_Response *response,
101 if (NULL == (hdr = malloc (sizeof (struct MHD_HTTP_Header)))) 101 if (NULL == (hdr = malloc (sizeof (struct MHD_HTTP_Header))))
102 return MHD_NO; 102 return MHD_NO;
103 if (NULL == (hdr->header = strdup (header))) 103 if (NULL == (hdr->header = strdup (header)))
104 { 104 {
105 free (hdr); 105 free (hdr);
106 return MHD_NO; 106 return MHD_NO;
107 } 107 }
108 hdr->header_size = strlen (header); 108 hdr->header_size = strlen (header);
109 if (NULL == (hdr->value = strdup (content))) 109 if (NULL == (hdr->value = strdup (content)))
110 { 110 {
111 free (hdr->header); 111 free (hdr->header);
112 free (hdr); 112 free (hdr);
113 return MHD_NO; 113 return MHD_NO;
114 } 114 }
115 hdr->value_size = strlen (content); 115 hdr->value_size = strlen (content);
116 hdr->kind = kind; 116 hdr->kind = kind;
117 hdr->next = response->first_header; 117 hdr->next = response->first_header;
@@ -140,25 +140,25 @@ MHD_add_response_header (struct MHD_Response *response,
140 "identity")) && 140 "identity")) &&
141 (! MHD_str_equal_caseless_ (content, 141 (! MHD_str_equal_caseless_ (content,
142 "chunked")) ) 142 "chunked")) )
143 { 143 {
144 /* Setting transfer encodings other than "identity" or 144 /* Setting transfer encodings other than "identity" or
145 "chunked" is not allowed. Note that MHD will set the 145 "chunked" is not allowed. Note that MHD will set the
146 correct transfer encoding if required automatically. */ 146 correct transfer encoding if required automatically. */
147 /* NOTE: for compressed bodies, use the "Content-encoding" header */ 147 /* NOTE: for compressed bodies, use the "Content-encoding" header */
148 return MHD_NO; 148 return MHD_NO;
149 } 149 }
150 if (MHD_str_equal_caseless_ (header, 150 if (MHD_str_equal_caseless_ (header,
151 MHD_HTTP_HEADER_CONTENT_LENGTH)) 151 MHD_HTTP_HEADER_CONTENT_LENGTH))
152 { 152 {
153 /* MHD will set Content-length if allowed and possible, 153 /* MHD will set Content-length if allowed and possible,
154 reject attempt by application */ 154 reject attempt by application */
155 return MHD_NO; 155 return MHD_NO;
156 } 156 }
157 157
158 return add_response_entry (response, 158 return add_response_entry (response,
159 MHD_HEADER_KIND, 159 MHD_HEADER_KIND,
160 header, 160 header,
161 content); 161 content);
162} 162}
163 163
164 164
@@ -177,9 +177,9 @@ MHD_add_response_footer (struct MHD_Response *response,
177 const char *content) 177 const char *content)
178{ 178{
179 return add_response_entry (response, 179 return add_response_entry (response,
180 MHD_FOOTER_KIND, 180 MHD_FOOTER_KIND,
181 footer, 181 footer,
182 content); 182 content);
183} 183}
184 184
185 185
@@ -203,35 +203,35 @@ MHD_del_response_header (struct MHD_Response *response,
203 size_t content_len; 203 size_t content_len;
204 204
205 if ( (NULL == header) || 205 if ( (NULL == header) ||
206 (NULL == content) ) 206 (NULL == content) )
207 return MHD_NO; 207 return MHD_NO;
208 header_len = strlen (header); 208 header_len = strlen (header);
209 content_len = strlen (content); 209 content_len = strlen (content);
210 prev = NULL; 210 prev = NULL;
211 pos = response->first_header; 211 pos = response->first_header;
212 while (NULL != pos) 212 while (NULL != pos)
213 {
214 if ((header_len == pos->header_size) &&
215 (content_len == pos->value_size) &&
216 (0 == memcmp (header,
217 pos->header,
218 header_len)) &&
219 (0 == memcmp (content,
220 pos->value,
221 content_len)))
213 { 222 {
214 if ((header_len == pos->header_size) && 223 free (pos->header);
215 (content_len == pos->value_size) && 224 free (pos->value);
216 (0 == memcmp (header, 225 if (NULL == prev)
217 pos->header, 226 response->first_header = pos->next;
218 header_len)) && 227 else
219 (0 == memcmp (content, 228 prev->next = pos->next;
220 pos->value, 229 free (pos);
221 content_len))) 230 return MHD_YES;
222 {
223 free (pos->header);
224 free (pos->value);
225 if (NULL == prev)
226 response->first_header = pos->next;
227 else
228 prev->next = pos->next;
229 free (pos);
230 return MHD_YES;
231 }
232 prev = pos;
233 pos = pos->next;
234 } 231 }
232 prev = pos;
233 pos = pos->next;
234 }
235 return MHD_NO; 235 return MHD_NO;
236} 236}
237 237
@@ -257,15 +257,15 @@ MHD_get_response_headers (struct MHD_Response *response,
257 for (pos = response->first_header; 257 for (pos = response->first_header;
258 NULL != pos; 258 NULL != pos;
259 pos = pos->next) 259 pos = pos->next)
260 { 260 {
261 numHeaders++; 261 numHeaders++;
262 if ((NULL != iterator) && 262 if ((NULL != iterator) &&
263 (MHD_YES != iterator (iterator_cls, 263 (MHD_YES != iterator (iterator_cls,
264 pos->kind, 264 pos->kind,
265 pos->header, 265 pos->header,
266 pos->value))) 266 pos->value)))
267 break; 267 break;
268 } 268 }
269 return numHeaders; 269 return numHeaders;
270} 270}
271 271
@@ -292,11 +292,11 @@ MHD_get_response_header (struct MHD_Response *response,
292 for (pos = response->first_header; 292 for (pos = response->first_header;
293 NULL != pos; 293 NULL != pos;
294 pos = pos->next) 294 pos = pos->next)
295 { 295 {
296 if ((pos->header_size == key_size) && 296 if ((pos->header_size == key_size) &&
297 (MHD_str_equal_caseless_bin_n_ (pos->header, key, pos->header_size))) 297 (MHD_str_equal_caseless_bin_n_ (pos->header, key, pos->header_size)))
298 return pos->value; 298 return pos->value;
299 } 299 }
300 return NULL; 300 return NULL;
301} 301}
302 302
@@ -333,22 +333,22 @@ MHD_check_response_header_token_ci (const struct MHD_Response *response,
333 return false; 333 return false;
334 334
335 /* Token must not contain binary zero! */ 335 /* Token must not contain binary zero! */
336 mhd_assert(strlen(token) == token_len); 336 mhd_assert (strlen (token) == token_len);
337 337
338 for (pos = response->first_header; 338 for (pos = response->first_header;
339 NULL != pos; 339 NULL != pos;
340 pos = pos->next) 340 pos = pos->next)
341 { 341 {
342 if ( (pos->kind == MHD_HEADER_KIND) && 342 if ( (pos->kind == MHD_HEADER_KIND) &&
343 (key_len == pos->header_size) && 343 (key_len == pos->header_size) &&
344 MHD_str_equal_caseless_bin_n_ (pos->header, 344 MHD_str_equal_caseless_bin_n_ (pos->header,
345 key, 345 key,
346 key_len) && 346 key_len) &&
347 MHD_str_has_token_caseless_ (pos->value, 347 MHD_str_has_token_caseless_ (pos->value,
348 token, 348 token,
349 token_len) ) 349 token_len) )
350 return true; 350 return true;
351 } 351 }
352 return false; 352 return false;
353} 353}
354 354
@@ -380,7 +380,8 @@ MHD_create_response_from_callback (uint64_t size,
380 380
381 if ((NULL == crc) || (0 == block_size)) 381 if ((NULL == crc) || (0 == block_size))
382 return NULL; 382 return NULL;
383 if (NULL == (response = MHD_calloc_ (1, sizeof (struct MHD_Response) + block_size))) 383 if (NULL == (response = MHD_calloc_ (1, sizeof (struct MHD_Response)
384 + block_size)))
384 return NULL; 385 return NULL;
385 response->fd = -1; 386 response->fd = -1;
386 response->data = (void *) &response[1]; 387 response->data = (void *) &response[1];
@@ -452,28 +453,28 @@ file_reader (void *cls,
452 size_t max) 453 size_t max)
453{ 454{
454 struct MHD_Response *response = cls; 455 struct MHD_Response *response = cls;
455#if !defined(_WIN32) || defined(__CYGWIN__) 456#if ! defined(_WIN32) || defined(__CYGWIN__)
456 ssize_t n; 457 ssize_t n;
457#else /* _WIN32 && !__CYGWIN__ */ 458#else /* _WIN32 && !__CYGWIN__ */
458 const HANDLE fh = (HANDLE) _get_osfhandle (response->fd); 459 const HANDLE fh = (HANDLE) _get_osfhandle (response->fd);
459#endif /* _WIN32 && !__CYGWIN__ */ 460#endif /* _WIN32 && !__CYGWIN__ */
460 const int64_t offset64 = (int64_t)(pos + response->fd_off); 461 const int64_t offset64 = (int64_t) (pos + response->fd_off);
461 462
462 if (offset64 < 0) 463 if (offset64 < 0)
463 return MHD_CONTENT_READER_END_WITH_ERROR; /* seek to required position is not possible */ 464 return MHD_CONTENT_READER_END_WITH_ERROR; /* seek to required position is not possible */
464 465
465#if !defined(_WIN32) || defined(__CYGWIN__) 466#if ! defined(_WIN32) || defined(__CYGWIN__)
466 if (max > SSIZE_MAX) 467 if (max > SSIZE_MAX)
467 max = SSIZE_MAX; /* Clamp to maximum return value. */ 468 max = SSIZE_MAX; /* Clamp to maximum return value. */
468 469
469#if defined(HAVE_PREAD64) 470#if defined(HAVE_PREAD64)
470 n = pread64(response->fd, buf, max, offset64); 471 n = pread64 (response->fd, buf, max, offset64);
471#elif defined(HAVE_PREAD) 472#elif defined(HAVE_PREAD)
472 if ( (sizeof(off_t) < sizeof (uint64_t)) && 473 if ( (sizeof(off_t) < sizeof (uint64_t)) &&
473 (offset64 > (uint64_t)INT32_MAX) ) 474 (offset64 > (uint64_t) INT32_MAX) )
474 return MHD_CONTENT_READER_END_WITH_ERROR; /* Read at required position is not possible. */ 475 return MHD_CONTENT_READER_END_WITH_ERROR; /* Read at required position is not possible. */
475 476
476 n = pread(response->fd, buf, max, (off_t) offset64); 477 n = pread (response->fd, buf, max, (off_t) offset64);
477#else /* ! HAVE_PREAD */ 478#else /* ! HAVE_PREAD */
478#if defined(HAVE_LSEEK64) 479#if defined(HAVE_LSEEK64)
479 if (lseek64 (response->fd, 480 if (lseek64 (response->fd,
@@ -482,7 +483,7 @@ file_reader (void *cls,
482 return MHD_CONTENT_READER_END_WITH_ERROR; /* can't seek to required position */ 483 return MHD_CONTENT_READER_END_WITH_ERROR; /* can't seek to required position */
483#else /* ! HAVE_LSEEK64 */ 484#else /* ! HAVE_LSEEK64 */
484 if ( (sizeof(off_t) < sizeof (uint64_t)) && 485 if ( (sizeof(off_t) < sizeof (uint64_t)) &&
485 (offset64 > (uint64_t)INT32_MAX) ) 486 (offset64 > (uint64_t) INT32_MAX) )
486 return MHD_CONTENT_READER_END_WITH_ERROR; /* seek to required position is not possible */ 487 return MHD_CONTENT_READER_END_WITH_ERROR; /* seek to required position is not possible */
487 488
488 if (lseek (response->fd, 489 if (lseek (response->fd,
@@ -504,21 +505,21 @@ file_reader (void *cls,
504 if (INVALID_HANDLE_VALUE == fh) 505 if (INVALID_HANDLE_VALUE == fh)
505 return MHD_CONTENT_READER_END_WITH_ERROR; /* Value of 'response->fd' is not valid. */ 506 return MHD_CONTENT_READER_END_WITH_ERROR; /* Value of 'response->fd' is not valid. */
506 else 507 else
507 { 508 {
508 OVERLAPPED f_ol = {0, 0, {{0, 0}}, 0}; /* Initialize to zero. */ 509 OVERLAPPED f_ol = {0, 0, {{0, 0}}, 0}; /* Initialize to zero. */
509 ULARGE_INTEGER pos_uli; 510 ULARGE_INTEGER pos_uli;
510 DWORD toRead = (max > INT32_MAX) ? INT32_MAX : (DWORD) max; 511 DWORD toRead = (max > INT32_MAX) ? INT32_MAX : (DWORD) max;
511 DWORD resRead; 512 DWORD resRead;
512 513
513 pos_uli.QuadPart = (uint64_t) offset64; /* Simple transformation 64bit -> 2x32bit. */ 514 pos_uli.QuadPart = (uint64_t) offset64; /* Simple transformation 64bit -> 2x32bit. */
514 f_ol.Offset = pos_uli.LowPart; 515 f_ol.Offset = pos_uli.LowPart;
515 f_ol.OffsetHigh = pos_uli.HighPart; 516 f_ol.OffsetHigh = pos_uli.HighPart;
516 if (! ReadFile(fh, (void*)buf, toRead, &resRead, &f_ol)) 517 if (! ReadFile (fh, (void*) buf, toRead, &resRead, &f_ol))
517 return MHD_CONTENT_READER_END_WITH_ERROR; /* Read error. */ 518 return MHD_CONTENT_READER_END_WITH_ERROR; /* Read error. */
518 if (0 == resRead) 519 if (0 == resRead)
519 return MHD_CONTENT_READER_END_OF_STREAM; 520 return MHD_CONTENT_READER_END_OF_STREAM;
520 return (ssize_t) resRead; 521 return (ssize_t) resRead;
521 } 522 }
522#endif /* _WIN32 && !__CYGWIN__ */ 523#endif /* _WIN32 && !__CYGWIN__ */
523} 524}
524 525
@@ -590,16 +591,16 @@ MHD_create_response_from_fd_at_offset64 (uint64_t size,
590{ 591{
591 struct MHD_Response *response; 592 struct MHD_Response *response;
592 593
593#if !defined(HAVE___LSEEKI64) && !defined(HAVE_LSEEK64) 594#if ! defined(HAVE___LSEEKI64) && ! defined(HAVE_LSEEK64)
594 if ( (sizeof(uint64_t) > sizeof(off_t)) && 595 if ( (sizeof(uint64_t) > sizeof(off_t)) &&
595 ( (size > (uint64_t)INT32_MAX) || 596 ( (size > (uint64_t) INT32_MAX) ||
596 (offset > (uint64_t)INT32_MAX) || 597 (offset > (uint64_t) INT32_MAX) ||
597 ((size + offset) >= (uint64_t)INT32_MAX) ) ) 598 ((size + offset) >= (uint64_t) INT32_MAX) ) )
598 return NULL; 599 return NULL;
599#endif 600#endif
600 if ( ((int64_t)size < 0) || 601 if ( ((int64_t) size < 0) ||
601 ((int64_t)offset < 0) || 602 ((int64_t) offset < 0) ||
602 ((int64_t)(size + offset) < 0) ) 603 ((int64_t) (size + offset) < 0) )
603 return NULL; 604 return NULL;
604 605
605 response = MHD_create_response_from_callback (size, 606 response = MHD_create_response_from_callback (size,
@@ -688,30 +689,30 @@ MHD_create_response_from_data (size_t size,
688 response->fd = -1; 689 response->fd = -1;
689#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 690#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
690 if (! MHD_mutex_init_ (&response->mutex)) 691 if (! MHD_mutex_init_ (&response->mutex))
691 { 692 {
692 free (response); 693 free (response);
693 return NULL; 694 return NULL;
694 } 695 }
695#endif 696#endif
696 if ((must_copy) && (size > 0)) 697 if ((must_copy) && (size > 0))
698 {
699 if (NULL == (tmp = malloc (size)))
697 { 700 {
698 if (NULL == (tmp = malloc (size)))
699 {
700#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 701#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
701 MHD_mutex_destroy_chk_ (&response->mutex); 702 MHD_mutex_destroy_chk_ (&response->mutex);
702#endif 703#endif
703 free (response); 704 free (response);
704 return NULL; 705 return NULL;
705 }
706 memcpy (tmp, data, size);
707 must_free = MHD_YES;
708 data = tmp;
709 } 706 }
707 memcpy (tmp, data, size);
708 must_free = MHD_YES;
709 data = tmp;
710 }
710 if (must_free) 711 if (must_free)
711 { 712 {
712 response->crfc = &free; 713 response->crfc = &free;
713 response->crc_cls = data; 714 response->crc_cls = data;
714 } 715 }
715 response->reference_count = 1; 716 response->reference_count = 1;
716 response->total_size = size; 717 response->total_size = size;
717 response->data = data; 718 response->data = data;
@@ -736,9 +737,9 @@ MHD_create_response_from_buffer (size_t size,
736 enum MHD_ResponseMemoryMode mode) 737 enum MHD_ResponseMemoryMode mode)
737{ 738{
738 return MHD_create_response_from_data (size, 739 return MHD_create_response_from_data (size,
739 buffer, 740 buffer,
740 mode == MHD_RESPMEM_MUST_FREE, 741 mode == MHD_RESPMEM_MUST_FREE,
741 mode == MHD_RESPMEM_MUST_COPY); 742 mode == MHD_RESPMEM_MUST_COPY);
742} 743}
743 744
744 745
@@ -755,7 +756,8 @@ MHD_create_response_from_buffer (size_t size,
755_MHD_EXTERN struct MHD_Response * 756_MHD_EXTERN struct MHD_Response *
756MHD_create_response_from_buffer_with_free_callback (size_t size, 757MHD_create_response_from_buffer_with_free_callback (size_t size,
757 void *buffer, 758 void *buffer,
758 MHD_ContentReaderFreeCallback crfc) 759 MHD_ContentReaderFreeCallback
760 crfc)
759{ 761{
760 struct MHD_Response *r; 762 struct MHD_Response *r;
761 763
@@ -811,12 +813,12 @@ MHD_upgrade_action (struct MHD_UpgradeResponseHandle *urh,
811 /* transition to special 'closed' state for start of cleanup */ 813 /* transition to special 'closed' state for start of cleanup */
812#ifdef HTTPS_SUPPORT 814#ifdef HTTPS_SUPPORT
813 if (0 != (daemon->options & MHD_USE_TLS) ) 815 if (0 != (daemon->options & MHD_USE_TLS) )
814 { 816 {
815 /* signal that app is done by shutdown() of 'app' socket */ 817 /* signal that app is done by shutdown() of 'app' socket */
816 /* Application will not use anyway this socket after this command. */ 818 /* Application will not use anyway this socket after this command. */
817 shutdown (urh->app.socket, 819 shutdown (urh->app.socket,
818 SHUT_RDWR); 820 SHUT_RDWR);
819 } 821 }
820#endif /* HTTPS_SUPPORT */ 822#endif /* HTTPS_SUPPORT */
821 mhd_assert (MHD_CONNECTION_UPGRADE == connection->state); 823 mhd_assert (MHD_CONNECTION_UPGRADE == connection->state);
822 urh->was_closed = true; 824 urh->was_closed = true;
@@ -830,42 +832,42 @@ MHD_upgrade_action (struct MHD_UpgradeResponseHandle *urh,
830 return MHD_YES; 832 return MHD_YES;
831#ifdef HTTPS_SUPPORT 833#ifdef HTTPS_SUPPORT
832 if (0 != (daemon->options & MHD_USE_TLS) ) 834 if (0 != (daemon->options & MHD_USE_TLS) )
833 { 835 {
834 gnutls_record_cork (connection->tls_session); 836 gnutls_record_cork (connection->tls_session);
835 connection->sk_cork_on = true; 837 connection->sk_cork_on = true;
836 return MHD_YES; 838 return MHD_YES;
837 } 839 }
838 else 840 else
839#else 841#else
840 { 842 {
841 if (0 == 843 if (0 ==
842 MHD_socket_cork_ (connection->socket_fd, 844 MHD_socket_cork_ (connection->socket_fd,
843 true)) 845 true))
844 connection->sk_cork_on = true; 846 connection->sk_cork_on = true;
845 } 847 }
846#endif 848#endif
847 case MHD_UPGRADE_ACTION_CORK_OFF: 849 case MHD_UPGRADE_ACTION_CORK_OFF:
848 if (! connection->sk_cork_on) 850 if (! connection->sk_cork_on)
849 return MHD_YES; 851 return MHD_YES;
850#ifdef HTTPS_SUPPORT 852#ifdef HTTPS_SUPPORT
851 if (0 != (daemon->options & MHD_USE_TLS) ) 853 if (0 != (daemon->options & MHD_USE_TLS) )
852 { 854 {
853 gnutls_record_uncork (connection->tls_session, 0); 855 gnutls_record_uncork (connection->tls_session, 0);
854 connection->sk_cork_on = false; 856 connection->sk_cork_on = false;
855 return MHD_YES; 857 return MHD_YES;
856 } 858 }
857 else 859 else
858#else 860#else
859 { 861 {
860 if (0 == 862 if (0 ==
861 MHD_socket_cork_ (connection->socket_fd, 863 MHD_socket_cork_ (connection->socket_fd,
862 false)) 864 false))
863 connection->sk_cork_on = false; 865 connection->sk_cork_on = false;
864 } 866 }
865#endif 867#endif
866 default: 868 default:
867 /* we don't understand this one */ 869 /* we don't understand this one */
868 return MHD_NO; 870 return MHD_NO;
869 } 871 }
870} 872}
871 873
@@ -897,13 +899,14 @@ MHD_response_execute_upgrade_ (struct MHD_Response *response,
897 if (NULL == 899 if (NULL ==
898 MHD_get_response_header (response, 900 MHD_get_response_header (response,
899 MHD_HTTP_HEADER_UPGRADE)) 901 MHD_HTTP_HEADER_UPGRADE))
900 { 902 {
901#ifdef HAVE_MESSAGES 903#ifdef HAVE_MESSAGES
902 MHD_DLOG (daemon, 904 MHD_DLOG (daemon,
903 _("Invalid response for upgrade: application failed to set the 'Upgrade' header!\n")); 905 _ (
906 "Invalid response for upgrade: application failed to set the 'Upgrade' header!\n"));
904#endif 907#endif
905 return MHD_NO; 908 return MHD_NO;
906 } 909 }
907 910
908 urh = MHD_calloc_ (1, sizeof (struct MHD_UpgradeResponseHandle)); 911 urh = MHD_calloc_ (1, sizeof (struct MHD_UpgradeResponseHandle));
909 if (NULL == urh) 912 if (NULL == urh)
@@ -918,77 +921,77 @@ MHD_response_execute_upgrade_ (struct MHD_Response *response,
918 size_t avail; 921 size_t avail;
919 char *buf; 922 char *buf;
920 MHD_socket sv[2]; 923 MHD_socket sv[2];
921#if defined(MHD_socket_nosignal_) || !defined(MHD_socket_pair_nblk_) 924#if defined(MHD_socket_nosignal_) || ! defined(MHD_socket_pair_nblk_)
922 int res1; 925 int res1;
923 int res2; 926 int res2;
924#endif /* MHD_socket_nosignal_ || !MHD_socket_pair_nblk_ */ 927#endif /* MHD_socket_nosignal_ || !MHD_socket_pair_nblk_ */
925 928
926#ifdef MHD_socket_pair_nblk_ 929#ifdef MHD_socket_pair_nblk_
927 if (! MHD_socket_pair_nblk_ (sv)) 930 if (! MHD_socket_pair_nblk_ (sv))
928 { 931 {
929 free (urh); 932 free (urh);
930 return MHD_NO; 933 return MHD_NO;
931 } 934 }
932#else /* !MHD_socket_pair_nblk_ */ 935#else /* !MHD_socket_pair_nblk_ */
933 if (! MHD_socket_pair_ (sv)) 936 if (! MHD_socket_pair_ (sv))
934 { 937 {
935 free (urh); 938 free (urh);
936 return MHD_NO; 939 return MHD_NO;
937 } 940 }
938 res1 = MHD_socket_nonblocking_(sv[0]); 941 res1 = MHD_socket_nonblocking_ (sv[0]);
939 res2 = MHD_socket_nonblocking_(sv[1]); 942 res2 = MHD_socket_nonblocking_ (sv[1]);
940 if ( (! res1) || (! res2) ) 943 if ( (! res1) || (! res2) )
941 { 944 {
942#ifdef HAVE_MESSAGES 945#ifdef HAVE_MESSAGES
943 MHD_DLOG (daemon, 946 MHD_DLOG (daemon,
944 _("Failed to make loopback sockets non-blocking.\n")); 947 _ ("Failed to make loopback sockets non-blocking.\n"));
945#endif 948#endif
946 if (! res2) 949 if (! res2)
947 { 950 {
948 /* Socketpair cannot be used. */ 951 /* Socketpair cannot be used. */
949 MHD_socket_close_chk_ (sv[0]); 952 MHD_socket_close_chk_ (sv[0]);
950 MHD_socket_close_chk_ (sv[1]); 953 MHD_socket_close_chk_ (sv[1]);
951 free (urh); 954 free (urh);
952 return MHD_NO; 955 return MHD_NO;
953 }
954 } 956 }
957 }
955#endif /* !MHD_socket_pair_nblk_ */ 958#endif /* !MHD_socket_pair_nblk_ */
956#ifdef MHD_socket_nosignal_ 959#ifdef MHD_socket_nosignal_
957 res1 = MHD_socket_nosignal_(sv[0]); 960 res1 = MHD_socket_nosignal_ (sv[0]);
958 res2 = MHD_socket_nosignal_(sv[1]); 961 res2 = MHD_socket_nosignal_ (sv[1]);
959 if ( (! res1) || (! res2) ) 962 if ( (! res1) || (! res2) )
960 { 963 {
961#ifdef HAVE_MESSAGES 964#ifdef HAVE_MESSAGES
962 MHD_DLOG (daemon, 965 MHD_DLOG (daemon,
963 _("Failed to set SO_NOSIGPIPE on loopback sockets.\n")); 966 _ ("Failed to set SO_NOSIGPIPE on loopback sockets.\n"));
964#endif 967#endif
965#ifndef MSG_NOSIGNAL 968#ifndef MSG_NOSIGNAL
966 if (!res2) 969 if (! res2)
967 { 970 {
968 /* Socketpair cannot be used. */ 971 /* Socketpair cannot be used. */
969 MHD_socket_close_chk_ (sv[0]); 972 MHD_socket_close_chk_ (sv[0]);
970 MHD_socket_close_chk_ (sv[1]); 973 MHD_socket_close_chk_ (sv[1]);
971 free (urh); 974 free (urh);
972 return MHD_NO; 975 return MHD_NO;
973 }
974#endif /* ! MSG_NOSIGNAL */
975 } 976 }
977#endif /* ! MSG_NOSIGNAL */
978 }
976#endif /* MHD_socket_nosignal_ */ 979#endif /* MHD_socket_nosignal_ */
977 if ( (! MHD_SCKT_FD_FITS_FDSET_ (sv[1], 980 if ( (! MHD_SCKT_FD_FITS_FDSET_ (sv[1],
978 NULL)) && 981 NULL)) &&
979 (0 == (daemon->options & (MHD_USE_POLL | MHD_USE_EPOLL))) ) 982 (0 == (daemon->options & (MHD_USE_POLL | MHD_USE_EPOLL))) )
980 { 983 {
981#ifdef HAVE_MESSAGES 984#ifdef HAVE_MESSAGES
982 MHD_DLOG (daemon, 985 MHD_DLOG (daemon,
983 _("Socketpair descriptor larger than FD_SETSIZE: %d > %d\n"), 986 _ ("Socketpair descriptor larger than FD_SETSIZE: %d > %d\n"),
984 (int) sv[1], 987 (int) sv[1],
985 (int) FD_SETSIZE); 988 (int) FD_SETSIZE);
986#endif 989#endif
987 MHD_socket_close_chk_ (sv[0]); 990 MHD_socket_close_chk_ (sv[0]);
988 MHD_socket_close_chk_ (sv[1]); 991 MHD_socket_close_chk_ (sv[1]);
989 free (urh); 992 free (urh);
990 return MHD_NO; 993 return MHD_NO;
991 } 994 }
992 urh->app.socket = sv[0]; 995 urh->app.socket = sv[0];
993 urh->app.urh = urh; 996 urh->app.urh = urh;
994 urh->app.celi = MHD_EPOLL_STATE_UNREADY; 997 urh->app.celi = MHD_EPOLL_STATE_UNREADY;
@@ -998,22 +1001,22 @@ MHD_response_execute_upgrade_ (struct MHD_Response *response,
998 pool = connection->pool; 1001 pool = connection->pool;
999 avail = MHD_pool_get_free (pool); 1002 avail = MHD_pool_get_free (pool);
1000 if (avail < RESERVE_EBUF_SIZE) 1003 if (avail < RESERVE_EBUF_SIZE)
1001 { 1004 {
1002 /* connection's pool is totally at the limit, 1005 /* connection's pool is totally at the limit,
1003 use our 'emergency' buffer of #RESERVE_EBUF_SIZE bytes. */ 1006 use our 'emergency' buffer of #RESERVE_EBUF_SIZE bytes. */
1004 avail = RESERVE_EBUF_SIZE; 1007 avail = RESERVE_EBUF_SIZE;
1005 buf = urh->e_buf; 1008 buf = urh->e_buf;
1006 } 1009 }
1007 else 1010 else
1008 { 1011 {
1009 /* Normal case: grab all remaining memory from the 1012 /* Normal case: grab all remaining memory from the
1010 connection's pool for the IO buffers; the connection 1013 connection's pool for the IO buffers; the connection
1011 certainly won't need it anymore as we've upgraded 1014 certainly won't need it anymore as we've upgraded
1012 to another protocol. */ 1015 to another protocol. */
1013 buf = MHD_pool_allocate (pool, 1016 buf = MHD_pool_allocate (pool,
1014 avail, 1017 avail,
1015 false); 1018 false);
1016 } 1019 }
1017 /* use half the buffer for inbound, half for outbound */ 1020 /* use half the buffer for inbound, half for outbound */
1018 urh->in_buffer_size = avail / 2; 1021 urh->in_buffer_size = avail / 2;
1019 urh->out_buffer_size = avail - urh->in_buffer_size; 1022 urh->out_buffer_size = avail - urh->in_buffer_size;
@@ -1022,81 +1025,81 @@ MHD_response_execute_upgrade_ (struct MHD_Response *response,
1022#ifdef EPOLL_SUPPORT 1025#ifdef EPOLL_SUPPORT
1023 /* Launch IO processing by the event loop */ 1026 /* Launch IO processing by the event loop */
1024 if (0 != (daemon->options & MHD_USE_EPOLL)) 1027 if (0 != (daemon->options & MHD_USE_EPOLL))
1028 {
1029 /* We're running with epoll(), need to add the sockets
1030 to the event set of the daemon's `epoll_upgrade_fd` */
1031 struct epoll_event event;
1032
1033 mhd_assert (-1 != daemon->epoll_upgrade_fd);
1034 /* First, add network socket */
1035 event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
1036 event.data.ptr = &urh->app;
1037 if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
1038 EPOLL_CTL_ADD,
1039 connection->socket_fd,
1040 &event))
1025 { 1041 {
1026 /* We're running with epoll(), need to add the sockets 1042#ifdef HAVE_MESSAGES
1027 to the event set of the daemon's `epoll_upgrade_fd` */ 1043 MHD_DLOG (daemon,
1028 struct epoll_event event; 1044 _ ("Call to epoll_ctl failed: %s\n"),
1045 MHD_socket_last_strerr_ ());
1046#endif
1047 MHD_socket_close_chk_ (sv[0]);
1048 MHD_socket_close_chk_ (sv[1]);
1049 free (urh);
1050 return MHD_NO;
1051 }
1029 1052
1030 mhd_assert (-1 != daemon->epoll_upgrade_fd); 1053 /* Second, add our end of the UNIX socketpair() */
1031 /* First, add network socket */ 1054 event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
1032 event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET; 1055 event.data.ptr = &urh->mhd;
1056 if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
1057 EPOLL_CTL_ADD,
1058 urh->mhd.socket,
1059 &event))
1060 {
1061 event.events = EPOLLIN | EPOLLOUT | EPOLLPRI;
1033 event.data.ptr = &urh->app; 1062 event.data.ptr = &urh->app;
1034 if (0 != epoll_ctl (daemon->epoll_upgrade_fd, 1063 if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
1035 EPOLL_CTL_ADD, 1064 EPOLL_CTL_DEL,
1036 connection->socket_fd, 1065 connection->socket_fd,
1037 &event)) 1066 &event))
1038 { 1067 MHD_PANIC (_ ("Error cleaning up while handling epoll error"));
1039#ifdef HAVE_MESSAGES 1068#ifdef HAVE_MESSAGES
1040 MHD_DLOG (daemon, 1069 MHD_DLOG (daemon,
1041 _("Call to epoll_ctl failed: %s\n"), 1070 _ ("Call to epoll_ctl failed: %s\n"),
1042 MHD_socket_last_strerr_ ()); 1071 MHD_socket_last_strerr_ ());
1043#endif
1044 MHD_socket_close_chk_ (sv[0]);
1045 MHD_socket_close_chk_ (sv[1]);
1046 free (urh);
1047 return MHD_NO;
1048 }
1049
1050 /* Second, add our end of the UNIX socketpair() */
1051 event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
1052 event.data.ptr = &urh->mhd;
1053 if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
1054 EPOLL_CTL_ADD,
1055 urh->mhd.socket,
1056 &event))
1057 {
1058 event.events = EPOLLIN | EPOLLOUT | EPOLLPRI;
1059 event.data.ptr = &urh->app;
1060 if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
1061 EPOLL_CTL_DEL,
1062 connection->socket_fd,
1063 &event))
1064 MHD_PANIC (_("Error cleaning up while handling epoll error"));
1065#ifdef HAVE_MESSAGES
1066 MHD_DLOG (daemon,
1067 _("Call to epoll_ctl failed: %s\n"),
1068 MHD_socket_last_strerr_ ());
1069#endif 1072#endif
1070 MHD_socket_close_chk_ (sv[0]); 1073 MHD_socket_close_chk_ (sv[0]);
1071 MHD_socket_close_chk_ (sv[1]); 1074 MHD_socket_close_chk_ (sv[1]);
1072 free (urh); 1075 free (urh);
1073 return MHD_NO; 1076 return MHD_NO;
1074 }
1075 EDLL_insert (daemon->eready_urh_head,
1076 daemon->eready_urh_tail,
1077 urh);
1078 urh->in_eready_list = true;
1079 } 1077 }
1078 EDLL_insert (daemon->eready_urh_head,
1079 daemon->eready_urh_tail,
1080 urh);
1081 urh->in_eready_list = true;
1082 }
1080#endif /* EPOLL_SUPPORT */ 1083#endif /* EPOLL_SUPPORT */
1081 if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION) ) 1084 if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION) )
1082 { 1085 {
1083 /* This takes care of further processing for most event loops: 1086 /* This takes care of further processing for most event loops:
1084 simply add to DLL for bi-direcitonal processing */ 1087 simply add to DLL for bi-direcitonal processing */
1085 DLL_insert (daemon->urh_head, 1088 DLL_insert (daemon->urh_head,
1086 daemon->urh_tail, 1089 daemon->urh_tail,
1087 urh); 1090 urh);
1088 } 1091 }
1089 /* In thread-per-connection mode, thread will switch to forwarding once 1092 /* In thread-per-connection mode, thread will switch to forwarding once
1090 * connection.urh is not NULL and connection.state == MHD_CONNECTION_UPGRADE. 1093 * connection.urh is not NULL and connection.state == MHD_CONNECTION_UPGRADE.
1091 */ 1094 */
1092 } 1095 }
1093 else 1096 else
1094 { 1097 {
1095 urh->app.socket = MHD_INVALID_SOCKET; 1098 urh->app.socket = MHD_INVALID_SOCKET;
1096 urh->mhd.socket = MHD_INVALID_SOCKET; 1099 urh->mhd.socket = MHD_INVALID_SOCKET;
1097 /* Non-TLS connection do not hold any additional resources. */ 1100 /* Non-TLS connection do not hold any additional resources. */
1098 urh->clean_ready = true; 1101 urh->clean_ready = true;
1099 } 1102 }
1100#else /* ! HTTPS_SUPPORT */ 1103#else /* ! HTTPS_SUPPORT */
1101 urh->clean_ready = true; 1104 urh->clean_ready = true;
1102#endif /* ! HTTPS_SUPPORT */ 1105#endif /* ! HTTPS_SUPPORT */
@@ -1154,7 +1157,7 @@ MHD_response_execute_upgrade_ (struct MHD_Response *response,
1154 */ 1157 */
1155_MHD_EXTERN struct MHD_Response * 1158_MHD_EXTERN struct MHD_Response *
1156MHD_create_response_for_upgrade (MHD_UpgradeHandler upgrade_handler, 1159MHD_create_response_for_upgrade (MHD_UpgradeHandler upgrade_handler,
1157 void *upgrade_handler_cls) 1160 void *upgrade_handler_cls)
1158{ 1161{
1159 struct MHD_Response *response; 1162 struct MHD_Response *response;
1160 1163
@@ -1165,10 +1168,10 @@ MHD_create_response_for_upgrade (MHD_UpgradeHandler upgrade_handler,
1165 return NULL; 1168 return NULL;
1166#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 1169#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1167 if (! MHD_mutex_init_ (&response->mutex)) 1170 if (! MHD_mutex_init_ (&response->mutex))
1168 { 1171 {
1169 free (response); 1172 free (response);
1170 return NULL; 1173 return NULL;
1171 } 1174 }
1172#endif 1175#endif
1173 response->upgrade_handler = upgrade_handler; 1176 response->upgrade_handler = upgrade_handler;
1174 response->upgrade_handler_cls = upgrade_handler_cls; 1177 response->upgrade_handler_cls = upgrade_handler_cls;
@@ -1178,10 +1181,10 @@ MHD_create_response_for_upgrade (MHD_UpgradeHandler upgrade_handler,
1178 MHD_add_response_header (response, 1181 MHD_add_response_header (response,
1179 MHD_HTTP_HEADER_CONNECTION, 1182 MHD_HTTP_HEADER_CONNECTION,
1180 "Upgrade")) 1183 "Upgrade"))
1181 { 1184 {
1182 MHD_destroy_response (response); 1185 MHD_destroy_response (response);
1183 return NULL; 1186 return NULL;
1184 } 1187 }
1185 return response; 1188 return response;
1186} 1189}
1187#endif /* UPGRADE_SUPPORT */ 1190#endif /* UPGRADE_SUPPORT */
@@ -1207,12 +1210,12 @@ MHD_destroy_response (struct MHD_Response *response)
1207 MHD_mutex_lock_chk_ (&response->mutex); 1210 MHD_mutex_lock_chk_ (&response->mutex);
1208#endif 1211#endif
1209 if (0 != --(response->reference_count)) 1212 if (0 != --(response->reference_count))
1210 { 1213 {
1211#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 1214#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1212 MHD_mutex_unlock_chk_ (&response->mutex); 1215 MHD_mutex_unlock_chk_ (&response->mutex);
1213#endif 1216#endif
1214 return; 1217 return;
1215 } 1218 }
1216#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 1219#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1217 MHD_mutex_unlock_chk_ (&response->mutex); 1220 MHD_mutex_unlock_chk_ (&response->mutex);
1218 MHD_mutex_destroy_chk_ (&response->mutex); 1221 MHD_mutex_destroy_chk_ (&response->mutex);
@@ -1220,13 +1223,13 @@ MHD_destroy_response (struct MHD_Response *response)
1220 if (NULL != response->crfc) 1223 if (NULL != response->crfc)
1221 response->crfc (response->crc_cls); 1224 response->crfc (response->crc_cls);
1222 while (NULL != response->first_header) 1225 while (NULL != response->first_header)
1223 { 1226 {
1224 pos = response->first_header; 1227 pos = response->first_header;
1225 response->first_header = pos->next; 1228 response->first_header = pos->next;
1226 free (pos->header); 1229 free (pos->header);
1227 free (pos->value); 1230 free (pos->value);
1228 free (pos); 1231 free (pos);
1229 } 1232 }
1230 free (response); 1233 free (response);
1231} 1234}
1232 1235