27 #define MHD_NO_DEPRECATION 1
30 #ifdef HAVE_SYS_IOCTL_H
31 #include <sys/ioctl.h>
33 #if defined(_WIN32) && ! defined(__CYGWIN__)
49 #if defined(MHD_W32_MUTEX_)
50 #ifndef WIN32_LEAN_AND_MEAN
51 #define WIN32_LEAN_AND_MEAN 1
64 #ifndef MHD_FILE_READ_BLOCK_SIZE
66 #define MHD_FILE_READ_BLOCK_SIZE 16384
68 #define MHD_FILE_READ_BLOCK_SIZE 4096
90 if ( (
NULL == response) ||
98 (
NULL != strchr (content,
'\t')) ||
99 (
NULL != strchr (content,
'\r')) ||
100 (
NULL != strchr (content,
'\n')) )
110 if (
NULL == (hdr->
value = strdup (content)))
152 & response->
flags)) &&
211 header_len = strlen (
header);
212 content_len = strlen (content);
222 (0 == memcmp (content,
265 if ((
NULL != iterator) &&
266 (
MHD_NO == iterator (iterator_cls,
294 key_size = strlen (key);
332 if ( (
NULL == key) ||
384 if ((
NULL ==
crc) || (0 == block_size))
390 response->
data = (
void *) &response[1];
392 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
427 va_start (ap,
flags);
459 #if ! defined(_WIN32) || defined(__CYGWIN__)
462 const HANDLE fh = (HANDLE) _get_osfhandle (response->
fd);
464 const int64_t offset64 = (int64_t) (pos + response->
fd_off);
469 #if ! defined(_WIN32) || defined(__CYGWIN__)
473 #if defined(HAVE_PREAD64)
474 n = pread64 (response->
fd, buf, max, offset64);
475 #elif defined(HAVE_PREAD)
476 if ( (
sizeof(off_t) <
sizeof (uint64_t)) &&
480 n = pread (response->
fd, buf, max, (off_t) offset64);
482 #if defined(HAVE_LSEEK64)
483 if (lseek64 (response->
fd,
485 SEEK_SET) != offset64)
488 if ( (
sizeof(off_t) <
sizeof (uint64_t)) &&
492 if (lseek (response->
fd,
494 SEEK_SET) != (off_t) offset64)
497 n = read (response->
fd,
508 if (INVALID_HANDLE_VALUE == fh)
512 OVERLAPPED f_ol = {0, 0, {{0, 0}}, 0};
513 ULARGE_INTEGER pos_uli;
517 pos_uli.QuadPart = (uint64_t) offset64;
518 f_ol.Offset = pos_uli.LowPart;
519 f_ol.OffsetHigh = pos_uli.HighPart;
520 if (! ReadFile (fh, (
void*) buf, toRead, &resRead, &f_ol))
524 return (ssize_t) resRead;
558 n = read (response->
fd,
580 (void) close (response->
fd);
585 #undef MHD_create_response_from_fd_at_offset
637 #if ! defined(HAVE___LSEEKI64) && ! defined(HAVE_LSEEK64)
638 if ( (
sizeof(uint64_t) >
sizeof(off_t)) &&
644 if ( ((int64_t) size < 0) ||
646 ((int64_t) (size +
offset) < 0) )
654 if (
NULL == response)
684 if (
NULL == response)
763 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
772 if (
NULL == (tmp = malloc (size)))
774 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
780 memcpy (tmp,
data, size);
786 response->
crfc = &free;
873 const void *last_valid_buffer =
NULL;
875 if ((
NULL == iov) && (0 < iovcnt))
879 if (
NULL == response)
887 for (i = 0; i < iovcnt; ++i)
889 if (0 == iov[i].iov_len)
891 if (
NULL == iov[i].iov_base)
903 last_valid_buffer = iov[i].
iov_base;
905 #if defined(MHD_POSIX_SOCKETS) || ! defined(_WIN64)
911 i_add = iov[i].
iov_len / ULONG_MAX;
912 if (0 != iov[i].iov_len % ULONG_MAX)
914 if (INT_MAX < (i_add + i_cp))
934 response->
crfc = free_cb;
943 response->
data = (
void *) last_valid_buffer;
950 int num_copy_elements = i_cp;
954 if (
NULL == iov_copy)
961 for (i = 0; i < iovcnt; ++i)
963 size_t element_size = iov[i].
iov_len;
964 const uint8_t *buf = (
const uint8_t *) iov[i].iov_base;
966 if (0 == element_size)
968 #if defined(MHD_WINSOCK_SOCKETS) && defined(_WIN64)
971 iov_copy[i_cp].
iov_base = (
char *) buf;
972 iov_copy[i_cp].
iov_len = ULONG_MAX;
974 element_size -= ULONG_MAX;
978 iov_copy[i_cp].
iov_base = (
void *) buf;
990 #ifdef UPGRADE_SUPPORT
1013 connection = urh->connection;
1016 if (
NULL == connection)
1018 daemon = connection->
daemon;
1025 if (urh->was_closed)
1029 #ifdef HTTPS_SUPPORT
1039 urh->was_closed =
true;
1078 struct MHD_UpgradeResponseHandle *urh;
1081 #ifdef MHD_USE_THREADS
1083 MHD_thread_ID_match_current_ (connection->
pid) );
1093 #ifdef HAVE_MESSAGES
1096 "Invalid response for upgrade: application failed to set the 'Upgrade' header!\n"));
1101 urh =
MHD_calloc_ (1,
sizeof (
struct MHD_UpgradeResponseHandle));
1104 urh->connection = connection;
1109 #ifdef HTTPS_SUPPORT
1112 struct MemoryPool *pool;
1116 #if defined(MHD_socket_nosignal_) || ! defined(MHD_socket_pair_nblk_)
1121 #ifdef MHD_socket_pair_nblk_
1122 if (! MHD_socket_pair_nblk_ (sv))
1128 if (! MHD_socket_pair_ (sv))
1135 if ( (! res1) || (! res2) )
1137 #ifdef HAVE_MESSAGES
1139 _ (
"Failed to make loopback sockets non-blocking.\n"));
1151 #ifdef MHD_socket_nosignal_
1152 res1 = MHD_socket_nosignal_ (sv[0]);
1153 res2 = MHD_socket_nosignal_ (sv[1]);
1154 if ( (! res1) || (! res2) )
1156 #ifdef HAVE_MESSAGES
1158 _ (
"Failed to set SO_NOSIGPIPE on loopback sockets.\n"));
1160 #ifndef MSG_NOSIGNAL
1176 #ifdef HAVE_MESSAGES
1178 _ (
"Socketpair descriptor larger than FD_SETSIZE: %d > %d\n"),
1187 urh->app.socket = sv[0];
1190 urh->mhd.socket = sv[1];
1193 pool = connection->
pool;
1195 if (avail < RESERVE_EBUF_SIZE)
1199 avail = RESERVE_EBUF_SIZE;
1213 urh->in_buffer_size = avail / 2;
1214 urh->out_buffer_size = avail - urh->in_buffer_size;
1215 urh->in_buffer = buf;
1216 urh->out_buffer = &buf[urh->in_buffer_size];
1217 #ifdef EPOLL_SUPPORT
1223 struct epoll_event event;
1227 event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
1228 event.data.ptr = &urh->app;
1229 if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
1234 #ifdef HAVE_MESSAGES
1236 _ (
"Call to epoll_ctl failed: %s\n"),
1246 event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
1247 event.data.ptr = &urh->mhd;
1248 if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
1253 event.events = EPOLLIN | EPOLLOUT | EPOLLPRI;
1254 event.data.ptr = &urh->app;
1255 if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
1259 MHD_PANIC (
_ (
"Error cleaning up while handling epoll error.\n"));
1260 #ifdef HAVE_MESSAGES
1262 _ (
"Call to epoll_ctl failed: %s\n"),
1271 daemon->eready_urh_tail,
1273 urh->in_eready_list =
true;
1293 urh->clean_ready =
true;
1296 urh->clean_ready =
true;
1298 connection->urh = urh;
1305 response->upgrade_handler (response->upgrade_handler_cls,
1310 #ifdef HTTPS_SUPPORT
1312 connection->
socket_fd : urh->app.socket,
1352 void *upgrade_handler_cls)
1356 if (
NULL == upgrade_handler)
1359 if (
NULL == response)
1361 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1368 response->upgrade_handler = upgrade_handler;
1369 response->upgrade_handler_cls = upgrade_handler_cls;
1401 if (
NULL == response)
1403 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1408 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1413 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1445 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1449 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
Methods for managing connections.
void internal_suspend_connection_(struct MHD_Connection *connection)
enum MHD_Result(* MHD_KeyValueIterator)(void *cls, enum MHD_ValueKind kind, const char *key, const char *value)
_MHD_EXTERN enum MHD_Result MHD_del_response_header(struct MHD_Response *response, const char *header, const char *content)
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_iovec(const struct MHD_IoVec *iov, unsigned int iovcnt, MHD_ContentReaderFreeCallback free_cb, void *cls)
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_buffer_with_free_callback(size_t size, void *buffer, MHD_ContentReaderFreeCallback crfc)
_MHD_EXTERN enum MHD_Result MHD_add_response_footer(struct MHD_Response *response, const char *footer, const char *content)
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_fd(size_t size, int fd)
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_pipe(int fd)
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_buffer(size_t size, void *buffer, enum MHD_ResponseMemoryMode mode)
_MHD_EXTERN int MHD_get_response_headers(struct MHD_Response *response, MHD_KeyValueIterator iterator, void *iterator_cls)
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_callback(uint64_t size, size_t block_size, MHD_ContentReaderCallback crc, void *crc_cls, MHD_ContentReaderFreeCallback crfc)
struct MHD_Response * MHD_create_response_from_fd_at_offset(size_t size, int fd, off_t offset)
void(* MHD_ContentReaderFreeCallback)(void *cls)
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_fd_at_offset64(uint64_t size, int fd, uint64_t offset)
_MHD_EXTERN void MHD_destroy_response(struct MHD_Response *response)
_MHD_EXTERN enum MHD_Result MHD_add_response_header(struct MHD_Response *response, const char *header, const char *content)
_MHD_EXTERN const char * MHD_get_response_header(struct MHD_Response *response, const char *key)
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_fd64(uint64_t size, int fd)
struct MHD_Response * MHD_create_response_from_data(size_t size, void *data, int must_free, int must_copy)
@ MHD_EPOLL_STATE_UNREADY
#define DLL_insert(head, tail, element)
#define EDLL_insert(head, tail, element)
size_t MHD_pool_get_free(struct MemoryPool *pool)
void * MHD_pool_allocate(struct MemoryPool *pool, size_t size, int from_end)
void * MHD_calloc_(size_t nelem, size_t elsize)
#define MHD_mutex_unlock_chk_(pmutex)
#define MHD_mutex_destroy_chk_(pmutex)
#define MHD_mutex_lock_chk_(pmutex)
int MHD_socket_nonblocking_(MHD_socket sock)
size_t MHD_SCKT_SEND_SIZE_
#define MHD_socket_last_strerr_()
#define MHD_socket_close_chk_(fd)
#define MHD_SCKT_FD_FITS_FDSET_(fd, pset)
int MHD_str_equal_caseless_(const char *str1, const char *str2)
bool MHD_str_has_token_caseless_(const char *str, const char *const token, size_t token_len)
additional automatic macros for MHD_config.h
bool MHD_connection_set_cork_state_(struct MHD_Connection *connection, bool cork_state)
bool MHD_connection_set_nodelay_state_(struct MHD_Connection *connection, bool nodelay_state)
Declarations of send() wrappers.
internal shared structures
#define MHD_IOV_ELMN_MAX_SIZE
memory pool; mostly used for efficient (de)allocation for each connection and bounding memory use for...
Header for platform missing functions.
Header for platform-independent inter-thread communication.
limits values definitions
#define MHD_mutex_init_(ignore)
bool MHD_str_equal_caseless_bin_n_(const char *const str1, const char *const str2, size_t len)
Header for string manipulating helpers.
static void free_callback(void *cls)
#define MHD_FILE_READ_BLOCK_SIZE
bool MHD_check_response_header_token_ci(const struct MHD_Response *response, const char *key, size_t key_len, const char *token, size_t token_len)
static enum MHD_Result add_response_entry(struct MHD_Response *response, enum MHD_ValueKind kind, const char *header, const char *content)
static ssize_t file_reader(void *cls, uint64_t pos, char *buf, size_t max)
enum MHD_Result MHD_set_response_options(struct MHD_Response *response, enum MHD_ResponseFlags flags,...)
static ssize_t pipe_reader(void *cls, uint64_t pos, char *buf, size_t max)
void MHD_increment_response_rc(struct MHD_Response *response)
void(* MHD_UpgradeHandler)(void *cls, struct MHD_Connection *connection, void *con_cls, const char *extra_in, size_t extra_in_size, MHD_socket sock, struct MHD_UpgradeResponseHandle *urh)
#define MHD_CONTENT_READER_END_OF_STREAM
_MHD_EXTERN struct MHD_Response * MHD_create_response_for_upgrade(MHD_UpgradeHandler upgrade_handler, void *upgrade_handler_cls)
_MHD_EXTERN void MHD_resume_connection(struct MHD_Connection *connection)
#define MHD_INVALID_SOCKET
ssize_t(* MHD_ContentReaderCallback)(void *cls, uint64_t pos, char *buf, size_t max)
#define MHD_CONTENT_READER_END_WITH_ERROR
@ MHD_UPGRADE_ACTION_CORK_ON
@ MHD_UPGRADE_ACTION_CLOSE
@ MHD_UPGRADE_ACTION_CORK_OFF
@ MHD_USE_THREAD_PER_CONNECTION
@ MHD_USE_INTERNAL_POLLING_THREAD
@ MHD_RF_INSANITY_HEADER_CONTENT_LENGTH
_MHD_EXTERN enum MHD_Result MHD_upgrade_action(struct MHD_UpgradeResponseHandle *urh, enum MHD_UpgradeAction action,...)
Methods for managing response objects.
enum MHD_Result MHD_response_execute_upgrade_(struct MHD_Response *response, struct MHD_Connection *connection)
size_t read_buffer_offset
MHD_thread_handle_ID_ pid
enum MHD_CONNECTION_STATE state
struct MHD_Daemon * daemon
MHD_ContentReaderFreeCallback crfc
struct MHD_HTTP_Header * first_header
MHD_ContentReaderCallback crc
enum MHD_ResponseFlags flags
unsigned int reference_count