diff options
Diffstat (limited to 'src/microhttpd/response.c')
-rw-r--r-- | src/microhttpd/response.c | 611 |
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 * |
756 | MHD_create_response_from_buffer_with_free_callback (size_t size, | 757 | MHD_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 * |
1156 | MHD_create_response_for_upgrade (MHD_UpgradeHandler upgrade_handler, | 1159 | MHD_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 | ||