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