GNU libmicrohttpd  0.9.73
response.c
Go to the documentation of this file.
1 /*
2  This file is part of libmicrohttpd
3  Copyright (C) 2007-2021 Daniel Pittman and Christian Grothoff
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Lesser General Public
7  License as published by the Free Software Foundation; either
8  version 2.1 of the License, or (at your option) any later version.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public
16  License along with this library; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
27 #define MHD_NO_DEPRECATION 1
28 
29 #include "mhd_options.h"
30 #ifdef HAVE_SYS_IOCTL_H
31 #include <sys/ioctl.h>
32 #endif /* HAVE_SYS_IOCTL_H */
33 #if defined(_WIN32) && ! defined(__CYGWIN__)
34 #include <windows.h>
35 #endif /* _WIN32 && !__CYGWIN__ */
36 
37 #include "internal.h"
38 #include "response.h"
39 #include "mhd_limits.h"
40 #include "mhd_sockets.h"
41 #include "mhd_itc.h"
42 #include "mhd_str.h"
43 #include "connection.h"
44 #include "memorypool.h"
45 #include "mhd_send.h"
46 #include "mhd_compat.h"
47 
48 
49 #if defined(MHD_W32_MUTEX_)
50 #ifndef WIN32_LEAN_AND_MEAN
51 #define WIN32_LEAN_AND_MEAN 1
52 #endif /* !WIN32_LEAN_AND_MEAN */
53 #include <windows.h>
54 #endif /* MHD_W32_MUTEX_ */
55 #if defined(_WIN32)
56 #include <io.h> /* for lseek(), read() */
57 #endif /* _WIN32 */
58 
59 
64 #ifndef MHD_FILE_READ_BLOCK_SIZE
65 #ifdef _WIN32
66 #define MHD_FILE_READ_BLOCK_SIZE 16384 /* 16k */
67 #else /* _WIN32 */
68 #define MHD_FILE_READ_BLOCK_SIZE 4096 /* 4k */
69 #endif /* _WIN32 */
70 #endif /* !MHD_FD_BLOCK_SIZE */
71 
72 
82 static enum MHD_Result
83 add_response_entry (struct MHD_Response *response,
84  enum MHD_ValueKind kind,
85  const char *header,
86  const char *content)
87 {
88  struct MHD_HTTP_Header *hdr;
89 
90  if ( (NULL == response) ||
91  (NULL == header) ||
92  (NULL == content) ||
93  (0 == header[0]) ||
94  (0 == content[0]) ||
95  (NULL != strchr (header, '\t')) ||
96  (NULL != strchr (header, '\r')) ||
97  (NULL != strchr (header, '\n')) ||
98  (NULL != strchr (content, '\t')) ||
99  (NULL != strchr (content, '\r')) ||
100  (NULL != strchr (content, '\n')) )
101  return MHD_NO;
102  if (NULL == (hdr = malloc (sizeof (struct MHD_HTTP_Header))))
103  return MHD_NO;
104  if (NULL == (hdr->header = strdup (header)))
105  {
106  free (hdr);
107  return MHD_NO;
108  }
109  hdr->header_size = strlen (header);
110  if (NULL == (hdr->value = strdup (content)))
111  {
112  free (hdr->header);
113  free (hdr);
114  return MHD_NO;
115  }
116  hdr->value_size = strlen (content);
117  hdr->kind = kind;
118  hdr->next = response->first_header;
119  response->first_header = hdr;
120  return MHD_YES;
121 }
122 
123 
133 enum MHD_Result
134 MHD_add_response_header (struct MHD_Response *response,
135  const char *header,
136  const char *content)
137 {
140  (! MHD_str_equal_caseless_ (content,
141  "identity")) &&
142  (! MHD_str_equal_caseless_ (content,
143  "chunked")) )
144  {
145  /* Setting transfer encodings other than "identity" or
146  "chunked" is not allowed. Note that MHD will set the
147  correct transfer encoding if required automatically. */
148  /* NOTE: for compressed bodies, use the "Content-encoding" header */
149  return MHD_NO;
150  }
152  & response->flags)) &&
155  {
156  /* MHD will set Content-length if allowed and possible,
157  reject attempt by application */
158  return MHD_NO;
159  }
160 
161  return add_response_entry (response,
163  header,
164  content);
165 }
166 
167 
177 enum MHD_Result
178 MHD_add_response_footer (struct MHD_Response *response,
179  const char *footer,
180  const char *content)
181 {
182  return add_response_entry (response,
184  footer,
185  content);
186 }
187 
188 
198 enum MHD_Result
199 MHD_del_response_header (struct MHD_Response *response,
200  const char *header,
201  const char *content)
202 {
203  struct MHD_HTTP_Header *pos;
204  struct MHD_HTTP_Header *prev;
205  size_t header_len;
206  size_t content_len;
207 
208  if ( (NULL == header) ||
209  (NULL == content) )
210  return MHD_NO;
211  header_len = strlen (header);
212  content_len = strlen (content);
213  prev = NULL;
214  pos = response->first_header;
215  while (NULL != pos)
216  {
217  if ((header_len == pos->header_size) &&
218  (content_len == pos->value_size) &&
219  (0 == memcmp (header,
220  pos->header,
221  header_len)) &&
222  (0 == memcmp (content,
223  pos->value,
224  content_len)))
225  {
226  free (pos->header);
227  free (pos->value);
228  if (NULL == prev)
229  response->first_header = pos->next;
230  else
231  prev->next = pos->next;
232  free (pos);
233  return MHD_YES;
234  }
235  prev = pos;
236  pos = pos->next;
237  }
238  return MHD_NO;
239 }
240 
241 
252 int
254  MHD_KeyValueIterator iterator,
255  void *iterator_cls)
256 {
257  int numHeaders = 0;
258  struct MHD_HTTP_Header *pos;
259 
260  for (pos = response->first_header;
261  NULL != pos;
262  pos = pos->next)
263  {
264  numHeaders++;
265  if ((NULL != iterator) &&
266  (MHD_NO == iterator (iterator_cls,
267  pos->kind,
268  pos->header,
269  pos->value)))
270  break;
271  }
272  return numHeaders;
273 }
274 
275 
284 const char *
286  const char *key)
287 {
288  struct MHD_HTTP_Header *pos;
289  size_t key_size;
290 
291  if (NULL == key)
292  return NULL;
293 
294  key_size = strlen (key);
295  for (pos = response->first_header;
296  NULL != pos;
297  pos = pos->next)
298  {
299  if ((pos->header_size == key_size) &&
301  return pos->value;
302  }
303  return NULL;
304 }
305 
306 
323 bool
325  const char *key,
326  size_t key_len,
327  const char *token,
328  size_t token_len)
329 {
330  struct MHD_HTTP_Header *pos;
331 
332  if ( (NULL == key) ||
333  ('\0' == key[0]) ||
334  (NULL == token) ||
335  ('\0' == token[0]) )
336  return false;
337 
338  /* Token must not contain binary zero! */
339  mhd_assert (strlen (token) == token_len);
340 
341  for (pos = response->first_header;
342  NULL != pos;
343  pos = pos->next)
344  {
345  if ( (pos->kind == MHD_HEADER_KIND) &&
346  (key_len == pos->header_size) &&
348  key,
349  key_len) &&
351  token,
352  token_len) )
353  return true;
354  }
355  return false;
356 }
357 
358 
375 struct MHD_Response *
377  size_t block_size,
379  void *crc_cls,
381 {
382  struct MHD_Response *response;
383 
384  if ((NULL == crc) || (0 == block_size))
385  return NULL;
386  if (NULL == (response = MHD_calloc_ (1, sizeof (struct MHD_Response)
387  + block_size)))
388  return NULL;
389  response->fd = -1;
390  response->data = (void *) &response[1];
391  response->data_buffer_size = block_size;
392 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
393  if (! MHD_mutex_init_ (&response->mutex))
394  {
395  free (response);
396  return NULL;
397  }
398 #endif
399  response->crc = crc;
400  response->crfc = crfc;
401  response->crc_cls = crc_cls;
402  response->reference_count = 1;
403  response->total_size = size;
404  return response;
405 }
406 
407 
416 enum MHD_Result
417 MHD_set_response_options (struct MHD_Response *response,
419  ...)
420 {
421  va_list ap;
422  enum MHD_Result ret;
423  enum MHD_ResponseOptions ro;
424 
425  ret = MHD_YES;
426  response->flags = flags;
427  va_start (ap, flags);
428  while (MHD_RO_END != (ro = va_arg (ap, enum MHD_ResponseOptions)))
429  {
430  switch (ro)
431  {
432  default:
433  ret = MHD_NO;
434  break;
435  }
436  }
437  va_end (ap);
438  return ret;
439 }
440 
441 
452 static ssize_t
453 file_reader (void *cls,
454  uint64_t pos,
455  char *buf,
456  size_t max)
457 {
458  struct MHD_Response *response = cls;
459 #if ! defined(_WIN32) || defined(__CYGWIN__)
460  ssize_t n;
461 #else /* _WIN32 && !__CYGWIN__ */
462  const HANDLE fh = (HANDLE) _get_osfhandle (response->fd);
463 #endif /* _WIN32 && !__CYGWIN__ */
464  const int64_t offset64 = (int64_t) (pos + response->fd_off);
465 
466  if (offset64 < 0)
467  return MHD_CONTENT_READER_END_WITH_ERROR; /* seek to required position is not possible */
468 
469 #if ! defined(_WIN32) || defined(__CYGWIN__)
470  if (max > SSIZE_MAX)
471  max = SSIZE_MAX; /* Clamp to maximum return value. */
472 
473 #if defined(HAVE_PREAD64)
474  n = pread64 (response->fd, buf, max, offset64);
475 #elif defined(HAVE_PREAD)
476  if ( (sizeof(off_t) < sizeof (uint64_t)) &&
477  (offset64 > (uint64_t) INT32_MAX) )
478  return MHD_CONTENT_READER_END_WITH_ERROR; /* Read at required position is not possible. */
479 
480  n = pread (response->fd, buf, max, (off_t) offset64);
481 #else /* ! HAVE_PREAD */
482 #if defined(HAVE_LSEEK64)
483  if (lseek64 (response->fd,
484  offset64,
485  SEEK_SET) != offset64)
486  return MHD_CONTENT_READER_END_WITH_ERROR; /* can't seek to required position */
487 #else /* ! HAVE_LSEEK64 */
488  if ( (sizeof(off_t) < sizeof (uint64_t)) &&
489  (offset64 > (uint64_t) INT32_MAX) )
490  return MHD_CONTENT_READER_END_WITH_ERROR; /* seek to required position is not possible */
491 
492  if (lseek (response->fd,
493  (off_t) offset64,
494  SEEK_SET) != (off_t) offset64)
495  return MHD_CONTENT_READER_END_WITH_ERROR; /* can't seek to required position */
496 #endif /* ! HAVE_LSEEK64 */
497  n = read (response->fd,
498  buf,
499  max);
500 
501 #endif /* ! HAVE_PREAD */
502  if (0 == n)
504  if (n < 0)
506  return n;
507 #else /* _WIN32 && !__CYGWIN__ */
508  if (INVALID_HANDLE_VALUE == fh)
509  return MHD_CONTENT_READER_END_WITH_ERROR; /* Value of 'response->fd' is not valid. */
510  else
511  {
512  OVERLAPPED f_ol = {0, 0, {{0, 0}}, 0}; /* Initialize to zero. */
513  ULARGE_INTEGER pos_uli;
514  DWORD toRead = (max > INT32_MAX) ? INT32_MAX : (DWORD) max;
515  DWORD resRead;
516 
517  pos_uli.QuadPart = (uint64_t) offset64; /* Simple transformation 64bit -> 2x32bit. */
518  f_ol.Offset = pos_uli.LowPart;
519  f_ol.OffsetHigh = pos_uli.HighPart;
520  if (! ReadFile (fh, (void*) buf, toRead, &resRead, &f_ol))
521  return MHD_CONTENT_READER_END_WITH_ERROR; /* Read error. */
522  if (0 == resRead)
524  return (ssize_t) resRead;
525  }
526 #endif /* _WIN32 && !__CYGWIN__ */
527 }
528 
529 
540 static ssize_t
541 pipe_reader (void *cls,
542  uint64_t pos,
543  char *buf,
544  size_t max)
545 {
546  struct MHD_Response *response = cls;
547  ssize_t n;
548 
549  (void) pos;
550 #ifndef _WIN32
551  if (SSIZE_MAX < max)
552  max = SSIZE_MAX;
553 #else /* _WIN32 */
554  if (UINT_MAX < max)
555  max = UINT_MAX;
556 #endif /* _WIN32 */
557 
558  n = read (response->fd,
559  buf,
560  (MHD_SCKT_SEND_SIZE_) max);
561  if (0 == n)
563  if (n < 0)
565  return n;
566 }
567 
568 
575 static void
576 free_callback (void *cls)
577 {
578  struct MHD_Response *response = cls;
579 
580  (void) close (response->fd);
581  response->fd = -1;
582 }
583 
584 
585 #undef MHD_create_response_from_fd_at_offset
586 
603 struct MHD_Response *
605  int fd,
606  off_t offset)
607 {
609  fd,
610  offset);
611 }
612 
613 
630 _MHD_EXTERN struct MHD_Response *
632  int fd,
633  uint64_t offset)
634 {
635  struct MHD_Response *response;
636 
637 #if ! defined(HAVE___LSEEKI64) && ! defined(HAVE_LSEEK64)
638  if ( (sizeof(uint64_t) > sizeof(off_t)) &&
639  ( (size > (uint64_t) INT32_MAX) ||
640  (offset > (uint64_t) INT32_MAX) ||
641  ((size + offset) >= (uint64_t) INT32_MAX) ) )
642  return NULL;
643 #endif
644  if ( ((int64_t) size < 0) ||
645  ((int64_t) offset < 0) ||
646  ((int64_t) (size + offset) < 0) )
647  return NULL;
648 
649  response = MHD_create_response_from_callback (size,
651  &file_reader,
652  NULL,
653  &free_callback);
654  if (NULL == response)
655  return NULL;
656  response->fd = fd;
657  response->is_pipe = false;
658  response->fd_off = offset;
659  response->crc_cls = response;
660  return response;
661 }
662 
663 
674 _MHD_EXTERN struct MHD_Response *
676 {
677  struct MHD_Response *response;
678 
681  &pipe_reader,
682  NULL,
683  &free_callback);
684  if (NULL == response)
685  return NULL;
686  response->fd = fd;
687  response->is_pipe = true;
688  response->crc_cls = response;
689  return response;
690 }
691 
692 
702 struct MHD_Response *
704  int fd)
705 {
707  fd,
708  0);
709 }
710 
711 
725 _MHD_EXTERN struct MHD_Response *
727  int fd)
728 {
730  fd,
731  0);
732 }
733 
734 
749 struct MHD_Response *
751  void *data,
752  int must_free,
753  int must_copy)
754 {
755  struct MHD_Response *response;
756  void *tmp;
757 
758  if ((NULL == data) && (size > 0))
759  return NULL;
760  if (NULL == (response = MHD_calloc_ (1, sizeof (struct MHD_Response))))
761  return NULL;
762  response->fd = -1;
763 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
764  if (! MHD_mutex_init_ (&response->mutex))
765  {
766  free (response);
767  return NULL;
768  }
769 #endif
770  if ((must_copy) && (size > 0))
771  {
772  if (NULL == (tmp = malloc (size)))
773  {
774 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
775  MHD_mutex_destroy_chk_ (&response->mutex);
776 #endif
777  free (response);
778  return NULL;
779  }
780  memcpy (tmp, data, size);
781  must_free = MHD_YES;
782  data = tmp;
783  }
784  if (must_free)
785  {
786  response->crfc = &free;
787  response->crc_cls = data;
788  }
789  response->reference_count = 1;
790  response->total_size = size;
791  response->data = data;
792  response->data_size = size;
793  if (must_copy)
794  response->data_buffer_size = size;
795  return response;
796 }
797 
798 
809 struct MHD_Response *
811  void *buffer,
812  enum MHD_ResponseMemoryMode mode)
813 {
814  return MHD_create_response_from_data (size,
815  buffer,
816  mode == MHD_RESPMEM_MUST_FREE,
817  mode == MHD_RESPMEM_MUST_COPY);
818 }
819 
820 
831 _MHD_EXTERN struct MHD_Response *
833  void *buffer,
835  crfc)
836 {
837  struct MHD_Response *r;
838 
840  buffer,
841  MHD_YES,
842  MHD_NO);
843  if (NULL == r)
844  return r;
845  r->crfc = crfc;
846  return r;
847 }
848 
849 
863 _MHD_EXTERN struct MHD_Response *
865  unsigned int iovcnt,
867  void *cls)
868 {
869  struct MHD_Response *response;
870  unsigned int i;
871  int i_cp = 0;
872  uint64_t total_size = 0;
873  const void *last_valid_buffer = NULL;
874 
875  if ((NULL == iov) && (0 < iovcnt))
876  return NULL;
877 
878  response = MHD_calloc_ (1, sizeof (struct MHD_Response));
879  if (NULL == response)
880  return NULL;
881  if (! MHD_mutex_init_ (&response->mutex))
882  {
883  free (response);
884  return NULL;
885  }
886  /* Calculate final size, number of valid elements, and check 'iov' */
887  for (i = 0; i < iovcnt; ++i)
888  {
889  if (0 == iov[i].iov_len)
890  continue; /* skip zero-sized elements */
891  if (NULL == iov[i].iov_base)
892  {
893  i_cp = -1; /* error */
894  break;
895  }
896  if ( (total_size > (total_size + iov[i].iov_len)) ||
897  (INT_MAX == i_cp) ||
898  (SSIZE_MAX < (total_size + iov[i].iov_len)) )
899  {
900  i_cp = -1; /* overflow */
901  break;
902  }
903  last_valid_buffer = iov[i].iov_base;
904  total_size += iov[i].iov_len;
905 #if defined(MHD_POSIX_SOCKETS) || ! defined(_WIN64)
906  i_cp++;
907 #else /* ! MHD_POSIX_SOCKETS && _WIN64 */
908  {
909  int64_t i_add;
910 
911  i_add = iov[i].iov_len / ULONG_MAX;
912  if (0 != iov[i].iov_len % ULONG_MAX)
913  i_add++;
914  if (INT_MAX < (i_add + i_cp))
915  {
916  i_cp = -1; /* overflow */
917  break;
918  }
919  i_cp += (int) i_add;
920  }
921 #endif /* ! MHD_POSIX_SOCKETS && _WIN64 */
922  }
923  if (-1 == i_cp)
924  {
925  /* Some error condition */
926  MHD_mutex_destroy_chk_ (&response->mutex);
927  free (response);
928  return NULL;
929  }
930  response->fd = -1;
931  response->reference_count = 1;
932  response->total_size = total_size;
933  response->crc_cls = cls;
934  response->crfc = free_cb;
935  if (0 == i_cp)
936  {
937  mhd_assert (0 == total_size);
938  return response;
939  }
940  if (1 == i_cp)
941  {
942  mhd_assert (NULL != last_valid_buffer);
943  response->data = (void *) last_valid_buffer;
944  response->data_size = (size_t) total_size;
945  return response;
946  }
947  mhd_assert (1 < i_cp);
948  {
949  MHD_iovec_ *iov_copy;
950  int num_copy_elements = i_cp;
951 
952  iov_copy = MHD_calloc_ (num_copy_elements,
953  sizeof(MHD_iovec_));
954  if (NULL == iov_copy)
955  {
956  MHD_mutex_destroy_chk_ (&response->mutex);
957  free (response);
958  return NULL;
959  }
960  i_cp = 0;
961  for (i = 0; i < iovcnt; ++i)
962  {
963  size_t element_size = iov[i].iov_len;
964  const uint8_t *buf = (const uint8_t *) iov[i].iov_base;
965 
966  if (0 == element_size)
967  continue; /* skip zero-sized elements */
968 #if defined(MHD_WINSOCK_SOCKETS) && defined(_WIN64)
969  while (MHD_IOV_ELMN_MAX_SIZE < element_size)
970  {
971  iov_copy[i_cp].iov_base = (char *) buf;
972  iov_copy[i_cp].iov_len = ULONG_MAX;
973  buf += ULONG_MAX;
974  element_size -= ULONG_MAX;
975  i_cp++;
976  }
977 #endif /* MHD_WINSOCK_SOCKETS && _WIN64 */
978  iov_copy[i_cp].iov_base = (void *) buf;
979  iov_copy[i_cp].iov_len = (MHD_iov_size_) element_size;
980  i_cp++;
981  }
982  mhd_assert (num_copy_elements == i_cp);
983  response->data_iov = iov_copy;
984  response->data_iovcnt = i_cp;
985  return response;
986  }
987 }
988 
989 
990 #ifdef UPGRADE_SUPPORT
1004 MHD_upgrade_action (struct MHD_UpgradeResponseHandle *urh,
1006  ...)
1007 {
1008  struct MHD_Connection *connection;
1009  struct MHD_Daemon *daemon;
1010 
1011  if (NULL == urh)
1012  return MHD_NO;
1013  connection = urh->connection;
1014 
1015  /* Precaution checks on external data. */
1016  if (NULL == connection)
1017  return MHD_NO;
1018  daemon = connection->daemon;
1019  if (NULL == daemon)
1020  return MHD_NO;
1021 
1022  switch (action)
1023  {
1025  if (urh->was_closed)
1026  return MHD_NO; /* Already closed. */
1027 
1028  /* transition to special 'closed' state for start of cleanup */
1029 #ifdef HTTPS_SUPPORT
1030  if (0 != (daemon->options & MHD_USE_TLS) )
1031  {
1032  /* signal that app is done by shutdown() of 'app' socket */
1033  /* Application will not use anyway this socket after this command. */
1034  shutdown (urh->app.socket,
1035  SHUT_RDWR);
1036  }
1037 #endif /* HTTPS_SUPPORT */
1038  mhd_assert (MHD_CONNECTION_UPGRADE == connection->state);
1039  urh->was_closed = true;
1040  /* As soon as connection will be marked with BOTH
1041  * 'urh->was_closed' AND 'urh->clean_ready', it will
1042  * be moved to cleanup list by MHD_resume_connection(). */
1043  MHD_resume_connection (connection);
1044  return MHD_YES;
1046  /* Unportable API. TODO: replace with portable action. */
1047  return MHD_connection_set_cork_state_ (connection,
1048  true) ? MHD_YES : MHD_NO;
1050  /* Unportable API. TODO: replace with portable action. */
1051  return MHD_connection_set_cork_state_ (connection,
1052  false) ? MHD_YES : MHD_NO;
1053  default:
1054  /* we don't understand this one */
1055  return MHD_NO;
1056  }
1057 }
1058 
1059 
1073 enum MHD_Result
1075  struct MHD_Connection *connection)
1076 {
1077  struct MHD_Daemon *daemon = connection->daemon;
1078  struct MHD_UpgradeResponseHandle *urh;
1079  size_t rbo;
1080 
1081 #ifdef MHD_USE_THREADS
1082  mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
1083  MHD_thread_ID_match_current_ (connection->pid) );
1084 #endif /* MHD_USE_THREADS */
1085 
1086  if (0 == (daemon->options & MHD_ALLOW_UPGRADE))
1087  return MHD_NO;
1088 
1089  if (NULL ==
1090  MHD_get_response_header (response,
1092  {
1093 #ifdef HAVE_MESSAGES
1094  MHD_DLOG (daemon,
1095  _ (
1096  "Invalid response for upgrade: application failed to set the 'Upgrade' header!\n"));
1097 #endif
1098  return MHD_NO;
1099  }
1100 
1101  urh = MHD_calloc_ (1, sizeof (struct MHD_UpgradeResponseHandle));
1102  if (NULL == urh)
1103  return MHD_NO;
1104  urh->connection = connection;
1105  rbo = connection->read_buffer_offset;
1106  connection->read_buffer_offset = 0;
1107  MHD_connection_set_nodelay_state_ (connection, false);
1108  MHD_connection_set_cork_state_ (connection, false);
1109 #ifdef HTTPS_SUPPORT
1110  if (0 != (daemon->options & MHD_USE_TLS) )
1111  {
1112  struct MemoryPool *pool;
1113  size_t avail;
1114  char *buf;
1115  MHD_socket sv[2];
1116 #if defined(MHD_socket_nosignal_) || ! defined(MHD_socket_pair_nblk_)
1117  int res1;
1118  int res2;
1119 #endif /* MHD_socket_nosignal_ || !MHD_socket_pair_nblk_ */
1120 
1121 #ifdef MHD_socket_pair_nblk_
1122  if (! MHD_socket_pair_nblk_ (sv))
1123  {
1124  free (urh);
1125  return MHD_NO;
1126  }
1127 #else /* !MHD_socket_pair_nblk_ */
1128  if (! MHD_socket_pair_ (sv))
1129  {
1130  free (urh);
1131  return MHD_NO;
1132  }
1133  res1 = MHD_socket_nonblocking_ (sv[0]);
1134  res2 = MHD_socket_nonblocking_ (sv[1]);
1135  if ( (! res1) || (! res2) )
1136  {
1137 #ifdef HAVE_MESSAGES
1138  MHD_DLOG (daemon,
1139  _ ("Failed to make loopback sockets non-blocking.\n"));
1140 #endif
1141  if (! res2)
1142  {
1143  /* Socketpair cannot be used. */
1144  MHD_socket_close_chk_ (sv[0]);
1145  MHD_socket_close_chk_ (sv[1]);
1146  free (urh);
1147  return MHD_NO;
1148  }
1149  }
1150 #endif /* !MHD_socket_pair_nblk_ */
1151 #ifdef MHD_socket_nosignal_
1152  res1 = MHD_socket_nosignal_ (sv[0]);
1153  res2 = MHD_socket_nosignal_ (sv[1]);
1154  if ( (! res1) || (! res2) )
1155  {
1156 #ifdef HAVE_MESSAGES
1157  MHD_DLOG (daemon,
1158  _ ("Failed to set SO_NOSIGPIPE on loopback sockets.\n"));
1159 #endif
1160 #ifndef MSG_NOSIGNAL
1161  if (! res2)
1162  {
1163  /* Socketpair cannot be used. */
1164  MHD_socket_close_chk_ (sv[0]);
1165  MHD_socket_close_chk_ (sv[1]);
1166  free (urh);
1167  return MHD_NO;
1168  }
1169 #endif /* ! MSG_NOSIGNAL */
1170  }
1171 #endif /* MHD_socket_nosignal_ */
1172  if ( (! MHD_SCKT_FD_FITS_FDSET_ (sv[1],
1173  NULL)) &&
1174  (0 == (daemon->options & (MHD_USE_POLL | MHD_USE_EPOLL))) )
1175  {
1176 #ifdef HAVE_MESSAGES
1177  MHD_DLOG (daemon,
1178  _ ("Socketpair descriptor larger than FD_SETSIZE: %d > %d\n"),
1179  (int) sv[1],
1180  (int) FD_SETSIZE);
1181 #endif
1182  MHD_socket_close_chk_ (sv[0]);
1183  MHD_socket_close_chk_ (sv[1]);
1184  free (urh);
1185  return MHD_NO;
1186  }
1187  urh->app.socket = sv[0];
1188  urh->app.urh = urh;
1189  urh->app.celi = MHD_EPOLL_STATE_UNREADY;
1190  urh->mhd.socket = sv[1];
1191  urh->mhd.urh = urh;
1192  urh->mhd.celi = MHD_EPOLL_STATE_UNREADY;
1193  pool = connection->pool;
1194  avail = MHD_pool_get_free (pool);
1195  if (avail < RESERVE_EBUF_SIZE)
1196  {
1197  /* connection's pool is totally at the limit,
1198  use our 'emergency' buffer of #RESERVE_EBUF_SIZE bytes. */
1199  avail = RESERVE_EBUF_SIZE;
1200  buf = urh->e_buf;
1201  }
1202  else
1203  {
1204  /* Normal case: grab all remaining memory from the
1205  connection's pool for the IO buffers; the connection
1206  certainly won't need it anymore as we've upgraded
1207  to another protocol. */
1208  buf = MHD_pool_allocate (pool,
1209  avail,
1210  false);
1211  }
1212  /* use half the buffer for inbound, half for outbound */
1213  urh->in_buffer_size = avail / 2;
1214  urh->out_buffer_size = avail - urh->in_buffer_size;
1215  urh->in_buffer = buf;
1216  urh->out_buffer = &buf[urh->in_buffer_size];
1217 #ifdef EPOLL_SUPPORT
1218  /* Launch IO processing by the event loop */
1219  if (0 != (daemon->options & MHD_USE_EPOLL))
1220  {
1221  /* We're running with epoll(), need to add the sockets
1222  to the event set of the daemon's `epoll_upgrade_fd` */
1223  struct epoll_event event;
1224 
1225  mhd_assert (-1 != daemon->epoll_upgrade_fd);
1226  /* First, add network socket */
1227  event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
1228  event.data.ptr = &urh->app;
1229  if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
1230  EPOLL_CTL_ADD,
1231  connection->socket_fd,
1232  &event))
1233  {
1234 #ifdef HAVE_MESSAGES
1235  MHD_DLOG (daemon,
1236  _ ("Call to epoll_ctl failed: %s\n"),
1238 #endif
1239  MHD_socket_close_chk_ (sv[0]);
1240  MHD_socket_close_chk_ (sv[1]);
1241  free (urh);
1242  return MHD_NO;
1243  }
1244 
1245  /* Second, add our end of the UNIX socketpair() */
1246  event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
1247  event.data.ptr = &urh->mhd;
1248  if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
1249  EPOLL_CTL_ADD,
1250  urh->mhd.socket,
1251  &event))
1252  {
1253  event.events = EPOLLIN | EPOLLOUT | EPOLLPRI;
1254  event.data.ptr = &urh->app;
1255  if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
1256  EPOLL_CTL_DEL,
1257  connection->socket_fd,
1258  &event))
1259  MHD_PANIC (_ ("Error cleaning up while handling epoll error.\n"));
1260 #ifdef HAVE_MESSAGES
1261  MHD_DLOG (daemon,
1262  _ ("Call to epoll_ctl failed: %s\n"),
1264 #endif
1265  MHD_socket_close_chk_ (sv[0]);
1266  MHD_socket_close_chk_ (sv[1]);
1267  free (urh);
1268  return MHD_NO;
1269  }
1270  EDLL_insert (daemon->eready_urh_head,
1271  daemon->eready_urh_tail,
1272  urh);
1273  urh->in_eready_list = true;
1274  }
1275 #endif /* EPOLL_SUPPORT */
1276  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION) )
1277  {
1278  /* This takes care of further processing for most event loops:
1279  simply add to DLL for bi-direcitonal processing */
1280  DLL_insert (daemon->urh_head,
1281  daemon->urh_tail,
1282  urh);
1283  }
1284  /* In thread-per-connection mode, thread will switch to forwarding once
1285  * connection.urh is not NULL and connection.state == MHD_CONNECTION_UPGRADE.
1286  */
1287  }
1288  else
1289  {
1290  urh->app.socket = MHD_INVALID_SOCKET;
1291  urh->mhd.socket = MHD_INVALID_SOCKET;
1292  /* Non-TLS connection do not hold any additional resources. */
1293  urh->clean_ready = true;
1294  }
1295 #else /* ! HTTPS_SUPPORT */
1296  urh->clean_ready = true;
1297 #endif /* ! HTTPS_SUPPORT */
1298  connection->urh = urh;
1299  /* As far as MHD's event loops are concerned, this connection is
1300  suspended; it will be resumed once application is done by the
1301  #MHD_upgrade_action() function */
1302  internal_suspend_connection_ (connection);
1303 
1304  /* hand over socket to application */
1305  response->upgrade_handler (response->upgrade_handler_cls,
1306  connection,
1307  connection->client_context,
1308  connection->read_buffer,
1309  rbo,
1310 #ifdef HTTPS_SUPPORT
1311  (0 == (daemon->options & MHD_USE_TLS) ) ?
1312  connection->socket_fd : urh->app.socket,
1313 #else /* ! HTTPS_SUPPORT */
1314  connection->socket_fd,
1315 #endif /* ! HTTPS_SUPPORT */
1316  urh);
1317  return MHD_YES;
1318 }
1319 
1320 
1350 _MHD_EXTERN struct MHD_Response *
1352  void *upgrade_handler_cls)
1353 {
1354  struct MHD_Response *response;
1355 
1356  if (NULL == upgrade_handler)
1357  return NULL; /* invalid request */
1358  response = MHD_calloc_ (1, sizeof (struct MHD_Response));
1359  if (NULL == response)
1360  return NULL;
1361 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1362  if (! MHD_mutex_init_ (&response->mutex))
1363  {
1364  free (response);
1365  return NULL;
1366  }
1367 #endif
1368  response->upgrade_handler = upgrade_handler;
1369  response->upgrade_handler_cls = upgrade_handler_cls;
1370  response->total_size = MHD_SIZE_UNKNOWN;
1371  response->reference_count = 1;
1372  if (MHD_NO ==
1373  MHD_add_response_header (response,
1375  "Upgrade"))
1376  {
1377  MHD_destroy_response (response);
1378  return NULL;
1379  }
1380  return response;
1381 }
1382 
1383 
1384 #endif /* UPGRADE_SUPPORT */
1385 
1386 
1396 void
1398 {
1399  struct MHD_HTTP_Header *pos;
1400 
1401  if (NULL == response)
1402  return;
1403 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1404  MHD_mutex_lock_chk_ (&response->mutex);
1405 #endif
1406  if (0 != --(response->reference_count))
1407  {
1408 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1409  MHD_mutex_unlock_chk_ (&response->mutex);
1410 #endif
1411  return;
1412  }
1413 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1414  MHD_mutex_unlock_chk_ (&response->mutex);
1415  MHD_mutex_destroy_chk_ (&response->mutex);
1416 #endif
1417  if (NULL != response->crfc)
1418  response->crfc (response->crc_cls);
1419 
1420  if (NULL != response->data_iov)
1421  {
1422  free (response->data_iov);
1423  }
1424 
1425  while (NULL != response->first_header)
1426  {
1427  pos = response->first_header;
1428  response->first_header = pos->next;
1429  free (pos->header);
1430  free (pos->value);
1431  free (pos);
1432  }
1433  free (response);
1434 }
1435 
1436 
1442 void
1444 {
1445 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1446  MHD_mutex_lock_chk_ (&response->mutex);
1447 #endif
1448  (response->reference_count)++;
1449 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1450  MHD_mutex_unlock_chk_ (&response->mutex);
1451 #endif
1452 }
1453 
1454 
1455 /* end of response.c */
Methods for managing connections.
void internal_suspend_connection_(struct MHD_Connection *connection)
Definition: daemon.c:3038
#define MHD_HTTP_HEADER_CONTENT_LENGTH
Definition: microhttpd.h:572
#define MHD_HTTP_HEADER_CONNECTION
Definition: microhttpd.h:566
#define MHD_HTTP_HEADER_TRANSFER_ENCODING
Definition: microhttpd.h:628
#define MHD_HTTP_HEADER_UPGRADE
Definition: microhttpd.h:630
enum MHD_Result(* MHD_KeyValueIterator)(void *cls, enum MHD_ValueKind kind, const char *key, const char *value)
Definition: microhttpd.h:2298
_MHD_EXTERN enum MHD_Result MHD_del_response_header(struct MHD_Response *response, const char *header, const char *content)
Definition: response.c:199
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_iovec(const struct MHD_IoVec *iov, unsigned int iovcnt, MHD_ContentReaderFreeCallback free_cb, void *cls)
Definition: response.c:864
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_buffer_with_free_callback(size_t size, void *buffer, MHD_ContentReaderFreeCallback crfc)
Definition: response.c:832
_MHD_EXTERN enum MHD_Result MHD_add_response_footer(struct MHD_Response *response, const char *footer, const char *content)
Definition: response.c:178
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_fd(size_t size, int fd)
Definition: response.c:703
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_pipe(int fd)
Definition: response.c:675
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_buffer(size_t size, void *buffer, enum MHD_ResponseMemoryMode mode)
Definition: response.c:810
_MHD_EXTERN int MHD_get_response_headers(struct MHD_Response *response, MHD_KeyValueIterator iterator, void *iterator_cls)
Definition: response.c:253
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_callback(uint64_t size, size_t block_size, MHD_ContentReaderCallback crc, void *crc_cls, MHD_ContentReaderFreeCallback crfc)
Definition: response.c:376
struct MHD_Response * MHD_create_response_from_fd_at_offset(size_t size, int fd, off_t offset)
Definition: response.c:604
MHD_ResponseMemoryMode
Definition: microhttpd.h:3136
void(* MHD_ContentReaderFreeCallback)(void *cls)
Definition: microhttpd.h:2392
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_fd_at_offset64(uint64_t size, int fd, uint64_t offset)
Definition: response.c:631
_MHD_EXTERN void MHD_destroy_response(struct MHD_Response *response)
Definition: response.c:1397
_MHD_EXTERN enum MHD_Result MHD_add_response_header(struct MHD_Response *response, const char *header, const char *content)
Definition: response.c:134
_MHD_EXTERN const char * MHD_get_response_header(struct MHD_Response *response, const char *key)
Definition: response.c:285
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_fd64(uint64_t size, int fd)
Definition: response.c:726
struct MHD_Response * MHD_create_response_from_data(size_t size, void *data, int must_free, int must_copy)
Definition: response.c:750
@ MHD_RESPMEM_MUST_FREE
Definition: microhttpd.h:3152
@ MHD_RESPMEM_MUST_COPY
Definition: microhttpd.h:3161
@ MHD_EPOLL_STATE_UNREADY
Definition: internal.h:594
#define DLL_insert(head, tail, element)
Definition: internal.h:1743
#define EDLL_insert(head, tail, element)
Definition: internal.h:1829
#define MHD_PANIC(msg)
Definition: internal.h:69
size_t MHD_pool_get_free(struct MemoryPool *pool)
Definition: memorypool.c:185
void * MHD_pool_allocate(struct MemoryPool *pool, size_t size, int from_end)
Definition: memorypool.c:203
#define mhd_assert(CHK)
Definition: mhd_assert.h:39
void * MHD_calloc_(size_t nelem, size_t elsize)
Definition: mhd_compat.c:98
#define INT32_MAX
Definition: mhd_limits.h:65
#define UINT_MAX
Definition: mhd_limits.h:45
#define MHD_mutex_unlock_chk_(pmutex)
Definition: mhd_locks.h:180
#define MHD_mutex_destroy_chk_(pmutex)
Definition: mhd_locks.h:121
#define MHD_mutex_lock_chk_(pmutex)
Definition: mhd_locks.h:154
int MHD_socket_nonblocking_(MHD_socket sock)
Definition: mhd_sockets.c:407
size_t MHD_SCKT_SEND_SIZE_
Definition: mhd_sockets.h:213
#define MHD_socket_last_strerr_()
Definition: mhd_sockets.h:549
#define MHD_socket_close_chk_(fd)
Definition: mhd_sockets.h:248
#define MHD_SCKT_FD_FITS_FDSET_(fd, pset)
Definition: mhd_sockets.h:309
int MHD_str_equal_caseless_(const char *str1, const char *str2)
Definition: mhd_str.c:346
bool MHD_str_has_token_caseless_(const char *str, const char *const token, size_t token_len)
Definition: mhd_str.c:412
#define NULL
Definition: reason_phrase.c:30
additional automatic macros for MHD_config.h
#define _(String)
Definition: mhd_options.h:42
#define _MHD_EXTERN
Definition: mhd_options.h:50
bool MHD_connection_set_cork_state_(struct MHD_Connection *connection, bool cork_state)
Definition: mhd_send.c:240
bool MHD_connection_set_nodelay_state_(struct MHD_Connection *connection, bool nodelay_state)
Definition: mhd_send.c:170
Declarations of send() wrappers.
internal shared structures
size_t MHD_iov_size_
Definition: internal.h:376
#define MHD_IOV_ELMN_MAX_SIZE
Definition: internal.h:375
memory pool; mostly used for efficient (de)allocation for each connection and bounding memory use for...
Header for platform missing functions.
Header for platform-independent inter-thread communication.
limits values definitions
#define SSIZE_MAX
Definition: mhd_limits.h:111
#define MHD_mutex_init_(ignore)
Definition: mhd_locks.h:189
bool MHD_str_equal_caseless_bin_n_(const char *const str1, const char *const str2, size_t len)
Definition: mhd_str.c:408
Header for string manipulating helpers.
static void free_callback(void *cls)
Definition: response.c:576
#define MHD_FILE_READ_BLOCK_SIZE
Definition: response.c:68
bool MHD_check_response_header_token_ci(const struct MHD_Response *response, const char *key, size_t key_len, const char *token, size_t token_len)
Definition: response.c:324
static enum MHD_Result add_response_entry(struct MHD_Response *response, enum MHD_ValueKind kind, const char *header, const char *content)
Definition: response.c:83
static ssize_t file_reader(void *cls, uint64_t pos, char *buf, size_t max)
Definition: response.c:453
enum MHD_Result MHD_set_response_options(struct MHD_Response *response, enum MHD_ResponseFlags flags,...)
Definition: response.c:417
static ssize_t pipe_reader(void *cls, uint64_t pos, char *buf, size_t max)
Definition: response.c:541
void MHD_increment_response_rc(struct MHD_Response *response)
Definition: response.c:1443
int MHD_socket
Definition: microhttpd.h:193
void(* MHD_UpgradeHandler)(void *cls, struct MHD_Connection *connection, void *con_cls, const char *extra_in, size_t extra_in_size, MHD_socket sock, struct MHD_UpgradeResponseHandle *urh)
Definition: microhttpd.h:3429
#define MHD_SIZE_UNKNOWN
Definition: microhttpd.h:165
MHD_Result
Definition: microhttpd.h:139
@ MHD_YES
Definition: microhttpd.h:148
@ MHD_NO
Definition: microhttpd.h:143
int off_t offset
Definition: microhttpd.h:3270
#define MHD_CONTENT_READER_END_OF_STREAM
Definition: microhttpd.h:172
_MHD_EXTERN struct MHD_Response * MHD_create_response_for_upgrade(MHD_UpgradeHandler upgrade_handler, void *upgrade_handler_cls)
void int int must_copy
Definition: microhttpd.h:3127
void int must_free
Definition: microhttpd.h:3126
int fd
Definition: microhttpd.h:3269
_MHD_EXTERN void MHD_resume_connection(struct MHD_Connection *connection)
Definition: daemon.c:3173
void * data
Definition: microhttpd.h:3125
#define MHD_INVALID_SOCKET
Definition: microhttpd.h:194
ssize_t(* MHD_ContentReaderCallback)(void *cls, uint64_t pos, char *buf, size_t max)
Definition: microhttpd.h:2376
#define MHD_CONTENT_READER_END_WITH_ERROR
Definition: microhttpd.h:173
MHD_UpgradeAction
Definition: microhttpd.h:3333
@ MHD_UPGRADE_ACTION_CORK_ON
Definition: microhttpd.h:3345
@ MHD_UPGRADE_ACTION_CLOSE
Definition: microhttpd.h:3340
@ MHD_UPGRADE_ACTION_CORK_OFF
Definition: microhttpd.h:3350
MHD_ValueKind
Definition: microhttpd.h:1800
@ MHD_FOOTER_KIND
Definition: microhttpd.h:1841
@ MHD_HEADER_KIND
Definition: microhttpd.h:1815
@ MHD_USE_EPOLL
Definition: microhttpd.h:1193
@ MHD_USE_THREAD_PER_CONNECTION
Definition: microhttpd.h:1087
@ MHD_USE_POLL
Definition: microhttpd.h:1143
@ MHD_USE_TLS
Definition: microhttpd.h:1072
@ MHD_ALLOW_UPGRADE
Definition: microhttpd.h:1302
@ MHD_USE_INTERNAL_POLLING_THREAD
Definition: microhttpd.h:1098
MHD_ResponseOptions
Definition: microhttpd.h:3062
@ MHD_RO_END
Definition: microhttpd.h:3066
MHD_ResponseFlags
Definition: microhttpd.h:3024
@ MHD_RF_INSANITY_HEADER_CONTENT_LENGTH
Definition: microhttpd.h:3052
_MHD_EXTERN enum MHD_Result MHD_upgrade_action(struct MHD_UpgradeResponseHandle *urh, enum MHD_UpgradeAction action,...)
Methods for managing response objects.
enum MHD_Result MHD_response_execute_upgrade_(struct MHD_Response *response, struct MHD_Connection *connection)
MHD_socket socket_fd
Definition: internal.h:752
struct MemoryPool * pool
Definition: internal.h:685
size_t read_buffer_offset
Definition: internal.h:905
MHD_thread_handle_ID_ pid
Definition: internal.h:723
void * client_context
Definition: internal.h:814
enum MHD_CONNECTION_STATE state
Definition: internal.h:1064
char * read_buffer
Definition: internal.h:854
struct MHD_Daemon * daemon
Definition: internal.h:675
volatile bool shutdown
Definition: internal.h:1526
enum MHD_FLAG options
Definition: internal.h:1411
size_t value_size
Definition: internal.h:338
char * header
Definition: internal.h:347
enum MHD_ValueKind kind
Definition: internal.h:358
size_t header_size
Definition: internal.h:328
struct MHD_HTTP_Header * next
Definition: internal.h:342
char * value
Definition: internal.h:352
const void * iov_base
Definition: microhttpd.h:2002
size_t iov_len
Definition: microhttpd.h:2007
MHD_ContentReaderFreeCallback crfc
Definition: internal.h:1606
struct MHD_HTTP_Header * first_header
Definition: internal.h:1582
void * crc_cls
Definition: internal.h:1594
size_t data_buffer_size
Definition: internal.h:1664
MHD_iovec_ * data_iov
Definition: internal.h:513
MHD_ContentReaderCallback crc
Definition: internal.h:1600
bool is_pipe
Definition: internal.h:508
struct MHD_Action action
Definition: internal.h:1575
unsigned int data_iovcnt
Definition: internal.h:518
size_t data_size
Definition: internal.h:1659
enum MHD_ResponseFlags flags
Definition: internal.h:503
unsigned int reference_count
Definition: internal.h:1675
char * data
Definition: internal.h:1588
MHD_mutex_ mutex
Definition: internal.h:1637
uint64_t total_size
Definition: internal.h:1642
uint64_t fd_off
Definition: internal.h:1653