GNU libmicrohttpd  0.9.29
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
connection.c
Go to the documentation of this file.
1 /*
2  This file is part of libmicrohttpd
3  (C) 2007-2013 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 
19 */
20 
28 #include "internal.h"
29 #include <limits.h>
30 #include "connection.h"
31 #include "memorypool.h"
32 #include "response.h"
33 #include "reason_phrase.h"
34 
35 #if HAVE_NETINET_TCP_H
36 /* for TCP_CORK */
37 #include <netinet/tcp.h>
38 #endif
39 
40 #if defined(_WIN32) && defined(MHD_W32_MUTEX_)
41 #ifndef WIN32_LEAN_AND_MEAN
42 #define WIN32_LEAN_AND_MEAN 1
43 #endif /* !WIN32_LEAN_AND_MEAN */
44 #include <windows.h>
45 #endif /* _WIN32 && MHD_W32_MUTEX_ */
46 
47 
51 #define HTTP_100_CONTINUE "HTTP/1.1 100 Continue\r\n\r\n"
52 
60 #if HAVE_MESSAGES
61 #define REQUEST_TOO_BIG "<html><head><title>Request too big</title></head><body>Your HTTP header was too big for the memory constraints of this webserver.</body></html>"
62 #else
63 #define REQUEST_TOO_BIG ""
64 #endif
65 
73 #if HAVE_MESSAGES
74 #define REQUEST_LACKS_HOST "<html><head><title>&quot;Host:&quot; header required</title></head><body>In HTTP 1.1, requests must include a &quot;Host:&quot; header, and your HTTP 1.1 request lacked such a header.</body></html>"
75 #else
76 #define REQUEST_LACKS_HOST ""
77 #endif
78 
86 #if HAVE_MESSAGES
87 #define REQUEST_MALFORMED "<html><head><title>Request malformed</title></head><body>Your HTTP request was syntactically incorrect.</body></html>"
88 #else
89 #define REQUEST_MALFORMED ""
90 #endif
91 
98 #if HAVE_MESSAGES
99 #define INTERNAL_ERROR "<html><head><title>Internal server error</title></head><body>Some programmer needs to study the manual more carefully.</body></html>"
100 #else
101 #define INTERNAL_ERROR ""
102 #endif
103 
108 #define DEBUG_CLOSE MHD_NO
109 
113 #define DEBUG_SEND_DATA MHD_NO
114 
115 
127 int
129  enum MHD_ValueKind kind,
130  MHD_KeyValueIterator iterator, void *iterator_cls)
131 {
132  int ret;
133  struct MHD_HTTP_Header *pos;
134 
135  if (NULL == connection)
136  return -1;
137  ret = 0;
138  for (pos = connection->headers_received; NULL != pos; pos = pos->next)
139  if (0 != (pos->kind & kind))
140  {
141  ret++;
142  if ((NULL != iterator) &&
143  (MHD_YES != iterator (iterator_cls,
144  kind, pos->header, pos->value)))
145  return ret;
146  }
147  return ret;
148 }
149 
150 
176 int
178  enum MHD_ValueKind kind,
179  const char *key, const char *value)
180 {
181  struct MHD_HTTP_Header *pos;
182 
183  pos = MHD_pool_allocate (connection->pool,
184  sizeof (struct MHD_HTTP_Header), MHD_YES);
185  if (NULL == pos)
186  return MHD_NO;
187  pos->header = (char *) key;
188  pos->value = (char *) value;
189  pos->kind = kind;
190  pos->next = NULL;
191  /* append 'pos' to the linked list of headers */
192  if (NULL == connection->headers_received_tail)
193  {
194  connection->headers_received = pos;
195  connection->headers_received_tail = pos;
196  }
197  else
198  {
199  connection->headers_received_tail->next = pos;
200  connection->headers_received_tail = pos;
201  }
202  return MHD_YES;
203 }
204 
205 
216 const char *
218  enum MHD_ValueKind kind, const char *key)
219 {
220  struct MHD_HTTP_Header *pos;
221 
222  if (NULL == connection)
223  return NULL;
224  for (pos = connection->headers_received; NULL != pos; pos = pos->next)
225  if ((0 != (pos->kind & kind)) &&
226  ( (key == pos->header) ||
227  ( (NULL != pos->header) &&
228  (NULL != key) &&
229  (MHD_str_equal_caseless_(key, pos->header)))))
230  return pos->value;
231  return NULL;
232 }
233 
234 
242 static int
243 need_100_continue (struct MHD_Connection *connection)
244 {
245  const char *expect;
246 
247  return ( (NULL == connection->response) &&
248  (NULL != connection->version) &&
249  (MHD_str_equal_caseless_(connection->version,
251  (NULL != (expect = MHD_lookup_connection_value (connection,
254  (MHD_str_equal_caseless_(expect, "100-continue")) &&
255  (connection->continue_message_write_offset <
256  strlen (HTTP_100_CONTINUE)) );
257 }
258 
259 
267 void
269  enum MHD_RequestTerminationCode termination_code)
270 {
271  struct MHD_Daemon *daemon;
272 
273  daemon = connection->daemon;
274  if (0 == (connection->daemon->options & MHD_USE_EPOLL_TURBO))
275  shutdown (connection->socket_fd,
276  (MHD_YES == connection->read_closed) ? SHUT_WR : SHUT_RDWR);
277  connection->state = MHD_CONNECTION_CLOSED;
279  if ( (NULL != daemon->notify_completed) &&
280  (MHD_YES == connection->client_aware) )
281  daemon->notify_completed (daemon->notify_completed_cls,
282  connection,
283  &connection->client_context,
284  termination_code);
285  connection->client_aware = MHD_NO;
286 }
287 
288 
296 static void
298  const char *emsg)
299 {
300 #if HAVE_MESSAGES
301  if (NULL != emsg)
302  MHD_DLOG (connection->daemon, emsg);
303 #endif
305 }
306 
307 
312 #if HAVE_MESSAGES
313 #define CONNECTION_CLOSE_ERROR(c, emsg) connection_close_error (c, emsg)
314 #else
315 #define CONNECTION_CLOSE_ERROR(c, emsg) connection_close_error (c, NULL)
316 #endif
317 
318 
331 static int
333 {
334  ssize_t ret;
335  struct MHD_Response *response;
336 
337  response = connection->response;
338  if (NULL == response->crc)
339  return MHD_YES;
340  if (0 == response->total_size)
341  return MHD_YES; /* 0-byte response is always ready */
342  if ( (response->data_start <=
343  connection->response_write_position) &&
344  (response->data_size + response->data_start >
345  connection->response_write_position) )
346  return MHD_YES; /* response already ready */
347 #if LINUX
348  if ( (MHD_INVALID_SOCKET != response->fd) &&
349  (0 == (connection->daemon->options & MHD_USE_SSL)) )
350  {
351  /* will use sendfile, no need to bother response crc */
352  return MHD_YES;
353  }
354 #endif
355 
356  ret = response->crc (response->crc_cls,
357  connection->response_write_position,
358  response->data,
359  MHD_MIN (response->data_buffer_size,
360  response->total_size -
361  connection->response_write_position));
362  if ( (((ssize_t) MHD_CONTENT_READER_END_OF_STREAM) == ret) ||
363  (((ssize_t) MHD_CONTENT_READER_END_WITH_ERROR) == ret) )
364  {
365  /* either error or http 1.0 transfer, close socket! */
366  response->total_size = connection->response_write_position;
367  if (NULL != response->crc)
368  (void) MHD_mutex_unlock_ (&response->mutex);
369  if ( ((ssize_t)MHD_CONTENT_READER_END_OF_STREAM) == ret)
371  else
372  CONNECTION_CLOSE_ERROR (connection,
373  "Closing connection (stream error)\n");
374  return MHD_NO;
375  }
376  response->data_start = connection->response_write_position;
377  response->data_size = ret;
378  if (0 == ret)
379  {
381  if (NULL != response->crc)
382  (void) MHD_mutex_unlock_ (&response->mutex);
383  return MHD_NO;
384  }
385  return MHD_YES;
386 }
387 
388 
398 static int
400 {
401  ssize_t ret;
402  char *buf;
403  struct MHD_Response *response;
404  size_t size;
405  char cbuf[10]; /* 10: max strlen of "%x\r\n" */
406  size_t cblen;
407 
408  response = connection->response;
409  if (0 == connection->write_buffer_size)
410  {
411  size = connection->daemon->pool_size;
412  do
413  {
414  size /= 2;
415  if (size < 128)
416  {
417  /* not enough memory */
418  CONNECTION_CLOSE_ERROR (connection,
419  "Closing connection (out of memory)\n");
420  return MHD_NO;
421  }
422  buf = MHD_pool_allocate (connection->pool, size, MHD_NO);
423  }
424  while (NULL == buf);
425  connection->write_buffer_size = size;
426  connection->write_buffer = buf;
427  }
428 
429  if ( (response->data_start <=
430  connection->response_write_position) &&
431  (response->data_size + response->data_start >
432  connection->response_write_position) )
433  {
434  /* buffer already ready, use what is there for the chunk */
435  ret = response->data_size + response->data_start - connection->response_write_position;
436  if ( (ret > 0) &&
437  (((size_t) ret) > connection->write_buffer_size - sizeof (cbuf) - 2) )
438  ret = connection->write_buffer_size - sizeof (cbuf) - 2;
439  memcpy (&connection->write_buffer[sizeof (cbuf)],
440  &response->data[connection->response_write_position - response->data_start],
441  ret);
442  }
443  else
444  {
445  /* buffer not in range, try to fill it */
446  if (0 == response->total_size)
447  ret = 0; /* response must be empty, don't bother calling crc */
448  else
449  ret = response->crc (response->crc_cls,
450  connection->response_write_position,
451  &connection->write_buffer[sizeof (cbuf)],
452  connection->write_buffer_size - sizeof (cbuf) - 2);
453  }
454  if ( ((ssize_t) MHD_CONTENT_READER_END_WITH_ERROR) == ret)
455  {
456  /* error, close socket! */
457  response->total_size = connection->response_write_position;
458  CONNECTION_CLOSE_ERROR (connection,
459  "Closing connection (error generating response)\n");
460  return MHD_NO;
461  }
462  if ( (((ssize_t) MHD_CONTENT_READER_END_OF_STREAM) == ret) ||
463  (0 == response->total_size) )
464  {
465  /* end of message, signal other side! */
466  strcpy (connection->write_buffer, "0\r\n");
467  connection->write_buffer_append_offset = 3;
468  connection->write_buffer_send_offset = 0;
469  response->total_size = connection->response_write_position;
470  return MHD_YES;
471  }
472  if (0 == ret)
473  {
475  return MHD_NO;
476  }
477  if (ret > 0xFFFFFF)
478  ret = 0xFFFFFF;
479  MHD_snprintf_ (cbuf,
480  sizeof (cbuf),
481  "%X\r\n", (unsigned int) ret);
482  cblen = strlen (cbuf);
483  EXTRA_CHECK (cblen <= sizeof (cbuf));
484  memcpy (&connection->write_buffer[sizeof (cbuf) - cblen], cbuf, cblen);
485  memcpy (&connection->write_buffer[sizeof (cbuf) + ret], "\r\n", 2);
486  connection->response_write_position += ret;
487  connection->write_buffer_send_offset = sizeof (cbuf) - cblen;
488  connection->write_buffer_append_offset = sizeof (cbuf) + ret + 2;
489  return MHD_YES;
490 }
491 
492 
509 static int
510 keepalive_possible (struct MHD_Connection *connection)
511 {
512  const char *end;
513 
514  if (NULL == connection->version)
515  return MHD_NO;
516  if ( (NULL != connection->response) &&
517  (0 != (connection->response->flags & MHD_RF_HTTP_VERSION_1_0_ONLY) ) )
518  return MHD_NO;
519  end = MHD_lookup_connection_value (connection,
522  if (MHD_str_equal_caseless_(connection->version,
524  {
525  if (NULL == end)
526  return MHD_YES;
527  if ( (MHD_str_equal_caseless_ (end, "close")) ||
528  (MHD_str_equal_caseless_ (end, "upgrade")) )
529  return MHD_NO;
530  return MHD_YES;
531  }
532  if (MHD_str_equal_caseless_(connection->version,
534  {
535  if (NULL == end)
536  return MHD_NO;
537  if (MHD_str_equal_caseless_(end, "Keep-Alive"))
538  return MHD_YES;
539  return MHD_NO;
540  }
541  return MHD_NO;
542 }
543 
544 
551 static void
552 get_date_string (char *date)
553 {
554  static const char *const days[] =
555  { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
556  static const char *const mons[] =
557  { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct",
558  "Nov", "Dec"
559  };
560  struct tm now;
561  time_t t;
562 #if defined(_WIN32) && !defined(HAVE_GMTIME_S) && !defined(__CYGWIN__)
563  struct tm* pNow;
564 #endif
565 
566  date[0] = 0;
567  time (&t);
568 #if !defined(_WIN32)
569  if (NULL != gmtime_r (&t, &now))
570  {
571 #elif defined(HAVE_GMTIME_S)
572  if (0 == gmtime_s (&now, &t))
573  {
574 #elif defined(__CYGWIN__)
575  if (NULL != gmtime_r (&t, &now))
576  {
577 #else
578  pNow = gmtime(&t);
579  if (NULL != pNow)
580  {
581  now = *pNow;
582 #endif
583  sprintf (date,
584  "Date: %3s, %02u %3s %04u %02u:%02u:%02u GMT\r\n",
585  days[now.tm_wday % 7],
586  (unsigned int) now.tm_mday,
587  mons[now.tm_mon % 12],
588  (unsigned int) (1900 + now.tm_year),
589  (unsigned int) now.tm_hour,
590  (unsigned int) now.tm_min,
591  (unsigned int) now.tm_sec);
592  }
593 }
594 
595 
607 static int
609 {
610  void *buf;
611  size_t new_size;
612 
613  if (0 == connection->read_buffer_size)
614  new_size = connection->daemon->pool_size / 2;
615  else
616  new_size = connection->read_buffer_size + MHD_BUF_INC_SIZE;
617  buf = MHD_pool_reallocate (connection->pool,
618  connection->read_buffer,
619  connection->read_buffer_size,
620  new_size);
621  if (NULL == buf)
622  return MHD_NO;
623  /* we can actually grow the buffer, do it! */
624  connection->read_buffer = buf;
625  connection->read_buffer_size = new_size;
626  return MHD_YES;
627 }
628 
629 
639 static int
641 {
642  size_t size;
643  size_t off;
644  struct MHD_HTTP_Header *pos;
645  char code[256];
646  char date[128];
647  char content_length_buf[128];
648  size_t content_length_len;
649  char *data;
650  enum MHD_ValueKind kind;
651  const char *reason_phrase;
652  uint32_t rc;
653  const char *client_requested_close;
654  const char *response_has_close;
655  const char *response_has_keepalive;
656  const char *have_encoding;
657  const char *have_content_length;
658  int must_add_close;
659  int must_add_chunked_encoding;
660  int must_add_keep_alive;
661  int must_add_content_length;
662 
663  EXTRA_CHECK (NULL != connection->version);
664  if (0 == strlen (connection->version))
665  {
666  data = MHD_pool_allocate (connection->pool, 0, MHD_YES);
667  connection->write_buffer = data;
668  connection->write_buffer_append_offset = 0;
669  connection->write_buffer_send_offset = 0;
670  connection->write_buffer_size = 0;
671  return MHD_YES;
672  }
673  if (MHD_CONNECTION_FOOTERS_RECEIVED == connection->state)
674  {
675  rc = connection->responseCode & (~MHD_ICY_FLAG);
676  reason_phrase = MHD_get_reason_phrase_for (rc);
677  sprintf (code,
678  "%s %u %s\r\n",
679  (0 != (connection->responseCode & MHD_ICY_FLAG))
680  ? "ICY"
682  connection->version))
685  rc,
686  reason_phrase);
687  off = strlen (code);
688  /* estimate size */
689  size = off + 2; /* +2 for extra "\r\n" at the end */
690  kind = MHD_HEADER_KIND;
691  if ( (0 == (connection->daemon->options & MHD_SUPPRESS_DATE_NO_CLOCK)) &&
692  (NULL == MHD_get_response_header (connection->response,
694  get_date_string (date);
695  else
696  date[0] = '\0';
697  size += strlen (date);
698  }
699  else
700  {
701  /* 2 bytes for final CRLF of a Chunked-Body */
702  size = 2;
703  kind = MHD_FOOTER_KIND;
704  off = 0;
705  }
706 
707  /* calculate extra headers we need to add, such as 'Connection: close',
708  first see what was explicitly requested by the application */
709  must_add_close = MHD_NO;
710  must_add_chunked_encoding = MHD_NO;
711  must_add_keep_alive = MHD_NO;
712  must_add_content_length = MHD_NO;
713  switch (connection->state)
714  {
716  response_has_close = MHD_get_response_header (connection->response,
718  response_has_keepalive = response_has_close;
719  if ( (NULL != response_has_close) &&
720  (!MHD_str_equal_caseless_ (response_has_close, "close")) )
721  response_has_close = NULL;
722  if ( (NULL != response_has_keepalive) &&
723  (!MHD_str_equal_caseless_ (response_has_keepalive, "Keep-Alive")) )
724  response_has_keepalive = NULL;
725  client_requested_close = MHD_lookup_connection_value (connection,
728  if ( (NULL != client_requested_close) &&
729  (!MHD_str_equal_caseless_ (client_requested_close, "close")) )
730  client_requested_close = NULL;
731 
732  /* now analyze chunked encoding situation */
733  connection->have_chunked_upload = MHD_NO;
734 
735  if ( (MHD_SIZE_UNKNOWN == connection->response->total_size) &&
736  (NULL == response_has_close) &&
737  (NULL == client_requested_close) )
738  {
739  /* size is unknown, and close was not explicitly requested;
740  need to either to HTTP 1.1 chunked encoding or
741  close the connection */
742  /* 'close' header doesn't exist yet, see if we need to add one;
743  if the client asked for a close, no need to start chunk'ing */
744  if (MHD_YES == keepalive_possible (connection))
745  {
746  have_encoding = MHD_get_response_header (connection->response,
748  if (NULL == have_encoding)
749  {
750  must_add_chunked_encoding = MHD_YES;
751  connection->have_chunked_upload = MHD_YES;
752  }
753  else if (MHD_str_equal_caseless_(have_encoding, "identity"))
754  {
755  /* application forced identity encoding, can't do 'chunked' */
756  must_add_close = MHD_YES;
757  }
758  else
759  {
760  connection->have_chunked_upload = MHD_YES;
761  }
762  }
763  else
764  {
765  /* Keep alive not possible => set close header if not present */
766  if (NULL == response_has_close)
767  must_add_close = MHD_YES;
768  }
769  }
770 
771  /* check for other reasons to add 'close' header */
772  if ( ( (NULL != client_requested_close) ||
773  (MHD_YES == connection->read_closed) ) &&
774  (NULL == response_has_close) &&
775  (0 != (connection->response->flags & MHD_RF_HTTP_VERSION_1_0_ONLY) ) )
776  must_add_close = MHD_YES;
777 
778  /* check if we should add a 'content length' header */
779  have_content_length = MHD_get_response_header (connection->response,
781 
782  if ( (MHD_SIZE_UNKNOWN != connection->response->total_size) &&
783  (NULL == have_content_length) &&
784  ( (NULL == connection->method) ||
785  (!MHD_str_equal_caseless_ (connection->method,
787  {
788  /*
789  Here we add a content-length if one is missing; however,
790  for 'connect' methods, the responses MUST NOT include a
791  content-length header *if* the response code is 2xx (in
792  which case we expect there to be no body). Still,
793  as we don't know the response code here in some cases, we
794  simply only force adding a content-length header if this
795  is not a 'connect' or if the response is not empty
796  (which is kind of more sane, because if some crazy
797  application did return content with a 2xx status code,
798  then having a content-length might again be a good idea).
799 
800  Note that the change from 'SHOULD NOT' to 'MUST NOT' is
801  a recent development of the HTTP 1.1 specification.
802  */
803  content_length_len
804  = sprintf (content_length_buf,
807  must_add_content_length = MHD_YES;
808  }
809 
810  /* check for adding keep alive */
811  if ( (NULL == response_has_keepalive) &&
812  (NULL == response_has_close) &&
813  (MHD_NO == must_add_close) &&
814  (0 == (connection->response->flags & MHD_RF_HTTP_VERSION_1_0_ONLY) ) &&
815  (MHD_YES == keepalive_possible (connection)) )
816  must_add_keep_alive = MHD_YES;
817  break;
819  break;
820  default:
821  EXTRA_CHECK (0);
822  }
823 
824  if (must_add_close)
825  size += strlen ("Connection: close\r\n");
826  if (must_add_keep_alive)
827  size += strlen ("Connection: Keep-Alive\r\n");
828  if (must_add_chunked_encoding)
829  size += strlen ("Transfer-Encoding: chunked\r\n");
830  if (must_add_content_length)
831  size += content_length_len;
832  EXTRA_CHECK (! (must_add_close && must_add_keep_alive) );
833  EXTRA_CHECK (! (must_add_chunked_encoding && must_add_content_length) );
834 
835  for (pos = connection->response->first_header; NULL != pos; pos = pos->next)
836  if ( (pos->kind == kind) &&
837  (! ( (MHD_YES == must_add_close) &&
838  (pos->value == response_has_keepalive) &&
841  size += strlen (pos->header) + strlen (pos->value) + 4; /* colon, space, linefeeds */
842  /* produce data */
843  data = MHD_pool_allocate (connection->pool, size + 1, MHD_NO);
844  if (NULL == data)
845  {
846 #if HAVE_MESSAGES
847  MHD_DLOG (connection->daemon,
848  "Not enough memory for write!\n");
849 #endif
850  return MHD_NO;
851  }
852  if (MHD_CONNECTION_FOOTERS_RECEIVED == connection->state)
853  {
854  memcpy (data, code, off);
855  }
856  if (must_add_close)
857  {
858  /* we must add the 'Connection: close' header */
859  memcpy (&data[off],
860  "Connection: close\r\n",
861  strlen ("Connection: close\r\n"));
862  off += strlen ("Connection: close\r\n");
863  }
864  if (must_add_keep_alive)
865  {
866  /* we must add the 'Connection: Keep-Alive' header */
867  memcpy (&data[off],
868  "Connection: Keep-Alive\r\n",
869  strlen ("Connection: Keep-Alive\r\n"));
870  off += strlen ("Connection: Keep-Alive\r\n");
871  }
872  if (must_add_chunked_encoding)
873  {
874  /* we must add the 'Transfer-Encoding: chunked' header */
875  memcpy (&data[off],
876  "Transfer-Encoding: chunked\r\n",
877  strlen ("Transfer-Encoding: chunked\r\n"));
878  off += strlen ("Transfer-Encoding: chunked\r\n");
879  }
880  if (must_add_content_length)
881  {
882  /* we must add the 'Content-Length' header */
883  memcpy (&data[off],
884  content_length_buf,
885  content_length_len);
886  off += content_length_len;
887  }
888  for (pos = connection->response->first_header; NULL != pos; pos = pos->next)
889  if ( (pos->kind == kind) &&
890  (! ( (pos->value == response_has_keepalive) &&
891  (MHD_YES == must_add_close) &&
894  off += sprintf (&data[off],
895  "%s: %s\r\n",
896  pos->header,
897  pos->value);
898  if (MHD_CONNECTION_FOOTERS_RECEIVED == connection->state)
899  {
900  strcpy (&data[off], date);
901  off += strlen (date);
902  }
903  memcpy (&data[off], "\r\n", 2);
904  off += 2;
905 
906  if (off != size)
907  mhd_panic (mhd_panic_cls, __FILE__, __LINE__, NULL);
908  connection->write_buffer = data;
909  connection->write_buffer_append_offset = size;
910  connection->write_buffer_send_offset = 0;
911  connection->write_buffer_size = size + 1;
912  return MHD_YES;
913 }
914 
915 
925 static void
927  unsigned int status_code,
928  const char *message)
929 {
930  struct MHD_Response *response;
931 
932  if (NULL == connection->version)
933  {
934  /* we were unable to process the full header line, so we don't
935  really know what version the client speaks; assume 1.0 */
936  connection->version = MHD_HTTP_VERSION_1_0;
937  }
939  connection->read_closed = MHD_YES;
940 #if HAVE_MESSAGES
941  MHD_DLOG (connection->daemon,
942  "Error %u (`%s') processing request, closing connection.\n",
943  status_code, message);
944 #endif
945  EXTRA_CHECK (NULL == connection->response);
946  response = MHD_create_response_from_buffer (strlen (message),
947  (void *) message,
949  MHD_queue_response (connection, status_code, response);
950  EXTRA_CHECK (NULL != connection->response);
951  MHD_destroy_response (response);
952  if (MHD_NO == build_header_response (connection))
953  {
954  /* oops - close! */
955  CONNECTION_CLOSE_ERROR (connection,
956  "Closing connection (failed to create response header)\n");
957  }
958  else
959  {
961  }
962 }
963 
964 
973 static void
975 {
976  while (1)
977  {
978 #if DEBUG_STATES
979  MHD_DLOG (connection->daemon,
980  "%s: state: %s\n",
981  __FUNCTION__,
982  MHD_state_to_string (connection->state));
983 #endif
984  switch (connection->state)
985  {
986 #if HTTPS_SUPPORT
988  if (0 == gnutls_record_get_direction (connection->tls_session))
990  else
992  break;
993 #endif
994  case MHD_CONNECTION_INIT:
997  /* while reading headers, we always grow the
998  read buffer if needed, no size-check required */
999  if ( (connection->read_buffer_offset == connection->read_buffer_size) &&
1000  (MHD_NO == try_grow_read_buffer (connection)) )
1001  {
1002  transmit_error_response (connection,
1003  (connection->url != NULL)
1006  REQUEST_TOO_BIG);
1007  continue;
1008  }
1009  if (MHD_NO == connection->read_closed)
1011  else
1013  break;
1015  EXTRA_CHECK (0);
1016  break;
1018  EXTRA_CHECK (0);
1019  break;
1022  break;
1024  if (connection->read_buffer_offset == connection->read_buffer_size)
1025  {
1026  if ((MHD_YES != try_grow_read_buffer (connection)) &&
1027  (0 != (connection->daemon->options &
1030  {
1031  /* failed to grow the read buffer, and the
1032  client which is supposed to handle the
1033  received data in a *blocking* fashion
1034  (in this mode) did not handle the data as
1035  it was supposed to!
1036  => we would either have to do busy-waiting
1037  (on the client, which would likely fail),
1038  or if we do nothing, we would just timeout
1039  on the connection (if a timeout is even
1040  set!).
1041  Solution: we kill the connection with an error */
1042  transmit_error_response (connection,
1044  INTERNAL_ERROR);
1045  continue;
1046  }
1047  }
1048  if ( (connection->read_buffer_offset < connection->read_buffer_size) &&
1049  (MHD_NO == connection->read_closed) )
1051  else
1053  break;
1056  /* while reading footers, we always grow the
1057  read buffer if needed, no size-check required */
1058  if (MHD_YES == connection->read_closed)
1059  {
1060  CONNECTION_CLOSE_ERROR (connection,
1061  NULL);
1062  continue;
1063  }
1065  /* transition to FOOTERS_RECEIVED
1066  happens in read handler */
1067  break;
1070  break;
1072  /* headers in buffer, keep writing */
1074  break;
1076  EXTRA_CHECK (0);
1077  break;
1080  break;
1083  break;
1086  break;
1089  break;
1091  EXTRA_CHECK (0);
1092  break;
1095  break;
1097  EXTRA_CHECK (0);
1098  break;
1099  case MHD_CONNECTION_CLOSED:
1101  return; /* do nothing, not even reading */
1102  default:
1103  EXTRA_CHECK (0);
1104  }
1105  break;
1106  }
1107 }
1108 
1109 
1121 static char *
1123 {
1124  char *rbuf;
1125  size_t pos;
1126 
1127  if (0 == connection->read_buffer_offset)
1128  return NULL;
1129  pos = 0;
1130  rbuf = connection->read_buffer;
1131  while ((pos < connection->read_buffer_offset - 1) &&
1132  ('\r' != rbuf[pos]) && ('\n' != rbuf[pos]))
1133  pos++;
1134  if ( (pos == connection->read_buffer_offset - 1) &&
1135  ('\n' != rbuf[pos]) )
1136  {
1137  /* not found, consider growing... */
1138  if ( (connection->read_buffer_offset == connection->read_buffer_size) &&
1139  (MHD_NO ==
1140  try_grow_read_buffer (connection)) )
1141  {
1142  transmit_error_response (connection,
1143  (NULL != connection->url)
1146  REQUEST_TOO_BIG);
1147  }
1148  return NULL;
1149  }
1150  /* found, check if we have proper LFCR */
1151  if (('\r' == rbuf[pos]) && ('\n' == rbuf[pos + 1]))
1152  rbuf[pos++] = '\0'; /* skip both r and n */
1153  rbuf[pos++] = '\0';
1154  connection->read_buffer += pos;
1155  connection->read_buffer_size -= pos;
1156  connection->read_buffer_offset -= pos;
1157  return rbuf;
1158 }
1159 
1160 
1172 static int
1174  char *key, char *value, enum MHD_ValueKind kind)
1175 {
1176  if (MHD_NO == MHD_set_connection_value (connection,
1177  kind,
1178  key, value))
1179  {
1180 #if HAVE_MESSAGES
1181  MHD_DLOG (connection->daemon,
1182  "Not enough memory to allocate header record!\n");
1183 #endif
1185  REQUEST_TOO_BIG);
1186  return MHD_NO;
1187  }
1188  return MHD_YES;
1189 }
1190 
1191 
1201 static int
1203  struct MHD_Connection *connection,
1204  char *args)
1205 {
1206  char *equals;
1207  char *amper;
1208 
1209  while (NULL != args)
1210  {
1211  equals = strchr (args, '=');
1212  amper = strchr (args, '&');
1213  if (NULL == amper)
1214  {
1215  /* last argument */
1216  if (NULL == equals)
1217  {
1218  /* got 'foo', add key 'foo' with NULL for value */
1219  MHD_unescape_plus (args);
1220  connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls,
1221  connection,
1222  args);
1223  return connection_add_header (connection,
1224  args,
1225  NULL,
1226  kind);
1227  }
1228  /* got 'foo=bar' */
1229  equals[0] = '\0';
1230  equals++;
1231  MHD_unescape_plus (args);
1232  connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls,
1233  connection,
1234  args);
1235  MHD_unescape_plus (equals);
1236  connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls,
1237  connection,
1238  equals);
1239  return connection_add_header (connection, args, equals, kind);
1240  }
1241  /* amper is non-NULL here */
1242  amper[0] = '\0';
1243  amper++;
1244  if ( (NULL == equals) ||
1245  (equals >= amper) )
1246  {
1247  /* got 'foo&bar' or 'foo&bar=val', add key 'foo' with NULL for value */
1248  MHD_unescape_plus (args);
1249  connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls,
1250  connection,
1251  args);
1252  if (MHD_NO ==
1253  connection_add_header (connection,
1254  args,
1255  NULL,
1256  kind))
1257  return MHD_NO;
1258  /* continue with 'bar' */
1259  args = amper;
1260  continue;
1261 
1262  }
1263  /* equals and amper are non-NULL here, and equals < amper,
1264  so we got regular 'foo=value&bar...'-kind of argument */
1265  equals[0] = '\0';
1266  equals++;
1267  MHD_unescape_plus (args);
1268  connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls,
1269  connection,
1270  args);
1271  MHD_unescape_plus (equals);
1272  connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls,
1273  connection,
1274  equals);
1275  if (MHD_NO == connection_add_header (connection, args, equals, kind))
1276  return MHD_NO;
1277  args = amper;
1278  }
1279  return MHD_YES;
1280 }
1281 
1282 
1288 static int
1290 {
1291  const char *hdr;
1292  char *cpy;
1293  char *pos;
1294  char *sce;
1295  char *semicolon;
1296  char *equals;
1297  char *ekill;
1298  char old;
1299  int quotes;
1300 
1301  hdr = MHD_lookup_connection_value (connection,
1304  if (NULL == hdr)
1305  return MHD_YES;
1306  cpy = MHD_pool_allocate (connection->pool, strlen (hdr) + 1, MHD_YES);
1307  if (NULL == cpy)
1308  {
1309 #if HAVE_MESSAGES
1310  MHD_DLOG (connection->daemon,
1311  "Not enough memory to parse cookies!\n");
1312 #endif
1314  REQUEST_TOO_BIG);
1315  return MHD_NO;
1316  }
1317  memcpy (cpy, hdr, strlen (hdr) + 1);
1318  pos = cpy;
1319  while (NULL != pos)
1320  {
1321  while (' ' == *pos)
1322  pos++; /* skip spaces */
1323 
1324  sce = pos;
1325  while (((*sce) != '\0') &&
1326  ((*sce) != ',') && ((*sce) != ';') && ((*sce) != '='))
1327  sce++;
1328  /* remove tailing whitespace (if any) from key */
1329  ekill = sce - 1;
1330  while ((*ekill == ' ') && (ekill >= pos))
1331  *(ekill--) = '\0';
1332  old = *sce;
1333  *sce = '\0';
1334  if (old != '=')
1335  {
1336  /* value part omitted, use empty string... */
1337  if (MHD_NO ==
1338  connection_add_header (connection, pos, "", MHD_COOKIE_KIND))
1339  return MHD_NO;
1340  if (old == '\0')
1341  break;
1342  pos = sce + 1;
1343  continue;
1344  }
1345  equals = sce + 1;
1346  quotes = 0;
1347  semicolon = equals;
1348  while ( ('\0' != semicolon[0]) &&
1349  ( (0 != quotes) ||
1350  ( (';' != semicolon[0]) &&
1351  (',' != semicolon[0]) ) ) )
1352  {
1353  if ('"' == semicolon[0])
1354  quotes = (quotes + 1) & 1;
1355  semicolon++;
1356  }
1357  if ('\0' == semicolon[0])
1358  semicolon = NULL;
1359  if (NULL != semicolon)
1360  {
1361  semicolon[0] = '\0';
1362  semicolon++;
1363  }
1364  /* remove quotes */
1365  if ( ('"' == equals[0]) &&
1366  ('"' == equals[strlen (equals) - 1]) )
1367  {
1368  equals[strlen (equals) - 1] = '\0';
1369  equals++;
1370  }
1371  if (MHD_NO == connection_add_header (connection,
1372  pos, equals, MHD_COOKIE_KIND))
1373  return MHD_NO;
1374  pos = semicolon;
1375  }
1376  return MHD_YES;
1377 }
1378 
1379 
1387 static int
1389  char *line)
1390 {
1391  char *uri;
1392  char *http_version;
1393  char *args;
1394 
1395  if (NULL == (uri = strchr (line, ' ')))
1396  return MHD_NO; /* serious error */
1397  uri[0] = '\0';
1398  connection->method = line;
1399  uri++;
1400  while (' ' == uri[0])
1401  uri++;
1402  http_version = strchr (uri, ' ');
1403  if (NULL != http_version)
1404  {
1405  http_version[0] = '\0';
1406  http_version++;
1407  }
1408  if (NULL != connection->daemon->uri_log_callback)
1409  connection->client_context
1410  = connection->daemon->uri_log_callback (connection->daemon->uri_log_callback_cls,
1411  uri,
1412  connection);
1413  args = strchr (uri, '?');
1414  if (NULL != args)
1415  {
1416  args[0] = '\0';
1417  args++;
1418  parse_arguments (MHD_GET_ARGUMENT_KIND, connection, args);
1419  }
1420  connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls,
1421  connection,
1422  uri);
1423  connection->url = uri;
1424  if (NULL == http_version)
1425  connection->version = "";
1426  else
1427  connection->version = http_version;
1428  return MHD_YES;
1429 }
1430 
1431 
1439 static void
1441 {
1442  size_t processed;
1443 
1444  if (NULL != connection->response)
1445  return; /* already queued a response */
1446  processed = 0;
1447  connection->client_aware = MHD_YES;
1448  if (MHD_NO ==
1449  connection->daemon->default_handler (connection->daemon-> default_handler_cls,
1450  connection,
1451  connection->url,
1452  connection->method,
1453  connection->version,
1454  NULL, &processed,
1455  &connection->client_context))
1456  {
1457  /* serious internal error, close connection */
1458  CONNECTION_CLOSE_ERROR (connection,
1459  "Internal application error, closing connection.\n");
1460  return;
1461  }
1462 }
1463 
1464 
1465 
1473 static void
1475 {
1476  size_t processed;
1477  size_t available;
1478  size_t used;
1479  size_t i;
1480  int instant_retry;
1481  int malformed;
1482  char *buffer_head;
1483  char *end;
1484 
1485  if (NULL != connection->response)
1486  return; /* already queued a response */
1487 
1488  buffer_head = connection->read_buffer;
1489  available = connection->read_buffer_offset;
1490  do
1491  {
1492  instant_retry = MHD_NO;
1493  if ( (MHD_YES == connection->have_chunked_upload) &&
1494  (MHD_SIZE_UNKNOWN == connection->remaining_upload_size) )
1495  {
1496  if ( (connection->current_chunk_offset == connection->current_chunk_size) &&
1497  (0 != connection->current_chunk_offset) &&
1498  (available >= 2) )
1499  {
1500  /* skip new line at the *end* of a chunk */
1501  i = 0;
1502  if ((buffer_head[i] == '\r') || (buffer_head[i] == '\n'))
1503  i++; /* skip 1st part of line feed */
1504  if ((buffer_head[i] == '\r') || (buffer_head[i] == '\n'))
1505  i++; /* skip 2nd part of line feed */
1506  if (i == 0)
1507  {
1508  /* malformed encoding */
1509  CONNECTION_CLOSE_ERROR (connection,
1510  "Received malformed HTTP request (bad chunked encoding), closing connection.\n");
1511  return;
1512  }
1513  available -= i;
1514  buffer_head += i;
1515  connection->current_chunk_offset = 0;
1516  connection->current_chunk_size = 0;
1517  }
1518  if (connection->current_chunk_offset <
1519  connection->current_chunk_size)
1520  {
1521  /* we are in the middle of a chunk, give
1522  as much as possible to the client (without
1523  crossing chunk boundaries) */
1524  processed =
1525  connection->current_chunk_size -
1526  connection->current_chunk_offset;
1527  if (processed > available)
1528  processed = available;
1529  if (available > processed)
1530  instant_retry = MHD_YES;
1531  }
1532  else
1533  {
1534  /* we need to read chunk boundaries */
1535  i = 0;
1536  while (i < available)
1537  {
1538  if ((buffer_head[i] == '\r') || (buffer_head[i] == '\n'))
1539  break;
1540  i++;
1541  if (i >= 6)
1542  break;
1543  }
1544  /* take '\n' into account; if '\n'
1545  is the unavailable character, we
1546  will need to wait until we have it
1547  before going further */
1548  if ((i + 1 >= available) &&
1549  !((i == 1) && (available == 2) && (buffer_head[0] == '0')))
1550  break; /* need more data... */
1551  malformed = (i >= 6);
1552  if (!malformed)
1553  {
1554  buffer_head[i] = '\0';
1555  connection->current_chunk_size = strtoul (buffer_head, &end, 16);
1556  malformed = ('\0' != *end);
1557  }
1558  if (malformed)
1559  {
1560  /* malformed encoding */
1561  CONNECTION_CLOSE_ERROR (connection,
1562  "Received malformed HTTP request (bad chunked encoding), closing connection.\n");
1563  return;
1564  }
1565  i++;
1566  if ((i < available) &&
1567  ((buffer_head[i] == '\r') || (buffer_head[i] == '\n')))
1568  i++; /* skip 2nd part of line feed */
1569 
1570  buffer_head += i;
1571  available -= i;
1572  connection->current_chunk_offset = 0;
1573 
1574  if (available > 0)
1575  instant_retry = MHD_YES;
1576  if (0 == connection->current_chunk_size)
1577  {
1578  connection->remaining_upload_size = 0;
1579  break;
1580  }
1581  continue;
1582  }
1583  }
1584  else
1585  {
1586  /* no chunked encoding, give all to the client */
1587  if ( (0 != connection->remaining_upload_size) &&
1588  (MHD_SIZE_UNKNOWN != connection->remaining_upload_size) &&
1589  (connection->remaining_upload_size < available) )
1590  {
1591  processed = connection->remaining_upload_size;
1592  }
1593  else
1594  {
1599  processed = available;
1600  }
1601  }
1602  used = processed;
1603  connection->client_aware = MHD_YES;
1604  if (MHD_NO ==
1605  connection->daemon->default_handler (connection->daemon->default_handler_cls,
1606  connection,
1607  connection->url,
1608  connection->method,
1609  connection->version,
1610  buffer_head,
1611  &processed,
1612  &connection->client_context))
1613  {
1614  /* serious internal error, close connection */
1615  CONNECTION_CLOSE_ERROR (connection,
1616  "Internal application error, closing connection.\n");
1617  return;
1618  }
1619  if (processed > used)
1620  mhd_panic (mhd_panic_cls, __FILE__, __LINE__
1621 #if HAVE_MESSAGES
1622  , "API violation"
1623 #else
1624  , NULL
1625 #endif
1626  );
1627  if (0 != processed)
1628  instant_retry = MHD_NO; /* client did not process everything */
1629  used -= processed;
1630  if (connection->have_chunked_upload == MHD_YES)
1631  connection->current_chunk_offset += used;
1632  /* dh left "processed" bytes in buffer for next time... */
1633  buffer_head += used;
1634  available -= used;
1635  if (connection->remaining_upload_size != MHD_SIZE_UNKNOWN)
1636  connection->remaining_upload_size -= used;
1637  }
1638  while (MHD_YES == instant_retry);
1639  if (available > 0)
1640  memmove (connection->read_buffer, buffer_head, available);
1641  connection->read_buffer_offset = available;
1642 }
1643 
1644 
1654 static int
1655 do_read (struct MHD_Connection *connection)
1656 {
1657  int bytes_read;
1658 
1659  if (connection->read_buffer_size == connection->read_buffer_offset)
1660  return MHD_NO;
1661  bytes_read = connection->recv_cls (connection,
1662  &connection->read_buffer
1663  [connection->read_buffer_offset],
1664  connection->read_buffer_size -
1665  connection->read_buffer_offset);
1666  if (bytes_read < 0)
1667  {
1668  const int err = MHD_socket_errno_;
1669  if ((EINTR == err) || (EAGAIN == err) || (EWOULDBLOCK == err))
1670  return MHD_NO;
1671  if (ECONNRESET == err)
1672  {
1673  CONNECTION_CLOSE_ERROR(connection, NULL);
1674  return MHD_NO;
1675  }
1676 #if HAVE_MESSAGES
1677 #if HTTPS_SUPPORT
1678  if (0 != (connection->daemon->options & MHD_USE_SSL))
1679  MHD_DLOG (connection->daemon,
1680  "Failed to receive data: %s\n",
1681  gnutls_strerror (bytes_read));
1682  else
1683 #endif
1684  MHD_DLOG (connection->daemon,
1685  "Failed to receive data: %s\n",
1687 #endif
1688  CONNECTION_CLOSE_ERROR (connection, NULL);
1689  return MHD_YES;
1690  }
1691  if (0 == bytes_read)
1692  {
1693  /* other side closed connection; RFC 2616, section 8.1.4 suggests
1694  we should then shutdown ourselves as well. */
1695  connection->read_closed = MHD_YES;
1696  MHD_connection_close (connection,
1698  return MHD_YES;
1699  }
1700  connection->read_buffer_offset += bytes_read;
1701  return MHD_YES;
1702 }
1703 
1704 
1713 static int
1714 do_write (struct MHD_Connection *connection)
1715 {
1716  ssize_t ret;
1717  size_t max;
1718 
1719  max = connection->write_buffer_append_offset - connection->write_buffer_send_offset;
1720  ret = connection->send_cls (connection,
1721  &connection->write_buffer
1722  [connection->write_buffer_send_offset],
1723  max);
1724 
1725  if (ret < 0)
1726  {
1727  const int err = MHD_socket_errno_;
1728  if ((EINTR == err) || (EAGAIN == err) || (EWOULDBLOCK == err))
1729  return MHD_NO;
1730 #if HAVE_MESSAGES
1731 #if HTTPS_SUPPORT
1732  if (0 != (connection->daemon->options & MHD_USE_SSL))
1733  MHD_DLOG (connection->daemon,
1734  "Failed to send data: %s\n",
1735  gnutls_strerror ((int) ret));
1736  else
1737 #endif
1738  MHD_DLOG (connection->daemon,
1739  "Failed to send data: %s\n", MHD_socket_last_strerr_ ());
1740 #endif
1741  CONNECTION_CLOSE_ERROR (connection, NULL);
1742  return MHD_YES;
1743  }
1744 #if DEBUG_SEND_DATA
1745  fprintf (stderr,
1746  "Sent response: `%.*s'\n",
1747  ret,
1748  &connection->write_buffer[connection->write_buffer_send_offset]);
1749 #endif
1750  /* only increment if this wasn't a "sendfile" transmission without
1751  buffer involvement! */
1752  if (0 != max)
1753  connection->write_buffer_send_offset += ret;
1754  return MHD_YES;
1755 }
1756 
1757 
1766 static int
1767 check_write_done (struct MHD_Connection *connection,
1768  enum MHD_CONNECTION_STATE next_state)
1769 {
1770  if (connection->write_buffer_append_offset !=
1771  connection->write_buffer_send_offset)
1772  return MHD_NO;
1773  connection->write_buffer_append_offset = 0;
1774  connection->write_buffer_send_offset = 0;
1775  connection->state = next_state;
1776  MHD_pool_reallocate (connection->pool,
1777  connection->write_buffer,
1778  connection->write_buffer_size, 0);
1779  connection->write_buffer = NULL;
1780  connection->write_buffer_size = 0;
1781  return MHD_YES;
1782 }
1783 
1784 
1794 static int
1795 process_header_line (struct MHD_Connection *connection, char *line)
1796 {
1797  char *colon;
1798 
1799  /* line should be normal header line, find colon */
1800  colon = strchr (line, ':');
1801  if (NULL == colon)
1802  {
1803  /* error in header line, die hard */
1804  CONNECTION_CLOSE_ERROR (connection,
1805  "Received malformed line (no colon), closing connection.\n");
1806  return MHD_NO;
1807  }
1808  /* zero-terminate header */
1809  colon[0] = '\0';
1810  colon++; /* advance to value */
1811  while ((colon[0] != '\0') && ((colon[0] == ' ') || (colon[0] == '\t')))
1812  colon++;
1813  /* we do the actual adding of the connection
1814  header at the beginning of the while
1815  loop since we need to be able to inspect
1816  the *next* header line (in case it starts
1817  with a space...) */
1818  connection->last = line;
1819  connection->colon = colon;
1820  return MHD_YES;
1821 }
1822 
1823 
1834 static int
1836  char *line, enum MHD_ValueKind kind)
1837 {
1838  char *last;
1839  char *tmp;
1840  size_t last_len;
1841  size_t tmp_len;
1842 
1843  last = connection->last;
1844  if ((line[0] == ' ') || (line[0] == '\t'))
1845  {
1846  /* value was continued on the next line, see
1847  http://www.jmarshall.com/easy/http/ */
1848  last_len = strlen (last);
1849  /* skip whitespace at start of 2nd line */
1850  tmp = line;
1851  while ((tmp[0] == ' ') || (tmp[0] == '\t'))
1852  tmp++;
1853  tmp_len = strlen (tmp);
1854  /* FIXME: we might be able to do this better (faster!), as most
1855  likely 'last' and 'line' should already be adjacent in
1856  memory; however, doing this right gets tricky if we have a
1857  value continued over multiple lines (in which case we need to
1858  record how often we have done this so we can check for
1859  adjaency); also, in the case where these are not adjacent
1860  (not sure how it can happen!), we would want to allocate from
1861  the end of the pool, so as to not destroy the read-buffer's
1862  ability to grow nicely. */
1863  last = MHD_pool_reallocate (connection->pool,
1864  last,
1865  last_len + 1,
1866  last_len + tmp_len + 1);
1867  if (NULL == last)
1868  {
1869  transmit_error_response (connection,
1871  REQUEST_TOO_BIG);
1872  return MHD_NO;
1873  }
1874  memcpy (&last[last_len], tmp, tmp_len + 1);
1875  connection->last = last;
1876  return MHD_YES; /* possibly more than 2 lines... */
1877  }
1878  EXTRA_CHECK ((NULL != last) && (NULL != connection->colon));
1879  if ((MHD_NO == connection_add_header (connection,
1880  last, connection->colon, kind)))
1881  {
1883  REQUEST_TOO_BIG);
1884  return MHD_NO;
1885  }
1886  /* we still have the current line to deal with... */
1887  if (0 != strlen (line))
1888  {
1889  if (MHD_NO == process_header_line (connection, line))
1890  {
1891  transmit_error_response (connection,
1893  return MHD_NO;
1894  }
1895  }
1896  return MHD_YES;
1897 }
1898 
1899 
1907 static void
1909 {
1910  const char *clen;
1912  struct MHD_Response *response;
1913  const char *enc;
1914  char *end;
1915 
1916  parse_cookie_header (connection);
1917  if ( (0 != (MHD_USE_PEDANTIC_CHECKS & connection->daemon->options)) &&
1918  (NULL != connection->version) &&
1920  (NULL ==
1921  MHD_lookup_connection_value (connection,
1924  {
1925  /* die, http 1.1 request without host and we are pedantic */
1926  connection->state = MHD_CONNECTION_FOOTERS_RECEIVED;
1927  connection->read_closed = MHD_YES;
1928 #if HAVE_MESSAGES
1929  MHD_DLOG (connection->daemon,
1930  "Received `%s' request without `%s' header.\n",
1932 #endif
1933  EXTRA_CHECK (NULL == connection->response);
1934  response =
1938  MHD_queue_response (connection, MHD_HTTP_BAD_REQUEST, response);
1939  MHD_destroy_response (response);
1940  return;
1941  }
1942 
1943  connection->remaining_upload_size = 0;
1944  enc = MHD_lookup_connection_value (connection,
1947  if (NULL != enc)
1948  {
1950  if (MHD_str_equal_caseless_(enc, "chunked"))
1951  connection->have_chunked_upload = MHD_YES;
1952  }
1953  else
1954  {
1955  clen = MHD_lookup_connection_value (connection,
1958  if (NULL != clen)
1959  {
1960  cval = strtoul (clen, &end, 10);
1961  if ( ('\0' != *end) ||
1962  ( (LONG_MAX == cval) && (errno == ERANGE) ) )
1963  {
1964 #if HAVE_MESSAGES
1965  MHD_DLOG (connection->daemon,
1966  "Failed to parse `%s' header `%s', closing connection.\n",
1968  clen);
1969 #endif
1970  CONNECTION_CLOSE_ERROR (connection, NULL);
1971  return;
1972  }
1973  connection->remaining_upload_size = cval;
1974  }
1975  }
1976 }
1977 
1978 
1986 static void
1988 {
1989  struct MHD_Daemon *daemon = connection->daemon;
1990 
1991  connection->last_activity = MHD_monotonic_time();
1992  if (connection->connection_timeout != daemon->connection_timeout)
1993  return; /* custom timeout, no need to move it in "normal" DLL */
1994 
1995  /* move connection to head of timeout list (by remove + add operation) */
1996  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1997  (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) )
1998  MHD_PANIC ("Failed to acquire cleanup mutex\n");
2000  daemon->normal_timeout_tail,
2001  connection);
2003  daemon->normal_timeout_tail,
2004  connection);
2005  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
2006  (MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) )
2007  MHD_PANIC ("Failed to release cleanup mutex\n");
2008 }
2009 
2010 
2019 int
2021 {
2022  update_last_activity (connection);
2023  if (MHD_CONNECTION_CLOSED == connection->state)
2024  return MHD_YES;
2025  /* make sure "read" has a reasonable number of bytes
2026  in buffer to use per system call (if possible) */
2027  if (connection->read_buffer_offset + connection->daemon->pool_increment >
2028  connection->read_buffer_size)
2029  try_grow_read_buffer (connection);
2030  if (MHD_NO == do_read (connection))
2031  return MHD_YES;
2032  while (1)
2033  {
2034 #if DEBUG_STATES
2035  MHD_DLOG (connection->daemon, "%s: state: %s\n",
2036  __FUNCTION__,
2037  MHD_state_to_string (connection->state));
2038 #endif
2039  switch (connection->state)
2040  {
2041  case MHD_CONNECTION_INIT:
2050  /* nothing to do but default action */
2051  if (MHD_YES == connection->read_closed)
2052  {
2053  MHD_connection_close (connection,
2055  continue;
2056  }
2057  break;
2058  case MHD_CONNECTION_CLOSED:
2059  return MHD_YES;
2060  default:
2061  /* shrink read buffer to how much is actually used */
2062  MHD_pool_reallocate (connection->pool,
2063  connection->read_buffer,
2064  connection->read_buffer_size + 1,
2065  connection->read_buffer_offset);
2066  break;
2067  }
2068  break;
2069  }
2070  return MHD_YES;
2071 }
2072 
2073 
2082 int
2084 {
2085  struct MHD_Response *response;
2086  ssize_t ret;
2087 
2088  update_last_activity (connection);
2089  while (1)
2090  {
2091 #if DEBUG_STATES
2092  MHD_DLOG (connection->daemon, "%s: state: %s\n",
2093  __FUNCTION__,
2094  MHD_state_to_string (connection->state));
2095 #endif
2096  switch (connection->state)
2097  {
2098  case MHD_CONNECTION_INIT:
2102  EXTRA_CHECK (0);
2103  break;
2105  break;
2107  ret = connection->send_cls (connection,
2109  [connection->continue_message_write_offset],
2110  strlen (HTTP_100_CONTINUE) -
2111  connection->continue_message_write_offset);
2112  if (ret < 0)
2113  {
2114  const int err = MHD_socket_errno_;
2115  if ((err == EINTR) || (err == EAGAIN) || (EWOULDBLOCK == err))
2116  break;
2117 #if HAVE_MESSAGES
2118  MHD_DLOG (connection->daemon,
2119  "Failed to send data: %s\n",
2121 #endif
2122  CONNECTION_CLOSE_ERROR (connection, NULL);
2123  return MHD_YES;
2124  }
2125 #if DEBUG_SEND_DATA
2126  fprintf (stderr,
2127  "Sent 100 continue response: `%.*s'\n",
2128  (int) ret,
2130 #endif
2131  connection->continue_message_write_offset += ret;
2132  break;
2137  EXTRA_CHECK (0);
2138  break;
2140  do_write (connection);
2141  if (connection->state != MHD_CONNECTION_HEADERS_SENDING)
2142  break;
2144  break;
2146  EXTRA_CHECK (0);
2147  break;
2149  response = connection->response;
2150  if (NULL != response->crc)
2151  (void) MHD_mutex_lock_ (&response->mutex);
2152  if (MHD_YES != try_ready_normal_body (connection))
2153  break;
2154  ret = connection->send_cls (connection,
2155  &response->data
2156  [connection->response_write_position
2157  - response->data_start],
2158  response->data_size -
2159  (connection->response_write_position
2160  - response->data_start));
2161  const int err = MHD_socket_errno_;
2162 #if DEBUG_SEND_DATA
2163  if (ret > 0)
2164  fprintf (stderr,
2165  "Sent DATA response: `%.*s'\n",
2166  (int) ret,
2167  &response->data[connection->response_write_position -
2168  response->data_start]);
2169 #endif
2170  if (NULL != response->crc)
2171  (void) MHD_mutex_unlock_ (&response->mutex);
2172  if (ret < 0)
2173  {
2174  if ((err == EINTR) || (err == EAGAIN) || (EWOULDBLOCK == err))
2175  return MHD_YES;
2176 #if HAVE_MESSAGES
2177  MHD_DLOG (connection->daemon,
2178  "Failed to send data: %s\n",
2180 #endif
2181  CONNECTION_CLOSE_ERROR (connection, NULL);
2182  return MHD_YES;
2183  }
2184  connection->response_write_position += ret;
2185  if (connection->response_write_position ==
2186  connection->response->total_size)
2187  connection->state = MHD_CONNECTION_FOOTERS_SENT; /* have no footers */
2188  break;
2190  EXTRA_CHECK (0);
2191  break;
2193  do_write (connection);
2194  if (MHD_CONNECTION_CHUNKED_BODY_READY != connection->state)
2195  break;
2196  check_write_done (connection,
2197  (connection->response->total_size ==
2198  connection->response_write_position) ?
2201  break;
2202  case MHD_CONNECTION_CHUNKED_BODY_UNREADY:
2204  EXTRA_CHECK (0);
2205  break;
2207  do_write (connection);
2208  if (connection->state != MHD_CONNECTION_FOOTERS_SENDING)
2209  break;
2211  break;
2213  EXTRA_CHECK (0);
2214  break;
2215  case MHD_CONNECTION_CLOSED:
2216  return MHD_YES;
2218  EXTRA_CHECK (0);
2219  break;
2220  default:
2221  EXTRA_CHECK (0);
2222  CONNECTION_CLOSE_ERROR (connection,
2223  "Internal error\n");
2224  return MHD_YES;
2225  }
2226  break;
2227  }
2228  return MHD_YES;
2229 }
2230 
2231 
2238 static void
2240 {
2241  struct MHD_Daemon *daemon = connection->daemon;
2242 
2243  if (NULL != connection->response)
2244  {
2245  MHD_destroy_response (connection->response);
2246  connection->response = NULL;
2247  }
2248  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
2249  (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) )
2250  MHD_PANIC ("Failed to acquire cleanup mutex\n");
2251  if (connection->connection_timeout == daemon->connection_timeout)
2253  daemon->normal_timeout_tail,
2254  connection);
2255  else
2257  daemon->manual_timeout_tail,
2258  connection);
2259  if (MHD_YES == connection->suspended)
2262  connection);
2263  else
2264  DLL_remove (daemon->connections_head,
2265  daemon->connections_tail,
2266  connection);
2267  DLL_insert (daemon->cleanup_head,
2268  daemon->cleanup_tail,
2269  connection);
2270  connection->suspended = MHD_NO;
2271  connection->resuming = MHD_NO;
2272  connection->in_idle = MHD_NO;
2273  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
2274  (MHD_YES != MHD_mutex_unlock_(&daemon->cleanup_connection_mutex)) )
2275  MHD_PANIC ("Failed to release cleanup mutex\n");
2276 }
2277 
2278 
2287 int
2289 {
2290  struct MHD_Daemon *daemon = connection->daemon;
2291  unsigned int timeout;
2292  const char *end;
2293  char *line;
2294  int client_close;
2295 
2296  connection->in_idle = MHD_YES;
2297  while (1)
2298  {
2299 #if DEBUG_STATES
2300  MHD_DLOG (daemon,
2301  "%s: state: %s\n",
2302  __FUNCTION__,
2303  MHD_state_to_string (connection->state));
2304 #endif
2305  switch (connection->state)
2306  {
2307  case MHD_CONNECTION_INIT:
2308  line = get_next_header_line (connection);
2309  if (NULL == line)
2310  {
2311  if (MHD_CONNECTION_INIT != connection->state)
2312  continue;
2313  if (MHD_YES == connection->read_closed)
2314  {
2315  CONNECTION_CLOSE_ERROR (connection,
2316  NULL);
2317  continue;
2318  }
2319  break;
2320  }
2321  if (MHD_NO == parse_initial_message_line (connection, line))
2322  CONNECTION_CLOSE_ERROR (connection, NULL);
2323  else
2324  connection->state = MHD_CONNECTION_URL_RECEIVED;
2325  continue;
2327  line = get_next_header_line (connection);
2328  if (NULL == line)
2329  {
2330  if (MHD_CONNECTION_URL_RECEIVED != connection->state)
2331  continue;
2332  if (MHD_YES == connection->read_closed)
2333  {
2334  CONNECTION_CLOSE_ERROR (connection,
2335  NULL);
2336  continue;
2337  }
2338  break;
2339  }
2340  if (strlen (line) == 0)
2341  {
2342  connection->state = MHD_CONNECTION_HEADERS_RECEIVED;
2343  continue;
2344  }
2345  if (MHD_NO == process_header_line (connection, line))
2346  {
2347  transmit_error_response (connection,
2350  break;
2351  }
2353  continue;
2355  line = get_next_header_line (connection);
2356  if (NULL == line)
2357  {
2358  if (connection->state != MHD_CONNECTION_HEADER_PART_RECEIVED)
2359  continue;
2360  if (MHD_YES == connection->read_closed)
2361  {
2362  CONNECTION_CLOSE_ERROR (connection,
2363  NULL);
2364  continue;
2365  }
2366  break;
2367  }
2368  if (MHD_NO ==
2369  process_broken_line (connection, line, MHD_HEADER_KIND))
2370  continue;
2371  if (0 == strlen (line))
2372  {
2373  connection->state = MHD_CONNECTION_HEADERS_RECEIVED;
2374  continue;
2375  }
2376  continue;
2378  parse_connection_headers (connection);
2379  if (MHD_CONNECTION_CLOSED == connection->state)
2380  continue;
2382  continue;
2384  call_connection_handler (connection); /* first call */
2385  if (MHD_CONNECTION_CLOSED == connection->state)
2386  continue;
2387  if (need_100_continue (connection))
2388  {
2389  connection->state = MHD_CONNECTION_CONTINUE_SENDING;
2390  break;
2391  }
2392  if ( (NULL != connection->response) &&
2393  ( (MHD_str_equal_caseless_ (connection->method,
2395  (MHD_str_equal_caseless_ (connection->method,
2396  MHD_HTTP_METHOD_PUT))) )
2397  {
2398  /* we refused (no upload allowed!) */
2399  connection->remaining_upload_size = 0;
2400  /* force close, in case client still tries to upload... */
2401  connection->read_closed = MHD_YES;
2402  }
2403  connection->state = (0 == connection->remaining_upload_size)
2405  continue;
2407  if (connection->continue_message_write_offset ==
2408  strlen (HTTP_100_CONTINUE))
2409  {
2410  connection->state = MHD_CONNECTION_CONTINUE_SENT;
2411  continue;
2412  }
2413  break;
2415  if (0 != connection->read_buffer_offset)
2416  {
2417  process_request_body (connection); /* loop call */
2418  if (MHD_CONNECTION_CLOSED == connection->state)
2419  continue;
2420  }
2421  if ((0 == connection->remaining_upload_size) ||
2422  ((connection->remaining_upload_size == MHD_SIZE_UNKNOWN) &&
2423  (0 == connection->read_buffer_offset) &&
2424  (MHD_YES == connection->read_closed)))
2425  {
2426  if ((MHD_YES == connection->have_chunked_upload) &&
2427  (MHD_NO == connection->read_closed))
2428  connection->state = MHD_CONNECTION_BODY_RECEIVED;
2429  else
2430  connection->state = MHD_CONNECTION_FOOTERS_RECEIVED;
2431  continue;
2432  }
2433  break;
2435  line = get_next_header_line (connection);
2436  if (NULL == line)
2437  {
2438  if (connection->state != MHD_CONNECTION_BODY_RECEIVED)
2439  continue;
2440  if (MHD_YES == connection->read_closed)
2441  {
2442  CONNECTION_CLOSE_ERROR (connection,
2443  NULL);
2444  continue;
2445  }
2446  break;
2447  }
2448  if (0 == strlen (line))
2449  {
2450  connection->state = MHD_CONNECTION_FOOTERS_RECEIVED;
2451  continue;
2452  }
2453  if (MHD_NO == process_header_line (connection, line))
2454  {
2455  transmit_error_response (connection,
2458  break;
2459  }
2461  continue;
2463  line = get_next_header_line (connection);
2464  if (NULL == line)
2465  {
2466  if (connection->state != MHD_CONNECTION_FOOTER_PART_RECEIVED)
2467  continue;
2468  if (MHD_YES == connection->read_closed)
2469  {
2470  CONNECTION_CLOSE_ERROR (connection,
2471  NULL);
2472  continue;
2473  }
2474  break;
2475  }
2476  if (MHD_NO ==
2477  process_broken_line (connection, line, MHD_FOOTER_KIND))
2478  continue;
2479  if (0 == strlen (line))
2480  {
2481  connection->state = MHD_CONNECTION_FOOTERS_RECEIVED;
2482  continue;
2483  }
2484  continue;
2486  call_connection_handler (connection); /* "final" call */
2487  if (connection->state == MHD_CONNECTION_CLOSED)
2488  continue;
2489  if (NULL == connection->response)
2490  break; /* try again next time */
2491  if (MHD_NO == build_header_response (connection))
2492  {
2493  /* oops - close! */
2494  CONNECTION_CLOSE_ERROR (connection,
2495  "Closing connection (failed to create response header)\n");
2496  continue;
2497  }
2498  connection->state = MHD_CONNECTION_HEADERS_SENDING;
2499 
2500 #if HAVE_DECL_TCP_CORK
2501  /* starting header send, set TCP cork */
2502  {
2503  const int val = 1;
2504  setsockopt (connection->socket_fd, IPPROTO_TCP, TCP_CORK, &val,
2505  sizeof (val));
2506  }
2507 #endif
2508  break;
2510  /* no default action */
2511  break;
2513  if (connection->have_chunked_upload)
2515  else
2517  continue;
2519  /* nothing to do here */
2520  break;
2522  if (NULL != connection->response->crc)
2523  (void) MHD_mutex_lock_ (&connection->response->mutex);
2524  if (0 == connection->response->total_size)
2525  {
2526  if (NULL != connection->response->crc)
2527  (void) MHD_mutex_unlock_ (&connection->response->mutex);
2528  connection->state = MHD_CONNECTION_BODY_SENT;
2529  continue;
2530  }
2531  if (MHD_YES == try_ready_normal_body (connection))
2532  {
2533  if (NULL != connection->response->crc)
2534  (void) MHD_mutex_unlock_ (&connection->response->mutex);
2536  break;
2537  }
2538  /* not ready, no socket action */
2539  break;
2541  /* nothing to do here */
2542  break;
2544  if (NULL != connection->response->crc)
2545  (void) MHD_mutex_lock_ (&connection->response->mutex);
2546  if (0 == connection->response->total_size)
2547  {
2548  if (NULL != connection->response->crc)
2549  (void) MHD_mutex_unlock_ (&connection->response->mutex);
2550  connection->state = MHD_CONNECTION_BODY_SENT;
2551  continue;
2552  }
2553  if (MHD_YES == try_ready_chunked_body (connection))
2554  {
2555  if (NULL != connection->response->crc)
2556  (void) MHD_mutex_unlock_ (&connection->response->mutex);
2558  continue;
2559  }
2560  if (NULL != connection->response->crc)
2561  (void) MHD_mutex_unlock_ (&connection->response->mutex);
2562  break;
2564  if (MHD_NO == build_header_response (connection))
2565  {
2566  /* oops - close! */
2567  CONNECTION_CLOSE_ERROR (connection,
2568  "Closing connection (failed to create response header)\n");
2569  continue;
2570  }
2571  if ( (MHD_NO == connection->have_chunked_upload) ||
2572  (connection->write_buffer_send_offset ==
2573  connection->write_buffer_append_offset) )
2574  connection->state = MHD_CONNECTION_FOOTERS_SENT;
2575  else
2576  connection->state = MHD_CONNECTION_FOOTERS_SENDING;
2577  continue;
2579  /* no default action */
2580  break;
2582 #if HAVE_DECL_TCP_CORK
2583  /* done sending, uncork */
2584  {
2585  const int val = 0;
2586  setsockopt (connection->socket_fd, IPPROTO_TCP, TCP_CORK, &val,
2587  sizeof (val));
2588  }
2589 #endif
2590  end =
2591  MHD_get_response_header (connection->response,
2593  client_close = ((NULL != end) && (0 == strcasecmp (end, "close")));
2594  MHD_destroy_response (connection->response);
2595  connection->response = NULL;
2596  if ( (NULL != daemon->notify_completed) &&
2597  (MHD_YES == connection->client_aware) )
2598  {
2599  daemon->notify_completed (daemon->notify_completed_cls,
2600  connection,
2601  &connection->client_context,
2603  connection->client_aware = MHD_NO;
2604  }
2605  end =
2608  if ( (MHD_YES == connection->read_closed) ||
2609  (client_close) ||
2610  ((NULL != end) && (MHD_str_equal_caseless_ (end, "close"))) )
2611  {
2612  connection->read_closed = MHD_YES;
2613  connection->read_buffer_offset = 0;
2614  }
2615  if (((MHD_YES == connection->read_closed) &&
2616  (0 == connection->read_buffer_offset)) ||
2617  (MHD_NO == keepalive_possible (connection)))
2618  {
2619  /* have to close for some reason */
2620  MHD_connection_close (connection,
2622  MHD_pool_destroy (connection->pool);
2623  connection->pool = NULL;
2624  connection->read_buffer = NULL;
2625  connection->read_buffer_size = 0;
2626  connection->read_buffer_offset = 0;
2627  }
2628  else
2629  {
2630  /* can try to keep-alive */
2631  connection->version = NULL;
2632  connection->state = MHD_CONNECTION_INIT;
2633  connection->read_buffer
2634  = MHD_pool_reset (connection->pool,
2635  connection->read_buffer,
2636  connection->read_buffer_size);
2637  }
2638  connection->client_aware = MHD_NO;
2639  connection->client_context = NULL;
2640  connection->continue_message_write_offset = 0;
2641  connection->responseCode = 0;
2642  connection->headers_received = NULL;
2643  connection->headers_received_tail = NULL;
2644  connection->response_write_position = 0;
2645  connection->have_chunked_upload = MHD_NO;
2646  connection->method = NULL;
2647  connection->url = NULL;
2648  connection->write_buffer = NULL;
2649  connection->write_buffer_size = 0;
2650  connection->write_buffer_send_offset = 0;
2651  connection->write_buffer_append_offset = 0;
2652  continue;
2653  case MHD_CONNECTION_CLOSED:
2654  cleanup_connection (connection);
2655  return MHD_NO;
2656  default:
2657  EXTRA_CHECK (0);
2658  break;
2659  }
2660  break;
2661  }
2662  timeout = connection->connection_timeout;
2663  if ( (0 != timeout) &&
2664  (timeout <= (MHD_monotonic_time() - connection->last_activity)) )
2665  {
2667  connection->in_idle = MHD_NO;
2668  return MHD_YES;
2669  }
2671 #if EPOLL_SUPPORT
2672  switch (connection->event_loop_info)
2673  {
2675  if ( (0 != (connection->epoll_state & MHD_EPOLL_STATE_READ_READY)) &&
2676  (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED)) &&
2677  (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) )
2678  {
2679  EDLL_insert (daemon->eready_head,
2680  daemon->eready_tail,
2681  connection);
2682  connection->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
2683  }
2684  break;
2686  if ( (connection->read_buffer_size > connection->read_buffer_offset) &&
2687  (0 != (connection->epoll_state & MHD_EPOLL_STATE_READ_READY)) &&
2688  (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED)) &&
2689  (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) )
2690  {
2691  EDLL_insert (daemon->eready_head,
2692  daemon->eready_tail,
2693  connection);
2694  connection->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
2695  }
2696  if ( (0 != (connection->epoll_state & MHD_EPOLL_STATE_WRITE_READY)) &&
2697  (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED)) &&
2698  (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) )
2699  {
2700  EDLL_insert (daemon->eready_head,
2701  daemon->eready_tail,
2702  connection);
2703  connection->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
2704  }
2705  break;
2707  /* we should look at this connection again in the next iteration
2708  of the event loop, as we're waiting on the application */
2709  if ( (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) &&
2710  (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED))) )
2711  {
2712  EDLL_insert (daemon->eready_head,
2713  daemon->eready_tail,
2714  connection);
2715  connection->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
2716  }
2717  break;
2719  /* This connection is finished, nothing left to do */
2720  break;
2721  }
2722  return MHD_connection_epoll_update_ (connection);
2723 #else
2724  return MHD_YES;
2725 #endif
2726 }
2727 
2728 
2729 #if EPOLL_SUPPORT
2730 
2738 int
2739 MHD_connection_epoll_update_ (struct MHD_Connection *connection)
2740 {
2741  struct MHD_Daemon *daemon = connection->daemon;
2742 
2743  if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
2744  (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) &&
2745  (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED)) &&
2746  ( (0 == (connection->epoll_state & MHD_EPOLL_STATE_WRITE_READY)) ||
2747  ( (0 == (connection->epoll_state & MHD_EPOLL_STATE_READ_READY)) &&
2748  ( (MHD_EVENT_LOOP_INFO_READ == connection->event_loop_info) ||
2749  (connection->read_buffer_size > connection->read_buffer_offset) ) &&
2750  (MHD_NO == connection->read_closed) ) ) )
2751  {
2752  /* add to epoll set */
2753  struct epoll_event event;
2754 
2755  event.events = EPOLLIN | EPOLLOUT | EPOLLET;
2756  event.data.ptr = connection;
2757  if (0 != epoll_ctl (daemon->epoll_fd,
2758  EPOLL_CTL_ADD,
2759  connection->socket_fd,
2760  &event))
2761  {
2762 #if HAVE_MESSAGES
2763  if (0 != (daemon->options & MHD_USE_DEBUG))
2764  MHD_DLOG (daemon,
2765  "Call to epoll_ctl failed: %s\n",
2767 #endif
2768  connection->state = MHD_CONNECTION_CLOSED;
2769  cleanup_connection (connection);
2770  return MHD_NO;
2771  }
2772  connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET;
2773  }
2774  connection->in_idle = MHD_NO;
2775  return MHD_YES;
2776 }
2777 #endif
2778 
2779 
2785 void
2787 {
2791 }
2792 
2793 
2804 const union MHD_ConnectionInfo *
2806  enum MHD_ConnectionInfoType info_type, ...)
2807 {
2808  switch (info_type)
2809  {
2810 #if HTTPS_SUPPORT
2812  if (connection->tls_session == NULL)
2813  return NULL;
2814  connection->cipher = gnutls_cipher_get (connection->tls_session);
2815  return (const union MHD_ConnectionInfo *) &connection->cipher;
2817  if (connection->tls_session == NULL)
2818  return NULL;
2819  connection->protocol = gnutls_protocol_get_version (connection->tls_session);
2820  return (const union MHD_ConnectionInfo *) &connection->protocol;
2822  if (connection->tls_session == NULL)
2823  return NULL;
2824  return (const union MHD_ConnectionInfo *) &connection->tls_session;
2825 #endif
2827  return (const union MHD_ConnectionInfo *) &connection->addr;
2829  return (const union MHD_ConnectionInfo *) &connection->daemon;
2831  return (const union MHD_ConnectionInfo *) &connection->socket_fd;
2832  default:
2833  return NULL;
2834  };
2835 }
2836 
2837 
2847 int
2849  enum MHD_CONNECTION_OPTION option,
2850  ...)
2851 {
2852  va_list ap;
2853  struct MHD_Daemon *daemon;
2854 
2855  daemon = connection->daemon;
2856  switch (option)
2857  {
2859  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
2860  (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) )
2861  MHD_PANIC ("Failed to acquire cleanup mutex\n");
2862  if (MHD_YES != connection->suspended) {
2863  if (connection->connection_timeout == daemon->connection_timeout)
2865  daemon->normal_timeout_tail,
2866  connection);
2867  else
2869  daemon->manual_timeout_tail,
2870  connection);
2871  }
2872  va_start (ap, option);
2873  connection->connection_timeout = va_arg (ap, unsigned int);
2874  va_end (ap);
2875  if (MHD_YES != connection->suspended) {
2876  if (connection->connection_timeout == daemon->connection_timeout)
2878  daemon->normal_timeout_tail,
2879  connection);
2880  else
2882  daemon->manual_timeout_tail,
2883  connection);
2884  }
2885  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
2886  (MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) )
2887  MHD_PANIC ("Failed to release cleanup mutex\n");
2888  return MHD_YES;
2889  default:
2890  return MHD_NO;
2891  }
2892 }
2893 
2894 
2906 int
2908  unsigned int status_code,
2909  struct MHD_Response *response)
2910 {
2911  if ( (NULL == connection) ||
2912  (NULL == response) ||
2913  (NULL != connection->response) ||
2914  ( (MHD_CONNECTION_HEADERS_PROCESSED != connection->state) &&
2915  (MHD_CONNECTION_FOOTERS_RECEIVED != connection->state) ) )
2916  return MHD_NO;
2917  MHD_increment_response_rc (response);
2918  connection->response = response;
2919  connection->responseCode = status_code;
2920  if ( (NULL != connection->method) &&
2922  {
2923  /* if this is a "HEAD" request, pretend that we
2924  have already sent the full message body */
2925  connection->response_write_position = response->total_size;
2926  }
2927  if ( (MHD_CONNECTION_HEADERS_PROCESSED == connection->state) &&
2928  (NULL != connection->method) &&
2929  ( (MHD_str_equal_caseless_ (connection->method,
2931  (MHD_str_equal_caseless_ (connection->method,
2932  MHD_HTTP_METHOD_PUT))) )
2933  {
2934  /* response was queued "early", refuse to read body / footers or
2935  further requests! */
2936  connection->read_closed = MHD_YES;
2937  connection->state = MHD_CONNECTION_FOOTERS_RECEIVED;
2938  }
2939  if (MHD_NO == connection->in_idle)
2940  (void) MHD_connection_handle_idle (connection);
2941  return MHD_YES;
2942 }
2943 
2944 
2945 /* end of connection.c */
static int process_header_line(struct MHD_Connection *connection, char *line)
Definition: connection.c:1795
#define MHD_HTTP_REQUEST_ENTITY_TOO_LARGE
Definition: microhttpd.h:263
int(* MHD_KeyValueIterator)(void *cls, enum MHD_ValueKind kind, const char *key, const char *value)
Definition: microhttpd.h:1254
static int parse_cookie_header(struct MHD_Connection *connection)
Definition: connection.c:1289
void * unescape_callback_cls
Definition: internal.h:1024
#define MHD_HTTP_HEADER_DATE
Definition: microhttpd.h:323
void MHD_unescape_plus(char *arg)
Definition: internal.c:113
#define XDLL_insert(head, tail, element)
Definition: internal.h:1330
uint64_t total_size
Definition: internal.h:287
static int try_ready_normal_body(struct MHD_Connection *connection)
Definition: connection.c:332
void * mhd_panic_cls
Definition: daemon.c:151
#define MHD_socket_errno_
_MHD_EXTERN const char * MHD_lookup_connection_value(struct MHD_Connection *connection, enum MHD_ValueKind kind, const char *key)
Definition: connection.c:217
#define MHD_HTTP_METHOD_CONNECT
Definition: microhttpd.h:376
int(* write_handler)(struct MHD_Connection *connection)
Definition: internal.h:808
static void MHD_connection_update_event_loop_info(struct MHD_Connection *connection)
Definition: connection.c:974
enum MHD_CONNECTION_STATE state
Definition: internal.h:755
int(* idle_handler)(struct MHD_Connection *connection)
Definition: internal.h:813
static int try_ready_chunked_body(struct MHD_Connection *connection)
Definition: connection.c:399
uint64_t response_write_position
Definition: internal.h:688
#define NULL
Definition: reason_phrase.c:31
void MHD_pool_destroy(struct MemoryPool *pool)
Definition: memorypool.c:135
#define HTTP_100_CONTINUE
Definition: connection.c:51
#define MHD_ICY_FLAG
Definition: microhttpd.h:297
enum MHD_ConnectionEventLoopInfo event_loop_info
Definition: internal.h:760
size_t current_chunk_size
Definition: internal.h:792
#define MHD_BUF_INC_SIZE
Definition: internal.h:65
int MHD_connection_handle_write(struct MHD_Connection *connection)
Definition: connection.c:2083
#define EXTRA_CHECK(a)
Definition: internal.h:1273
#define DLL_remove(head, tail, element)
Definition: internal.h:1306
Methods for managing connections.
MHD_CONNECTION_STATE
Definition: internal.h:344
char * version
Definition: internal.h:604
#define INTERNAL_ERROR
Definition: connection.c:101
#define MHD_HTTP_HEADER_HOST
Definition: microhttpd.h:328
static int connection_add_header(struct MHD_Connection *connection, char *key, char *value, enum MHD_ValueKind kind)
Definition: connection.c:1173
#define MHD_YES
Definition: microhttpd.h:138
struct MHD_Response * response
Definition: internal.h:566
char * colon
Definition: internal.h:633
#define REQUEST_LACKS_HOST
Definition: connection.c:76
char * write_buffer
Definition: internal.h:618
struct MHD_Connection * normal_timeout_tail
Definition: internal.h:965
MHD_RequestTerminationCode
Definition: microhttpd.h:946
size_t data_size
Definition: internal.h:304
static int do_read(struct MHD_Connection *connection)
Definition: connection.c:1655
int have_chunked_upload
Definition: internal.h:784
enum MHD_ValueKind kind
Definition: internal.h:236
struct MHD_HTTP_Header * first_header
Definition: internal.h:252
static void transmit_error_response(struct MHD_Connection *connection, unsigned int status_code, const char *message)
Definition: connection.c:926
MHD_AccessHandlerCallback default_handler
Definition: internal.h:898
void * MHD_pool_allocate(struct MemoryPool *pool, size_t size, int from_end)
Definition: memorypool.c:165
size_t current_chunk_offset
Definition: internal.h:798
static void call_connection_handler(struct MHD_Connection *connection)
Definition: connection.c:1440
uint64_t remaining_upload_size
Definition: internal.h:681
unsigned int responseCode
Definition: internal.h:766
char * value
Definition: internal.h:230
Methods for managing response objects.
static void cleanup_connection(struct MHD_Connection *connection)
Definition: connection.c:2239
#define MHD_socket_last_strerr_()
#define MHD_UNSIGNED_LONG_LONG
Definition: microhttpd.h:206
void * uri_log_callback_cls
Definition: internal.h:1014
int(* read_handler)(struct MHD_Connection *connection)
Definition: internal.h:803
struct MHD_Daemon * daemon
Definition: internal.h:551
#define MHD_str_equal_caseless_(a, b)
struct MHD_Connection * manual_timeout_head
Definition: internal.h:972
struct MHD_Connection * cleanup_head
Definition: internal.h:928
#define MHD_HTTP_HEADER_COOKIE
Definition: microhttpd.h:322
static void connection_close_error(struct MHD_Connection *connection, const char *emsg)
Definition: connection.c:297
int client_aware
Definition: internal.h:718
_MHD_EXTERN const union MHD_ConnectionInfo * MHD_get_connection_info(struct MHD_Connection *connection, enum MHD_ConnectionInfoType info_type,...)
Definition: connection.c:2805
static int keepalive_possible(struct MHD_Connection *connection)
Definition: connection.c:510
struct MHD_Connection * cleanup_tail
Definition: internal.h:933
#define EWOULDBLOCK
Definition: w32functions.h:45
int MHD_connection_handle_read(struct MHD_Connection *connection)
Definition: connection.c:2020
size_t data_buffer_size
Definition: internal.h:309
MHD_CONNECTION_OPTION
Definition: microhttpd.h:2376
size_t write_buffer_send_offset
Definition: internal.h:669
#define ECONNRESET
Definition: w32functions.h:96
void * MHD_pool_reallocate(struct MemoryPool *pool, void *old, size_t old_size, size_t new_size)
Definition: memorypool.c:208
static void get_date_string(char *date)
Definition: connection.c:552
size_t read_buffer_size
Definition: internal.h:653
void * client_context
Definition: internal.h:586
#define MHD_MIN(a, b)
Definition: internal.h:55
struct MHD_Connection * manual_timeout_tail
Definition: internal.h:978
size_t continue_message_write_offset
Definition: internal.h:694
#define REQUEST_MALFORMED
Definition: connection.c:89
#define MHD_INVALID_SOCKET
Definition: microhttpd.h:186
MHD_socket socket_fd
Definition: internal.h:725
internal shared structures
char * method
Definition: internal.h:592
time_t MHD_monotonic_time(void)
Definition: internal.c:182
LogCallback uri_log_callback
Definition: internal.h:1009
_MHD_EXTERN void MHD_destroy_response(struct MHD_Response *response)
Definition: response.c:488
_MHD_EXTERN int MHD_set_connection_option(struct MHD_Connection *connection, enum MHD_CONNECTION_OPTION option,...)
Definition: connection.c:2848
int shutdown
Definition: internal.h:1128
void MHD_increment_response_rc(struct MHD_Response *response)
Definition: response.c:517
#define MHD_CONTENT_READER_END_OF_STREAM
Definition: microhttpd.h:164
char * last
Definition: internal.h:625
struct MHD_Connection * normal_timeout_head
Definition: internal.h:959
#define MHD_snprintf_
MHD_ValueKind
Definition: microhttpd.h:900
char * read_buffer
Definition: internal.h:612
ReceiveCallback recv_cls
Definition: internal.h:818
static void update_last_activity(struct MHD_Connection *connection)
Definition: connection.c:1987
char * url
Definition: internal.h:598
static int need_100_continue(struct MHD_Connection *connection)
Definition: connection.c:243
size_t write_buffer_size
Definition: internal.h:664
static char * get_next_header_line(struct MHD_Connection *connection)
Definition: connection.c:1122
const char * MHD_get_reason_phrase_for(unsigned int code)
MHD_ConnectionInfoType
Definition: microhttpd.h:1048
uint64_t data_start
Definition: internal.h:293
#define MHD_HTTP_VERSION_1_1
Definition: microhttpd.h:367
UnescapeCallback unescape_callback
Definition: internal.h:1019
static int try_grow_read_buffer(struct MHD_Connection *connection)
Definition: connection.c:608
_MHD_EXTERN int MHD_queue_response(struct MHD_Connection *connection, unsigned int status_code, struct MHD_Response *response)
Definition: connection.c:2907
void * MHD_pool_reset(struct MemoryPool *pool, void *keep, size_t size)
Definition: memorypool.c:262
#define MHD_HTTP_BAD_REQUEST
Definition: microhttpd.h:248
static int parse_initial_message_line(struct MHD_Connection *connection, char *line)
Definition: connection.c:1388
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_buffer(size_t size, void *buffer, enum MHD_ResponseMemoryMode mode)
Definition: response.c:467
struct MHD_Connection * connections_head
Definition: internal.h:908
size_t pool_size
Definition: internal.h:1057
char * header
Definition: internal.h:225
static int check_write_done(struct MHD_Connection *connection, enum MHD_CONNECTION_STATE next_state)
Definition: connection.c:1767
time_t last_activity
Definition: internal.h:705
int MHD_connection_handle_idle(struct MHD_Connection *connection)
Definition: connection.c:2288
unsigned int connection_timeout
Definition: internal.h:711
static int process_broken_line(struct MHD_Connection *connection, char *line, enum MHD_ValueKind kind)
Definition: connection.c:1835
enum MHD_ResponseFlags flags
Definition: internal.h:325
#define MHD_HTTP_HEADER_EXPECT
Definition: microhttpd.h:325
#define MHD_PANIC(msg)
Definition: internal.h:99
struct MemoryPool * pool
Definition: internal.h:578
#define MHD_HTTP_METHOD_HEAD
Definition: microhttpd.h:379
static void parse_connection_headers(struct MHD_Connection *connection)
Definition: connection.c:1908
size_t write_buffer_append_offset
Definition: internal.h:675
struct MHD_HTTP_Header * next
Definition: internal.h:219
MHD_RequestCompletedCallback notify_completed
Definition: internal.h:995
enum MHD_OPTION options
Definition: internal.h:1160
#define MHD_HTTP_HEADER_CONNECTION
Definition: microhttpd.h:314
void MHD_set_http_callbacks_(struct MHD_Connection *connection)
Definition: connection.c:2786
#define MHD_HTTP_METHOD_PUT
Definition: microhttpd.h:382
void * notify_completed_cls
Definition: internal.h:1000
static void process_request_body(struct MHD_Connection *connection)
Definition: connection.c:1474
#define MHD_HTTP_VERSION_1_0
Definition: microhttpd.h:366
TransmitCallback send_cls
Definition: internal.h:823
_MHD_EXTERN int MHD_get_connection_values(struct MHD_Connection *connection, enum MHD_ValueKind kind, MHD_KeyValueIterator iterator, void *iterator_cls)
Definition: connection.c:128
#define XDLL_remove(head, tail, element)
Definition: internal.h:1351
#define DLL_insert(head, tail, element)
Definition: internal.h:1285
#define MHD_HTTP_INTERNAL_SERVER_ERROR
Definition: microhttpd.h:278
#define MHD_CONTENT_READER_END_WITH_ERROR
Definition: microhttpd.h:165
MHD_ContentReaderCallback crc
Definition: internal.h:270
void * crc_cls
Definition: internal.h:264
struct sockaddr * addr
Definition: internal.h:639
MHD_mutex_ mutex
Definition: internal.h:282
struct MHD_Connection * suspended_connections_tail
Definition: internal.h:923
MHD_PanicCallback mhd_panic
Definition: daemon.c:146
#define MHD_UNSIGNED_LONG_LONG_PRINTF
Definition: microhttpd.h:217
#define MHD_HTTP_HEADER_CONTENT_LENGTH
Definition: microhttpd.h:317
static int parse_arguments(enum MHD_ValueKind kind, struct MHD_Connection *connection, char *args)
Definition: connection.c:1202
#define MHD_SIZE_UNKNOWN
Definition: microhttpd.h:157
char * data
Definition: internal.h:258
static int do_write(struct MHD_Connection *connection)
Definition: connection.c:1714
size_t read_buffer_offset
Definition: internal.h:659
void * default_handler_cls
Definition: internal.h:903
#define MHD_NO
Definition: microhttpd.h:143
unsigned int connection_timeout
Definition: internal.h:1149
_MHD_EXTERN const char * MHD_get_response_header(struct MHD_Response *response, const char *key)
Definition: response.c:210
#define MHD_HTTP_REQUEST_URI_TOO_LONG
Definition: microhttpd.h:264
MHD_mutex_ cleanup_connection_mutex
Definition: internal.h:1087
#define CONNECTION_CLOSE_ERROR(c, emsg)
Definition: connection.c:315
struct MHD_HTTP_Header * headers_received
Definition: internal.h:556
struct MHD_Connection * connections_tail
Definition: internal.h:913
#define MHD_HTTP_HEADER_TRANSFER_ENCODING
Definition: microhttpd.h:349
#define EDLL_insert(head, tail, element)
Definition: internal.h:1374
void MHD_connection_close(struct MHD_Connection *connection, enum MHD_RequestTerminationCode termination_code)
Definition: connection.c:268
_MHD_EXTERN int MHD_set_connection_value(struct MHD_Connection *connection, enum MHD_ValueKind kind, const char *key, const char *value)
Definition: connection.c:177
#define REQUEST_TOO_BIG
Definition: connection.c:63
struct MHD_HTTP_Header * headers_received_tail
Definition: internal.h:561
static int build_header_response(struct MHD_Connection *connection)
Definition: connection.c:640
size_t pool_increment
Definition: internal.h:1062
#define MHD_HTTP_METHOD_POST
Definition: microhttpd.h:381
struct MHD_Connection * suspended_connections_head
Definition: internal.h:918
memory pool; mostly used for efficient (de)allocation for each connection and bounding memory use for...