• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
127 int
MHD_get_connection_values(struct MHD_Connection * connection,enum MHD_ValueKind kind,MHD_KeyValueIterator iterator,void * iterator_cls)128 MHD_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  */
176 int
MHD_set_connection_value(struct MHD_Connection * connection,enum MHD_ValueKind kind,const char * key,const char * value)177 MHD_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  */
216 const char *
MHD_lookup_connection_value(struct MHD_Connection * connection,enum MHD_ValueKind kind,const char * key)217 MHD_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  */
242 static int
need_100_continue(struct MHD_Connection * connection)243 need_100_continue (struct MHD_Connection *connection)
244 {
245   const char *expect;
246 
247   return ( (NULL == connection->response) &&
248 	   (NULL != connection->version) &&
249        (MHD_str_equal_caseless_(connection->version,
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  */
267 void
MHD_connection_close(struct MHD_Connection * connection,enum MHD_RequestTerminationCode termination_code)268 MHD_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  */
296 static void
connection_close_error(struct MHD_Connection * connection,const char * emsg)297 connection_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  */
331 static int
try_ready_normal_body(struct MHD_Connection * connection)332 try_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  */
398 static int
try_ready_chunked_body(struct MHD_Connection * connection)399 try_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  */
509 static int
keepalive_possible(struct MHD_Connection * connection)510 keepalive_possible (struct MHD_Connection *connection)
511 {
512   const char *end;
513 
514   if (NULL == connection->version)
515     return MHD_NO;
516   if ( (NULL != connection->response) &&
517        (0 != (connection->response->flags & MHD_RF_HTTP_VERSION_1_0_ONLY) ) )
518     return MHD_NO;
519   end = MHD_lookup_connection_value (connection,
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  */
551 static void
get_date_string(char * date)552 get_date_string (char *date)
553 {
554   static const char *const days[] =
555     { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
556   static const char *const mons[] =
557     { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct",
558     "Nov", "Dec"
559   };
560   struct tm now;
561   time_t t;
562 #if defined(_WIN32) && !defined(HAVE_GMTIME_S) && !defined(__CYGWIN__)
563   struct tm* pNow;
564 #endif
565 
566   date[0] = 0;
567   time (&t);
568 #if !defined(_WIN32)
569   if (NULL != gmtime_r (&t, &now))
570     {
571 #elif defined(HAVE_GMTIME_S)
572   if (0 == gmtime_s (&now, &t))
573     {
574 #elif defined(__CYGWIN__)
575   if (NULL != gmtime_r (&t, &now))
576     {
577 #else
578   pNow = gmtime(&t);
579   if (NULL != pNow)
580     {
581       now = *pNow;
582 #endif
583       sprintf (date,
584              "Date: %3s, %02u %3s %04u %02u:%02u:%02u GMT\r\n",
585              days[now.tm_wday % 7],
586              (unsigned int) now.tm_mday,
587              mons[now.tm_mon % 12],
588              (unsigned int) (1900 + now.tm_year),
589              (unsigned int) now.tm_hour,
590              (unsigned int) now.tm_min,
591              (unsigned int) now.tm_sec);
592     }
593 }
594 
595 
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  */
607 static int
608 try_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  */
639 static int
640 build_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  */
928 static void
929 transmit_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  */
976 static void
977 MHD_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 (0 == gnutls_record_get_direction (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  */
1124 static char *
1125 get_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  */
1175 static int
1176 connection_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  */
1204 static int
1205 parse_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  */
1291 static int
1292 parse_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  */
1390 static int
1391 parse_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  */
1442 static void
1443 call_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  */
1476 static void
1477 process_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  */
1657 static int
1658 do_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  */
1704 static int
1705 do_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  */
1746 static int
1747 check_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  */
1774 static int
1775 process_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  */
1814 static int
1815 process_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  */
1887 static void
1888 parse_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  */
1966 static void
1967 update_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  */
1999 int
2000 MHD_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  */
2062 int
2063 MHD_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  */
2218 static void
2219 cleanup_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  */
2267 int
2268 MHD_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  */
2708 int
2709 MHD_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  */
2755 void
2756 MHD_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  */
2774 const union MHD_ConnectionInfo *
2775 MHD_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 = gnutls_cipher_get (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 = gnutls_protocol_get_version (connection->tls_session);
2790       return (const union MHD_ConnectionInfo *) &connection->protocol;
2791     case MHD_CONNECTION_INFO_GNUTLS_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  */
2819 int
2820 MHD_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  */
2880 int
2881 MHD_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