00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
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