|
GNU libmicrohttpd
0.9.5
|
00001 /* 00002 This file is part of libmicrohttpd 00003 (C) 2007, 2008, 2009, 2010, 2011, 2012 Daniel Pittman and Christian Grothoff 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Lesser General Public 00007 License as published by the Free Software Foundation; either 00008 version 2.1 of the License, or (at your option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Lesser General Public License for more details. 00014 00015 You should have received a copy of the GNU Lesser General Public 00016 License along with this library; if not, write to the Free Software 00017 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00018 */ 00019 00027 #ifndef INTERNAL_H 00028 #define INTERNAL_H 00029 00030 #include "platform.h" 00031 #include "microhttpd.h" 00032 #if HTTPS_SUPPORT 00033 #include <gnutls/gnutls.h> 00034 #endif 00035 00040 #define EXTRA_CHECKS MHD_NO 00041 00042 #define MHD_MAX(a,b) ((a)<(b)) ? (b) : (a) 00043 #define MHD_MIN(a,b) ((a)<(b)) ? (a) : (b) 00044 00045 00051 #define MHD_BUF_INC_SIZE 2048 00052 00056 extern MHD_PanicCallback mhd_panic; 00057 00061 extern void *mhd_panic_cls; 00062 00063 #if HAVE_MESSAGES 00064 00069 #define MHD_PANIC(msg) mhd_panic (mhd_panic_cls, __FILE__, __LINE__, msg) 00070 #else 00071 00076 #define MHD_PANIC(msg) mhd_panic (mhd_panic_cls, __FILE__, __LINE__, NULL) 00077 #endif 00078 00083 enum MHD_PollActions 00084 { 00088 MHD_POLL_ACTION_NOTHING = 0, 00089 00093 MHD_POLL_ACTION_IN = 1, 00094 00098 MHD_POLL_ACTION_OUT = 2 00099 }; 00100 00101 00105 struct MHD_Pollfd 00106 { 00110 int fd; 00111 00115 enum MHD_PollActions events; 00116 }; 00117 00118 00125 #define MAX_NONCE_LENGTH 129 00126 00127 00132 struct MHD_NonceNc 00133 { 00134 00139 unsigned long int nc; 00140 00144 char nonce[MAX_NONCE_LENGTH]; 00145 00146 }; 00147 00148 #if HAVE_MESSAGES 00149 00153 void MHD_DLOG (const struct MHD_Daemon *daemon, const char *format, ...); 00154 00155 #endif 00156 00167 size_t MHD_http_unescape (void *cls, 00168 struct MHD_Connection *connection, 00169 char *val); 00170 00174 struct MHD_HTTP_Header 00175 { 00179 struct MHD_HTTP_Header *next; 00180 00185 char *header; 00186 00190 char *value; 00191 00196 enum MHD_ValueKind kind; 00197 00198 }; 00199 00200 00204 struct MHD_Response 00205 { 00206 00212 struct MHD_HTTP_Header *first_header; 00213 00218 char *data; 00219 00224 void *crc_cls; 00225 00230 MHD_ContentReaderCallback crc; 00231 00236 MHD_ContentReaderFreeCallback crfc; 00237 00242 pthread_mutex_t mutex; 00243 00247 uint64_t total_size; 00248 00253 uint64_t data_start; 00254 00258 off_t fd_off; 00259 00263 size_t data_size; 00264 00268 size_t data_buffer_size; 00269 00274 unsigned int reference_count; 00275 00279 int fd; 00280 00281 }; 00282 00283 00298 enum MHD_CONNECTION_STATE 00299 { 00304 MHD_CONNECTION_INIT = 0, 00305 00309 MHD_CONNECTION_URL_RECEIVED = MHD_CONNECTION_INIT + 1, 00310 00314 MHD_CONNECTION_HEADER_PART_RECEIVED = MHD_CONNECTION_URL_RECEIVED + 1, 00315 00319 MHD_CONNECTION_HEADERS_RECEIVED = MHD_CONNECTION_HEADER_PART_RECEIVED + 1, 00320 00324 MHD_CONNECTION_HEADERS_PROCESSED = MHD_CONNECTION_HEADERS_RECEIVED + 1, 00325 00329 MHD_CONNECTION_CONTINUE_SENDING = MHD_CONNECTION_HEADERS_PROCESSED + 1, 00330 00334 MHD_CONNECTION_CONTINUE_SENT = MHD_CONNECTION_CONTINUE_SENDING + 1, 00335 00339 MHD_CONNECTION_BODY_RECEIVED = MHD_CONNECTION_CONTINUE_SENT + 1, 00340 00345 MHD_CONNECTION_FOOTER_PART_RECEIVED = MHD_CONNECTION_BODY_RECEIVED + 1, 00346 00351 MHD_CONNECTION_FOOTERS_RECEIVED = MHD_CONNECTION_FOOTER_PART_RECEIVED + 1, 00352 00357 MHD_CONNECTION_HEADERS_SENDING = MHD_CONNECTION_FOOTERS_RECEIVED + 1, 00358 00362 MHD_CONNECTION_HEADERS_SENT = MHD_CONNECTION_HEADERS_SENDING + 1, 00363 00367 MHD_CONNECTION_NORMAL_BODY_READY = MHD_CONNECTION_HEADERS_SENT + 1, 00368 00373 MHD_CONNECTION_NORMAL_BODY_UNREADY = MHD_CONNECTION_NORMAL_BODY_READY + 1, 00374 00378 MHD_CONNECTION_CHUNKED_BODY_READY = MHD_CONNECTION_NORMAL_BODY_UNREADY + 1, 00379 00383 MHD_CONNECTION_CHUNKED_BODY_UNREADY = MHD_CONNECTION_CHUNKED_BODY_READY + 1, 00384 00388 MHD_CONNECTION_BODY_SENT = MHD_CONNECTION_CHUNKED_BODY_UNREADY + 1, 00389 00393 MHD_CONNECTION_FOOTERS_SENDING = MHD_CONNECTION_BODY_SENT + 1, 00394 00398 MHD_CONNECTION_FOOTERS_SENT = MHD_CONNECTION_FOOTERS_SENDING + 1, 00399 00403 MHD_CONNECTION_CLOSED = MHD_CONNECTION_FOOTERS_SENT + 1, 00404 00408 MHD_CONNECTION_IN_CLEANUP = MHD_CONNECTION_CLOSED + 1, 00409 00410 /* 00411 * SSL/TLS connection states 00412 */ 00413 00419 MHD_TLS_CONNECTION_INIT = MHD_CONNECTION_CLOSED + 1 00420 00421 }; 00422 00426 #define DEBUG_STATES MHD_NO 00427 00428 00429 #if HAVE_MESSAGES 00430 #if DEBUG_STATES 00431 const char * 00432 MHD_state_to_string (enum MHD_CONNECTION_STATE state); 00433 #endif 00434 #endif 00435 00444 typedef ssize_t (*ReceiveCallback) (struct MHD_Connection * conn, 00445 void *write_to, size_t max_bytes); 00446 00447 00456 typedef ssize_t (*TransmitCallback) (struct MHD_Connection * conn, 00457 const void *write_to, size_t max_bytes); 00458 00459 00463 struct MHD_Connection 00464 { 00465 00469 struct MHD_Connection *next; 00470 00474 struct MHD_Connection *prev; 00475 00479 struct MHD_Daemon *daemon; 00480 00484 struct MHD_HTTP_Header *headers_received; 00485 00489 struct MHD_HTTP_Header *headers_received_tail; 00490 00494 struct MHD_Response *response; 00495 00506 struct MemoryPool *pool; 00507 00514 void *client_context; 00515 00520 char *method; 00521 00526 char *url; 00527 00532 char *version; 00533 00540 char *read_buffer; 00541 00546 char *write_buffer; 00547 00553 char *last; 00554 00561 char *colon; 00562 00567 struct sockaddr *addr; 00568 00573 pthread_t pid; 00574 00581 size_t read_buffer_size; 00582 00587 size_t read_buffer_offset; 00588 00592 size_t write_buffer_size; 00593 00597 size_t write_buffer_send_offset; 00598 00603 size_t write_buffer_append_offset; 00604 00609 uint64_t remaining_upload_size; 00610 00616 uint64_t response_write_position; 00617 00622 size_t continue_message_write_offset; 00623 00627 socklen_t addr_len; 00628 00633 time_t last_activity; 00634 00639 unsigned int connection_timeout; 00640 00646 int client_aware; 00647 00653 int socket_fd; 00654 00662 int read_closed; 00663 00667 int thread_joined; 00668 00672 enum MHD_CONNECTION_STATE state; 00673 00678 unsigned int responseCode; 00679 00687 int response_unready; 00688 00696 int have_chunked_upload; 00697 00704 unsigned int current_chunk_size; 00705 00710 unsigned int current_chunk_offset; 00711 00715 int (*read_handler) (struct MHD_Connection * connection); 00716 00720 int (*write_handler) (struct MHD_Connection * connection); 00721 00725 int (*idle_handler) (struct MHD_Connection * connection); 00726 00730 ReceiveCallback recv_cls; 00731 00735 TransmitCallback send_cls; 00736 00737 #if HTTPS_SUPPORT 00738 00741 gnutls_session_t tls_session; 00742 00746 int protocol; 00747 00751 int cipher; 00752 00753 #endif 00754 }; 00755 00763 typedef void * (*LogCallback)(void * cls, const char * uri); 00764 00774 typedef size_t (*UnescapeCallback)(void *cls, 00775 struct MHD_Connection *conn, 00776 char *uri); 00777 00778 00782 struct MHD_Daemon 00783 { 00784 00788 MHD_AccessHandlerCallback default_handler; 00789 00793 void *default_handler_cls; 00794 00798 struct MHD_Connection *connections_head; 00799 00803 struct MHD_Connection *connections_tail; 00804 00808 struct MHD_Connection *cleanup_head; 00809 00813 struct MHD_Connection *cleanup_tail; 00814 00820 MHD_AcceptPolicyCallback apc; 00821 00825 void *apc_cls; 00826 00831 MHD_RequestCompletedCallback notify_completed; 00832 00836 void *notify_completed_cls; 00837 00845 LogCallback uri_log_callback; 00846 00850 void *uri_log_callback_cls; 00851 00855 UnescapeCallback unescape_callback; 00856 00860 void *unescape_callback_cls; 00861 00862 #if HAVE_MESSAGES 00863 00867 void (*custom_error_log) (void *cls, const char *fmt, va_list va); 00868 00872 void *custom_error_log_cls; 00873 #endif 00874 00878 struct MHD_Daemon *master; 00879 00883 struct MHD_Daemon *worker_pool; 00884 00888 void *per_ip_connection_count; 00889 00893 size_t pool_size; 00894 00898 size_t thread_stack_size; 00899 00903 unsigned int worker_pool_size; 00904 00908 pthread_t pid; 00909 00913 pthread_mutex_t per_ip_connection_mutex; 00914 00918 pthread_mutex_t cleanup_connection_mutex; 00919 00923 int socket_fd; 00924 00930 int wpipe[2]; 00931 00935 int shutdown; 00936 00940 unsigned int max_connections; 00941 00946 unsigned int connection_timeout; 00947 00952 unsigned int per_ip_connection_limit; 00953 00957 enum MHD_OPTION options; 00958 00962 uint16_t port; 00963 00964 #if HTTPS_SUPPORT 00965 00968 gnutls_priority_t priority_cache; 00969 00974 gnutls_credentials_type_t cred_type; 00975 00979 gnutls_certificate_credentials_t x509_cred; 00980 00984 gnutls_dh_params_t dh_params; 00985 00989 const char *https_mem_key; 00990 00994 const char *https_mem_cert; 00995 00999 const char *https_mem_trust; 01000 01001 #endif 01002 01003 #ifdef DAUTH_SUPPORT 01004 01008 const char *digest_auth_random; 01009 01013 struct MHD_NonceNc *nnc; 01014 01018 pthread_mutex_t nnc_lock; 01019 01023 unsigned int digest_auth_rand_size; 01024 01028 unsigned int nonce_nc_size; 01029 01030 #endif 01031 01032 }; 01033 01034 01035 #if EXTRA_CHECKS 01036 #define EXTRA_CHECK(a) if (!(a)) abort(); 01037 #else 01038 #define EXTRA_CHECK(a) 01039 #endif 01040 01041 01050 #define DLL_insert(head,tail,element) do { \ 01051 (element)->next = (head); \ 01052 (element)->prev = NULL; \ 01053 if ((tail) == NULL) \ 01054 (tail) = element; \ 01055 else \ 01056 (head)->prev = element; \ 01057 (head) = (element); } while (0) 01058 01059 01069 #define DLL_remove(head,tail,element) do { \ 01070 if ((element)->prev == NULL) \ 01071 (head) = (element)->next; \ 01072 else \ 01073 (element)->prev->next = (element)->next; \ 01074 if ((element)->next == NULL) \ 01075 (tail) = (element)->prev; \ 01076 else \ 01077 (element)->next->prev = (element)->prev; \ 01078 (element)->next = NULL; \ 01079 (element)->prev = NULL; } while (0) 01080 01081 01087 time_t MHD_monotonic_time(void); 01088 01089 #endif