GNU libmicrohttpd  0.9.72
response.c
Go to the documentation of this file.
1 /*
2  This file is part of libmicrohttpd
3  Copyright (C) 2007, 2009, 2010, 2016, 2017 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_compat.h"
46 
47 
48 #if defined(MHD_W32_MUTEX_)
49 #ifndef WIN32_LEAN_AND_MEAN
50 #define WIN32_LEAN_AND_MEAN 1
51 #endif /* !WIN32_LEAN_AND_MEAN */
52 #include <windows.h>
53 #endif /* MHD_W32_MUTEX_ */
54 #if defined(_WIN32)
55 #include <io.h> /* for lseek(), read() */
56 #endif /* _WIN32 */
57 
58 
63 #ifndef MHD_FILE_READ_BLOCK_SIZE
64 #ifdef _WIN32
65 #define MHD_FILE_READ_BLOCK_SIZE 16384 /* 16k */
66 #else /* _WIN32 */
67 #define MHD_FILE_READ_BLOCK_SIZE 4096 /* 4k */
68 #endif /* _WIN32 */
69 #endif /* !MHD_FD_BLOCK_SIZE */
70 
71 
81 static enum MHD_Result
82 add_response_entry (struct MHD_Response *response,
83  enum MHD_ValueKind kind,
84  const char *header,
85  const char *content)
86 {
87  struct MHD_HTTP_Header *hdr;
88 
89  if ( (NULL == response) ||
90  (NULL == header) ||
91  (NULL == content) ||
92  (0 == header[0]) ||
93  (0 == content[0]) ||
94  (NULL != strchr (header, '\t')) ||
95  (NULL != strchr (header, '\r')) ||
96  (NULL != strchr (header, '\n')) ||
97  (NULL != strchr (content, '\t')) ||
98  (NULL != strchr (content, '\r')) ||
99  (NULL != strchr (content, '\n')) )
100  return MHD_NO;
101  if (NULL == (hdr = malloc (sizeof (struct MHD_HTTP_Header))))
102  return MHD_NO;
103  if (NULL == (hdr->header = strdup (header)))
104  {
105  free (hdr);
106  return MHD_NO;
107  }
108  hdr->header_size = strlen (header);
109  if (NULL == (hdr->value = strdup (content)))
110  {
111  free (hdr->header);
112  free (hdr);
113  return MHD_NO;
114  }
115  hdr->value_size = strlen (content);
116  hdr->kind = kind;
117  hdr->next = response->first_header;
118  response->first_header = hdr;
119  return MHD_YES;
120 }
121 
122 
132 enum MHD_Result
133 MHD_add_response_header (struct MHD_Response *response,
134  const char *header,
135  const char *content)
136 {
139  (! MHD_str_equal_caseless_ (content,
140  "identity")) &&
141  (! MHD_str_equal_caseless_ (content,
142  "chunked")) )
143  {
144  /* Setting transfer encodings other than "identity" or
145  "chunked" is not allowed. Note that MHD will set the
146  correct transfer encoding if required automatically. */
147  /* NOTE: for compressed bodies, use the "Content-encoding" header */
148  return MHD_NO;
149  }
151  & response->flags)) &&
154  {
155  /* MHD will set Content-length if allowed and possible,
156  reject attempt by application */
157  return MHD_NO;
158  }
159 
160  return add_response_entry (response,
162  header,
163  content);
164 }
165 
166 
176 enum MHD_Result
177 MHD_add_response_footer (struct MHD_Response *response,
178  const char *footer,
179  const char *content)
180 {
181  return add_response_entry (response,
183  footer,
184  content);
185 }
186 
187 
197 enum MHD_Result
198 MHD_del_response_header (struct MHD_Response *response,
199  const char *header,
200  const char *content)
201 {
202  struct MHD_HTTP_Header *pos;
203  struct MHD_HTTP_Header *prev;
204  size_t header_len;
205  size_t content_len;
206 
207  if ( (NULL == header) ||
208  (NULL == content) )
209  return MHD_NO;
210  header_len = strlen (header);
211  content_len = strlen (content);
212  prev = NULL;
213  pos = response->first_header;
214  while (NULL != pos)
215  {
216  if ((header_len == pos->header_size) &&
217  (content_len == pos->value_size) &&
218  (0 == memcmp (header,
219  pos->header,
220  header_len)) &&
221  (0 == memcmp (content,
222  pos->value,
223  content_len)))
224  {
225  free (pos->header);
226  free (pos->value);
227  if (NULL == prev)
228  response->first_header = pos->next;
229  else
230  prev->next = pos->next;
231  free (pos);
232  return MHD_YES;
233  }
234  prev = pos;
235  pos = pos->next;
236  }
237  return MHD_NO;
238 }
239 
240 
251 int
253  MHD_KeyValueIterator iterator,
254  void *iterator_cls)
255 {
256  int numHeaders = 0;
257  struct MHD_HTTP_Header *pos;
258 
259  for (pos = response->first_header;
260  NULL != pos;
261  pos = pos->next)
262  {
263  numHeaders++;
264  if ((NULL != iterator) &&
265  (MHD_NO == iterator (iterator_cls,
266  pos->kind,
267  pos->header,
268  pos->value)))
269  break;
270  }
271  return numHeaders;
272 }
273 
274 
283 const char *
285  const char *key)
286 {
287  struct MHD_HTTP_Header *pos;
288  size_t key_size;
289 
290  if (NULL == key)
291  return NULL;
292 
293  key_size = strlen (key);
294  for (pos = response->first_header;
295  NULL != pos;
296  pos = pos->next)
297  {
298  if ((pos->header_size == key_size) &&
300  return pos->value;
301  }
302  return NULL;
303 }
304 
305 
322 bool
324  const char *key,
325  size_t key_len,
326  const char *token,
327  size_t token_len)
328 {
329  struct MHD_HTTP_Header *pos;
330 
331  if ( (NULL == key) ||
332  ('\0' == key[0]) ||
333  (NULL == token) ||
334  ('\0' == token[0]) )
335  return false;
336 
337  /* Token must not contain binary zero! */
338  mhd_assert (strlen (token) == token_len);
339 
340  for (pos = response->first_header;
341  NULL != pos;
342  pos = pos->next)
343  {
344  if ( (pos->kind == MHD_HEADER_KIND) &&
345  (key_len == pos->header_size) &&
347  key,
348  key_len) &&
350  token,
351  token_len) )
352  return true;
353  }
354  return false;
355 }
356 
357 
374 struct MHD_Response *
376  size_t block_size,
378  void *crc_cls,
380 {
381  struct MHD_Response *response;
382 
383  if ((NULL == crc) || (0 == block_size))
384  return NULL;
385  if (NULL == (response = MHD_calloc_ (1, sizeof (struct MHD_Response)
386  + block_size)))
387  return NULL;
388  response->fd = -1;
389  response->data = (void *) &response[1];
390  response->data_buffer_size = block_size;
391 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
392  if (! MHD_mutex_init_ (&response->mutex))
393  {
394  free (response);
395  return NULL;
396  }
397 #endif
398  response->crc = crc;
399  response->crfc = crfc;
400  response->crc_cls = crc_cls;
401  response->reference_count = 1;
402  response->total_size = size;
403  return response;
404 }
405 
406 
415 enum MHD_Result
416 MHD_set_response_options (struct MHD_Response *response,
418  ...)
419 {
420  va_list ap;
421  enum MHD_Result ret;
422  enum MHD_ResponseOptions ro;
423 
424  ret = MHD_YES;
425  response->flags = flags;
426  va_start (ap, flags);
427  while (MHD_RO_END != (ro = va_arg (ap, enum MHD_ResponseOptions)))
428  {
429  switch (ro)
430  {
431  default:
432  ret = MHD_NO;
433  break;
434  }
435  }
436  va_end (ap);
437  return ret;
438 }
439 
440 
451 static ssize_t
452 file_reader (void *cls,
453  uint64_t pos,
454  char *buf,
455  size_t max)
456 {
457  struct MHD_Response *response = cls;
458 #if ! defined(_WIN32) || defined(__CYGWIN__)
459  ssize_t n;
460 #else /* _WIN32 && !__CYGWIN__ */
461  const HANDLE fh = (HANDLE) _get_osfhandle (response->fd);
462 #endif /* _WIN32 && !__CYGWIN__ */
463  const int64_t offset64 = (int64_t) (pos + response->fd_off);
464 
465  if (offset64 < 0)
466  return MHD_CONTENT_READER_END_WITH_ERROR; /* seek to required position is not possible */
467 
468 #if ! defined(_WIN32) || defined(__CYGWIN__)
469  if (max > SSIZE_MAX)
470  max = SSIZE_MAX; /* Clamp to maximum return value. */
471 
472 #if defined(HAVE_PREAD64)
473  n = pread64 (response->fd, buf, max, offset64);
474 #elif defined(HAVE_PREAD)
475  if ( (sizeof(off_t) < sizeof (uint64_t)) &&
476  (offset64 > (uint64_t) INT32_MAX) )
477  return MHD_CONTENT_READER_END_WITH_ERROR; /* Read at required position is not possible. */
478 
479  n = pread (response->fd, buf, max, (off_t) offset64);
480 #else /* ! HAVE_PREAD */
481 #if defined(HAVE_LSEEK64)
482  if (lseek64 (response->fd,
483  offset64,
484  SEEK_SET) != offset64)
485  return MHD_CONTENT_READER_END_WITH_ERROR; /* can't seek to required position */
486 #else /* ! HAVE_LSEEK64 */
487  if ( (sizeof(off_t) < sizeof (uint64_t)) &&
488  (offset64 > (uint64_t) INT32_MAX) )
489  return MHD_CONTENT_READER_END_WITH_ERROR; /* seek to required position is not possible */
490 
491  if (lseek (response->fd,
492  (off_t) offset64,
493  SEEK_SET) != (off_t) offset64)
494  return MHD_CONTENT_READER_END_WITH_ERROR; /* can't seek to required position */
495 #endif /* ! HAVE_LSEEK64 */
496  n = read (response->fd,
497  buf,
498  max);
499 
500 #endif /* ! HAVE_PREAD */
501  if (0 == n)
503  if (n < 0)
505  return n;
506 #else /* _WIN32 && !__CYGWIN__ */
507  if (INVALID_HANDLE_VALUE == fh)
508  return MHD_CONTENT_READER_END_WITH_ERROR; /* Value of 'response->fd' is not valid. */
509  else
510  {
511  OVERLAPPED f_ol = {0, 0, {{0, 0}}, 0}; /* Initialize to zero. */
512  ULARGE_INTEGER pos_uli;
513  DWORD toRead = (max > INT32_MAX) ? INT32_MAX : (DWORD) max;
514  DWORD resRead;
515 
516  pos_uli.QuadPart = (uint64_t) offset64; /* Simple transformation 64bit -> 2x32bit. */
517  f_ol.Offset = pos_uli.LowPart;
518  f_ol.OffsetHigh = pos_uli.HighPart;
519  if (! ReadFile (fh, (void*) buf, toRead, &resRead, &f_ol))
520  return MHD_CONTENT_READER_END_WITH_ERROR; /* Read error. */
521  if (0 == resRead)
523  return (ssize_t) resRead;
524  }
525 #endif /* _WIN32 && !__CYGWIN__ */
526 }
527 
528 
539 static ssize_t
540 pipe_reader (void *cls,
541  uint64_t pos,
542  char *buf,
543  size_t max)
544 {
545  struct MHD_Response *response = cls;
546  ssize_t n;
547 
548  (void) pos;
549 #ifndef _WIN32
550  if (SSIZE_MAX < max)
551  max = SSIZE_MAX;
552 #else /* _WIN32 */
553  if (UINT_MAX < max)
554  max = UINT_MAX;
555 #endif /* _WIN32 */
556 
557  n = read (response->fd,
558  buf,
559  (MHD_SCKT_SEND_SIZE_) max);
560  if (0 == n)
562  if (n < 0)
564  return n;
565 }
566 
567 
574 static void
575 free_callback (void *cls)
576 {
577  struct MHD_Response *response = cls;
578 
579  (void) close (response->fd);
580  response->fd = -1;
581 }
582 
583 
584 #undef MHD_create_response_from_fd_at_offset
585 
602 struct MHD_Response *
604  int fd,
605  off_t offset)
606 {
608  fd,
609  offset);
610 }
611 
612 
629 _MHD_EXTERN struct MHD_Response *
631  int fd,
632  uint64_t offset)
633 {
634  struct MHD_Response *response;
635 
636 #if ! defined(HAVE___LSEEKI64) && ! defined(HAVE_LSEEK64)
637  if ( (sizeof(uint64_t) > sizeof(off_t)) &&
638  ( (size > (uint64_t) INT32_MAX) ||
639  (offset > (uint64_t) INT32_MAX) ||
640  ((size + offset) >= (uint64_t) INT32_MAX) ) )
641  return NULL;
642 #endif
643  if ( ((int64_t) size < 0) ||
644  ((int64_t) offset < 0) ||
645  ((int64_t) (size + offset) < 0) )
646  return NULL;
647 
648  response = MHD_create_response_from_callback (size,
650  &file_reader,
651  NULL,
652  &free_callback);
653  if (NULL == response)
654  return NULL;
655  response->fd = fd;
656  response->is_pipe = false;
657  response->fd_off = offset;
658  response->crc_cls = response;
659  return response;
660 }
661 
662 
673 _MHD_EXTERN struct MHD_Response *
675 {
676  struct MHD_Response *response;
677 
680  &pipe_reader,
681  NULL,
682  &free_callback);
683  if (NULL == response)
684  return NULL;
685  response->fd = fd;
686  response->is_pipe = true;
687  response->crc_cls = response;
688  return response;
689 }
690 
691 
701 struct MHD_Response *
703  int fd)
704 {
706  fd,
707  0);
708 }
709 
710 
724 _MHD_EXTERN struct MHD_Response *
726  int fd)
727 {
729  fd,
730  0);
731 }
732 
733 
748 struct MHD_Response *
750  void *data,
751  int must_free,
752  int must_copy)
753 {
754  struct MHD_Response *response;
755  void *tmp;
756 
757  if ((NULL == data) && (size > 0))
758  return NULL;
759  if (NULL == (response = MHD_calloc_ (1, sizeof (struct MHD_Response))))
760  return NULL;
761  response->fd = -1;
762 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
763  if (! MHD_mutex_init_ (&response->mutex))
764  {
765  free (response);
766  return NULL;
767  }
768 #endif
769  if ((must_copy) && (size > 0))
770  {
771  if (NULL == (tmp = malloc (size)))
772  {
773 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
774  MHD_mutex_destroy_chk_ (&response->mutex);
775 #endif
776  free (response);
777  return NULL;
778  }
779  memcpy (tmp, data, size);
780  must_free = MHD_YES;
781  data = tmp;
782  }
783  if (must_free)
784  {
785  response->crfc = &free;
786  response->crc_cls = data;
787  }
788  response->reference_count = 1;
789  response->total_size = size;
790  response->data = data;
791  response->data_size = size;
792  if (must_copy)
793  response->data_buffer_size = size;
794  return response;
795 }
796 
797 
808 struct MHD_Response *
810  void *buffer,
811  enum MHD_ResponseMemoryMode mode)
812 {
813  return MHD_create_response_from_data (size,
814  buffer,
815  mode == MHD_RESPMEM_MUST_FREE,
816  mode == MHD_RESPMEM_MUST_COPY);
817 }
818 
819 
830 _MHD_EXTERN struct MHD_Response *
832  void *buffer,
834  crfc)
835 {
836  struct MHD_Response *r;
837 
839  buffer,
840  MHD_YES,
841  MHD_NO);
842  if (NULL == r)
843  return r;
844  r->crfc = crfc;
845  return r;
846 }
847 
848 
849 #ifdef UPGRADE_SUPPORT
863 MHD_upgrade_action (struct MHD_UpgradeResponseHandle *urh,
865  ...)
866 {
867  struct MHD_Connection *connection;
868  struct MHD_Daemon *daemon;
869 
870  if (NULL == urh)
871  return MHD_NO;
872  connection = urh->connection;
873 
874  /* Precaution checks on external data. */
875  if (NULL == connection)
876  return MHD_NO;
877  daemon = connection->daemon;
878  if (NULL == daemon)
879  return MHD_NO;
880 
881  switch (action)
882  {
884  if (urh->was_closed)
885  return MHD_NO; /* Already closed. */
886 
887  /* transition to special 'closed' state for start of cleanup */
888 #ifdef HTTPS_SUPPORT
889  if (0 != (daemon->options & MHD_USE_TLS) )
890  {
891  /* signal that app is done by shutdown() of 'app' socket */
892  /* Application will not use anyway this socket after this command. */
893  shutdown (urh->app.socket,
894  SHUT_RDWR);
895  }
896 #endif /* HTTPS_SUPPORT */
897  mhd_assert (MHD_CONNECTION_UPGRADE == connection->state);
898  urh->was_closed = true;
899  /* As soon as connection will be marked with BOTH
900  * 'urh->was_closed' AND 'urh->clean_ready', it will
901  * be moved to cleanup list by MHD_resume_connection(). */
902  MHD_resume_connection (connection);
903  return MHD_YES;
905  if (_MHD_ON == connection->sk_corked)
906  return MHD_YES;
907  if (0 !=
908  MHD_socket_cork_ (connection->socket_fd,
909  true))
910  {
911  connection->sk_corked = _MHD_ON;
912  return MHD_YES;
913  }
914  return MHD_NO;
916  if (_MHD_OFF == connection->sk_corked)
917  return MHD_YES;
918  if (0 !=
919  MHD_socket_cork_ (connection->socket_fd,
920  false))
921  {
922  connection->sk_corked = _MHD_OFF;
923  return MHD_YES;
924  }
925  return MHD_NO;
926  default:
927  /* we don't understand this one */
928  return MHD_NO;
929  }
930 }
931 
932 
946 enum MHD_Result
948  struct MHD_Connection *connection)
949 {
950  struct MHD_Daemon *daemon = connection->daemon;
951  struct MHD_UpgradeResponseHandle *urh;
952  size_t rbo;
953 
954 #ifdef MHD_USE_THREADS
955  mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
956  MHD_thread_ID_match_current_ (connection->pid) );
957 #endif /* MHD_USE_THREADS */
958 
959  if (0 == (daemon->options & MHD_ALLOW_UPGRADE))
960  return MHD_NO;
961 
962  if (NULL ==
963  MHD_get_response_header (response,
965  {
966 #ifdef HAVE_MESSAGES
967  MHD_DLOG (daemon,
968  _ (
969  "Invalid response for upgrade: application failed to set the 'Upgrade' header!\n"));
970 #endif
971  return MHD_NO;
972  }
973 
974  urh = MHD_calloc_ (1, sizeof (struct MHD_UpgradeResponseHandle));
975  if (NULL == urh)
976  return MHD_NO;
977  urh->connection = connection;
978  rbo = connection->read_buffer_offset;
979  connection->read_buffer_offset = 0;
980 #ifdef HTTPS_SUPPORT
981  if (0 != (daemon->options & MHD_USE_TLS) )
982  {
983  struct MemoryPool *pool;
984  size_t avail;
985  char *buf;
986  MHD_socket sv[2];
987 #if defined(MHD_socket_nosignal_) || ! defined(MHD_socket_pair_nblk_)
988  int res1;
989  int res2;
990 #endif /* MHD_socket_nosignal_ || !MHD_socket_pair_nblk_ */
991 
992 #ifdef MHD_socket_pair_nblk_
993  if (! MHD_socket_pair_nblk_ (sv))
994  {
995  free (urh);
996  return MHD_NO;
997  }
998 #else /* !MHD_socket_pair_nblk_ */
999  if (! MHD_socket_pair_ (sv))
1000  {
1001  free (urh);
1002  return MHD_NO;
1003  }
1004  res1 = MHD_socket_nonblocking_ (sv[0]);
1005  res2 = MHD_socket_nonblocking_ (sv[1]);
1006  if ( (! res1) || (! res2) )
1007  {
1008 #ifdef HAVE_MESSAGES
1009  MHD_DLOG (daemon,
1010  _ ("Failed to make loopback sockets non-blocking.\n"));
1011 #endif
1012  if (! res2)
1013  {
1014  /* Socketpair cannot be used. */
1015  MHD_socket_close_chk_ (sv[0]);
1016  MHD_socket_close_chk_ (sv[1]);
1017  free (urh);
1018  return MHD_NO;
1019  }
1020  }
1021 #endif /* !MHD_socket_pair_nblk_ */
1022 #ifdef MHD_socket_nosignal_
1023  res1 = MHD_socket_nosignal_ (sv[0]);
1024  res2 = MHD_socket_nosignal_ (sv[1]);
1025  if ( (! res1) || (! res2) )
1026  {
1027 #ifdef HAVE_MESSAGES
1028  MHD_DLOG (daemon,
1029  _ ("Failed to set SO_NOSIGPIPE on loopback sockets.\n"));
1030 #endif
1031 #ifndef MSG_NOSIGNAL
1032  if (! res2)
1033  {
1034  /* Socketpair cannot be used. */
1035  MHD_socket_close_chk_ (sv[0]);
1036  MHD_socket_close_chk_ (sv[1]);
1037  free (urh);
1038  return MHD_NO;
1039  }
1040 #endif /* ! MSG_NOSIGNAL */
1041  }
1042 #endif /* MHD_socket_nosignal_ */
1043  if ( (! MHD_SCKT_FD_FITS_FDSET_ (sv[1],
1044  NULL)) &&
1045  (0 == (daemon->options & (MHD_USE_POLL | MHD_USE_EPOLL))) )
1046  {
1047 #ifdef HAVE_MESSAGES
1048  MHD_DLOG (daemon,
1049  _ ("Socketpair descriptor larger than FD_SETSIZE: %d > %d\n"),
1050  (int) sv[1],
1051  (int) FD_SETSIZE);
1052 #endif
1053  MHD_socket_close_chk_ (sv[0]);
1054  MHD_socket_close_chk_ (sv[1]);
1055  free (urh);
1056  return MHD_NO;
1057  }
1058  urh->app.socket = sv[0];
1059  urh->app.urh = urh;
1060  urh->app.celi = MHD_EPOLL_STATE_UNREADY;
1061  urh->mhd.socket = sv[1];
1062  urh->mhd.urh = urh;
1063  urh->mhd.celi = MHD_EPOLL_STATE_UNREADY;
1064  pool = connection->pool;
1065  avail = MHD_pool_get_free (pool);
1066  if (avail < RESERVE_EBUF_SIZE)
1067  {
1068  /* connection's pool is totally at the limit,
1069  use our 'emergency' buffer of #RESERVE_EBUF_SIZE bytes. */
1070  avail = RESERVE_EBUF_SIZE;
1071  buf = urh->e_buf;
1072  }
1073  else
1074  {
1075  /* Normal case: grab all remaining memory from the
1076  connection's pool for the IO buffers; the connection
1077  certainly won't need it anymore as we've upgraded
1078  to another protocol. */
1079  buf = MHD_pool_allocate (pool,
1080  avail,
1081  false);
1082  }
1083  /* use half the buffer for inbound, half for outbound */
1084  urh->in_buffer_size = avail / 2;
1085  urh->out_buffer_size = avail - urh->in_buffer_size;
1086  urh->in_buffer = buf;
1087  urh->out_buffer = &buf[urh->in_buffer_size];
1088 #ifdef EPOLL_SUPPORT
1089  /* Launch IO processing by the event loop */
1090  if (0 != (daemon->options & MHD_USE_EPOLL))
1091  {
1092  /* We're running with epoll(), need to add the sockets
1093  to the event set of the daemon's `epoll_upgrade_fd` */
1094  struct epoll_event event;
1095 
1096  mhd_assert (-1 != daemon->epoll_upgrade_fd);
1097  /* First, add network socket */
1098  event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
1099  event.data.ptr = &urh->app;
1100  if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
1101  EPOLL_CTL_ADD,
1102  connection->socket_fd,
1103  &event))
1104  {
1105 #ifdef HAVE_MESSAGES
1106  MHD_DLOG (daemon,
1107  _ ("Call to epoll_ctl failed: %s\n"),
1109 #endif
1110  MHD_socket_close_chk_ (sv[0]);
1111  MHD_socket_close_chk_ (sv[1]);
1112  free (urh);
1113  return MHD_NO;
1114  }
1115 
1116  /* Second, add our end of the UNIX socketpair() */
1117  event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
1118  event.data.ptr = &urh->mhd;
1119  if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
1120  EPOLL_CTL_ADD,
1121  urh->mhd.socket,
1122  &event))
1123  {
1124  event.events = EPOLLIN | EPOLLOUT | EPOLLPRI;
1125  event.data.ptr = &urh->app;
1126  if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
1127  EPOLL_CTL_DEL,
1128  connection->socket_fd,
1129  &event))
1130  MHD_PANIC (_ ("Error cleaning up while handling epoll error.\n"));
1131 #ifdef HAVE_MESSAGES
1132  MHD_DLOG (daemon,
1133  _ ("Call to epoll_ctl failed: %s\n"),
1135 #endif
1136  MHD_socket_close_chk_ (sv[0]);
1137  MHD_socket_close_chk_ (sv[1]);
1138  free (urh);
1139  return MHD_NO;
1140  }
1141  EDLL_insert (daemon->eready_urh_head,
1142  daemon->eready_urh_tail,
1143  urh);
1144  urh->in_eready_list = true;
1145  }
1146 #endif /* EPOLL_SUPPORT */
1147  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION) )
1148  {
1149  /* This takes care of further processing for most event loops:
1150  simply add to DLL for bi-direcitonal processing */
1151  DLL_insert (daemon->urh_head,
1152  daemon->urh_tail,
1153  urh);
1154  }
1155  /* In thread-per-connection mode, thread will switch to forwarding once
1156  * connection.urh is not NULL and connection.state == MHD_CONNECTION_UPGRADE.
1157  */
1158  }
1159  else
1160  {
1161  urh->app.socket = MHD_INVALID_SOCKET;
1162  urh->mhd.socket = MHD_INVALID_SOCKET;
1163  /* Non-TLS connection do not hold any additional resources. */
1164  urh->clean_ready = true;
1165  }
1166 #else /* ! HTTPS_SUPPORT */
1167  urh->clean_ready = true;
1168 #endif /* ! HTTPS_SUPPORT */
1169  connection->urh = urh;
1170  /* As far as MHD's event loops are concerned, this connection is
1171  suspended; it will be resumed once application is done by the
1172  #MHD_upgrade_action() function */
1173  internal_suspend_connection_ (connection);
1174 
1175  /* hand over socket to application */
1176  response->upgrade_handler (response->upgrade_handler_cls,
1177  connection,
1178  connection->client_context,
1179  connection->read_buffer,
1180  rbo,
1181 #ifdef HTTPS_SUPPORT
1182  (0 == (daemon->options & MHD_USE_TLS) ) ?
1183  connection->socket_fd : urh->app.socket,
1184 #else /* ! HTTPS_SUPPORT */
1185  connection->socket_fd,
1186 #endif /* ! HTTPS_SUPPORT */
1187  urh);
1188  return MHD_YES;
1189 }
1190 
1191 
1221 _MHD_EXTERN struct MHD_Response *
1223  void *upgrade_handler_cls)
1224 {
1225  struct MHD_Response *response;
1226 
1227  if (NULL == upgrade_handler)
1228  return NULL; /* invalid request */
1229  response = MHD_calloc_ (1, sizeof (struct MHD_Response));
1230  if (NULL == response)
1231  return NULL;
1232 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1233  if (! MHD_mutex_init_ (&response->mutex))
1234  {
1235  free (response);
1236  return NULL;
1237  }
1238 #endif
1239  response->upgrade_handler = upgrade_handler;
1240  response->upgrade_handler_cls = upgrade_handler_cls;
1241  response->total_size = MHD_SIZE_UNKNOWN;
1242  response->reference_count = 1;
1243  if (MHD_NO ==
1244  MHD_add_response_header (response,
1246  "Upgrade"))
1247  {
1248  MHD_destroy_response (response);
1249  return NULL;
1250  }
1251  return response;
1252 }
1253 
1254 
1255 #endif /* UPGRADE_SUPPORT */
1256 
1257 
1267 void
1269 {
1270  struct MHD_HTTP_Header *pos;
1271 
1272  if (NULL == response)
1273  return;
1274 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1275  MHD_mutex_lock_chk_ (&response->mutex);
1276 #endif
1277  if (0 != --(response->reference_count))
1278  {
1279 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1280  MHD_mutex_unlock_chk_ (&response->mutex);
1281 #endif
1282  return;
1283  }
1284 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1285  MHD_mutex_unlock_chk_ (&response->mutex);
1286  MHD_mutex_destroy_chk_ (&response->mutex);
1287 #endif
1288  if (NULL != response->crfc)
1289  response->crfc (response->crc_cls);
1290  while (NULL != response->first_header)
1291  {
1292  pos = response->first_header;
1293  response->first_header = pos->next;
1294  free (pos->header);
1295  free (pos->value);
1296  free (pos);
1297  }
1298  free (response);
1299 }
1300 
1301 
1307 void
1309 {
1310 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1311  MHD_mutex_lock_chk_ (&response->mutex);
1312 #endif
1313  (response->reference_count)++;
1314 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1315  MHD_mutex_unlock_chk_ (&response->mutex);
1316 #endif
1317 }
1318 
1319 
1320 /* end of response.c */
Methods for managing connections.
void internal_suspend_connection_(struct MHD_Connection *connection)
Definition: daemon.c:2999
#define MHD_HTTP_HEADER_CONTENT_LENGTH
Definition: microhttpd.h:575
#define MHD_HTTP_HEADER_CONNECTION
Definition: microhttpd.h:569
#define MHD_HTTP_HEADER_TRANSFER_ENCODING
Definition: microhttpd.h:631
#define MHD_HTTP_HEADER_UPGRADE
Definition: microhttpd.h:633
enum MHD_Result(* MHD_KeyValueIterator)(void *cls, enum MHD_ValueKind kind, const char *key, const char *value)
Definition: microhttpd.h:2261
_MHD_EXTERN enum MHD_Result MHD_del_response_header(struct MHD_Response *response, const char *header, const char *content)
Definition: response.c:198
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_buffer_with_free_callback(size_t size, void *buffer, MHD_ContentReaderFreeCallback crfc)
Definition: response.c:831
_MHD_EXTERN enum MHD_Result MHD_add_response_footer(struct MHD_Response *response, const char *footer, const char *content)
Definition: response.c:177
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_fd(size_t size, int fd)
Definition: response.c:702
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_pipe(int fd)
Definition: response.c:674
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_buffer(size_t size, void *buffer, enum MHD_ResponseMemoryMode mode)
Definition: response.c:809
_MHD_EXTERN int MHD_get_response_headers(struct MHD_Response *response, MHD_KeyValueIterator iterator, void *iterator_cls)
Definition: response.c:252
_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:375
struct MHD_Response * MHD_create_response_from_fd_at_offset(size_t size, int fd, off_t offset)
Definition: response.c:603
MHD_ResponseMemoryMode
Definition: microhttpd.h:3064
void(* MHD_ContentReaderFreeCallback)(void *cls)
Definition: microhttpd.h:2355
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_fd_at_offset64(uint64_t size, int fd, uint64_t offset)
Definition: response.c:630
_MHD_EXTERN void MHD_destroy_response(struct MHD_Response *response)
Definition: response.c:1268
_MHD_EXTERN enum MHD_Result MHD_add_response_header(struct MHD_Response *response, const char *header, const char *content)
Definition: response.c:133
_MHD_EXTERN const char * MHD_get_response_header(struct MHD_Response *response, const char *key)
Definition: response.c:284
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_fd64(uint64_t size, int fd)
Definition: response.c:725
struct MHD_Response * MHD_create_response_from_data(size_t size, void *data, int must_free, int must_copy)
Definition: response.c:749
@ MHD_RESPMEM_MUST_FREE
Definition: microhttpd.h:3080
@ MHD_RESPMEM_MUST_COPY
Definition: microhttpd.h:3089
@ 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
internal shared structures
@ _MHD_ON
Definition: internal.h:176
@ _MHD_OFF
Definition: internal.h:175
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
int MHD_socket_cork_(MHD_socket sock, bool on)
Definition: mhd_sockets.c:500
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:575
#define MHD_FILE_READ_BLOCK_SIZE
Definition: response.c:67
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:323
static enum MHD_Result add_response_entry(struct MHD_Response *response, enum MHD_ValueKind kind, const char *header, const char *content)
Definition: response.c:82
static ssize_t file_reader(void *cls, uint64_t pos, char *buf, size_t max)
Definition: response.c:452
enum MHD_Result MHD_set_response_options(struct MHD_Response *response, enum MHD_ResponseFlags flags,...)
Definition: response.c:416
static ssize_t pipe_reader(void *cls, uint64_t pos, char *buf, size_t max)
Definition: response.c:540
void MHD_increment_response_rc(struct MHD_Response *response)
Definition: response.c:1308
int MHD_socket
Definition: microhttpd.h:196
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:3333
#define MHD_SIZE_UNKNOWN
Definition: microhttpd.h:168
MHD_Result
Definition: microhttpd.h:142
@ MHD_YES
Definition: microhttpd.h:151
@ MHD_NO
Definition: microhttpd.h:146
int off_t offset
Definition: microhttpd.h:3196
#define MHD_CONTENT_READER_END_OF_STREAM
Definition: microhttpd.h:175
_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:3055
void int must_free
Definition: microhttpd.h:3054
int fd
Definition: microhttpd.h:3195
_MHD_EXTERN void MHD_resume_connection(struct MHD_Connection *connection)
Definition: daemon.c:3134
void * data
Definition: microhttpd.h:3053
#define MHD_INVALID_SOCKET
Definition: microhttpd.h:197
ssize_t(* MHD_ContentReaderCallback)(void *cls, uint64_t pos, char *buf, size_t max)
Definition: microhttpd.h:2339
#define MHD_CONTENT_READER_END_WITH_ERROR
Definition: microhttpd.h:176
MHD_UpgradeAction
Definition: microhttpd.h:3237
@ MHD_UPGRADE_ACTION_CORK_ON
Definition: microhttpd.h:3249
@ MHD_UPGRADE_ACTION_CLOSE
Definition: microhttpd.h:3244
@ MHD_UPGRADE_ACTION_CORK_OFF
Definition: microhttpd.h:3254
MHD_ValueKind
Definition: microhttpd.h:1781
@ MHD_FOOTER_KIND
Definition: microhttpd.h:1822
@ MHD_HEADER_KIND
Definition: microhttpd.h:1796
@ MHD_USE_EPOLL
Definition: microhttpd.h:1196
@ MHD_USE_THREAD_PER_CONNECTION
Definition: microhttpd.h:1090
@ MHD_USE_POLL
Definition: microhttpd.h:1146
@ MHD_USE_TLS
Definition: microhttpd.h:1075
@ MHD_ALLOW_UPGRADE
Definition: microhttpd.h:1305
@ MHD_USE_INTERNAL_POLLING_THREAD
Definition: microhttpd.h:1101
MHD_ResponseOptions
Definition: microhttpd.h:2990
@ MHD_RO_END
Definition: microhttpd.h:2994
MHD_ResponseFlags
Definition: microhttpd.h:2952
@ MHD_RF_INSANITY_HEADER_CONTENT_LENGTH
Definition: microhttpd.h:2980
_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:839
MHD_thread_handle_ID_ pid
Definition: internal.h:723
void * client_context
Definition: internal.h:748
enum MHD_CONNECTION_STATE state
Definition: internal.h:983
char * read_buffer
Definition: internal.h:788
struct MHD_Daemon * daemon
Definition: internal.h:675
enum MHD_tristate sk_corked
Definition: internal.h:939
volatile bool shutdown
Definition: internal.h:1526
enum MHD_FLAG options
Definition: internal.h:1330
size_t value_size
Definition: internal.h:335
char * header
Definition: internal.h:347
enum MHD_ValueKind kind
Definition: internal.h:358
size_t header_size
Definition: internal.h:325
struct MHD_HTTP_Header * next
Definition: internal.h:342
char * value
Definition: internal.h:352
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_ContentReaderCallback crc
Definition: internal.h:1600
bool is_pipe
Definition: internal.h:451
struct MHD_Action action
Definition: internal.h:1575
size_t data_size
Definition: internal.h:1659
enum MHD_ResponseFlags flags
Definition: internal.h:446
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