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>"Host:" header required</title></head><body>In HTTP 1.1, requests must include a "Host:" 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