27 #define MHD_NO_DEPRECATION 1 30 #ifdef HAVE_SYS_IOCTL_H 31 #include <sys/ioctl.h> 48 #if defined(_WIN32) && defined(MHD_W32_MUTEX_) 49 #ifndef WIN32_LEAN_AND_MEAN 50 #define WIN32_LEAN_AND_MEAN 1 76 if ( (
NULL == response) ||
81 (
NULL != strchr (header,
'\t')) ||
82 (
NULL != strchr (header,
'\r')) ||
83 (
NULL != strchr (header,
'\n')) ||
84 (
NULL != strchr (content,
'\t')) ||
85 (
NULL != strchr (content,
'\r')) ||
86 (
NULL != strchr (content,
'\n')) )
95 if (
NULL == (hdr->
value = strdup (content)))
167 if ( (
NULL == header) ||
174 if ((0 == strcmp (header,
176 (0 == strcmp (content,
216 if ((
NULL != iterator) &&
217 (
MHD_YES != iterator (iterator_cls,
272 if (
NULL == key || 0 == key[0] ||
NULL == token || 0 == token[0])
311 if ((
NULL == crc) || (0 == block_size))
316 response->
data = (
void *) &response[1];
318 if (! MHD_mutex_init_ (&response->
mutex))
342 enum MHD_ResponseFlags
flags,
347 enum MHD_ResponseOptions ro;
351 va_start (ap, flags);
352 while (MHD_RO_END != (ro = va_arg (ap,
enum MHD_ResponseOptions)))
386 const HANDLE fh = (HANDLE) _get_osfhandle (response->
fd);
388 const int64_t offset64 = (int64_t)(pos + response->
fd_off);
397 #if defined(HAVE_PREAD64) 398 n = pread64(response->
fd, buf, max, offset64);
399 #elif defined(HAVE_PREAD) 400 if ( (
sizeof(off_t) <
sizeof (uint64_t)) &&
404 n = pread(response->
fd, buf, max, (off_t) offset64);
406 #if defined(HAVE_LSEEK64) 407 if (lseek64 (response->
fd,
409 SEEK_SET) != offset64)
412 if ( (
sizeof(off_t) <
sizeof (uint64_t)) &&
413 (offset64 > (uint64_t)INT32_MAX) )
416 if (lseek (response->
fd,
418 SEEK_SET) != (off_t) offset64)
421 n = read (response->
fd,
432 if (INVALID_HANDLE_VALUE == fh)
436 OVERLAPPED f_ol = {0, 0, {{0, 0}}, 0};
437 ULARGE_INTEGER pos_uli;
438 DWORD toRead = (max >
INT32_MAX) ? INT32_MAX : (DWORD) max;
441 pos_uli.QuadPart = (uint64_t) offset64;
442 f_ol.Offset = pos_uli.LowPart;
443 f_ol.OffsetHigh = pos_uli.HighPart;
444 if (! ReadFile(fh, (
void*)buf, toRead, &resRead, &f_ol))
448 return (ssize_t) resRead;
465 (void) close (response->
fd);
469 #undef MHD_create_response_from_fd_at_offset 521 #if !defined(HAVE___LSEEKI64) && !defined(HAVE_LSEEK64) 522 if ( (
sizeof(uint64_t) >
sizeof(off_t)) &&
524 (offset > (uint64_t)INT32_MAX) ||
525 ((size + offset) >= (uint64_t)INT32_MAX) ) )
528 if ( ((int64_t)size < 0) ||
529 ((int64_t)offset < 0) ||
530 ((int64_t)(size + offset) < 0) )
538 if (
NULL == response)
541 response->
fd_off = offset;
612 if ((
NULL == data) && (size > 0))
617 if (! MHD_mutex_init_ (&response->
mutex))
622 if ((must_copy) && (size > 0))
624 if (
NULL == (tmp = malloc (size)))
630 memcpy (tmp, data, size);
636 response->
crfc = &free;
660 enum MHD_ResponseMemoryMode mode)
664 mode == MHD_RESPMEM_MUST_FREE,
665 mode == MHD_RESPMEM_MUST_COPY);
669 #ifdef UPGRADE_SUPPORT 683 MHD_upgrade_action (
struct MHD_UpgradeResponseHandle *urh,
684 enum MHD_UpgradeAction action,
692 connection = urh->connection;
695 if (
NULL == connection)
697 daemon = connection->
daemon;
703 case MHD_UPGRADE_ACTION_CLOSE:
718 urh->was_closed =
true;
749 struct MHD_UpgradeResponseHandle *urh;
761 _(
"Invalid response for upgrade: application failed to set the 'Upgrade' header!\n"));
766 urh =
MHD_calloc_ (1,
sizeof (
struct MHD_UpgradeResponseHandle));
769 urh->connection = connection;
775 struct MemoryPool *pool;
779 #if defined(MHD_socket_nosignal_) || !defined(MHD_socket_pair_nblk_) 784 #ifdef MHD_socket_pair_nblk_ 785 if (! MHD_socket_pair_nblk_ (sv))
791 if (! MHD_socket_pair_ (sv))
798 if ( (! res1) || (! res2) )
802 _(
"Failed to make loopback sockets non-blocking.\n"));
814 #ifdef MHD_socket_nosignal_ 815 res1 = MHD_socket_nosignal_(sv[0]);
816 res2 = MHD_socket_nosignal_(sv[1]);
817 if ( (! res1) || (! res2) )
821 _(
"Failed to set SO_NOSIGPIPE on loopback sockets.\n"));
841 _(
"Socketpair descriptor larger than FD_SETSIZE: %d > %d\n"),
850 urh->app.socket = sv[0];
853 urh->mhd.socket = sv[1];
856 pool = connection->
pool;
858 if (avail < RESERVE_EBUF_SIZE)
862 avail = RESERVE_EBUF_SIZE;
876 urh->in_buffer_size = avail / 2;
877 urh->out_buffer_size = avail - urh->in_buffer_size;
878 urh->in_buffer = buf;
879 urh->out_buffer = &buf[urh->in_buffer_size];
886 struct epoll_event event;
890 event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
891 event.data.ptr = &urh->app;
892 if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
899 _(
"Call to epoll_ctl failed: %s\n"),
909 event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
910 event.data.ptr = &urh->mhd;
911 if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
916 event.events = EPOLLIN | EPOLLOUT | EPOLLPRI;
917 event.data.ptr = &urh->app;
918 if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
922 MHD_PANIC (
_(
"Error cleaning up while handling epoll error"));
925 _(
"Call to epoll_ctl failed: %s\n"),
934 daemon->eready_urh_tail,
936 urh->in_eready_list =
true;
956 urh->clean_ready =
true;
959 urh->clean_ready =
true;
961 connection->urh = urh;
968 response->upgrade_handler (response->upgrade_handler_cls,
1014 MHD_create_response_for_upgrade (MHD_UpgradeHandler upgrade_handler,
1015 void *upgrade_handler_cls)
1019 if (
NULL == upgrade_handler)
1022 if (
NULL == response)
1024 if (! MHD_mutex_init_ (&response->
mutex))
1029 response->upgrade_handler = upgrade_handler;
1030 response->upgrade_handler_cls = upgrade_handler_cls;
1060 if (
NULL == response)
int(* MHD_KeyValueIterator)(void *cls, enum MHD_ValueKind kind, const char *key, const char *value)
int MHD_socket_nonblocking_(MHD_socket sock)
int MHD_set_response_options(struct MHD_Response *response, enum MHD_ResponseFlags flags,...)
additional automatic macros for MHD_config.h
static void free_callback(void *cls)
#define DLL_insert(head, tail, element)
enum MHD_CONNECTION_STATE state
int MHD_add_response_header(struct MHD_Response *response, const char *header, const char *content)
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_fd64(uint64_t size, int fd)
MHD_ContentReaderFreeCallback crfc
Methods for managing connections.
void(* MHD_ContentReaderFreeCallback)(void *cls)
static ssize_t file_reader(void *cls, uint64_t pos, char *buf, size_t max)
const char * MHD_get_response_header(struct MHD_Response *response, const char *key)
Header for platform missing functions.
struct MHD_HTTP_Header * first_header
void * MHD_pool_allocate(struct MemoryPool *pool, size_t size, int from_end)
#define MHD_mutex_destroy_chk_(pmutex)
#define EDLL_insert(head, tail, element)
Methods for managing response objects.
int MHD_response_execute_upgrade_(struct MHD_Response *response, struct MHD_Connection *connection)
struct MHD_Daemon * daemon
#define MHD_mutex_unlock_chk_(pmutex)
struct MHD_Response * MHD_create_response_from_callback(uint64_t size, size_t block_size, MHD_ContentReaderCallback crc, void *crc_cls, MHD_ContentReaderFreeCallback crfc)
Header for platform-independent inter-thread communication.
struct MHD_Response * MHD_create_response_from_buffer(size_t size, void *buffer, enum MHD_ResponseMemoryMode mode)
#define MHD_socket_close_chk_(fd)
#define MHD_INVALID_SOCKET
int MHD_add_response_footer(struct MHD_Response *response, const char *footer, const char *content)
ssize_t(* MHD_ContentReaderCallback)(void *cls, uint64_t pos, char *buf, size_t max)
unsigned int reference_count
void MHD_destroy_response(struct MHD_Response *response)
void MHD_increment_response_rc(struct MHD_Response *response)
#define MHD_CONTENT_READER_END_OF_STREAM
struct MHD_Response * MHD_create_response_from_data(size_t size, void *data, int must_free, int must_copy)
limits values definitions
bool MHD_check_response_header_token_ci(const struct MHD_Response *response, const char *key, const char *token, size_t token_len)
internal shared structures
void * MHD_calloc_(size_t nelem, size_t elsize)
size_t MHD_pool_get_free(struct MemoryPool *pool)
#define MHD_socket_last_strerr_()
void internal_suspend_connection_(struct MHD_Connection *connection)
static int add_response_entry(struct MHD_Response *response, enum MHD_ValueKind kind, const char *header, const char *content)
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_fd_at_offset64(uint64_t size, int fd, uint64_t offset)
enum MHD_ResponseFlags flags
Header for string manipulating helpers.
#define MHD_SCKT_FD_FITS_FDSET_(fd, pset)
bool MHD_str_has_token_caseless_(const char *str, const char *const token, size_t token_len)
int MHD_str_equal_caseless_(const char *str1, const char *str2)
#define MHD_CONTENT_READER_END_WITH_ERROR
MHD_ContentReaderCallback crc
void MHD_resume_connection(struct MHD_Connection *connection)
int MHD_del_response_header(struct MHD_Response *response, const char *header, const char *content)
size_t read_buffer_offset
struct MHD_Response * MHD_create_response_from_fd(size_t size, int fd)
struct MHD_Response * MHD_create_response_from_fd_at_offset(size_t size, int fd, off_t offset)
#define MHD_mutex_lock_chk_(pmutex)
int MHD_get_response_headers(struct MHD_Response *response, MHD_KeyValueIterator iterator, void *iterator_cls)
memory pool; mostly used for efficient (de)allocation for each connection and bounding memory use for...