GNU libmicrohttpd  0.9.59
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 
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 (NULL != pos)
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  int numHeaders = 0;
211  struct MHD_HTTP_Header *pos;
212 
213  for (pos = response->first_header;
214  NULL != pos;
215  pos = pos->next)
216  {
217  numHeaders++;
218  if ((NULL != iterator) &&
219  (MHD_YES != iterator (iterator_cls,
220  pos->kind,
221  pos->header,
222  pos->value)))
223  break;
224  }
225  return numHeaders;
226 }
227 
228 
237 const char *
239  const char *key)
240 {
241  struct MHD_HTTP_Header *pos;
242 
243  if (NULL == key)
244  return NULL;
245  for (pos = response->first_header;
246  NULL != pos;
247  pos = pos->next)
248  {
249  if ( MHD_str_equal_caseless_ (pos->header, key) )
250  return pos->value;
251  }
252  return NULL;
253 }
254 
269 bool
271  const char *key,
272  const char *token,
273  size_t token_len)
274 {
275  struct MHD_HTTP_Header *pos;
276 
277  if ( (NULL == key) ||
278  ('\0' == key[0]) ||
279  (NULL == token) ||
280  ('\0' == token[0]) )
281  return false;
282 
283  for (pos = response->first_header;
284  NULL != pos;
285  pos = pos->next)
286  {
287  if ( (pos->kind == MHD_HEADER_KIND) &&
289  key) &&
291  token,
292  token_len) )
293  return true;
294  }
295  return false;
296 }
297 
298 
315 struct MHD_Response *
317  size_t block_size,
319  void *crc_cls,
321 {
322  struct MHD_Response *response;
323 
324  if ((NULL == crc) || (0 == block_size))
325  return NULL;
326  if (NULL == (response = MHD_calloc_ (1, sizeof (struct MHD_Response) + block_size)))
327  return NULL;
328  response->fd = -1;
329  response->data = (void *) &response[1];
330  response->data_buffer_size = block_size;
331  if (! MHD_mutex_init_ (&response->mutex))
332  {
333  free (response);
334  return NULL;
335  }
336  response->crc = crc;
337  response->crfc = crfc;
338  response->crc_cls = crc_cls;
339  response->reference_count = 1;
340  response->total_size = size;
341  return response;
342 }
343 
344 
353 int
356  ...)
357 {
358  va_list ap;
359  int ret;
360  enum MHD_ResponseOptions ro;
361 
362  ret = MHD_YES;
363  response->flags = flags;
364  va_start (ap, flags);
365  while (MHD_RO_END != (ro = va_arg (ap, enum MHD_ResponseOptions)))
366  {
367  switch (ro)
368  {
369  default:
370  ret = MHD_NO;
371  break;
372  }
373  }
374  va_end (ap);
375  return ret;
376 }
377 
378 
389 static ssize_t
390 file_reader (void *cls,
391  uint64_t pos,
392  char *buf,
393  size_t max)
394 {
395  struct MHD_Response *response = cls;
396 #if !defined(_WIN32) || defined(__CYGWIN__)
397  ssize_t n;
398 #else /* _WIN32 && !__CYGWIN__ */
399  const HANDLE fh = (HANDLE) _get_osfhandle (response->fd);
400 #endif /* _WIN32 && !__CYGWIN__ */
401  const int64_t offset64 = (int64_t)(pos + response->fd_off);
402 
403  if (offset64 < 0)
404  return MHD_CONTENT_READER_END_WITH_ERROR; /* seek to required position is not possible */
405 
406 #if !defined(_WIN32) || defined(__CYGWIN__)
407  if (max > SSIZE_MAX)
408  max = SSIZE_MAX; /* Clamp to maximum return value. */
409 
410 #if defined(HAVE_PREAD64)
411  n = pread64(response->fd, buf, max, offset64);
412 #elif defined(HAVE_PREAD)
413  if ( (sizeof(off_t) < sizeof (uint64_t)) &&
414  (offset64 > (uint64_t)INT32_MAX) )
415  return MHD_CONTENT_READER_END_WITH_ERROR; /* Read at required position is not possible. */
416 
417  n = pread(response->fd, buf, max, (off_t) offset64);
418 #else /* ! HAVE_PREAD */
419 #if defined(HAVE_LSEEK64)
420  if (lseek64 (response->fd,
421  offset64,
422  SEEK_SET) != offset64)
423  return MHD_CONTENT_READER_END_WITH_ERROR; /* can't seek to required position */
424 #else /* ! HAVE_LSEEK64 */
425  if ( (sizeof(off_t) < sizeof (uint64_t)) &&
426  (offset64 > (uint64_t)INT32_MAX) )
427  return MHD_CONTENT_READER_END_WITH_ERROR; /* seek to required position is not possible */
428 
429  if (lseek (response->fd,
430  (off_t) offset64,
431  SEEK_SET) != (off_t) offset64)
432  return MHD_CONTENT_READER_END_WITH_ERROR; /* can't seek to required position */
433 #endif /* ! HAVE_LSEEK64 */
434  n = read (response->fd,
435  buf,
436  max);
437 
438 #endif /* ! HAVE_PREAD */
439  if (0 == n)
441  if (n < 0)
443  return n;
444 #else /* _WIN32 && !__CYGWIN__ */
445  if (INVALID_HANDLE_VALUE == fh)
446  return MHD_CONTENT_READER_END_WITH_ERROR; /* Value of 'response->fd' is not valid. */
447  else
448  {
449  OVERLAPPED f_ol = {0, 0, {{0, 0}}, 0}; /* Initialize to zero. */
450  ULARGE_INTEGER pos_uli;
451  DWORD toRead = (max > INT32_MAX) ? INT32_MAX : (DWORD) max;
452  DWORD resRead;
453 
454  pos_uli.QuadPart = (uint64_t) offset64; /* Simple transformation 64bit -> 2x32bit. */
455  f_ol.Offset = pos_uli.LowPart;
456  f_ol.OffsetHigh = pos_uli.HighPart;
457  if (! ReadFile(fh, (void*)buf, toRead, &resRead, &f_ol))
458  return MHD_CONTENT_READER_END_WITH_ERROR; /* Read error. */
459  if (0 == resRead)
461  return (ssize_t) resRead;
462  }
463 #endif /* _WIN32 && !__CYGWIN__ */
464 }
465 
466 
473 static void
474 free_callback (void *cls)
475 {
476  struct MHD_Response *response = cls;
477 
478  (void) close (response->fd);
479  response->fd = -1;
480 }
481 
482 #undef MHD_create_response_from_fd_at_offset
483 
500 struct MHD_Response *
502  int fd,
503  off_t offset)
504 {
506  fd,
507  offset);
508 }
509 
510 
527 _MHD_EXTERN struct MHD_Response *
529  int fd,
530  uint64_t offset)
531 {
532  struct MHD_Response *response;
533 
534 #if !defined(HAVE___LSEEKI64) && !defined(HAVE_LSEEK64)
535  if ( (sizeof(uint64_t) > sizeof(off_t)) &&
536  ( (size > (uint64_t)INT32_MAX) ||
537  (offset > (uint64_t)INT32_MAX) ||
538  ((size + offset) >= (uint64_t)INT32_MAX) ) )
539  return NULL;
540 #endif
541  if ( ((int64_t)size < 0) ||
542  ((int64_t)offset < 0) ||
543  ((int64_t)(size + offset) < 0) )
544  return NULL;
545 
546  response = MHD_create_response_from_callback (size,
547  4 * 1024,
548  &file_reader,
549  NULL,
550  &free_callback);
551  if (NULL == response)
552  return NULL;
553  response->fd = fd;
554  response->fd_off = offset;
555  response->crc_cls = response;
556  return response;
557 }
558 
559 
569 struct MHD_Response *
571  int fd)
572 {
574  fd,
575  0);
576 }
577 
578 
592 _MHD_EXTERN struct MHD_Response *
594  int fd)
595 {
597  fd,
598  0);
599 }
600 
601 
616 struct MHD_Response *
618  void *data,
619  int must_free,
620  int must_copy)
621 {
622  struct MHD_Response *response;
623  void *tmp;
624 
625  if ((NULL == data) && (size > 0))
626  return NULL;
627  if (NULL == (response = MHD_calloc_ (1, sizeof (struct MHD_Response))))
628  return NULL;
629  response->fd = -1;
630  if (! MHD_mutex_init_ (&response->mutex))
631  {
632  free (response);
633  return NULL;
634  }
635  if ((must_copy) && (size > 0))
636  {
637  if (NULL == (tmp = malloc (size)))
638  {
639  MHD_mutex_destroy_chk_ (&response->mutex);
640  free (response);
641  return NULL;
642  }
643  memcpy (tmp, data, size);
644  must_free = MHD_YES;
645  data = tmp;
646  }
647  if (must_free)
648  {
649  response->crfc = &free;
650  response->crc_cls = data;
651  }
652  response->reference_count = 1;
653  response->total_size = size;
654  response->data = data;
655  response->data_size = size;
656  return response;
657 }
658 
659 
670 struct MHD_Response *
672  void *buffer,
673  enum MHD_ResponseMemoryMode mode)
674 {
675  return MHD_create_response_from_data (size,
676  buffer,
677  mode == MHD_RESPMEM_MUST_FREE,
678  mode == MHD_RESPMEM_MUST_COPY);
679 }
680 
681 
682 #ifdef UPGRADE_SUPPORT
683 
695 _MHD_EXTERN int
696 MHD_upgrade_action (struct MHD_UpgradeResponseHandle *urh,
697  enum MHD_UpgradeAction action,
698  ...)
699 {
700  struct MHD_Connection *connection;
701  struct MHD_Daemon *daemon;
702 
703  if (NULL == urh)
704  return MHD_NO;
705  connection = urh->connection;
706 
707  /* Precaution checks on external data. */
708  if (NULL == connection)
709  return MHD_NO;
710  daemon = connection->daemon;
711  if (NULL == daemon)
712  return MHD_NO;
713 
714  switch (action)
715  {
717  if (urh->was_closed)
718  return MHD_NO; /* Already closed. */
719 
720  /* transition to special 'closed' state for start of cleanup */
721 #ifdef HTTPS_SUPPORT
722  if (0 != (daemon->options & MHD_USE_TLS) )
723  {
724  /* signal that app is done by shutdown() of 'app' socket */
725  /* Application will not use anyway this socket after this command. */
726  shutdown (urh->app.socket,
727  SHUT_RDWR);
728  }
729 #endif /* HTTPS_SUPPORT */
730  mhd_assert (MHD_CONNECTION_UPGRADE == connection->state);
731  urh->was_closed = true;
732  /* As soon as connection will be marked with BOTH
733  * 'urh->was_closed' AND 'urh->clean_ready', it will
734  * be moved to cleanup list by MHD_resume_connection(). */
735  MHD_resume_connection (connection);
736  return MHD_YES;
737  default:
738  /* we don't understand this one */
739  return MHD_NO;
740  }
741 }
742 
743 
757 int
759  struct MHD_Connection *connection)
760 {
761  struct MHD_Daemon *daemon = connection->daemon;
762  struct MHD_UpgradeResponseHandle *urh;
763  size_t rbo;
764 
765  if (0 == (daemon->options & MHD_ALLOW_UPGRADE))
766  return MHD_NO;
767 
768  if (NULL ==
769  MHD_get_response_header (response,
771  {
772 #ifdef HAVE_MESSAGES
773  MHD_DLOG (daemon,
774  _("Invalid response for upgrade: application failed to set the 'Upgrade' header!\n"));
775 #endif
776  return MHD_NO;
777  }
778 
779  urh = MHD_calloc_ (1, sizeof (struct MHD_UpgradeResponseHandle));
780  if (NULL == urh)
781  return MHD_NO;
782  urh->connection = connection;
783  rbo = connection->read_buffer_offset;
784  connection->read_buffer_offset = 0;
785 #ifdef HTTPS_SUPPORT
786  if (0 != (daemon->options & MHD_USE_TLS) )
787  {
788  struct MemoryPool *pool;
789  size_t avail;
790  char *buf;
791  MHD_socket sv[2];
792 #if defined(MHD_socket_nosignal_) || !defined(MHD_socket_pair_nblk_)
793  int res1;
794  int res2;
795 #endif /* MHD_socket_nosignal_ || !MHD_socket_pair_nblk_ */
796 
797 #ifdef MHD_socket_pair_nblk_
798  if (! MHD_socket_pair_nblk_ (sv))
799  {
800  free (urh);
801  return MHD_NO;
802  }
803 #else /* !MHD_socket_pair_nblk_ */
804  if (! MHD_socket_pair_ (sv))
805  {
806  free (urh);
807  return MHD_NO;
808  }
809  res1 = MHD_socket_nonblocking_(sv[0]);
810  res2 = MHD_socket_nonblocking_(sv[1]);
811  if ( (! res1) || (! res2) )
812  {
813 #ifdef HAVE_MESSAGES
814  MHD_DLOG (daemon,
815  _("Failed to make loopback sockets non-blocking.\n"));
816 #endif
817  if (! res2)
818  {
819  /* Socketpair cannot be used. */
820  MHD_socket_close_chk_ (sv[0]);
821  MHD_socket_close_chk_ (sv[1]);
822  free (urh);
823  return MHD_NO;
824  }
825  }
826 #endif /* !MHD_socket_pair_nblk_ */
827 #ifdef MHD_socket_nosignal_
828  res1 = MHD_socket_nosignal_(sv[0]);
829  res2 = MHD_socket_nosignal_(sv[1]);
830  if ( (! res1) || (! res2) )
831  {
832 #ifdef HAVE_MESSAGES
833  MHD_DLOG (daemon,
834  _("Failed to set SO_NOSIGPIPE on loopback sockets.\n"));
835 #endif
836 #ifndef MSG_NOSIGNAL
837  if (!res2)
838  {
839  /* Socketpair cannot be used. */
840  MHD_socket_close_chk_ (sv[0]);
841  MHD_socket_close_chk_ (sv[1]);
842  free (urh);
843  return MHD_NO;
844  }
845 #endif /* ! MSG_NOSIGNAL */
846  }
847 #endif /* MHD_socket_nosignal_ */
848  if ( (! MHD_SCKT_FD_FITS_FDSET_ (sv[1],
849  NULL)) &&
850  (0 == (daemon->options & (MHD_USE_POLL | MHD_USE_EPOLL))) )
851  {
852 #ifdef HAVE_MESSAGES
853  MHD_DLOG (daemon,
854  _("Socketpair descriptor larger than FD_SETSIZE: %d > %d\n"),
855  (int) sv[1],
856  (int) FD_SETSIZE);
857 #endif
858  MHD_socket_close_chk_ (sv[0]);
859  MHD_socket_close_chk_ (sv[1]);
860  free (urh);
861  return MHD_NO;
862  }
863  urh->app.socket = sv[0];
864  urh->app.urh = urh;
865  urh->app.celi = MHD_EPOLL_STATE_UNREADY;
866  urh->mhd.socket = sv[1];
867  urh->mhd.urh = urh;
868  urh->mhd.celi = MHD_EPOLL_STATE_UNREADY;
869  pool = connection->pool;
870  avail = MHD_pool_get_free (pool);
871  if (avail < RESERVE_EBUF_SIZE)
872  {
873  /* connection's pool is totally at the limit,
874  use our 'emergency' buffer of #RESERVE_EBUF_SIZE bytes. */
875  avail = RESERVE_EBUF_SIZE;
876  buf = urh->e_buf;
877  }
878  else
879  {
880  /* Normal case: grab all remaining memory from the
881  connection's pool for the IO buffers; the connection
882  certainly won't need it anymore as we've upgraded
883  to another protocol. */
884  buf = MHD_pool_allocate (pool,
885  avail,
886  MHD_NO);
887  }
888  /* use half the buffer for inbound, half for outbound */
889  urh->in_buffer_size = avail / 2;
890  urh->out_buffer_size = avail - urh->in_buffer_size;
891  urh->in_buffer = buf;
892  urh->out_buffer = &buf[urh->in_buffer_size];
893 #ifdef EPOLL_SUPPORT
894  /* Launch IO processing by the event loop */
895  if (0 != (daemon->options & MHD_USE_EPOLL))
896  {
897  /* We're running with epoll(), need to add the sockets
898  to the event set of the daemon's `epoll_upgrade_fd` */
899  struct epoll_event event;
900 
901  mhd_assert (-1 != daemon->epoll_upgrade_fd);
902  /* First, add network socket */
903  event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
904  event.data.ptr = &urh->app;
905  if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
906  EPOLL_CTL_ADD,
907  connection->socket_fd,
908  &event))
909  {
910 #ifdef HAVE_MESSAGES
911  MHD_DLOG (daemon,
912  _("Call to epoll_ctl failed: %s\n"),
914 #endif
915  MHD_socket_close_chk_ (sv[0]);
916  MHD_socket_close_chk_ (sv[1]);
917  free (urh);
918  return MHD_NO;
919  }
920 
921  /* Second, add our end of the UNIX socketpair() */
922  event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
923  event.data.ptr = &urh->mhd;
924  if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
925  EPOLL_CTL_ADD,
926  urh->mhd.socket,
927  &event))
928  {
929  event.events = EPOLLIN | EPOLLOUT | EPOLLPRI;
930  event.data.ptr = &urh->app;
931  if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
932  EPOLL_CTL_DEL,
933  connection->socket_fd,
934  &event))
935  MHD_PANIC (_("Error cleaning up while handling epoll error"));
936 #ifdef HAVE_MESSAGES
937  MHD_DLOG (daemon,
938  _("Call to epoll_ctl failed: %s\n"),
940 #endif
941  MHD_socket_close_chk_ (sv[0]);
942  MHD_socket_close_chk_ (sv[1]);
943  free (urh);
944  return MHD_NO;
945  }
946  EDLL_insert (daemon->eready_urh_head,
947  daemon->eready_urh_tail,
948  urh);
949  urh->in_eready_list = true;
950  }
951 #endif /* EPOLL_SUPPORT */
952  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION) )
953  {
954  /* This takes care of further processing for most event loops:
955  simply add to DLL for bi-direcitonal processing */
956  DLL_insert (daemon->urh_head,
957  daemon->urh_tail,
958  urh);
959  }
960  /* In thread-per-connection mode, thread will switch to forwarding once
961  * connection.urh is not NULL and connection.state == MHD_CONNECTION_UPGRADE.
962  */
963  }
964  else
965  {
966  urh->app.socket = MHD_INVALID_SOCKET;
967  urh->mhd.socket = MHD_INVALID_SOCKET;
968  /* Non-TLS connection do not hold any additional resources. */
969  urh->clean_ready = true;
970  }
971 #else /* ! HTTPS_SUPPORT */
972  urh->clean_ready = true;
973 #endif /* ! HTTPS_SUPPORT */
974  connection->urh = urh;
975  /* As far as MHD's event loops are concerned, this connection is
976  suspended; it will be resumed once application is done by the
977  #MHD_upgrade_action() function */
978  internal_suspend_connection_ (connection);
979 
980  /* hand over socket to application */
981  response->upgrade_handler (response->upgrade_handler_cls,
982  connection,
983  connection->client_context,
984  connection->read_buffer,
985  rbo,
986 #ifdef HTTPS_SUPPORT
987  (0 == (daemon->options & MHD_USE_TLS) ) ?
988  connection->socket_fd : urh->app.socket,
989 #else /* ! HTTPS_SUPPORT */
990  connection->socket_fd,
991 #endif /* ! HTTPS_SUPPORT */
992  urh);
993  return MHD_YES;
994 }
995 
996 
1026 _MHD_EXTERN struct MHD_Response *
1028  void *upgrade_handler_cls)
1029 {
1030  struct MHD_Response *response;
1031 
1032  if (NULL == upgrade_handler)
1033  return NULL; /* invalid request */
1034  response = MHD_calloc_ (1, sizeof (struct MHD_Response));
1035  if (NULL == response)
1036  return NULL;
1037  if (! MHD_mutex_init_ (&response->mutex))
1038  {
1039  free (response);
1040  return NULL;
1041  }
1042  response->upgrade_handler = upgrade_handler;
1043  response->upgrade_handler_cls = upgrade_handler_cls;
1044  response->total_size = MHD_SIZE_UNKNOWN;
1045  response->reference_count = 1;
1046  if (MHD_NO ==
1047  MHD_add_response_header (response,
1049  "Upgrade"))
1050  {
1051  MHD_destroy_response (response);
1052  return NULL;
1053  }
1054  return response;
1055 }
1056 #endif /* UPGRADE_SUPPORT */
1057 
1058 
1068 void
1070 {
1071  struct MHD_HTTP_Header *pos;
1072 
1073  if (NULL == response)
1074  return;
1075  MHD_mutex_lock_chk_ (&response->mutex);
1076  if (0 != --(response->reference_count))
1077  {
1078  MHD_mutex_unlock_chk_ (&response->mutex);
1079  return;
1080  }
1081  MHD_mutex_unlock_chk_ (&response->mutex);
1082  MHD_mutex_destroy_chk_ (&response->mutex);
1083  if (NULL != response->crfc)
1084  response->crfc (response->crc_cls);
1085  while (NULL != response->first_header)
1086  {
1087  pos = response->first_header;
1088  response->first_header = pos->next;
1089  free (pos->header);
1090  free (pos->value);
1091  free (pos);
1092  }
1093  free (response);
1094 }
1095 
1096 
1102 void
1104 {
1105  MHD_mutex_lock_chk_ (&response->mutex);
1106  (response->reference_count)++;
1107  MHD_mutex_unlock_chk_ (&response->mutex);
1108 }
1109 
1110 
1111 /* end of response.c */
int(* MHD_KeyValueIterator)(void *cls, enum MHD_ValueKind kind, const char *key, const char *value)
Definition: microhttpd.h:1996
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:354
uint64_t total_size
Definition: internal.h:345
additional automatic macros for MHD_config.h
_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:316
uint64_t fd_off
Definition: internal.h:356
static void free_callback(void *cls)
Definition: response.c:474
#define DLL_insert(head, tail, element)
Definition: internal.h:1710
enum MHD_CONNECTION_STATE state
Definition: internal.h:899
void * data
Definition: microhttpd.h:2661
_MHD_EXTERN 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
void int int must_copy
Definition: microhttpd.h:2661
MHD_ContentReaderFreeCallback crfc
Definition: internal.h:320
Methods for managing connections.
void(* MHD_ContentReaderFreeCallback)(void *cls)
Definition: microhttpd.h:2063
static ssize_t file_reader(void *cls, uint64_t pos, char *buf, size_t max)
Definition: response.c:390
#define MHD_YES
Definition: microhttpd.h:134
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_fd64(uint64_t size, int fd)
Definition: response.c:593
Header for platform missing functions.
size_t data_size
Definition: internal.h:362
enum MHD_ValueKind kind
Definition: internal.h:280
struct MHD_HTTP_Header * first_header
Definition: internal.h:296
#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:203
int MHD_socket
Definition: microhttpd.h:181
#define MHD_mutex_destroy_chk_(pmutex)
Definition: mhd_locks.h:118
#define EDLL_insert(head, tail, element)
Definition: internal.h:1799
char * value
Definition: internal.h:274
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:650
#define mhd_assert(CHK)
Definition: mhd_assert.h:39
MHD_ResponseOptions
Definition: microhttpd.h:2598
#define MHD_mutex_unlock_chk_(pmutex)
Definition: mhd_locks.h:177
Header for platform-independent inter-thread communication.
size_t data_buffer_size
Definition: internal.h:367
int fd
Definition: microhttpd.h:2771
void * client_context
Definition: internal.h:683
#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:857
_MHD_EXTERN int MHD_add_response_footer(struct MHD_Response *response, const char *footer, const char *content)
Definition: response.c:139
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_fd_at_offset64(uint64_t size, int fd, uint64_t offset)
Definition: response.c:528
enum MHD_FLAG options
Definition: internal.h:1569
ssize_t(* MHD_ContentReaderCallback)(void *cls, uint64_t pos, char *buf, size_t max)
Definition: microhttpd.h:2047
unsigned int reference_count
Definition: internal.h:373
_MHD_EXTERN void MHD_destroy_response(struct MHD_Response *response)
Definition: response.c:1069
#define _MHD_EXTERN
Definition: mhd_options.h:51
void MHD_increment_response_rc(struct MHD_Response *response)
Definition: response.c:1103
void int must_free
Definition: microhttpd.h:2661
#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:617
MHD_ValueKind
Definition: microhttpd.h:1517
char * read_buffer
Definition: internal.h:723
limits values definitions
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_fd(size_t size, int fd)
Definition: response.c:570
_MHD_EXTERN int MHD_upgrade_action(struct MHD_UpgradeResponseHandle *urh, enum MHD_UpgradeAction action,...)
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:270
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:185
#define INT32_MAX
Definition: mhd_limits.h:65
#define MHD_socket_last_strerr_()
Definition: mhd_sockets.h:532
int off_t offset
Definition: microhttpd.h:2771
void internal_suspend_connection_(struct MHD_Connection *connection)
Definition: daemon.c:2559
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_buffer(size_t size, void *buffer, enum MHD_ResponseMemoryMode mode)
Definition: response.c:671
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:269
enum MHD_ResponseFlags flags
Definition: internal.h:383
struct MemoryPool * pool
Definition: internal.h:675
_MHD_EXTERN struct MHD_Response * MHD_create_response_for_upgrade(MHD_UpgradeHandler upgrade_handler, void *upgrade_handler_cls)
#define MHD_PANIC(msg)
Definition: internal.h:65
Header for string manipulating helpers.
struct MHD_HTTP_Header * next
Definition: internal.h:264
#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:393
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:2898
#define MHD_HTTP_HEADER_CONNECTION
Definition: microhttpd.h:440
int MHD_str_equal_caseless_(const char *str1, const char *str2)
Definition: mhd_str.c:329
#define MHD_CONTENT_READER_END_WITH_ERROR
Definition: microhttpd.h:161
MHD_ContentReaderCallback crc
Definition: internal.h:314
void * crc_cls
Definition: internal.h:308
MHD_UpgradeAction
Definition: microhttpd.h:2811
MHD_mutex_ mutex
Definition: internal.h:340
#define _(String)
Definition: mhd_options.h:42
#define MHD_SIZE_UNKNOWN
Definition: microhttpd.h:153
char * data
Definition: internal.h:302
_MHD_EXTERN 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:772
#define MHD_NO
Definition: microhttpd.h:139
volatile bool shutdown
Definition: internal.h:1510
MHD_ResponseFlags
Definition: microhttpd.h:2578
_MHD_EXTERN const char * MHD_get_response_header(struct MHD_Response *response, const char *key)
Definition: response.c:238
struct MHD_Response * MHD_create_response_from_fd_at_offset(size_t size, int fd, off_t offset)
Definition: response.c:501
#define MHD_mutex_lock_chk_(pmutex)
Definition: mhd_locks.h:151
_MHD_EXTERN int MHD_get_response_headers(struct MHD_Response *response, MHD_KeyValueIterator iterator, void *iterator_cls)
Definition: response.c:206
MHD_ResponseMemoryMode
Definition: microhttpd.h:2671
_MHD_EXTERN void MHD_resume_connection(struct MHD_Connection *connection)
Definition: daemon.c:2677
memory pool; mostly used for efficient (de)allocation for each connection and bounding memory use for...