1/*
2    This file is part of libmicrohttpd
3     Copyright (C) 2007-2015 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
21/**
22 * @file connection.c
23 * @brief  Methods for managing connections
24 * @author Daniel Pittman
25 * @author Christian Grothoff
26 */
27
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
48/**
49 * Message to transmit when http 1.1 request is received
50 */
51#define HTTP_100_CONTINUE "HTTP/1.1 100 Continue\r\n\r\n"
52
53/**
54 * Response text used when the request (http header) is too big to
55 * be processed.
56 *
57 * Intentionally empty here to keep our memory footprint
58 * minimal.
59 */
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
66/**
67 * Response text used when the request (http header) does not
68 * contain a "Host:" header and still claims to be HTTP 1.1.
69 *
70 * Intentionally empty here to keep our memory footprint
71 * minimal.
72 */
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
79/**
80 * Response text used when the request (http header) is
81 * malformed.
82 *
83 * Intentionally empty here to keep our memory footprint
84 * minimal.
85 */
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
92/**
93 * Response text used when there is an internal server error.
94 *
95 * Intentionally empty here to keep our memory footprint
96 * minimal.
97 */
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
104/**
105 * Add extra debug messages with reasons for closing connections
106 * (non-error reasons).
107 */
108#define DEBUG_CLOSE MHD_NO
109
110/**
111 * Should all data send be printed to stderr?
112 */
113#define DEBUG_SEND_DATA MHD_NO
114
115
116/**
117 * Get all of the headers from the request.
118 *
119 * @param connection connection to get values from
120 * @param kind types of values to iterate over
121 * @param iterator callback to call on each header;
122 *        maybe NULL (then just count headers)
123 * @param iterator_cls extra argument to @a iterator
124 * @return number of entries iterated over
125 * @ingroup request
126 */
127int
128MHD_get_connection_values (struct MHD_Connection *connection,
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
151/**
152 * This function can be used to add an entry to the HTTP headers of a
153 * connection (so that the #MHD_get_connection_values function will
154 * return them -- and the `struct MHD_PostProcessor` will also see
155 * them).  This maybe required in certain situations (see Mantis
156 * #1399) where (broken) HTTP implementations fail to supply values
157 * needed by the post processor (or other parts of the application).
158 *
159 * This function MUST only be called from within the
160 * #MHD_AccessHandlerCallback (otherwise, access maybe improperly
161 * synchronized).  Furthermore, the client must guarantee that the key
162 * and value arguments are 0-terminated strings that are NOT freed
163 * until the connection is closed.  (The easiest way to do this is by
164 * passing only arguments to permanently allocated strings.).
165 *
166 * @param connection the connection for which a
167 *  value should be set
168 * @param kind kind of the value
169 * @param key key for the value
170 * @param value the value itself
171 * @return #MHD_NO if the operation could not be
172 *         performed due to insufficient memory;
173 *         #MHD_YES on success
174 * @ingroup request
175 */
176int
177MHD_set_connection_value (struct MHD_Connection *connection,
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
206/**
207 * Get a particular header value.  If multiple
208 * values match the kind, return any one of them.
209 *
210 * @param connection connection to get values from
211 * @param kind what kind of value are we looking for
212 * @param key the header to look for, NULL to lookup 'trailing' value without a key
213 * @return NULL if no such item was found
214 * @ingroup request
215 */
216const char *
217MHD_lookup_connection_value (struct MHD_Connection *connection,
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
235/**
236 * Do we (still) need to send a 100 continue
237 * message for this connection?
238 *
239 * @param connection connection to test
240 * @return 0 if we don't need 100 CONTINUE, 1 if we do
241 */
242static int
243need_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,
250			     MHD_HTTP_VERSION_1_1)) &&
251	   (NULL != (expect = MHD_lookup_connection_value (connection,
252							   MHD_HEADER_KIND,
253							   MHD_HTTP_HEADER_EXPECT))) &&
254	   (MHD_str_equal_caseless_(expect, "100-continue")) &&
255	   (connection->continue_message_write_offset <
256	    strlen (HTTP_100_CONTINUE)) );
257}
258
259
260/**
261 * Close the given connection and give the
262 * specified termination code to the user.
263 *
264 * @param connection connection to close
265 * @param termination_code termination reason to give
266 */
267void
268MHD_connection_close (struct MHD_Connection *connection,
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;
278  connection->event_loop_info = MHD_EVENT_LOOP_INFO_CLEANUP;
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
289/**
290 * A serious error occured, close the
291 * connection (and notify the application).
292 *
293 * @param connection connection to close with error
294 * @param emsg error message (can be NULL)
295 */
296static void
297connection_close_error (struct MHD_Connection *connection,
298			const char *emsg)
299{
300#if HAVE_MESSAGES
301  if (NULL != emsg)
302    MHD_DLOG (connection->daemon, emsg);
303#endif
304  MHD_connection_close (connection, MHD_REQUEST_TERMINATED_WITH_ERROR);
305}
306
307
308/**
309 * Macro to only include error message in call to
310 * "connection_close_error" if we have HAVE_MESSAGES.
311 */
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
319/**
320 * Prepare the response buffer of this connection for
321 * sending.  Assumes that the response mutex is
322 * already held.  If the transmission is complete,
323 * this function may close the socket (and return
324 * #MHD_NO).
325 *
326 * @param connection the connection
327 * @return #MHD_NO if readying the response failed (the
328 *  lock on the response will have been released already
329 *  in this case).
330 */
331static int
332try_ready_normal_body (struct MHD_Connection *connection)
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)
370	MHD_connection_close (connection, MHD_REQUEST_TERMINATED_COMPLETED_OK);
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    {
380      connection->state = MHD_CONNECTION_NORMAL_BODY_UNREADY;
381      if (NULL != response->crc)
382        (void) MHD_mutex_unlock_ (&response->mutex);
383      return MHD_NO;
384    }
385  return MHD_YES;
386}
387
388
389/**
390 * Prepare the response buffer of this connection for sending.
391 * Assumes that the response mutex is already held.  If the
392 * transmission is complete, this function may close the socket (and
393 * return MHD_NO).
394 *
395 * @param connection the connection
396 * @return #MHD_NO if readying the response failed
397 */
398static int
399try_ready_chunked_body (struct MHD_Connection *connection)
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    {
474      connection->state = MHD_CONNECTION_CHUNKED_BODY_UNREADY;
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
493/**
494 * Are we allowed to keep the given connection alive?  We can use the
495 * TCP stream for a second request if the connection is HTTP 1.1 and
496 * the "Connection" header either does not exist or is not set to
497 * "close", or if the connection is HTTP 1.0 and the "Connection"
498 * header is explicitly set to "keep-alive".  If no HTTP version is
499 * specified (or if it is not 1.0 or 1.1), we definitively close the
500 * connection.  If the "Connection" header is not exactly "close" or
501 * "keep-alive", we proceed to use the default for the respective HTTP
502 * version (which is conservative for HTTP 1.0, but might be a bit
503 * optimistic for HTTP 1.1).
504 *
505 * @param connection the connection to check for keepalive
506 * @return #MHD_YES if (based on the request), a keepalive is
507 *        legal
508 */
509static int
510keepalive_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,
520                                     MHD_HEADER_KIND,
521                                     MHD_HTTP_HEADER_CONNECTION);
522  if (MHD_str_equal_caseless_(connection->version,
523                       MHD_HTTP_VERSION_1_1))
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,
533                       MHD_HTTP_VERSION_1_0))
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
545/**
546 * Produce HTTP "Date:" header.
547 *
548 * @param date where to write the header, with
549 *        at least 128 bytes available space.
550 */
551static void
552get_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
596/**
597 * Try growing the read buffer.  We initially claim half the
598 * available buffer space for the read buffer (the other half
599 * being left for management data structures; the write
600 * buffer can in the end take virtually everything as the
601 * read buffer can be reduced to the minimum necessary at that
602 * point.
603 *
604 * @param connection the connection
605 * @return #MHD_YES on success, #MHD_NO on failure
606 */
607static int
608try_grow_read_buffer (struct MHD_Connection *connection)
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
630/**
631 * Allocate the connection's write buffer and fill it with all of the
632 * headers (or footers, if we have already sent the body) from the
633 * HTTPd's response.  If headers are missing in the response supplied
634 * by the application, additional headers may be added here.
635 *
636 * @param connection the connection
637 * @return #MHD_YES on success, #MHD_NO on failure (out of memory)
638 */
639static int
640build_header_response (struct MHD_Connection *connection)
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"
681	       : ( (MHD_str_equal_caseless_ (MHD_HTTP_VERSION_1_0,
682				     connection->version))
683		   ? MHD_HTTP_VERSION_1_0
684		   : MHD_HTTP_VERSION_1_1),
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,
693					     MHD_HTTP_HEADER_DATE)) )
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    {
715    case MHD_CONNECTION_FOOTERS_RECEIVED:
716      response_has_close = MHD_get_response_header (connection->response,
717                                                    MHD_HTTP_HEADER_CONNECTION);
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,
726                                                            MHD_HEADER_KIND,
727                                                            MHD_HTTP_HEADER_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               (MHD_str_equal_caseless_ (MHD_HTTP_VERSION_1_1,
746                                         connection->version) ) )
747            {
748              have_encoding = MHD_get_response_header (connection->response,
749                                                       MHD_HTTP_HEADER_TRANSFER_ENCODING);
750              if (NULL == have_encoding)
751                {
752                  must_add_chunked_encoding = MHD_YES;
753                  connection->have_chunked_upload = MHD_YES;
754                }
755              else if (MHD_str_equal_caseless_(have_encoding, "identity"))
756                {
757                  /* application forced identity encoding, can't do 'chunked' */
758                  must_add_close = MHD_YES;
759                }
760              else
761                {
762                  connection->have_chunked_upload = MHD_YES;
763                }
764            }
765          else
766            {
767              /* Keep alive or chunking not possible
768                 => set close header if not present */
769              if (NULL == response_has_close)
770                must_add_close = MHD_YES;
771            }
772        }
773
774      /* check for other reasons to add 'close' header */
775      if ( ( (NULL != client_requested_close) ||
776             (MHD_YES == connection->read_closed) ) &&
777           (NULL == response_has_close) &&
778           (0 == (connection->response->flags & MHD_RF_HTTP_VERSION_1_0_ONLY) ) )
779        must_add_close = MHD_YES;
780
781      /* check if we should add a 'content length' header */
782      have_content_length = MHD_get_response_header (connection->response,
783                                                     MHD_HTTP_HEADER_CONTENT_LENGTH);
784
785      if ( (MHD_SIZE_UNKNOWN != connection->response->total_size) &&
786           (NULL == have_content_length) &&
787           ( (NULL == connection->method) ||
788             (! MHD_str_equal_caseless_ (connection->method,
789                                         MHD_HTTP_METHOD_CONNECT)) ) )
790        {
791          /*
792            Here we add a content-length if one is missing; however,
793            for 'connect' methods, the responses MUST NOT include a
794            content-length header *if* the response code is 2xx (in
795            which case we expect there to be no body).  Still,
796            as we don't know the response code here in some cases, we
797            simply only force adding a content-length header if this
798            is not a 'connect' or if the response is not empty
799            (which is kind of more sane, because if some crazy
800            application did return content with a 2xx status code,
801            then having a content-length might again be a good idea).
802
803            Note that the change from 'SHOULD NOT' to 'MUST NOT' is
804            a recent development of the HTTP 1.1 specification.
805          */
806          content_length_len
807            = sprintf (content_length_buf,
808                       MHD_HTTP_HEADER_CONTENT_LENGTH ": " MHD_UNSIGNED_LONG_LONG_PRINTF "\r\n",
809                       (MHD_UNSIGNED_LONG_LONG) connection->response->total_size);
810          must_add_content_length = MHD_YES;
811        }
812
813      /* check for adding keep alive */
814      if ( (NULL == response_has_keepalive) &&
815           (NULL == response_has_close) &&
816           (MHD_NO == must_add_close) &&
817           (0 == (connection->response->flags & MHD_RF_HTTP_VERSION_1_0_ONLY) ) &&
818           (MHD_YES == keepalive_possible (connection)) )
819        must_add_keep_alive = MHD_YES;
820      break;
821    case MHD_CONNECTION_BODY_SENT:
822      break;
823    default:
824      EXTRA_CHECK (0);
825    }
826
827  if (must_add_close)
828    size += strlen ("Connection: close\r\n");
829  if (must_add_keep_alive)
830    size += strlen ("Connection: Keep-Alive\r\n");
831  if (must_add_chunked_encoding)
832    size += strlen ("Transfer-Encoding: chunked\r\n");
833  if (must_add_content_length)
834    size += content_length_len;
835  EXTRA_CHECK (! (must_add_close && must_add_keep_alive) );
836  EXTRA_CHECK (! (must_add_chunked_encoding && must_add_content_length) );
837
838  for (pos = connection->response->first_header; NULL != pos; pos = pos->next)
839    if ( (pos->kind == kind) &&
840         (! ( (MHD_YES == must_add_close) &&
841              (pos->value == response_has_keepalive) &&
842              (MHD_str_equal_caseless_(pos->header,
843                                MHD_HTTP_HEADER_CONNECTION) ) ) ) )
844      size += strlen (pos->header) + strlen (pos->value) + 4; /* colon, space, linefeeds */
845  /* produce data */
846  data = MHD_pool_allocate (connection->pool, size + 1, MHD_NO);
847  if (NULL == data)
848    {
849#if HAVE_MESSAGES
850      MHD_DLOG (connection->daemon,
851                "Not enough memory for write!\n");
852#endif
853      return MHD_NO;
854    }
855  if (MHD_CONNECTION_FOOTERS_RECEIVED == connection->state)
856    {
857      memcpy (data, code, off);
858    }
859  if (must_add_close)
860    {
861      /* we must add the 'Connection: close' header */
862      memcpy (&data[off],
863              "Connection: close\r\n",
864	      strlen ("Connection: close\r\n"));
865      off += strlen ("Connection: close\r\n");
866    }
867  if (must_add_keep_alive)
868    {
869      /* we must add the 'Connection: Keep-Alive' header */
870      memcpy (&data[off],
871              "Connection: Keep-Alive\r\n",
872	      strlen ("Connection: Keep-Alive\r\n"));
873      off += strlen ("Connection: Keep-Alive\r\n");
874    }
875  if (must_add_chunked_encoding)
876    {
877      /* we must add the 'Transfer-Encoding: chunked' header */
878      memcpy (&data[off],
879              "Transfer-Encoding: chunked\r\n",
880	      strlen ("Transfer-Encoding: chunked\r\n"));
881      off += strlen ("Transfer-Encoding: chunked\r\n");
882    }
883  if (must_add_content_length)
884    {
885      /* we must add the 'Content-Length' header */
886      memcpy (&data[off],
887              content_length_buf,
888	      content_length_len);
889      off += content_length_len;
890    }
891  for (pos = connection->response->first_header; NULL != pos; pos = pos->next)
892    if ( (pos->kind == kind) &&
893         (! ( (pos->value == response_has_keepalive) &&
894              (MHD_YES == must_add_close) &&
895              (MHD_str_equal_caseless_(pos->header,
896                                MHD_HTTP_HEADER_CONNECTION) ) ) ) )
897      off += sprintf (&data[off],
898		      "%s: %s\r\n",
899		      pos->header,
900		      pos->value);
901  if (MHD_CONNECTION_FOOTERS_RECEIVED == connection->state)
902    {
903      strcpy (&data[off], date);
904      off += strlen (date);
905    }
906  memcpy (&data[off], "\r\n", 2);
907  off += 2;
908
909  if (off != size)
910    mhd_panic (mhd_panic_cls, __FILE__, __LINE__, NULL);
911  connection->write_buffer = data;
912  connection->write_buffer_append_offset = size;
913  connection->write_buffer_send_offset = 0;
914  connection->write_buffer_size = size + 1;
915  return MHD_YES;
916}
917
918
919/**
920 * We encountered an error processing the request.
921 * Handle it properly by stopping to read data
922 * and sending the indicated response code and message.
923 *
924 * @param connection the connection
925 * @param status_code the response code to send (400, 413 or 414)
926 * @param message the error message to send
927 */
928static void
929transmit_error_response (struct MHD_Connection *connection,
930                         unsigned int status_code,
931			 const char *message)
932{
933  struct MHD_Response *response;
934
935  if (NULL == connection->version)
936    {
937      /* we were unable to process the full header line, so we don't
938	 really know what version the client speaks; assume 1.0 */
939      connection->version = MHD_HTTP_VERSION_1_0;
940    }
941  connection->state = MHD_CONNECTION_FOOTERS_RECEIVED;
942  connection->read_closed = MHD_YES;
943#if HAVE_MESSAGES
944  MHD_DLOG (connection->daemon,
945            "Error %u (`%s') processing request, closing connection.\n",
946            status_code, message);
947#endif
948  EXTRA_CHECK (NULL == connection->response);
949  response = MHD_create_response_from_buffer (strlen (message),
950					      (void *) message,
951					      MHD_RESPMEM_PERSISTENT);
952  MHD_queue_response (connection, status_code, response);
953  EXTRA_CHECK (NULL != connection->response);
954  MHD_destroy_response (response);
955  if (MHD_NO == build_header_response (connection))
956    {
957      /* oops - close! */
958      CONNECTION_CLOSE_ERROR (connection,
959			      "Closing connection (failed to create response header)\n");
960    }
961  else
962    {
963      connection->state = MHD_CONNECTION_HEADERS_SENDING;
964    }
965}
966
967
968/**
969 * Update the 'event_loop_info' field of this connection based on the state
970 * that the connection is now in.  May also close the connection or
971 * perform other updates to the connection if needed to prepare for
972 * the next round of the event loop.
973 *
974 * @param connection connetion to get poll set for
975 */
976static void
977MHD_connection_update_event_loop_info (struct MHD_Connection *connection)
978{
979  while (1)
980    {
981#if DEBUG_STATES
982      MHD_DLOG (connection->daemon,
983                "%s: state: %s\n",
984                __FUNCTION__,
985                MHD_state_to_string (connection->state));
986#endif
987      switch (connection->state)
988        {
989#if HTTPS_SUPPORT
990	case MHD_TLS_CONNECTION_INIT:
991	  if (SSL_want_read (connection->tls_session))
992            connection->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
993	  else
994            connection->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
995	  break;
996#endif
997        case MHD_CONNECTION_INIT:
998        case MHD_CONNECTION_URL_RECEIVED:
999        case MHD_CONNECTION_HEADER_PART_RECEIVED:
1000          /* while reading headers, we always grow the
1001             read buffer if needed, no size-check required */
1002          if ( (connection->read_buffer_offset == connection->read_buffer_size) &&
1003	       (MHD_NO == try_grow_read_buffer (connection)) )
1004            {
1005              transmit_error_response (connection,
1006                                       (connection->url != NULL)
1007                                       ? MHD_HTTP_REQUEST_ENTITY_TOO_LARGE
1008                                       : MHD_HTTP_REQUEST_URI_TOO_LONG,
1009                                       REQUEST_TOO_BIG);
1010              continue;
1011            }
1012	  if (MHD_NO == connection->read_closed)
1013	    connection->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
1014	  else
1015	    connection->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
1016          break;
1017        case MHD_CONNECTION_HEADERS_RECEIVED:
1018          EXTRA_CHECK (0);
1019          break;
1020        case MHD_CONNECTION_HEADERS_PROCESSED:
1021          EXTRA_CHECK (0);
1022          break;
1023        case MHD_CONNECTION_CONTINUE_SENDING:
1024          connection->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
1025          break;
1026        case MHD_CONNECTION_CONTINUE_SENT:
1027          if (connection->read_buffer_offset == connection->read_buffer_size)
1028            {
1029              if ((MHD_YES != try_grow_read_buffer (connection)) &&
1030                  (0 != (connection->daemon->options &
1031                         (MHD_USE_SELECT_INTERNALLY |
1032                          MHD_USE_THREAD_PER_CONNECTION))))
1033                {
1034                  /* failed to grow the read buffer, and the
1035                     client which is supposed to handle the
1036                     received data in a *blocking* fashion
1037                     (in this mode) did not handle the data as
1038                     it was supposed to!
1039                     => we would either have to do busy-waiting
1040                     (on the client, which would likely fail),
1041                     or if we do nothing, we would just timeout
1042                     on the connection (if a timeout is even
1043                     set!).
1044                     Solution: we kill the connection with an error */
1045                  transmit_error_response (connection,
1046                                           MHD_HTTP_INTERNAL_SERVER_ERROR,
1047                                           INTERNAL_ERROR);
1048                  continue;
1049                }
1050            }
1051          if ( (connection->read_buffer_offset < connection->read_buffer_size) &&
1052	       (MHD_NO == connection->read_closed) )
1053	    connection->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
1054	  else
1055	    connection->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
1056          break;
1057        case MHD_CONNECTION_BODY_RECEIVED:
1058        case MHD_CONNECTION_FOOTER_PART_RECEIVED:
1059          /* while reading footers, we always grow the
1060             read buffer if needed, no size-check required */
1061          if (MHD_YES == connection->read_closed)
1062            {
1063	      CONNECTION_CLOSE_ERROR (connection,
1064				      NULL);
1065              continue;
1066            }
1067	  connection->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
1068          /* transition to FOOTERS_RECEIVED
1069             happens in read handler */
1070          break;
1071        case MHD_CONNECTION_FOOTERS_RECEIVED:
1072	  connection->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
1073          break;
1074        case MHD_CONNECTION_HEADERS_SENDING:
1075          /* headers in buffer, keep writing */
1076	  connection->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
1077          break;
1078        case MHD_CONNECTION_HEADERS_SENT:
1079          EXTRA_CHECK (0);
1080          break;
1081        case MHD_CONNECTION_NORMAL_BODY_READY:
1082	  connection->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
1083          break;
1084        case MHD_CONNECTION_NORMAL_BODY_UNREADY:
1085	  connection->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
1086          break;
1087        case MHD_CONNECTION_CHUNKED_BODY_READY:
1088	  connection->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
1089          break;
1090        case MHD_CONNECTION_CHUNKED_BODY_UNREADY:
1091	  connection->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
1092          break;
1093        case MHD_CONNECTION_BODY_SENT:
1094          EXTRA_CHECK (0);
1095          break;
1096        case MHD_CONNECTION_FOOTERS_SENDING:
1097	  connection->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
1098          break;
1099        case MHD_CONNECTION_FOOTERS_SENT:
1100          EXTRA_CHECK (0);
1101          break;
1102        case MHD_CONNECTION_CLOSED:
1103	  connection->event_loop_info = MHD_EVENT_LOOP_INFO_CLEANUP;
1104          return;       /* do nothing, not even reading */
1105        default:
1106          EXTRA_CHECK (0);
1107        }
1108      break;
1109    }
1110}
1111
1112
1113/**
1114 * Parse a single line of the HTTP header.  Advance
1115 * read_buffer (!) appropriately.  If the current line does not
1116 * fit, consider growing the buffer.  If the line is
1117 * far too long, close the connection.  If no line is
1118 * found (incomplete, buffer too small, line too long),
1119 * return NULL.  Otherwise return a pointer to the line.
1120 *
1121 * @param connection connection we're processing
1122 * @return NULL if no full line is available
1123 */
1124static char *
1125get_next_header_line (struct MHD_Connection *connection)
1126{
1127  char *rbuf;
1128  size_t pos;
1129
1130  if (0 == connection->read_buffer_offset)
1131    return NULL;
1132  pos = 0;
1133  rbuf = connection->read_buffer;
1134  while ((pos < connection->read_buffer_offset - 1) &&
1135         ('\r' != rbuf[pos]) && ('\n' != rbuf[pos]))
1136    pos++;
1137  if ( (pos == connection->read_buffer_offset - 1) &&
1138       ('\n' != rbuf[pos]) )
1139    {
1140      /* not found, consider growing... */
1141      if ( (connection->read_buffer_offset == connection->read_buffer_size) &&
1142	   (MHD_NO ==
1143	    try_grow_read_buffer (connection)) )
1144	{
1145	  transmit_error_response (connection,
1146				   (NULL != connection->url)
1147				   ? MHD_HTTP_REQUEST_ENTITY_TOO_LARGE
1148				   : MHD_HTTP_REQUEST_URI_TOO_LONG,
1149				   REQUEST_TOO_BIG);
1150	}
1151      return NULL;
1152    }
1153  /* found, check if we have proper LFCR */
1154  if (('\r' == rbuf[pos]) && ('\n' == rbuf[pos + 1]))
1155    rbuf[pos++] = '\0';         /* skip both r and n */
1156  rbuf[pos++] = '\0';
1157  connection->read_buffer += pos;
1158  connection->read_buffer_size -= pos;
1159  connection->read_buffer_offset -= pos;
1160  return rbuf;
1161}
1162
1163
1164/**
1165 * Add an entry to the HTTP headers of a connection.  If this fails,
1166 * transmit an error response (request too big).
1167 *
1168 * @param connection the connection for which a
1169 *  value should be set
1170 * @param kind kind of the value
1171 * @param key key for the value
1172 * @param value the value itself
1173 * @return #MHD_NO on failure (out of memory), #MHD_YES for success
1174 */
1175static int
1176connection_add_header (struct MHD_Connection *connection,
1177                       char *key, char *value, enum MHD_ValueKind kind)
1178{
1179  if (MHD_NO == MHD_set_connection_value (connection,
1180					  kind,
1181					  key, value))
1182    {
1183#if HAVE_MESSAGES
1184      MHD_DLOG (connection->daemon,
1185                "Not enough memory to allocate header record!\n");
1186#endif
1187      transmit_error_response (connection, MHD_HTTP_REQUEST_ENTITY_TOO_LARGE,
1188                               REQUEST_TOO_BIG);
1189      return MHD_NO;
1190    }
1191  return MHD_YES;
1192}
1193
1194
1195/**
1196 * Parse and unescape the arguments given by the client as part
1197 * of the HTTP request URI.
1198 *
1199 * @param kind header kind to use for adding to the connection
1200 * @param connection connection to add headers to
1201 * @param args argument URI string (after "?" in URI)
1202 * @return #MHD_NO on failure (out of memory), #MHD_YES for success
1203 */
1204static int
1205parse_arguments (enum MHD_ValueKind kind,
1206                 struct MHD_Connection *connection,
1207		 char *args)
1208{
1209  char *equals;
1210  char *amper;
1211
1212  while (NULL != args)
1213    {
1214      equals = strchr (args, '=');
1215      amper = strchr (args, '&');
1216      if (NULL == amper)
1217	{
1218	  /* last argument */
1219	  if (NULL == equals)
1220	    {
1221	      /* got 'foo', add key 'foo' with NULL for value */
1222              MHD_unescape_plus (args);
1223	      connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls,
1224						     connection,
1225						     args);
1226	      return connection_add_header (connection,
1227					    args,
1228					    NULL,
1229					    kind);
1230	    }
1231	  /* got 'foo=bar' */
1232	  equals[0] = '\0';
1233	  equals++;
1234          MHD_unescape_plus (args);
1235	  connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls,
1236						 connection,
1237						 args);
1238          MHD_unescape_plus (equals);
1239	  connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls,
1240						 connection,
1241						 equals);
1242	  return connection_add_header (connection, args, equals, kind);
1243	}
1244      /* amper is non-NULL here */
1245      amper[0] = '\0';
1246      amper++;
1247      if ( (NULL == equals) ||
1248	   (equals >= amper) )
1249	{
1250	  /* got 'foo&bar' or 'foo&bar=val', add key 'foo' with NULL for value */
1251          MHD_unescape_plus (args);
1252	  connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls,
1253						 connection,
1254						 args);
1255	  if (MHD_NO ==
1256	      connection_add_header (connection,
1257				     args,
1258				     NULL,
1259				     kind))
1260	    return MHD_NO;
1261	  /* continue with 'bar' */
1262	  args = amper;
1263	  continue;
1264
1265	}
1266      /* equals and amper are non-NULL here, and equals < amper,
1267	 so we got regular 'foo=value&bar...'-kind of argument */
1268      equals[0] = '\0';
1269      equals++;
1270      MHD_unescape_plus (args);
1271      connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls,
1272					     connection,
1273					     args);
1274      MHD_unescape_plus (equals);
1275      connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls,
1276					     connection,
1277					     equals);
1278      if (MHD_NO == connection_add_header (connection, args, equals, kind))
1279        return MHD_NO;
1280      args = amper;
1281    }
1282  return MHD_YES;
1283}
1284
1285
1286/**
1287 * Parse the cookie header (see RFC 2109).
1288 *
1289 * @return #MHD_YES for success, #MHD_NO for failure (malformed, out of memory)
1290 */
1291static int
1292parse_cookie_header (struct MHD_Connection *connection)
1293{
1294  const char *hdr;
1295  char *cpy;
1296  char *pos;
1297  char *sce;
1298  char *semicolon;
1299  char *equals;
1300  char *ekill;
1301  char old;
1302  int quotes;
1303
1304  hdr = MHD_lookup_connection_value (connection,
1305				     MHD_HEADER_KIND,
1306				     MHD_HTTP_HEADER_COOKIE);
1307  if (NULL == hdr)
1308    return MHD_YES;
1309  cpy = MHD_pool_allocate (connection->pool, strlen (hdr) + 1, MHD_YES);
1310  if (NULL == cpy)
1311    {
1312#if HAVE_MESSAGES
1313      MHD_DLOG (connection->daemon,
1314                "Not enough memory to parse cookies!\n");
1315#endif
1316      transmit_error_response (connection, MHD_HTTP_REQUEST_ENTITY_TOO_LARGE,
1317                               REQUEST_TOO_BIG);
1318      return MHD_NO;
1319    }
1320  memcpy (cpy, hdr, strlen (hdr) + 1);
1321  pos = cpy;
1322  while (NULL != pos)
1323    {
1324      while (' ' == *pos)
1325        pos++;                  /* skip spaces */
1326
1327      sce = pos;
1328      while (((*sce) != '\0') &&
1329             ((*sce) != ',') && ((*sce) != ';') && ((*sce) != '='))
1330        sce++;
1331      /* remove tailing whitespace (if any) from key */
1332      ekill = sce - 1;
1333      while ((*ekill == ' ') && (ekill >= pos))
1334        *(ekill--) = '\0';
1335      old = *sce;
1336      *sce = '\0';
1337      if (old != '=')
1338        {
1339          /* value part omitted, use empty string... */
1340          if (MHD_NO ==
1341              connection_add_header (connection, pos, "", MHD_COOKIE_KIND))
1342            return MHD_NO;
1343          if (old == '\0')
1344            break;
1345          pos = sce + 1;
1346          continue;
1347        }
1348      equals = sce + 1;
1349      quotes = 0;
1350      semicolon = equals;
1351      while ( ('\0' != semicolon[0]) &&
1352              ( (0 != quotes) ||
1353                ( (';' != semicolon[0]) &&
1354                  (',' != semicolon[0]) ) ) )
1355        {
1356          if ('"' == semicolon[0])
1357            quotes = (quotes + 1) & 1;
1358          semicolon++;
1359        }
1360      if ('\0' == semicolon[0])
1361        semicolon = NULL;
1362      if (NULL != semicolon)
1363        {
1364          semicolon[0] = '\0';
1365          semicolon++;
1366        }
1367      /* remove quotes */
1368      if ( ('"' == equals[0]) &&
1369           ('"' == equals[strlen (equals) - 1]) )
1370        {
1371          equals[strlen (equals) - 1] = '\0';
1372          equals++;
1373        }
1374      if (MHD_NO == connection_add_header (connection,
1375                                           pos, equals, MHD_COOKIE_KIND))
1376        return MHD_NO;
1377      pos = semicolon;
1378    }
1379  return MHD_YES;
1380}
1381
1382
1383/**
1384 * Parse the first line of the HTTP HEADER.
1385 *
1386 * @param connection the connection (updated)
1387 * @param line the first line
1388 * @return #MHD_YES if the line is ok, #MHD_NO if it is malformed
1389 */
1390static int
1391parse_initial_message_line (struct MHD_Connection *connection,
1392                            char *line)
1393{
1394  char *uri;
1395  char *http_version;
1396  char *args;
1397
1398  if (NULL == (uri = strchr (line, ' ')))
1399    return MHD_NO;              /* serious error */
1400  uri[0] = '\0';
1401  connection->method = line;
1402  uri++;
1403  while (' ' == uri[0])
1404    uri++;
1405  http_version = strchr (uri, ' ');
1406  if (NULL != http_version)
1407    {
1408      http_version[0] = '\0';
1409      http_version++;
1410    }
1411  if (NULL != connection->daemon->uri_log_callback)
1412    connection->client_context
1413      = connection->daemon->uri_log_callback (connection->daemon->uri_log_callback_cls,
1414					      uri,
1415					      connection);
1416  args = strchr (uri, '?');
1417  if (NULL != args)
1418    {
1419      args[0] = '\0';
1420      args++;
1421      parse_arguments (MHD_GET_ARGUMENT_KIND, connection, args);
1422    }
1423  connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls,
1424					 connection,
1425					 uri);
1426  connection->url = uri;
1427  if (NULL == http_version)
1428    connection->version = "";
1429  else
1430    connection->version = http_version;
1431  return MHD_YES;
1432}
1433
1434
1435/**
1436 * Call the handler of the application for this
1437 * connection.  Handles chunking of the upload
1438 * as well as normal uploads.
1439 *
1440 * @param connection connection we're processing
1441 */
1442static void
1443call_connection_handler (struct MHD_Connection *connection)
1444{
1445  size_t processed;
1446
1447  if (NULL != connection->response)
1448    return;                     /* already queued a response */
1449  processed = 0;
1450  connection->client_aware = MHD_YES;
1451  if (MHD_NO ==
1452      connection->daemon->default_handler (connection->daemon-> default_handler_cls,
1453					   connection,
1454                                           connection->url,
1455					   connection->method,
1456					   connection->version,
1457					   NULL, &processed,
1458					   &connection->client_context))
1459    {
1460      /* serious internal error, close connection */
1461      CONNECTION_CLOSE_ERROR (connection,
1462			      "Internal application error, closing connection.\n");
1463      return;
1464    }
1465}
1466
1467
1468
1469/**
1470 * Call the handler of the application for this
1471 * connection.  Handles chunking of the upload
1472 * as well as normal uploads.
1473 *
1474 * @param connection connection we're processing
1475 */
1476static void
1477process_request_body (struct MHD_Connection *connection)
1478{
1479  size_t processed;
1480  size_t available;
1481  size_t used;
1482  size_t i;
1483  int instant_retry;
1484  int malformed;
1485  char *buffer_head;
1486  char *end;
1487
1488  if (NULL != connection->response)
1489    return;                     /* already queued a response */
1490
1491  buffer_head = connection->read_buffer;
1492  available = connection->read_buffer_offset;
1493  do
1494    {
1495      instant_retry = MHD_NO;
1496      if ( (MHD_YES == connection->have_chunked_upload) &&
1497           (MHD_SIZE_UNKNOWN == connection->remaining_upload_size) )
1498        {
1499          if ( (connection->current_chunk_offset == connection->current_chunk_size) &&
1500               (0 != connection->current_chunk_offset) &&
1501               (available >= 2) )
1502            {
1503              /* skip new line at the *end* of a chunk */
1504              i = 0;
1505              if ((buffer_head[i] == '\r') || (buffer_head[i] == '\n'))
1506                i++;            /* skip 1st part of line feed */
1507              if ((buffer_head[i] == '\r') || (buffer_head[i] == '\n'))
1508                i++;            /* skip 2nd part of line feed */
1509              if (i == 0)
1510                {
1511                  /* malformed encoding */
1512                  CONNECTION_CLOSE_ERROR (connection,
1513					  "Received malformed HTTP request (bad chunked encoding), closing connection.\n");
1514                  return;
1515                }
1516              available -= i;
1517              buffer_head += i;
1518              connection->current_chunk_offset = 0;
1519              connection->current_chunk_size = 0;
1520            }
1521          if (connection->current_chunk_offset <
1522              connection->current_chunk_size)
1523            {
1524              /* we are in the middle of a chunk, give
1525                 as much as possible to the client (without
1526                 crossing chunk boundaries) */
1527              processed =
1528                connection->current_chunk_size -
1529                connection->current_chunk_offset;
1530              if (processed > available)
1531                processed = available;
1532              if (available > processed)
1533                instant_retry = MHD_YES;
1534            }
1535          else
1536            {
1537              /* we need to read chunk boundaries */
1538              i = 0;
1539              while (i < available)
1540                {
1541                  if ((buffer_head[i] == '\r') || (buffer_head[i] == '\n'))
1542                    break;
1543                  i++;
1544                  if (i >= 6)
1545                    break;
1546                }
1547              /* take '\n' into account; if '\n'
1548                 is the unavailable character, we
1549                 will need to wait until we have it
1550                 before going further */
1551              if ((i + 1 >= available) &&
1552                  !((i == 1) && (available == 2) && (buffer_head[0] == '0')))
1553                break;          /* need more data... */
1554              malformed = (i >= 6);
1555              if (!malformed)
1556                {
1557                  buffer_head[i] = '\0';
1558		  connection->current_chunk_size = strtoul (buffer_head, &end, 16);
1559                  malformed = ('\0' != *end);
1560                }
1561              if (malformed)
1562                {
1563                  /* malformed encoding */
1564                  CONNECTION_CLOSE_ERROR (connection,
1565					  "Received malformed HTTP request (bad chunked encoding), closing connection.\n");
1566                  return;
1567                }
1568              i++;
1569              if ((i < available) &&
1570                  ((buffer_head[i] == '\r') || (buffer_head[i] == '\n')))
1571                i++;            /* skip 2nd part of line feed */
1572
1573              buffer_head += i;
1574              available -= i;
1575              connection->current_chunk_offset = 0;
1576
1577              if (available > 0)
1578                instant_retry = MHD_YES;
1579              if (0 == connection->current_chunk_size)
1580                {
1581                  connection->remaining_upload_size = 0;
1582                  break;
1583                }
1584              continue;
1585            }
1586        }
1587      else
1588        {
1589          /* no chunked encoding, give all to the client */
1590          if ( (0 != connection->remaining_upload_size) &&
1591	       (MHD_SIZE_UNKNOWN != connection->remaining_upload_size) &&
1592	       (connection->remaining_upload_size < available) )
1593	    {
1594              processed = connection->remaining_upload_size;
1595	    }
1596          else
1597	    {
1598              /**
1599               * 1. no chunked encoding, give all to the client
1600               * 2. client may send large chunked data, but only a smaller part is available at one time.
1601               */
1602              processed = available;
1603	    }
1604        }
1605      used = processed;
1606      connection->client_aware = MHD_YES;
1607      if (MHD_NO ==
1608          connection->daemon->default_handler (connection->daemon->default_handler_cls,
1609                                               connection,
1610                                               connection->url,
1611                                               connection->method,
1612                                               connection->version,
1613                                               buffer_head,
1614                                               &processed,
1615                                               &connection->client_context))
1616        {
1617          /* serious internal error, close connection */
1618	  CONNECTION_CLOSE_ERROR (connection,
1619				  "Internal application error, closing connection.\n");
1620          return;
1621        }
1622      if (processed > used)
1623        mhd_panic (mhd_panic_cls, __FILE__, __LINE__
1624#if HAVE_MESSAGES
1625		   , "API violation"
1626#else
1627		   , NULL
1628#endif
1629		   );
1630      if (0 != processed)
1631        instant_retry = MHD_NO; /* client did not process everything */
1632      used -= processed;
1633      if (connection->have_chunked_upload == MHD_YES)
1634        connection->current_chunk_offset += used;
1635      /* dh left "processed" bytes in buffer for next time... */
1636      buffer_head += used;
1637      available -= used;
1638      if (connection->remaining_upload_size != MHD_SIZE_UNKNOWN)
1639        connection->remaining_upload_size -= used;
1640    }
1641  while (MHD_YES == instant_retry);
1642  if (available > 0)
1643    memmove (connection->read_buffer, buffer_head, available);
1644  connection->read_buffer_offset = available;
1645}
1646
1647
1648/**
1649 * Try reading data from the socket into the
1650 * read buffer of the connection.
1651 *
1652 * @param connection connection we're processing
1653 * @return #MHD_YES if something changed,
1654 *         #MHD_NO if we were interrupted or if
1655 *                no space was available
1656 */
1657static int
1658do_read (struct MHD_Connection *connection)
1659{
1660  int bytes_read;
1661
1662  if (connection->read_buffer_size == connection->read_buffer_offset)
1663    return MHD_NO;
1664  bytes_read = connection->recv_cls (connection,
1665                                     &connection->read_buffer
1666                                     [connection->read_buffer_offset],
1667                                     connection->read_buffer_size -
1668                                     connection->read_buffer_offset);
1669  if (bytes_read < 0)
1670    {
1671      const int err = MHD_socket_errno_;
1672      if ((EINTR == err) || (EAGAIN == err) || (EWOULDBLOCK == err))
1673	  return MHD_NO;
1674      if (ECONNRESET == err)
1675        {
1676           CONNECTION_CLOSE_ERROR (connection, NULL);
1677	   return MHD_NO;
1678	}
1679      CONNECTION_CLOSE_ERROR (connection, NULL);
1680      return MHD_YES;
1681    }
1682  if (0 == bytes_read)
1683    {
1684      /* other side closed connection; RFC 2616, section 8.1.4 suggests
1685	 we should then shutdown ourselves as well. */
1686      connection->read_closed = MHD_YES;
1687      MHD_connection_close (connection,
1688			    MHD_REQUEST_TERMINATED_CLIENT_ABORT);
1689      return MHD_YES;
1690    }
1691  connection->read_buffer_offset += bytes_read;
1692  return MHD_YES;
1693}
1694
1695
1696/**
1697 * Try writing data to the socket from the
1698 * write buffer of the connection.
1699 *
1700 * @param connection connection we're processing
1701 * @return #MHD_YES if something changed,
1702 *         #MHD_NO if we were interrupted
1703 */
1704static int
1705do_write (struct MHD_Connection *connection)
1706{
1707  ssize_t ret;
1708  size_t max;
1709
1710  max = connection->write_buffer_append_offset - connection->write_buffer_send_offset;
1711  ret = connection->send_cls (connection,
1712                              &connection->write_buffer
1713                              [connection->write_buffer_send_offset],
1714                              max);
1715
1716  if (ret < 0)
1717    {
1718      const int err = MHD_socket_errno_;
1719      if ((EINTR == err) || (EAGAIN == err) || (EWOULDBLOCK == err))
1720        return MHD_NO;
1721      CONNECTION_CLOSE_ERROR (connection, NULL);
1722      return MHD_YES;
1723    }
1724#if DEBUG_SEND_DATA
1725  fprintf (stderr,
1726           "Sent response: `%.*s'\n",
1727           ret,
1728           &connection->write_buffer[connection->write_buffer_send_offset]);
1729#endif
1730  /* only increment if this wasn't a "sendfile" transmission without
1731     buffer involvement! */
1732  if (0 != max)
1733    connection->write_buffer_send_offset += ret;
1734  return MHD_YES;
1735}
1736
1737
1738/**
1739 * Check if we are done sending the write-buffer.
1740 * If so, transition into "next_state".
1741 *
1742 * @param connection connection to check write status for
1743 * @param next_state the next state to transition to
1744 * @return #MHD_NO if we are not done, #MHD_YES if we are
1745 */
1746static int
1747check_write_done (struct MHD_Connection *connection,
1748                  enum MHD_CONNECTION_STATE next_state)
1749{
1750  if (connection->write_buffer_append_offset !=
1751      connection->write_buffer_send_offset)
1752    return MHD_NO;
1753  connection->write_buffer_append_offset = 0;
1754  connection->write_buffer_send_offset = 0;
1755  connection->state = next_state;
1756  MHD_pool_reallocate (connection->pool,
1757		       connection->write_buffer,
1758                       connection->write_buffer_size, 0);
1759  connection->write_buffer = NULL;
1760  connection->write_buffer_size = 0;
1761  return MHD_YES;
1762}
1763
1764
1765/**
1766 * We have received (possibly the beginning of) a line in the
1767 * header (or footer).  Validate (check for ":") and prepare
1768 * to process.
1769 *
1770 * @param connection connection we're processing
1771 * @param line line from the header to process
1772 * @return #MHD_YES on success, #MHD_NO on error (malformed @a line)
1773 */
1774static int
1775process_header_line (struct MHD_Connection *connection, char *line)
1776{
1777  char *colon;
1778
1779  /* line should be normal header line, find colon */
1780  colon = strchr (line, ':');
1781  if (NULL == colon)
1782    {
1783      /* error in header line, die hard */
1784      CONNECTION_CLOSE_ERROR (connection,
1785			      "Received malformed line (no colon), closing connection.\n");
1786      return MHD_NO;
1787    }
1788  /* zero-terminate header */
1789  colon[0] = '\0';
1790  colon++;                      /* advance to value */
1791  while ((colon[0] != '\0') && ((colon[0] == ' ') || (colon[0] == '\t')))
1792    colon++;
1793  /* we do the actual adding of the connection
1794     header at the beginning of the while
1795     loop since we need to be able to inspect
1796     the *next* header line (in case it starts
1797     with a space...) */
1798  connection->last = line;
1799  connection->colon = colon;
1800  return MHD_YES;
1801}
1802
1803
1804/**
1805 * Process a header value that spans multiple lines.
1806 * The previous line(s) are in connection->last.
1807 *
1808 * @param connection connection we're processing
1809 * @param line the current input line
1810 * @param kind if the line is complete, add a header
1811 *        of the given kind
1812 * @return #MHD_YES if the line was processed successfully
1813 */
1814static int
1815process_broken_line (struct MHD_Connection *connection,
1816                     char *line, enum MHD_ValueKind kind)
1817{
1818  char *last;
1819  char *tmp;
1820  size_t last_len;
1821  size_t tmp_len;
1822
1823  last = connection->last;
1824  if ((line[0] == ' ') || (line[0] == '\t'))
1825    {
1826      /* value was continued on the next line, see
1827         http://www.jmarshall.com/easy/http/ */
1828      last_len = strlen (last);
1829      /* skip whitespace at start of 2nd line */
1830      tmp = line;
1831      while ((tmp[0] == ' ') || (tmp[0] == '\t'))
1832        tmp++;
1833      tmp_len = strlen (tmp);
1834      /* FIXME: we might be able to do this better (faster!), as most
1835	 likely 'last' and 'line' should already be adjacent in
1836	 memory; however, doing this right gets tricky if we have a
1837	 value continued over multiple lines (in which case we need to
1838	 record how often we have done this so we can check for
1839	 adjaency); also, in the case where these are not adjacent
1840	 (not sure how it can happen!), we would want to allocate from
1841	 the end of the pool, so as to not destroy the read-buffer's
1842	 ability to grow nicely. */
1843      last = MHD_pool_reallocate (connection->pool,
1844                                  last,
1845                                  last_len + 1,
1846                                  last_len + tmp_len + 1);
1847      if (NULL == last)
1848        {
1849          transmit_error_response (connection,
1850                                   MHD_HTTP_REQUEST_ENTITY_TOO_LARGE,
1851                                   REQUEST_TOO_BIG);
1852          return MHD_NO;
1853        }
1854      memcpy (&last[last_len], tmp, tmp_len + 1);
1855      connection->last = last;
1856      return MHD_YES;           /* possibly more than 2 lines... */
1857    }
1858  EXTRA_CHECK ((NULL != last) && (NULL != connection->colon));
1859  if ((MHD_NO == connection_add_header (connection,
1860                                        last, connection->colon, kind)))
1861    {
1862      transmit_error_response (connection, MHD_HTTP_REQUEST_ENTITY_TOO_LARGE,
1863                               REQUEST_TOO_BIG);
1864      return MHD_NO;
1865    }
1866  /* we still have the current line to deal with... */
1867  if (0 != strlen (line))
1868    {
1869      if (MHD_NO == process_header_line (connection, line))
1870        {
1871          transmit_error_response (connection,
1872                                   MHD_HTTP_BAD_REQUEST, REQUEST_MALFORMED);
1873          return MHD_NO;
1874        }
1875    }
1876  return MHD_YES;
1877}
1878
1879
1880/**
1881 * Parse the various headers; figure out the size
1882 * of the upload and make sure the headers follow
1883 * the protocol.  Advance to the appropriate state.
1884 *
1885 * @param connection connection we're processing
1886 */
1887static void
1888parse_connection_headers (struct MHD_Connection *connection)
1889{
1890  const char *clen;
1891  MHD_UNSIGNED_LONG_LONG cval;
1892  struct MHD_Response *response;
1893  const char *enc;
1894  char *end;
1895
1896  parse_cookie_header (connection);
1897  if ( (0 != (MHD_USE_PEDANTIC_CHECKS & connection->daemon->options)) &&
1898       (NULL != connection->version) &&
1899       (MHD_str_equal_caseless_(MHD_HTTP_VERSION_1_1, connection->version)) &&
1900       (NULL ==
1901        MHD_lookup_connection_value (connection,
1902                                     MHD_HEADER_KIND,
1903                                     MHD_HTTP_HEADER_HOST)) )
1904    {
1905      /* die, http 1.1 request without host and we are pedantic */
1906      connection->state = MHD_CONNECTION_FOOTERS_RECEIVED;
1907      connection->read_closed = MHD_YES;
1908#if HAVE_MESSAGES
1909      MHD_DLOG (connection->daemon,
1910                "Received `%s' request without `%s' header.\n",
1911                MHD_HTTP_VERSION_1_1, MHD_HTTP_HEADER_HOST);
1912#endif
1913      EXTRA_CHECK (NULL == connection->response);
1914      response =
1915        MHD_create_response_from_buffer (strlen (REQUEST_LACKS_HOST),
1916					 REQUEST_LACKS_HOST,
1917					 MHD_RESPMEM_PERSISTENT);
1918      MHD_queue_response (connection, MHD_HTTP_BAD_REQUEST, response);
1919      MHD_destroy_response (response);
1920      return;
1921    }
1922
1923  connection->remaining_upload_size = 0;
1924  enc = MHD_lookup_connection_value (connection,
1925				     MHD_HEADER_KIND,
1926				     MHD_HTTP_HEADER_TRANSFER_ENCODING);
1927  if (NULL != enc)
1928    {
1929      connection->remaining_upload_size = MHD_SIZE_UNKNOWN;
1930      if (MHD_str_equal_caseless_(enc, "chunked"))
1931        connection->have_chunked_upload = MHD_YES;
1932    }
1933  else
1934    {
1935      clen = MHD_lookup_connection_value (connection,
1936					  MHD_HEADER_KIND,
1937					  MHD_HTTP_HEADER_CONTENT_LENGTH);
1938      if (NULL != clen)
1939        {
1940          cval = strtoul (clen, &end, 10);
1941          if ( ('\0' != *end) ||
1942	     ( (LONG_MAX == cval) && (errno == ERANGE) ) )
1943            {
1944#if HAVE_MESSAGES
1945              MHD_DLOG (connection->daemon,
1946                        "Failed to parse `%s' header `%s', closing connection.\n",
1947                        MHD_HTTP_HEADER_CONTENT_LENGTH,
1948                        clen);
1949#endif
1950	      CONNECTION_CLOSE_ERROR (connection, NULL);
1951              return;
1952            }
1953          connection->remaining_upload_size = cval;
1954        }
1955    }
1956}
1957
1958
1959/**
1960 * Update the 'last_activity' field of the connection to the current time
1961 * and move the connection to the head of the 'normal_timeout' list if
1962 * the timeout for the connection uses the default value.
1963 *
1964 * @param connection the connection that saw some activity
1965 */
1966static void
1967update_last_activity (struct MHD_Connection *connection)
1968{
1969  struct MHD_Daemon *daemon = connection->daemon;
1970
1971  connection->last_activity = MHD_monotonic_time();
1972  if (connection->connection_timeout != daemon->connection_timeout)
1973    return; /* custom timeout, no need to move it in "normal" DLL */
1974
1975  /* move connection to head of timeout list (by remove + add operation) */
1976  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1977       (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) )
1978    MHD_PANIC ("Failed to acquire cleanup mutex\n");
1979  XDLL_remove (daemon->normal_timeout_head,
1980	       daemon->normal_timeout_tail,
1981	       connection);
1982  XDLL_insert (daemon->normal_timeout_head,
1983	       daemon->normal_timeout_tail,
1984	       connection);
1985  if  ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1986	(MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) )
1987    MHD_PANIC ("Failed to release cleanup mutex\n");
1988}
1989
1990
1991/**
1992 * This function handles a particular connection when it has been
1993 * determined that there is data to be read off a socket.
1994 *
1995 * @param connection connection to handle
1996 * @return always #MHD_YES (we should continue to process the
1997 *         connection)
1998 */
1999int
2000MHD_connection_handle_read (struct MHD_Connection *connection)
2001{
2002  update_last_activity (connection);
2003  if (MHD_CONNECTION_CLOSED == connection->state)
2004    return MHD_YES;
2005  /* make sure "read" has a reasonable number of bytes
2006     in buffer to use per system call (if possible) */
2007  if (connection->read_buffer_offset + connection->daemon->pool_increment >
2008      connection->read_buffer_size)
2009    try_grow_read_buffer (connection);
2010  if (MHD_NO == do_read (connection))
2011    return MHD_YES;
2012  while (1)
2013    {
2014#if DEBUG_STATES
2015      MHD_DLOG (connection->daemon, "%s: state: %s\n",
2016                __FUNCTION__,
2017                MHD_state_to_string (connection->state));
2018#endif
2019      switch (connection->state)
2020        {
2021        case MHD_CONNECTION_INIT:
2022        case MHD_CONNECTION_URL_RECEIVED:
2023        case MHD_CONNECTION_HEADER_PART_RECEIVED:
2024        case MHD_CONNECTION_HEADERS_RECEIVED:
2025        case MHD_CONNECTION_HEADERS_PROCESSED:
2026        case MHD_CONNECTION_CONTINUE_SENDING:
2027        case MHD_CONNECTION_CONTINUE_SENT:
2028        case MHD_CONNECTION_BODY_RECEIVED:
2029        case MHD_CONNECTION_FOOTER_PART_RECEIVED:
2030          /* nothing to do but default action */
2031          if (MHD_YES == connection->read_closed)
2032            {
2033	      MHD_connection_close (connection,
2034				    MHD_REQUEST_TERMINATED_READ_ERROR);
2035              continue;
2036            }
2037          break;
2038        case MHD_CONNECTION_CLOSED:
2039          return MHD_YES;
2040        default:
2041          /* shrink read buffer to how much is actually used */
2042          MHD_pool_reallocate (connection->pool,
2043                               connection->read_buffer,
2044                               connection->read_buffer_size + 1,
2045                               connection->read_buffer_offset);
2046          break;
2047        }
2048      break;
2049    }
2050  return MHD_YES;
2051}
2052
2053
2054/**
2055 * This function was created to handle writes to sockets when it has
2056 * been determined that the socket can be written to.
2057 *
2058 * @param connection connection to handle
2059 * @return always #MHD_YES (we should continue to process the
2060 *         connection)
2061 */
2062int
2063MHD_connection_handle_write (struct MHD_Connection *connection)
2064{
2065  struct MHD_Response *response;
2066  ssize_t ret;
2067
2068  update_last_activity (connection);
2069  while (1)
2070    {
2071#if DEBUG_STATES
2072      MHD_DLOG (connection->daemon, "%s: state: %s\n",
2073                __FUNCTION__,
2074                MHD_state_to_string (connection->state));
2075#endif
2076      switch (connection->state)
2077        {
2078        case MHD_CONNECTION_INIT:
2079        case MHD_CONNECTION_URL_RECEIVED:
2080        case MHD_CONNECTION_HEADER_PART_RECEIVED:
2081        case MHD_CONNECTION_HEADERS_RECEIVED:
2082          EXTRA_CHECK (0);
2083          break;
2084        case MHD_CONNECTION_HEADERS_PROCESSED:
2085          break;
2086        case MHD_CONNECTION_CONTINUE_SENDING:
2087          ret = connection->send_cls (connection,
2088                                      &HTTP_100_CONTINUE
2089                                      [connection->continue_message_write_offset],
2090                                      strlen (HTTP_100_CONTINUE) -
2091                                      connection->continue_message_write_offset);
2092          if (ret < 0)
2093            {
2094              const int err = MHD_socket_errno_;
2095              if ((err == EINTR) || (err == EAGAIN) || (EWOULDBLOCK == err))
2096                break;
2097#if HAVE_MESSAGES
2098              MHD_DLOG (connection->daemon,
2099                        "Failed to send data: %s\n",
2100                        MHD_socket_last_strerr_ ());
2101#endif
2102	      CONNECTION_CLOSE_ERROR (connection, NULL);
2103              return MHD_YES;
2104            }
2105#if DEBUG_SEND_DATA
2106          fprintf (stderr,
2107                   "Sent 100 continue response: `%.*s'\n",
2108                   (int) ret,
2109                   &HTTP_100_CONTINUE[connection->continue_message_write_offset]);
2110#endif
2111          connection->continue_message_write_offset += ret;
2112          break;
2113        case MHD_CONNECTION_CONTINUE_SENT:
2114        case MHD_CONNECTION_BODY_RECEIVED:
2115        case MHD_CONNECTION_FOOTER_PART_RECEIVED:
2116        case MHD_CONNECTION_FOOTERS_RECEIVED:
2117          EXTRA_CHECK (0);
2118          break;
2119        case MHD_CONNECTION_HEADERS_SENDING:
2120          do_write (connection);
2121	  if (connection->state != MHD_CONNECTION_HEADERS_SENDING)
2122 	     break;
2123          check_write_done (connection, MHD_CONNECTION_HEADERS_SENT);
2124          break;
2125        case MHD_CONNECTION_HEADERS_SENT:
2126          EXTRA_CHECK (0);
2127          break;
2128        case MHD_CONNECTION_NORMAL_BODY_READY:
2129          response = connection->response;
2130          if (NULL != response->crc)
2131            (void) MHD_mutex_lock_ (&response->mutex);
2132          if (MHD_YES != try_ready_normal_body (connection))
2133	    break;
2134	  ret = connection->send_cls (connection,
2135				      &response->data
2136				      [connection->response_write_position
2137				       - response->data_start],
2138				      response->data_size -
2139				      (connection->response_write_position
2140				       - response->data_start));
2141	  const int err = MHD_socket_errno_;
2142#if DEBUG_SEND_DATA
2143          if (ret > 0)
2144            fprintf (stderr,
2145                     "Sent DATA response: `%.*s'\n",
2146                     (int) ret,
2147                     &response->data[connection->response_write_position -
2148                                     response->data_start]);
2149#endif
2150          if (NULL != response->crc)
2151            (void) MHD_mutex_unlock_ (&response->mutex);
2152          if (ret < 0)
2153            {
2154              if ((err == EINTR) || (err == EAGAIN) || (EWOULDBLOCK == err))
2155                return MHD_YES;
2156#if HAVE_MESSAGES
2157              MHD_DLOG (connection->daemon,
2158                        "Failed to send data: %s\n",
2159                        MHD_socket_last_strerr_ ());
2160#endif
2161	      CONNECTION_CLOSE_ERROR (connection, NULL);
2162              return MHD_YES;
2163            }
2164          connection->response_write_position += ret;
2165          if (connection->response_write_position ==
2166              connection->response->total_size)
2167            connection->state = MHD_CONNECTION_FOOTERS_SENT; /* have no footers */
2168          break;
2169        case MHD_CONNECTION_NORMAL_BODY_UNREADY:
2170          EXTRA_CHECK (0);
2171          break;
2172        case MHD_CONNECTION_CHUNKED_BODY_READY:
2173          do_write (connection);
2174	  if (MHD_CONNECTION_CHUNKED_BODY_READY != connection->state)
2175	     break;
2176          check_write_done (connection,
2177                            (connection->response->total_size ==
2178                             connection->response_write_position) ?
2179                            MHD_CONNECTION_BODY_SENT :
2180                            MHD_CONNECTION_CHUNKED_BODY_UNREADY);
2181          break;
2182        case MHD_CONNECTION_CHUNKED_BODY_UNREADY:
2183        case MHD_CONNECTION_BODY_SENT:
2184          EXTRA_CHECK (0);
2185          break;
2186        case MHD_CONNECTION_FOOTERS_SENDING:
2187          do_write (connection);
2188	  if (connection->state != MHD_CONNECTION_FOOTERS_SENDING)
2189	    break;
2190          check_write_done (connection, MHD_CONNECTION_FOOTERS_SENT);
2191          break;
2192        case MHD_CONNECTION_FOOTERS_SENT:
2193          EXTRA_CHECK (0);
2194          break;
2195        case MHD_CONNECTION_CLOSED:
2196          return MHD_YES;
2197        case MHD_TLS_CONNECTION_INIT:
2198          EXTRA_CHECK (0);
2199          break;
2200        default:
2201          EXTRA_CHECK (0);
2202	  CONNECTION_CLOSE_ERROR (connection,
2203                                  "Internal error\n");
2204          return MHD_YES;
2205        }
2206      break;
2207    }
2208  return MHD_YES;
2209}
2210
2211
2212/**
2213 * Clean up the state of the given connection and move it into the
2214 * clean up queue for final disposal.
2215 *
2216 * @param connection handle for the connection to clean up
2217 */
2218static void
2219cleanup_connection (struct MHD_Connection *connection)
2220{
2221  struct MHD_Daemon *daemon = connection->daemon;
2222
2223  if (NULL != connection->response)
2224    {
2225      MHD_destroy_response (connection->response);
2226      connection->response = NULL;
2227    }
2228  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
2229       (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) )
2230    MHD_PANIC ("Failed to acquire cleanup mutex\n");
2231  if (connection->connection_timeout == daemon->connection_timeout)
2232    XDLL_remove (daemon->normal_timeout_head,
2233		 daemon->normal_timeout_tail,
2234		 connection);
2235  else
2236    XDLL_remove (daemon->manual_timeout_head,
2237		 daemon->manual_timeout_tail,
2238		 connection);
2239  if (MHD_YES == connection->suspended)
2240    DLL_remove (daemon->suspended_connections_head,
2241                daemon->suspended_connections_tail,
2242                connection);
2243  else
2244    DLL_remove (daemon->connections_head,
2245                daemon->connections_tail,
2246                connection);
2247  DLL_insert (daemon->cleanup_head,
2248	      daemon->cleanup_tail,
2249	      connection);
2250  connection->suspended = MHD_NO;
2251  connection->resuming = MHD_NO;
2252  connection->in_idle = MHD_NO;
2253  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
2254       (MHD_YES != MHD_mutex_unlock_(&daemon->cleanup_connection_mutex)) )
2255    MHD_PANIC ("Failed to release cleanup mutex\n");
2256}
2257
2258
2259/**
2260 * This function was created to handle per-connection processing that
2261 * has to happen even if the socket cannot be read or written to.
2262 *
2263 * @param connection connection to handle
2264 * @return #MHD_YES if we should continue to process the
2265 *         connection (not dead yet), #MHD_NO if it died
2266 */
2267int
2268MHD_connection_handle_idle (struct MHD_Connection *connection)
2269{
2270  struct MHD_Daemon *daemon = connection->daemon;
2271  unsigned int timeout;
2272  const char *end;
2273  char *line;
2274  int client_close;
2275
2276  connection->in_idle = MHD_YES;
2277  while (1)
2278    {
2279#if DEBUG_STATES
2280      MHD_DLOG (daemon,
2281                "%s: state: %s\n",
2282                __FUNCTION__,
2283                MHD_state_to_string (connection->state));
2284#endif
2285      switch (connection->state)
2286        {
2287        case MHD_CONNECTION_INIT:
2288          line = get_next_header_line (connection);
2289          if (NULL == line)
2290            {
2291              if (MHD_CONNECTION_INIT != connection->state)
2292                continue;
2293              if (MHD_YES == connection->read_closed)
2294                {
2295		  CONNECTION_CLOSE_ERROR (connection,
2296					  NULL);
2297                  continue;
2298                }
2299              break;
2300            }
2301          if (MHD_NO == parse_initial_message_line (connection, line))
2302            CONNECTION_CLOSE_ERROR (connection, NULL);
2303          else
2304            connection->state = MHD_CONNECTION_URL_RECEIVED;
2305          continue;
2306        case MHD_CONNECTION_URL_RECEIVED:
2307          line = get_next_header_line (connection);
2308          if (NULL == line)
2309            {
2310              if (MHD_CONNECTION_URL_RECEIVED != connection->state)
2311                continue;
2312              if (MHD_YES == connection->read_closed)
2313                {
2314		  CONNECTION_CLOSE_ERROR (connection,
2315					  NULL);
2316                  continue;
2317                }
2318              break;
2319            }
2320          if (strlen (line) == 0)
2321            {
2322              connection->state = MHD_CONNECTION_HEADERS_RECEIVED;
2323              continue;
2324            }
2325          if (MHD_NO == process_header_line (connection, line))
2326            {
2327              transmit_error_response (connection,
2328                                       MHD_HTTP_BAD_REQUEST,
2329                                       REQUEST_MALFORMED);
2330              break;
2331            }
2332          connection->state = MHD_CONNECTION_HEADER_PART_RECEIVED;
2333          continue;
2334        case MHD_CONNECTION_HEADER_PART_RECEIVED:
2335          line = get_next_header_line (connection);
2336          if (NULL == line)
2337            {
2338              if (connection->state != MHD_CONNECTION_HEADER_PART_RECEIVED)
2339                continue;
2340              if (MHD_YES == connection->read_closed)
2341                {
2342		  CONNECTION_CLOSE_ERROR (connection,
2343					  NULL);
2344                  continue;
2345                }
2346              break;
2347            }
2348          if (MHD_NO ==
2349              process_broken_line (connection, line, MHD_HEADER_KIND))
2350            continue;
2351          if (0 == strlen (line))
2352            {
2353              connection->state = MHD_CONNECTION_HEADERS_RECEIVED;
2354              continue;
2355            }
2356          continue;
2357        case MHD_CONNECTION_HEADERS_RECEIVED:
2358          parse_connection_headers (connection);
2359          if (MHD_CONNECTION_CLOSED == connection->state)
2360            continue;
2361          connection->state = MHD_CONNECTION_HEADERS_PROCESSED;
2362          continue;
2363        case MHD_CONNECTION_HEADERS_PROCESSED:
2364          call_connection_handler (connection); /* first call */
2365          if (MHD_CONNECTION_CLOSED == connection->state)
2366            continue;
2367          if (need_100_continue (connection))
2368            {
2369              connection->state = MHD_CONNECTION_CONTINUE_SENDING;
2370              break;
2371            }
2372          if ( (NULL != connection->response) &&
2373	       ( (MHD_str_equal_caseless_ (connection->method,
2374				   MHD_HTTP_METHOD_POST)) ||
2375		 (MHD_str_equal_caseless_ (connection->method,
2376				   MHD_HTTP_METHOD_PUT))) )
2377            {
2378              /* we refused (no upload allowed!) */
2379              connection->remaining_upload_size = 0;
2380              /* force close, in case client still tries to upload... */
2381              connection->read_closed = MHD_YES;
2382            }
2383          connection->state = (0 == connection->remaining_upload_size)
2384            ? MHD_CONNECTION_FOOTERS_RECEIVED : MHD_CONNECTION_CONTINUE_SENT;
2385          continue;
2386        case MHD_CONNECTION_CONTINUE_SENDING:
2387          if (connection->continue_message_write_offset ==
2388              strlen (HTTP_100_CONTINUE))
2389            {
2390              connection->state = MHD_CONNECTION_CONTINUE_SENT;
2391              continue;
2392            }
2393          break;
2394        case MHD_CONNECTION_CONTINUE_SENT:
2395          if (0 != connection->read_buffer_offset)
2396            {
2397              process_request_body (connection);     /* loop call */
2398              if (MHD_CONNECTION_CLOSED == connection->state)
2399                continue;
2400            }
2401          if ((0 == connection->remaining_upload_size) ||
2402              ((connection->remaining_upload_size == MHD_SIZE_UNKNOWN) &&
2403               (0 == connection->read_buffer_offset) &&
2404               (MHD_YES == connection->read_closed)))
2405            {
2406              if ((MHD_YES == connection->have_chunked_upload) &&
2407                  (MHD_NO == connection->read_closed))
2408                connection->state = MHD_CONNECTION_BODY_RECEIVED;
2409              else
2410                connection->state = MHD_CONNECTION_FOOTERS_RECEIVED;
2411              continue;
2412            }
2413          break;
2414        case MHD_CONNECTION_BODY_RECEIVED:
2415          line = get_next_header_line (connection);
2416          if (NULL == line)
2417            {
2418              if (connection->state != MHD_CONNECTION_BODY_RECEIVED)
2419                continue;
2420              if (MHD_YES == connection->read_closed)
2421                {
2422		  CONNECTION_CLOSE_ERROR (connection,
2423					  NULL);
2424                  continue;
2425                }
2426              break;
2427            }
2428          if (0 == strlen (line))
2429            {
2430              connection->state = MHD_CONNECTION_FOOTERS_RECEIVED;
2431              continue;
2432            }
2433          if (MHD_NO == process_header_line (connection, line))
2434            {
2435              transmit_error_response (connection,
2436                                       MHD_HTTP_BAD_REQUEST,
2437                                       REQUEST_MALFORMED);
2438              break;
2439            }
2440          connection->state = MHD_CONNECTION_FOOTER_PART_RECEIVED;
2441          continue;
2442        case MHD_CONNECTION_FOOTER_PART_RECEIVED:
2443          line = get_next_header_line (connection);
2444          if (NULL == line)
2445            {
2446              if (connection->state != MHD_CONNECTION_FOOTER_PART_RECEIVED)
2447                continue;
2448              if (MHD_YES == connection->read_closed)
2449                {
2450		  CONNECTION_CLOSE_ERROR (connection,
2451					  NULL);
2452                  continue;
2453                }
2454              break;
2455            }
2456          if (MHD_NO ==
2457              process_broken_line (connection, line, MHD_FOOTER_KIND))
2458            continue;
2459          if (0 == strlen (line))
2460            {
2461              connection->state = MHD_CONNECTION_FOOTERS_RECEIVED;
2462              continue;
2463            }
2464          continue;
2465        case MHD_CONNECTION_FOOTERS_RECEIVED:
2466          call_connection_handler (connection); /* "final" call */
2467          if (connection->state == MHD_CONNECTION_CLOSED)
2468            continue;
2469          if (NULL == connection->response)
2470            break;              /* try again next time */
2471          if (MHD_NO == build_header_response (connection))
2472            {
2473              /* oops - close! */
2474	      CONNECTION_CLOSE_ERROR (connection,
2475				      "Closing connection (failed to create response header)\n");
2476              continue;
2477            }
2478          connection->state = MHD_CONNECTION_HEADERS_SENDING;
2479
2480#if HAVE_DECL_TCP_CORK
2481          /* starting header send, set TCP cork */
2482          {
2483            const int val = 1;
2484            setsockopt (connection->socket_fd, IPPROTO_TCP, TCP_CORK, &val,
2485                        sizeof (val));
2486          }
2487#endif
2488          break;
2489        case MHD_CONNECTION_HEADERS_SENDING:
2490          /* no default action */
2491          break;
2492        case MHD_CONNECTION_HEADERS_SENT:
2493          if (connection->have_chunked_upload)
2494            connection->state = MHD_CONNECTION_CHUNKED_BODY_UNREADY;
2495          else
2496            connection->state = MHD_CONNECTION_NORMAL_BODY_UNREADY;
2497          continue;
2498        case MHD_CONNECTION_NORMAL_BODY_READY:
2499          /* nothing to do here */
2500          break;
2501        case MHD_CONNECTION_NORMAL_BODY_UNREADY:
2502          if (NULL != connection->response->crc)
2503            (void) MHD_mutex_lock_ (&connection->response->mutex);
2504          if (0 == connection->response->total_size)
2505            {
2506              if (NULL != connection->response->crc)
2507                (void) MHD_mutex_unlock_ (&connection->response->mutex);
2508              connection->state = MHD_CONNECTION_BODY_SENT;
2509              continue;
2510            }
2511          if (MHD_YES == try_ready_normal_body (connection))
2512            {
2513	      if (NULL != connection->response->crc)
2514	        (void) MHD_mutex_unlock_ (&connection->response->mutex);
2515              connection->state = MHD_CONNECTION_NORMAL_BODY_READY;
2516              break;
2517            }
2518          /* not ready, no socket action */
2519          break;
2520        case MHD_CONNECTION_CHUNKED_BODY_READY:
2521          /* nothing to do here */
2522          break;
2523        case MHD_CONNECTION_CHUNKED_BODY_UNREADY:
2524          if (NULL != connection->response->crc)
2525            (void) MHD_mutex_lock_ (&connection->response->mutex);
2526          if (0 == connection->response->total_size)
2527            {
2528              if (NULL != connection->response->crc)
2529                (void) MHD_mutex_unlock_ (&connection->response->mutex);
2530              connection->state = MHD_CONNECTION_BODY_SENT;
2531              continue;
2532            }
2533          if (MHD_YES == try_ready_chunked_body (connection))
2534            {
2535              if (NULL != connection->response->crc)
2536                (void) MHD_mutex_unlock_ (&connection->response->mutex);
2537              connection->state = MHD_CONNECTION_CHUNKED_BODY_READY;
2538              continue;
2539            }
2540          if (NULL != connection->response->crc)
2541            (void) MHD_mutex_unlock_ (&connection->response->mutex);
2542          break;
2543        case MHD_CONNECTION_BODY_SENT:
2544          if (MHD_NO == build_header_response (connection))
2545            {
2546              /* oops - close! */
2547	      CONNECTION_CLOSE_ERROR (connection,
2548				      "Closing connection (failed to create response header)\n");
2549              continue;
2550            }
2551          if ( (MHD_NO == connection->have_chunked_upload) ||
2552               (connection->write_buffer_send_offset ==
2553                connection->write_buffer_append_offset) )
2554            connection->state = MHD_CONNECTION_FOOTERS_SENT;
2555          else
2556            connection->state = MHD_CONNECTION_FOOTERS_SENDING;
2557          continue;
2558        case MHD_CONNECTION_FOOTERS_SENDING:
2559          /* no default action */
2560          break;
2561        case MHD_CONNECTION_FOOTERS_SENT:
2562#if HAVE_DECL_TCP_CORK
2563          /* done sending, uncork */
2564          {
2565            const int val = 0;
2566            setsockopt (connection->socket_fd, IPPROTO_TCP, TCP_CORK, &val,
2567                        sizeof (val));
2568          }
2569#endif
2570          end =
2571            MHD_get_response_header (connection->response,
2572				     MHD_HTTP_HEADER_CONNECTION);
2573          client_close = ((NULL != end) && (MHD_str_equal_caseless_(end, "close")));
2574          MHD_destroy_response (connection->response);
2575          connection->response = NULL;
2576          if ( (NULL != daemon->notify_completed) &&
2577               (MHD_YES == connection->client_aware) )
2578          {
2579	    daemon->notify_completed (daemon->notify_completed_cls,
2580				      connection,
2581				      &connection->client_context,
2582						  MHD_REQUEST_TERMINATED_COMPLETED_OK);
2583            connection->client_aware = MHD_NO;
2584          }
2585          end =
2586            MHD_lookup_connection_value (connection, MHD_HEADER_KIND,
2587                                         MHD_HTTP_HEADER_CONNECTION);
2588          if ( (MHD_YES == connection->read_closed) ||
2589               (client_close) ||
2590               ((NULL != end) && (MHD_str_equal_caseless_ (end, "close"))) )
2591            {
2592              connection->read_closed = MHD_YES;
2593              connection->read_buffer_offset = 0;
2594            }
2595          if (((MHD_YES == connection->read_closed) &&
2596               (0 == connection->read_buffer_offset)) ||
2597              (MHD_NO == keepalive_possible (connection)))
2598            {
2599              /* have to close for some reason */
2600              MHD_connection_close (connection,
2601                                    MHD_REQUEST_TERMINATED_COMPLETED_OK);
2602              MHD_pool_destroy (connection->pool);
2603              connection->pool = NULL;
2604              connection->read_buffer = NULL;
2605              connection->read_buffer_size = 0;
2606              connection->read_buffer_offset = 0;
2607            }
2608          else
2609            {
2610              /* can try to keep-alive */
2611              connection->version = NULL;
2612              connection->state = MHD_CONNECTION_INIT;
2613              connection->read_buffer
2614                = MHD_pool_reset (connection->pool,
2615                                  connection->read_buffer,
2616                                  connection->read_buffer_size);
2617            }
2618	  connection->client_aware = MHD_NO;
2619          connection->client_context = NULL;
2620          connection->continue_message_write_offset = 0;
2621          connection->responseCode = 0;
2622          connection->headers_received = NULL;
2623	  connection->headers_received_tail = NULL;
2624          connection->response_write_position = 0;
2625          connection->have_chunked_upload = MHD_NO;
2626          connection->method = NULL;
2627          connection->url = NULL;
2628          connection->write_buffer = NULL;
2629          connection->write_buffer_size = 0;
2630          connection->write_buffer_send_offset = 0;
2631          connection->write_buffer_append_offset = 0;
2632          continue;
2633        case MHD_CONNECTION_CLOSED:
2634	  cleanup_connection (connection);
2635	  return MHD_NO;
2636        default:
2637          EXTRA_CHECK (0);
2638          break;
2639        }
2640      break;
2641    }
2642  timeout = connection->connection_timeout;
2643  if ( (0 != timeout) &&
2644       (timeout <= (MHD_monotonic_time() - connection->last_activity)) )
2645    {
2646      MHD_connection_close (connection, MHD_REQUEST_TERMINATED_TIMEOUT_REACHED);
2647      connection->in_idle = MHD_NO;
2648      return MHD_YES;
2649    }
2650  MHD_connection_update_event_loop_info (connection);
2651#if EPOLL_SUPPORT
2652  switch (connection->event_loop_info)
2653    {
2654    case MHD_EVENT_LOOP_INFO_READ:
2655      if ( (0 != (connection->epoll_state & MHD_EPOLL_STATE_READ_READY)) &&
2656           (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED)) &&
2657	   (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) )
2658	{
2659	  EDLL_insert (daemon->eready_head,
2660		       daemon->eready_tail,
2661		       connection);
2662	  connection->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
2663	}
2664      break;
2665    case MHD_EVENT_LOOP_INFO_WRITE:
2666      if ( (0 != (connection->epoll_state & MHD_EPOLL_STATE_WRITE_READY)) &&
2667           (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED)) &&
2668	   (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) )
2669	{
2670	  EDLL_insert (daemon->eready_head,
2671		       daemon->eready_tail,
2672		       connection);
2673	  connection->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
2674	}
2675      break;
2676    case MHD_EVENT_LOOP_INFO_BLOCK:
2677      /* we should look at this connection again in the next iteration
2678	 of the event loop, as we're waiting on the application */
2679      if ( (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) &&
2680           (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED))) )
2681	{
2682	  EDLL_insert (daemon->eready_head,
2683		       daemon->eready_tail,
2684		       connection);
2685	  connection->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
2686	}
2687      break;
2688    case MHD_EVENT_LOOP_INFO_CLEANUP:
2689      /* This connection is finished, nothing left to do */
2690      break;
2691    }
2692  return MHD_connection_epoll_update_ (connection);
2693#else
2694  return MHD_YES;
2695#endif
2696}
2697
2698
2699#if EPOLL_SUPPORT
2700/**
2701 * Perform epoll() processing, possibly moving the connection back into
2702 * the epoll() set if needed.
2703 *
2704 * @param connection connection to process
2705 * @return #MHD_YES if we should continue to process the
2706 *         connection (not dead yet), #MHD_NO if it died
2707 */
2708int
2709MHD_connection_epoll_update_ (struct MHD_Connection *connection)
2710{
2711  struct MHD_Daemon *daemon = connection->daemon;
2712
2713  if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
2714       (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) &&
2715       (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED)) &&
2716       ( (0 == (connection->epoll_state & MHD_EPOLL_STATE_WRITE_READY)) ||
2717	 ( (0 == (connection->epoll_state & MHD_EPOLL_STATE_READ_READY)) &&
2718	   ( (MHD_EVENT_LOOP_INFO_READ == connection->event_loop_info) ||
2719	     (connection->read_buffer_size > connection->read_buffer_offset) ) &&
2720	   (MHD_NO == connection->read_closed) ) ) )
2721    {
2722      /* add to epoll set */
2723      struct epoll_event event;
2724
2725      event.events = EPOLLIN | EPOLLOUT | EPOLLET;
2726      event.data.ptr = connection;
2727      if (0 != epoll_ctl (daemon->epoll_fd,
2728			  EPOLL_CTL_ADD,
2729			  connection->socket_fd,
2730			  &event))
2731	{
2732#if HAVE_MESSAGES
2733	  if (0 != (daemon->options & MHD_USE_DEBUG))
2734	    MHD_DLOG (daemon,
2735		      "Call to epoll_ctl failed: %s\n",
2736		      MHD_socket_last_strerr_ ());
2737#endif
2738	  connection->state = MHD_CONNECTION_CLOSED;
2739	  cleanup_connection (connection);
2740	  return MHD_NO;
2741	}
2742      connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET;
2743    }
2744  connection->in_idle = MHD_NO;
2745  return MHD_YES;
2746}
2747#endif
2748
2749
2750/**
2751 * Set callbacks for this connection to those for HTTP.
2752 *
2753 * @param connection connection to initialize
2754 */
2755void
2756MHD_set_http_callbacks_ (struct MHD_Connection *connection)
2757{
2758  connection->read_handler = &MHD_connection_handle_read;
2759  connection->write_handler = &MHD_connection_handle_write;
2760  connection->idle_handler = &MHD_connection_handle_idle;
2761}
2762
2763
2764/**
2765 * Obtain information about the given connection.
2766 *
2767 * @param connection what connection to get information about
2768 * @param info_type what information is desired?
2769 * @param ... depends on @a info_type
2770 * @return NULL if this information is not available
2771 *         (or if the @a info_type is unknown)
2772 * @ingroup specialized
2773 */
2774const union MHD_ConnectionInfo *
2775MHD_get_connection_info (struct MHD_Connection *connection,
2776                         enum MHD_ConnectionInfoType info_type, ...)
2777{
2778  switch (info_type)
2779    {
2780#if HTTPS_SUPPORT
2781    case MHD_CONNECTION_INFO_CIPHER_ALGO:
2782      if (connection->tls_session == NULL)
2783	return NULL;
2784      connection->cipher = SSL_CIPHER_get_name (SSL_get_current_cipher (connection->tls_session));
2785      return (const union MHD_ConnectionInfo *) &connection->cipher;
2786    case MHD_CONNECTION_INFO_PROTOCOL:
2787      if (connection->tls_session == NULL)
2788	return NULL;
2789      connection->protocol = SSL_CIPHER_get_version (SSL_get_current_cipher (connection->tls_session));
2790      return (const union MHD_ConnectionInfo *) &connection->protocol;
2791    case MHD_CONNECTION_INFO_TLS_SESSION:
2792      if (connection->tls_session == NULL)
2793	return NULL;
2794      return (const union MHD_ConnectionInfo *) &connection->tls_session;
2795#endif
2796    case MHD_CONNECTION_INFO_CLIENT_ADDRESS:
2797      return (const union MHD_ConnectionInfo *) &connection->addr;
2798    case MHD_CONNECTION_INFO_DAEMON:
2799      return (const union MHD_ConnectionInfo *) &connection->daemon;
2800    case MHD_CONNECTION_INFO_CONNECTION_FD:
2801      return (const union MHD_ConnectionInfo *) &connection->socket_fd;
2802    case MHD_CONNECTION_INFO_SOCKET_CONTEXT:
2803      return (const union MHD_ConnectionInfo *) &connection->socket_context;
2804    default:
2805      return NULL;
2806    };
2807}
2808
2809
2810/**
2811 * Set a custom option for the given connection, overriding defaults.
2812 *
2813 * @param connection connection to modify
2814 * @param option option to set
2815 * @param ... arguments to the option, depending on the option type
2816 * @return #MHD_YES on success, #MHD_NO if setting the option failed
2817 * @ingroup specialized
2818 */
2819int
2820MHD_set_connection_option (struct MHD_Connection *connection,
2821			   enum MHD_CONNECTION_OPTION option,
2822			   ...)
2823{
2824  va_list ap;
2825  struct MHD_Daemon *daemon;
2826
2827  daemon = connection->daemon;
2828  switch (option)
2829    {
2830    case MHD_CONNECTION_OPTION_TIMEOUT:
2831      if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
2832	   (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) )
2833	MHD_PANIC ("Failed to acquire cleanup mutex\n");
2834      if (MHD_YES != connection->suspended)
2835        {
2836          if (connection->connection_timeout == daemon->connection_timeout)
2837            XDLL_remove (daemon->normal_timeout_head,
2838                         daemon->normal_timeout_tail,
2839                         connection);
2840          else
2841            XDLL_remove (daemon->manual_timeout_head,
2842                         daemon->manual_timeout_tail,
2843                         connection);
2844        }
2845      va_start (ap, option);
2846      connection->connection_timeout = va_arg (ap, unsigned int);
2847      va_end (ap);
2848      if (MHD_YES != connection->suspended)
2849        {
2850          if (connection->connection_timeout == daemon->connection_timeout)
2851            XDLL_insert (daemon->normal_timeout_head,
2852                         daemon->normal_timeout_tail,
2853                         connection);
2854          else
2855            XDLL_insert (daemon->manual_timeout_head,
2856                         daemon->manual_timeout_tail,
2857                         connection);
2858        }
2859      if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
2860	   (MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) )
2861	MHD_PANIC ("Failed to release cleanup mutex\n");
2862      return MHD_YES;
2863    default:
2864      return MHD_NO;
2865    }
2866}
2867
2868
2869/**
2870 * Queue a response to be transmitted to the client (as soon as
2871 * possible but after #MHD_AccessHandlerCallback returns).
2872 *
2873 * @param connection the connection identifying the client
2874 * @param status_code HTTP status code (i.e. #MHD_HTTP_OK)
2875 * @param response response to transmit
2876 * @return #MHD_NO on error (i.e. reply already sent),
2877 *         #MHD_YES on success or if message has been queued
2878 * @ingroup response
2879 */
2880int
2881MHD_queue_response (struct MHD_Connection *connection,
2882                    unsigned int status_code,
2883                    struct MHD_Response *response)
2884{
2885  if ( (NULL == connection) ||
2886       (NULL == response) ||
2887       (NULL != connection->response) ||
2888       ( (MHD_CONNECTION_HEADERS_PROCESSED != connection->state) &&
2889	 (MHD_CONNECTION_FOOTERS_RECEIVED != connection->state) ) )
2890    return MHD_NO;
2891  MHD_increment_response_rc (response);
2892  connection->response = response;
2893  connection->responseCode = status_code;
2894  if ( (NULL != connection->method) &&
2895       (MHD_str_equal_caseless_ (connection->method, MHD_HTTP_METHOD_HEAD)) )
2896    {
2897      /* if this is a "HEAD" request, pretend that we
2898         have already sent the full message body */
2899      connection->response_write_position = response->total_size;
2900    }
2901  if ( (MHD_CONNECTION_HEADERS_PROCESSED == connection->state) &&
2902       (NULL != connection->method) &&
2903       ( (MHD_str_equal_caseless_ (connection->method,
2904			   MHD_HTTP_METHOD_POST)) ||
2905	 (MHD_str_equal_caseless_ (connection->method,
2906			   MHD_HTTP_METHOD_PUT))) )
2907    {
2908      /* response was queued "early", refuse to read body / footers or
2909         further requests! */
2910      connection->read_closed = MHD_YES;
2911      connection->state = MHD_CONNECTION_FOOTERS_RECEIVED;
2912    }
2913  if (MHD_NO == connection->in_idle)
2914    (void) MHD_connection_handle_idle (connection);
2915  return MHD_YES;
2916}
2917
2918
2919/* end of connection.c */
2920