GNU libmicrohttpd  0.9.29
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 #ifdef _WIN32
34 #include <windows.h>
35 #endif /* _WIN32 */
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(_WIN32) && 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 /* _WIN32 && MHD_W32_MUTEX_ */
54 #if defined(_WIN32)
55 #include <io.h> /* for lseek(), read() */
56 #endif /* _WIN32 */
57 
58 
68 static int
69 add_response_entry (struct MHD_Response *response,
70  enum MHD_ValueKind kind,
71  const char *header,
72  const char *content)
73 {
74  struct MHD_HTTP_Header *hdr;
75 
76  if ( (NULL == response) ||
77  (NULL == header) ||
78  (NULL == content) ||
79  (0 == header[0]) ||
80  (0 == content[0]) ||
81  (NULL != strchr (header, '\t')) ||
82  (NULL != strchr (header, '\r')) ||
83  (NULL != strchr (header, '\n')) ||
84  (NULL != strchr (content, '\t')) ||
85  (NULL != strchr (content, '\r')) ||
86  (NULL != strchr (content, '\n')) )
87  return MHD_NO;
88  if (NULL == (hdr = malloc (sizeof (struct MHD_HTTP_Header))))
89  return MHD_NO;
90  if (NULL == (hdr->header = strdup (header)))
91  {
92  free (hdr);
93  return MHD_NO;
94  }
95  if (NULL == (hdr->value = strdup (content)))
96  {
97  free (hdr->header);
98  free (hdr);
99  return MHD_NO;
100  }
101  hdr->kind = kind;
102  hdr->next = response->first_header;
103  response->first_header = hdr;
104  return MHD_YES;
105 }
106 
107 
117 int
119  const char *header,
120  const char *content)
121 {
122  return add_response_entry (response,
124  header,
125  content);
126 }
127 
128 
138 int
140  const char *footer,
141  const char *content)
142 {
143  return add_response_entry (response,
145  footer,
146  content);
147 }
148 
149 
159 int
161  const char *header,
162  const char *content)
163 {
164  struct MHD_HTTP_Header *pos;
165  struct MHD_HTTP_Header *prev;
166 
167  if ( (NULL == header) ||
168  (NULL == content) )
169  return MHD_NO;
170  prev = NULL;
171  pos = response->first_header;
172  while (pos != NULL)
173  {
174  if ((0 == strcmp (header,
175  pos->header)) &&
176  (0 == strcmp (content,
177  pos->value)))
178  {
179  free (pos->header);
180  free (pos->value);
181  if (NULL == prev)
182  response->first_header = pos->next;
183  else
184  prev->next = pos->next;
185  free (pos);
186  return MHD_YES;
187  }
188  prev = pos;
189  pos = pos->next;
190  }
191  return MHD_NO;
192 }
193 
194 
205 int
207  MHD_KeyValueIterator iterator,
208  void *iterator_cls)
209 {
210  struct MHD_HTTP_Header *pos;
211  int numHeaders = 0;
212 
213  for (pos = response->first_header; NULL != pos; pos = pos->next)
214  {
215  numHeaders++;
216  if ((NULL != iterator) &&
217  (MHD_YES != iterator (iterator_cls,
218  pos->kind,
219  pos->header,
220  pos->value)))
221  break;
222  }
223  return numHeaders;
224 }
225 
226 
235 const char *
237  const char *key)
238 {
239  struct MHD_HTTP_Header *pos;
240 
241  if (NULL == key)
242  return NULL;
243  for (pos = response->first_header; NULL != pos; pos = pos->next)
244  {
245  if ( MHD_str_equal_caseless_ (pos->header, key) )
246  return pos->value;
247  }
248  return NULL;
249 }
250 
264 bool
266  const char *key,
267  const char *token,
268  size_t token_len)
269 {
270  struct MHD_HTTP_Header *pos;
271 
272  if (NULL == key || 0 == key[0] || NULL == token || 0 == token[0])
273  return false;
274 
275  for (pos = response->first_header; NULL != pos; pos = pos->next)
276  {
277  if ( (pos->kind == MHD_HEADER_KIND) &&
278  MHD_str_equal_caseless_ (pos->header, key) &&
279  MHD_str_has_token_caseless_ (pos->value, token, token_len) )
280  return true;
281  }
282  return false;
283 }
284 
285 
302 struct MHD_Response *
304  size_t block_size,
306  void *crc_cls,
308 {
309  struct MHD_Response *response;
310 
311  if ((NULL == crc) || (0 == block_size))
312  return NULL;
313  if (NULL == (response = MHD_calloc_ (1, sizeof (struct MHD_Response) + block_size)))
314  return NULL;
315  response->fd = -1;
316  response->data = (void *) &response[1];
317  response->data_buffer_size = block_size;
318  if (! MHD_mutex_init_ (&response->mutex))
319  {
320  free (response);
321  return NULL;
322  }
323  response->crc = crc;
324  response->crfc = crfc;
325  response->crc_cls = crc_cls;
326  response->reference_count = 1;
327  response->total_size = size;
328  return response;
329 }
330 
331 
340 int
342  enum MHD_ResponseFlags flags,
343  ...)
344 {
345  va_list ap;
346  int ret;
347  enum MHD_ResponseOptions ro;
348 
349  ret = MHD_YES;
350  response->flags = flags;
351  va_start (ap, flags);
352  while (MHD_RO_END != (ro = va_arg (ap, enum MHD_ResponseOptions)))
353  {
354  switch (ro)
355  {
356  default:
357  ret = MHD_NO;
358  break;
359  }
360  }
361  va_end (ap);
362  return ret;
363 }
364 
365 
376 static ssize_t
377 file_reader (void *cls,
378  uint64_t pos,
379  char *buf,
380  size_t max)
381 {
382  struct MHD_Response *response = cls;
383 #ifndef _WIN32
384  ssize_t n;
385 #else /* _WIN32 */
386  const HANDLE fh = (HANDLE) _get_osfhandle (response->fd);
387 #endif /* _WIN32 */
388  const int64_t offset64 = (int64_t)(pos + response->fd_off);
389 
390  if (offset64 < 0)
391  return MHD_CONTENT_READER_END_WITH_ERROR; /* seek to required position is not possible */
392 
393 #ifndef _WIN32
394  if (max > SSIZE_MAX)
395  max = SSIZE_MAX; /* Clamp to maximum return value. */
396 
397 #if defined(HAVE_PREAD64)
398  n = pread64(response->fd, buf, max, offset64);
399 #elif defined(HAVE_PREAD)
400  if ( (sizeof(off_t) < sizeof (uint64_t)) &&
401  (offset64 > (uint64_t)INT32_MAX) )
402  return MHD_CONTENT_READER_END_WITH_ERROR; /* Read at required position is not possible. */
403 
404  n = pread(response->fd, buf, max, (off_t) offset64);
405 #else /* ! HAVE_PREAD */
406 #if defined(HAVE_LSEEK64)
407  if (lseek64 (response->fd,
408  offset64,
409  SEEK_SET) != offset64)
410  return MHD_CONTENT_READER_END_WITH_ERROR; /* can't seek to required position */
411 #else /* ! HAVE_LSEEK64 */
412  if ( (sizeof(off_t) < sizeof (uint64_t)) &&
413  (offset64 > (uint64_t)INT32_MAX) )
414  return MHD_CONTENT_READER_END_WITH_ERROR; /* seek to required position is not possible */
415 
416  if (lseek (response->fd,
417  (off_t) offset64,
418  SEEK_SET) != (off_t) offset64)
419  return MHD_CONTENT_READER_END_WITH_ERROR; /* can't seek to required position */
420 #endif /* ! HAVE_LSEEK64 */
421  n = read (response->fd,
422  buf,
423  max);
424 
425 #endif /* ! HAVE_PREAD */
426  if (0 == n)
428  if (n < 0)
430  return n;
431 #else /* _WIN32 */
432  if (INVALID_HANDLE_VALUE == fh)
433  return MHD_CONTENT_READER_END_WITH_ERROR; /* Value of 'response->fd' is not valid. */
434  else
435  {
436  OVERLAPPED f_ol = {0, 0, {{0, 0}}, 0}; /* Initialize to zero. */
437  ULARGE_INTEGER pos_uli;
438  DWORD toRead = (max > INT32_MAX) ? INT32_MAX : (DWORD) max;
439  DWORD resRead;
440 
441  pos_uli.QuadPart = (uint64_t) offset64; /* Simple transformation 64bit -> 2x32bit. */
442  f_ol.Offset = pos_uli.LowPart;
443  f_ol.OffsetHigh = pos_uli.HighPart;
444  if (! ReadFile(fh, (void*)buf, toRead, &resRead, &f_ol))
445  return MHD_CONTENT_READER_END_WITH_ERROR; /* Read error. */
446  if (0 == resRead)
448  return (ssize_t) resRead;
449  }
450 #endif /* _WIN32 */
451 }
452 
453 
460 static void
461 free_callback (void *cls)
462 {
463  struct MHD_Response *response = cls;
464 
465  (void) close (response->fd);
466  response->fd = -1;
467 }
468 
469 #undef MHD_create_response_from_fd_at_offset
470 
487 struct MHD_Response *
489  int fd,
490  off_t offset)
491 {
493  fd,
494  offset);
495 }
496 
497 
514 _MHD_EXTERN struct MHD_Response *
516  int fd,
517  uint64_t offset)
518 {
519  struct MHD_Response *response;
520 
521 #if !defined(HAVE___LSEEKI64) && !defined(HAVE_LSEEK64)
522  if ( (sizeof(uint64_t) > sizeof(off_t)) &&
523  ( (size > (uint64_t)INT32_MAX) ||
524  (offset > (uint64_t)INT32_MAX) ||
525  ((size + offset) >= (uint64_t)INT32_MAX) ) )
526  return NULL;
527 #endif
528  if ( ((int64_t)size < 0) ||
529  ((int64_t)offset < 0) ||
530  ((int64_t)(size + offset) < 0) )
531  return NULL;
532 
533  response = MHD_create_response_from_callback (size,
534  4 * 1024,
535  &file_reader,
536  NULL,
537  &free_callback);
538  if (NULL == response)
539  return NULL;
540  response->fd = fd;
541  response->fd_off = offset;
542  response->crc_cls = response;
543  return response;
544 }
545 
546 
556 struct MHD_Response *
558  int fd)
559 {
561  fd,
562  0);
563 }
564 
565 
579 _MHD_EXTERN struct MHD_Response *
581  int fd)
582 {
584  fd,
585  0);
586 }
587 
588 
603 struct MHD_Response *
605  void *data,
606  int must_free,
607  int must_copy)
608 {
609  struct MHD_Response *response;
610  void *tmp;
611 
612  if ((NULL == data) && (size > 0))
613  return NULL;
614  if (NULL == (response = MHD_calloc_ (1, sizeof (struct MHD_Response))))
615  return NULL;
616  response->fd = -1;
617  if (! MHD_mutex_init_ (&response->mutex))
618  {
619  free (response);
620  return NULL;
621  }
622  if ((must_copy) && (size > 0))
623  {
624  if (NULL == (tmp = malloc (size)))
625  {
626  MHD_mutex_destroy_chk_ (&response->mutex);
627  free (response);
628  return NULL;
629  }
630  memcpy (tmp, data, size);
631  must_free = MHD_YES;
632  data = tmp;
633  }
634  if (must_free)
635  {
636  response->crfc = &free;
637  response->crc_cls = data;
638  }
639  response->reference_count = 1;
640  response->total_size = size;
641  response->data = data;
642  response->data_size = size;
643  return response;
644 }
645 
646 
657 struct MHD_Response *
659  void *buffer,
660  enum MHD_ResponseMemoryMode mode)
661 {
662  return MHD_create_response_from_data (size,
663  buffer,
664  mode == MHD_RESPMEM_MUST_FREE,
665  mode == MHD_RESPMEM_MUST_COPY);
666 }
667 
668 
669 #ifdef UPGRADE_SUPPORT
670 
682 _MHD_EXTERN int
683 MHD_upgrade_action (struct MHD_UpgradeResponseHandle *urh,
684  enum MHD_UpgradeAction action,
685  ...)
686 {
687  struct MHD_Connection *connection;
688  struct MHD_Daemon *daemon;
689 
690  if (NULL == urh)
691  return MHD_NO;
692  connection = urh->connection;
693 
694  /* Precaution checks on external data. */
695  if (NULL == connection)
696  return MHD_NO;
697  daemon = connection->daemon;
698  if (NULL == daemon)
699  return MHD_NO;
700 
701  switch (action)
702  {
703  case MHD_UPGRADE_ACTION_CLOSE:
704  if (urh->was_closed)
705  return MHD_NO; /* Already closed. */
706 
707  /* transition to special 'closed' state for start of cleanup */
708 #ifdef HTTPS_SUPPORT
709  if (0 != (daemon->options & MHD_USE_TLS) )
710  {
711  /* signal that app is done by shutdown() of 'app' socket */
712  /* Application will not use anyway this socket after this command. */
713  shutdown (urh->app.socket,
714  SHUT_RDWR);
715  }
716 #endif /* HTTPS_SUPPORT */
717  EXTRA_CHECK (MHD_CONNECTION_UPGRADE == connection->state);
718  urh->was_closed = true;
719  /* As soon as connection will be marked with BOTH
720  * 'urh->was_closed' AND 'urh->clean_ready', it will
721  * be moved to cleanup list by MHD_resume_connection(). */
722  MHD_resume_connection (connection);
723  return MHD_YES;
724  default:
725  /* we don't understand this one */
726  return MHD_NO;
727  }
728 }
729 
730 
744 int
746  struct MHD_Connection *connection)
747 {
748  struct MHD_Daemon *daemon = connection->daemon;
749  struct MHD_UpgradeResponseHandle *urh;
750  size_t rbo;
751 
752  if (0 == (daemon->options & MHD_ALLOW_UPGRADE))
753  return MHD_NO;
754 
755  if (NULL ==
756  MHD_get_response_header (response,
758  {
759 #ifdef HAVE_MESSAGES
760  MHD_DLOG (daemon,
761  _("Invalid response for upgrade: application failed to set the 'Upgrade' header!\n"));
762 #endif
763  return MHD_NO;
764  }
765 
766  urh = MHD_calloc_ (1, sizeof (struct MHD_UpgradeResponseHandle));
767  if (NULL == urh)
768  return MHD_NO;
769  urh->connection = connection;
770  rbo = connection->read_buffer_offset;
771  connection->read_buffer_offset = 0;
772 #ifdef HTTPS_SUPPORT
773  if (0 != (daemon->options & MHD_USE_TLS) )
774  {
775  struct MemoryPool *pool;
776  size_t avail;
777  char *buf;
778  MHD_socket sv[2];
779 #if defined(MHD_socket_nosignal_) || !defined(MHD_socket_pair_nblk_)
780  int res1;
781  int res2;
782 #endif /* MHD_socket_nosignal_ || !MHD_socket_pair_nblk_ */
783 
784 #ifdef MHD_socket_pair_nblk_
785  if (! MHD_socket_pair_nblk_ (sv))
786  {
787  free (urh);
788  return MHD_NO;
789  }
790 #else /* !MHD_socket_pair_nblk_ */
791  if (! MHD_socket_pair_ (sv))
792  {
793  free (urh);
794  return MHD_NO;
795  }
796  res1 = MHD_socket_nonblocking_(sv[0]);
797  res2 = MHD_socket_nonblocking_(sv[1]);
798  if ( (! res1) || (! res2) )
799  {
800 #ifdef HAVE_MESSAGES
801  MHD_DLOG (daemon,
802  _("Failed to make loopback sockets non-blocking.\n"));
803 #endif
804  if (! res2)
805  {
806  /* Socketpair cannot be used. */
807  MHD_socket_close_chk_ (sv[0]);
808  MHD_socket_close_chk_ (sv[1]);
809  free (urh);
810  return MHD_NO;
811  }
812  }
813 #endif /* !MHD_socket_pair_nblk_ */
814 #ifdef MHD_socket_nosignal_
815  res1 = MHD_socket_nosignal_(sv[0]);
816  res2 = MHD_socket_nosignal_(sv[1]);
817  if ( (! res1) || (! res2) )
818  {
819 #ifdef HAVE_MESSAGES
820  MHD_DLOG (daemon,
821  _("Failed to set SO_NOSIGPIPE on loopback sockets.\n"));
822 #endif
823 #ifndef MSG_NOSIGNAL
824  if (!res2)
825  {
826  /* Socketpair cannot be used. */
827  MHD_socket_close_chk_ (sv[0]);
828  MHD_socket_close_chk_ (sv[1]);
829  free (urh);
830  return MHD_NO;
831  }
832 #endif /* ! MSG_NOSIGNAL */
833  }
834 #endif /* MHD_socket_nosignal_ */
835  if ( (! MHD_SCKT_FD_FITS_FDSET_ (sv[1],
836  NULL)) &&
837  (0 == (daemon->options & (MHD_USE_POLL | MHD_USE_EPOLL))) )
838  {
839 #ifdef HAVE_MESSAGES
840  MHD_DLOG (daemon,
841  _("Socketpair descriptor larger than FD_SETSIZE: %d > %d\n"),
842  (int) sv[1],
843  (int) FD_SETSIZE);
844 #endif
845  MHD_socket_close_chk_ (sv[0]);
846  MHD_socket_close_chk_ (sv[1]);
847  free (urh);
848  return MHD_NO;
849  }
850  urh->app.socket = sv[0];
851  urh->app.urh = urh;
852  urh->app.celi = MHD_EPOLL_STATE_UNREADY;
853  urh->mhd.socket = sv[1];
854  urh->mhd.urh = urh;
855  urh->mhd.celi = MHD_EPOLL_STATE_UNREADY;
856  pool = connection->pool;
857  avail = MHD_pool_get_free (pool);
858  if (avail < RESERVE_EBUF_SIZE)
859  {
860  /* connection's pool is totally at the limit,
861  use our 'emergency' buffer of #RESERVE_EBUF_SIZE bytes. */
862  avail = RESERVE_EBUF_SIZE;
863  buf = urh->e_buf;
864  }
865  else
866  {
867  /* Normal case: grab all remaining memory from the
868  connection's pool for the IO buffers; the connection
869  certainly won't need it anymore as we've upgraded
870  to another protocol. */
871  buf = MHD_pool_allocate (pool,
872  avail,
873  MHD_NO);
874  }
875  /* use half the buffer for inbound, half for outbound */
876  urh->in_buffer_size = avail / 2;
877  urh->out_buffer_size = avail - urh->in_buffer_size;
878  urh->in_buffer = buf;
879  urh->out_buffer = &buf[urh->in_buffer_size];
880 #ifdef EPOLL_SUPPORT
881  /* Launch IO processing by the event loop */
882  if (0 != (daemon->options & MHD_USE_EPOLL))
883  {
884  /* We're running with epoll(), need to add the sockets
885  to the event set of the daemon's `epoll_upgrade_fd` */
886  struct epoll_event event;
887 
888  EXTRA_CHECK (-1 != daemon->epoll_upgrade_fd);
889  /* First, add network socket */
890  event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
891  event.data.ptr = &urh->app;
892  if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
893  EPOLL_CTL_ADD,
894  connection->socket_fd,
895  &event))
896  {
897 #ifdef HAVE_MESSAGES
898  MHD_DLOG (daemon,
899  _("Call to epoll_ctl failed: %s\n"),
901 #endif
902  MHD_socket_close_chk_ (sv[0]);
903  MHD_socket_close_chk_ (sv[1]);
904  free (urh);
905  return MHD_NO;
906  }
907 
908  /* Second, add our end of the UNIX socketpair() */
909  event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
910  event.data.ptr = &urh->mhd;
911  if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
912  EPOLL_CTL_ADD,
913  urh->mhd.socket,
914  &event))
915  {
916  event.events = EPOLLIN | EPOLLOUT | EPOLLPRI;
917  event.data.ptr = &urh->app;
918  if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
919  EPOLL_CTL_DEL,
920  connection->socket_fd,
921  &event))
922  MHD_PANIC (_("Error cleaning up while handling epoll error"));
923 #ifdef HAVE_MESSAGES
924  MHD_DLOG (daemon,
925  _("Call to epoll_ctl failed: %s\n"),
927 #endif
928  MHD_socket_close_chk_ (sv[0]);
929  MHD_socket_close_chk_ (sv[1]);
930  free (urh);
931  return MHD_NO;
932  }
933  EDLL_insert (daemon->eready_urh_head,
934  daemon->eready_urh_tail,
935  urh);
936  urh->in_eready_list = true;
937  }
938 #endif /* EPOLL_SUPPORT */
939  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION) )
940  {
941  /* This takes care of further processing for most event loops:
942  simply add to DLL for bi-direcitonal processing */
943  DLL_insert (daemon->urh_head,
944  daemon->urh_tail,
945  urh);
946  }
947  /* In thread-per-connection mode, thread will switch to forwarding once
948  * connection.urh is not NULL and connection.state == MHD_CONNECTION_UPGRADE.
949  */
950  }
951  else
952  {
953  urh->app.socket = MHD_INVALID_SOCKET;
954  urh->mhd.socket = MHD_INVALID_SOCKET;
955  /* Non-TLS connection do not hold any additional resources. */
956  urh->clean_ready = true;
957  }
958 #else /* ! HTTPS_SUPPORT */
959  urh->clean_ready = true;
960 #endif /* ! HTTPS_SUPPORT */
961  connection->urh = urh;
962  /* As far as MHD's event loops are concerned, this connection is
963  suspended; it will be resumed once application is done by the
964  #MHD_upgrade_action() function */
965  internal_suspend_connection_ (connection);
966 
967  /* hand over socket to application */
968  response->upgrade_handler (response->upgrade_handler_cls,
969  connection,
970  connection->client_context,
971  connection->read_buffer,
972  rbo,
973 #ifdef HTTPS_SUPPORT
974  (0 == (daemon->options & MHD_USE_TLS) ) ?
975  connection->socket_fd : urh->app.socket,
976 #else /* ! HTTPS_SUPPORT */
977  connection->socket_fd,
978 #endif /* ! HTTPS_SUPPORT */
979  urh);
980  return MHD_YES;
981 }
982 
983 
1013 _MHD_EXTERN struct MHD_Response *
1014 MHD_create_response_for_upgrade (MHD_UpgradeHandler upgrade_handler,
1015  void *upgrade_handler_cls)
1016 {
1017  struct MHD_Response *response;
1018 
1019  if (NULL == upgrade_handler)
1020  return NULL; /* invalid request */
1021  response = MHD_calloc_ (1, sizeof (struct MHD_Response));
1022  if (NULL == response)
1023  return NULL;
1024  if (! MHD_mutex_init_ (&response->mutex))
1025  {
1026  free (response);
1027  return NULL;
1028  }
1029  response->upgrade_handler = upgrade_handler;
1030  response->upgrade_handler_cls = upgrade_handler_cls;
1031  response->total_size = MHD_SIZE_UNKNOWN;
1032  response->reference_count = 1;
1033  if (MHD_NO ==
1034  MHD_add_response_header (response,
1036  "Upgrade"))
1037  {
1038  MHD_destroy_response (response);
1039  return NULL;
1040  }
1041  return response;
1042 }
1043 #endif /* UPGRADE_SUPPORT */
1044 
1045 
1055 void
1057 {
1058  struct MHD_HTTP_Header *pos;
1059 
1060  if (NULL == response)
1061  return;
1062  MHD_mutex_lock_chk_ (&response->mutex);
1063  if (0 != --(response->reference_count))
1064  {
1065  MHD_mutex_unlock_chk_ (&response->mutex);
1066  return;
1067  }
1068  MHD_mutex_unlock_chk_ (&response->mutex);
1069  MHD_mutex_destroy_chk_ (&response->mutex);
1070  if (NULL != response->crfc)
1071  response->crfc (response->crc_cls);
1072  while (NULL != response->first_header)
1073  {
1074  pos = response->first_header;
1075  response->first_header = pos->next;
1076  free (pos->header);
1077  free (pos->value);
1078  free (pos);
1079  }
1080  free (response);
1081 }
1082 
1083 
1089 void
1091 {
1092  MHD_mutex_lock_chk_ (&response->mutex);
1093  (response->reference_count)++;
1094  MHD_mutex_unlock_chk_ (&response->mutex);
1095 }
1096 
1097 
1098 /* end of response.c */
int(* MHD_KeyValueIterator)(void *cls, enum MHD_ValueKind kind, const char *key, const char *value)
Definition: microhttpd.h:1992
int MHD_socket_nonblocking_(MHD_socket sock)
Definition: mhd_sockets.c:404
int MHD_set_response_options(struct MHD_Response *response, enum MHD_ResponseFlags flags,...)
Definition: response.c:341
uint64_t total_size
Definition: internal.h:343
additional automatic macros for MHD_config.h
uint64_t fd_off
Definition: internal.h:354
static void free_callback(void *cls)
Definition: response.c:461
#define DLL_insert(head, tail, element)
Definition: internal.h:1726
enum MHD_CONNECTION_STATE state
Definition: internal.h:890
int MHD_add_response_header(struct MHD_Response *response, const char *header, const char *content)
Definition: response.c:118
#define NULL
Definition: reason_phrase.c:31
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_fd64(uint64_t size, int fd)
Definition: response.c:580
MHD_ContentReaderFreeCallback crfc
Definition: internal.h:318
Methods for managing connections.
void(* MHD_ContentReaderFreeCallback)(void *cls)
Definition: microhttpd.h:2059
static ssize_t file_reader(void *cls, uint64_t pos, char *buf, size_t max)
Definition: response.c:377
#define MHD_YES
Definition: microhttpd.h:134
const char * MHD_get_response_header(struct MHD_Response *response, const char *key)
Definition: response.c:236
Header for platform missing functions.
size_t data_size
Definition: internal.h:360
#define EXTRA_CHECK(a)
Definition: internal.h:1714
enum MHD_ValueKind kind
Definition: internal.h:278
struct MHD_HTTP_Header * first_header
Definition: internal.h:294
#define MHD_HTTP_HEADER_UPGRADE
Definition: microhttpd.h:504
void * MHD_pool_allocate(struct MemoryPool *pool, size_t size, int from_end)
Definition: memorypool.c:188
int MHD_socket
Definition: microhttpd.h:181
#define MHD_mutex_destroy_chk_(pmutex)
Definition: mhd_locks.h:109
#define EDLL_insert(head, tail, element)
Definition: internal.h:1815
char * value
Definition: internal.h:272
Methods for managing response objects.
int MHD_response_execute_upgrade_(struct MHD_Response *response, struct MHD_Connection *connection)
struct MHD_Daemon * daemon
Definition: internal.h:641
#define MHD_mutex_unlock_chk_(pmutex)
Definition: mhd_locks.h:168
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:303
Header for platform-independent inter-thread communication.
size_t data_buffer_size
Definition: internal.h:365
struct MHD_Response * MHD_create_response_from_buffer(size_t size, void *buffer, enum MHD_ResponseMemoryMode mode)
Definition: response.c:658
void * client_context
Definition: internal.h:674
#define MHD_socket_close_chk_(fd)
Definition: mhd_sockets.h:246
#define MHD_INVALID_SOCKET
Definition: microhttpd.h:182
MHD_socket socket_fd
Definition: internal.h:848
int MHD_add_response_footer(struct MHD_Response *response, const char *footer, const char *content)
Definition: response.c:139
enum MHD_FLAG options
Definition: internal.h:1578
ssize_t(* MHD_ContentReaderCallback)(void *cls, uint64_t pos, char *buf, size_t max)
Definition: microhttpd.h:2043
unsigned int reference_count
Definition: internal.h:371
void MHD_destroy_response(struct MHD_Response *response)
Definition: response.c:1056
#define _MHD_EXTERN
Definition: mhd_options.h:51
void MHD_increment_response_rc(struct MHD_Response *response)
Definition: response.c:1090
#define MHD_CONTENT_READER_END_OF_STREAM
Definition: microhttpd.h:160
struct MHD_Response * MHD_create_response_from_data(size_t size, void *data, int must_free, int must_copy)
Definition: response.c:604
MHD_ValueKind
Definition: microhttpd.h:1524
char * read_buffer
Definition: internal.h:714
limits values definitions
bool MHD_check_response_header_token_ci(const struct MHD_Response *response, const char *key, const char *token, size_t token_len)
Definition: response.c:265
internal shared structures
void * MHD_calloc_(size_t nelem, size_t elsize)
Definition: mhd_compat.c:96
size_t MHD_pool_get_free(struct MemoryPool *pool)
Definition: memorypool.c:170
#define INT32_MAX
Definition: mhd_limits.h:59
#define MHD_socket_last_strerr_()
Definition: mhd_sockets.h:532
void internal_suspend_connection_(struct MHD_Connection *connection)
Definition: daemon.c:2711
static int add_response_entry(struct MHD_Response *response, enum MHD_ValueKind kind, const char *header, const char *content)
Definition: response.c:69
char * header
Definition: internal.h:267
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_fd_at_offset64(uint64_t size, int fd, uint64_t offset)
Definition: response.c:515
enum MHD_ResponseFlags flags
Definition: internal.h:381
struct MemoryPool * pool
Definition: internal.h:666
#define MHD_PANIC(msg)
Definition: internal.h:63
Header for string manipulating helpers.
struct MHD_HTTP_Header * next
Definition: internal.h:262
#define MHD_SCKT_FD_FITS_FDSET_(fd, pset)
Definition: mhd_sockets.h:299
bool MHD_str_has_token_caseless_(const char *str, const char *const token, size_t token_len)
Definition: mhd_str.c:383
#define MHD_HTTP_HEADER_CONNECTION
Definition: microhttpd.h:440
int MHD_str_equal_caseless_(const char *str1, const char *str2)
Definition: mhd_str.c:319
#define MHD_CONTENT_READER_END_WITH_ERROR
Definition: microhttpd.h:161
MHD_ContentReaderCallback crc
Definition: internal.h:312
void * crc_cls
Definition: internal.h:306
MHD_mutex_ mutex
Definition: internal.h:338
#define _(String)
Definition: mhd_options.h:42
void MHD_resume_connection(struct MHD_Connection *connection)
Definition: daemon.c:2829
#define MHD_SIZE_UNKNOWN
Definition: microhttpd.h:153
char * data
Definition: internal.h:300
int MHD_del_response_header(struct MHD_Response *response, const char *header, const char *content)
Definition: response.c:160
size_t read_buffer_offset
Definition: internal.h:763
#define MHD_NO
Definition: microhttpd.h:139
volatile bool shutdown
Definition: internal.h:1519
struct MHD_Response * MHD_create_response_from_fd(size_t size, int fd)
Definition: response.c:557
struct MHD_Response * MHD_create_response_from_fd_at_offset(size_t size, int fd, off_t offset)
Definition: response.c:488
#define MHD_mutex_lock_chk_(pmutex)
Definition: mhd_locks.h:142
int MHD_get_response_headers(struct MHD_Response *response, MHD_KeyValueIterator iterator, void *iterator_cls)
Definition: response.c:206
memory pool; mostly used for efficient (de)allocation for each connection and bounding memory use for...