mirror of
https://git.gnunet.org/libmicrohttpd.git
synced 2026-09-25 04:09:31 +03:00
fixing 1438 and 1432
This commit is contained in:
@@ -1,3 +1,7 @@
|
||||
Sat Dec 6 18:36:17 MST 2008
|
||||
Added configure option to disable checking for CURL support.
|
||||
Added MHD_OPTION to allow specification of custom logger. -CG
|
||||
|
||||
Tue Nov 18 01:19:53 MST 2008
|
||||
Removed support for untested and/or broken SSL features
|
||||
and (largely useless) options. -CG
|
||||
|
||||
+22
-12
@@ -175,17 +175,26 @@ AC_CHECK_DECL([TCP_CORK], [], [], [[#include <netinet/tcp.h>]])
|
||||
|
||||
# libcurl (required for testing)
|
||||
SAVE_LIBS=$LIBS
|
||||
LIBCURL_CHECK_CONFIG(,,curl=1,curl=0)
|
||||
AM_CONDITIONAL(HAVE_CURL, test x$curl = x1)
|
||||
LIBS=$SAVE_LIBS
|
||||
|
||||
AC_MSG_CHECKING(whether to use libcurl for testing)
|
||||
AC_ARG_ENABLE(curl,
|
||||
[AS_HELP_STRING([--enable-curl],[support cURL based testcases])],
|
||||
[enable_curl=$enableval],
|
||||
[enable_curl="yes"])
|
||||
|
||||
if test "$enable_curl" = "yes"
|
||||
then
|
||||
LIBCURL_CHECK_CONFIG(,,curl=1,curl=0)
|
||||
AM_CONDITIONAL(HAVE_CURL, test x$curl = x1)
|
||||
# Lib cURL & cURL - OpenSSL versions
|
||||
MHD_REQ_CURL_VERSION=7.16.4
|
||||
MHD_REQ_CURL_OPENSSL_VERSION=0.9.8
|
||||
MHD_REQ_CURL_GNUTLS_VERSION=2.2.3
|
||||
AC_DEFINE_UNQUOTED([MHD_REQ_CURL_VERSION], "$MHD_REQ_CURL_VERSION", [required cURL version to run tests])
|
||||
AC_DEFINE_UNQUOTED([MHD_REQ_CURL_OPENSSL_VERSION], "$MHD_REQ_CURL_OPENSSL_VERSION", [required cURL SSL version to run tests])
|
||||
AC_DEFINE_UNQUOTED([MHD_REQ_CURL_GNUTLS_VERSION], "$MHD_REQ_CURL_GNUTLS_VERSION", [gnuTLS lib version - used in conjunction with cURL])
|
||||
MHD_REQ_CURL_VERSION=7.16.4
|
||||
MHD_REQ_CURL_OPENSSL_VERSION=0.9.8
|
||||
MHD_REQ_CURL_GNUTLS_VERSION=2.2.3
|
||||
AC_DEFINE_UNQUOTED([MHD_REQ_CURL_VERSION], "$MHD_REQ_CURL_VERSION", [required cURL version to run tests])
|
||||
AC_DEFINE_UNQUOTED([MHD_REQ_CURL_OPENSSL_VERSION], "$MHD_REQ_CURL_OPENSSL_VERSION", [required cURL SSL version to run tests])
|
||||
AC_DEFINE_UNQUOTED([MHD_REQ_CURL_GNUTLS_VERSION], "$MHD_REQ_CURL_GNUTLS_VERSION", [gnuTLS lib version - used in conjunction with cURL])
|
||||
fi
|
||||
LIBS=$SAVE_LIBS
|
||||
|
||||
# large file support (> 4 GB)
|
||||
AC_SYS_LARGEFILE
|
||||
@@ -271,9 +280,10 @@ AC_DEFINE([GNULIB_GC_RANDOM],[1],[GNULIB_GC_RANDOM])
|
||||
|
||||
# gcov compilation
|
||||
use_gcov=no
|
||||
AC_ARG_ENABLE([coverage], AS_HELP_STRING([--enable-coverage],
|
||||
[compile the library with code coverage support (default is NO)]),
|
||||
[use_gcov=yes], [use_gcov=no])
|
||||
AC_ARG_ENABLE([coverage],
|
||||
AS_HELP_STRING([--enable-coverage],
|
||||
[compile the library with code coverage support (default is NO)]),
|
||||
[use_gcov=yes], [use_gcov=no])
|
||||
AM_CONDITIONAL([USE_COVERAGE], [test "x$use_gcov" = "xyes"])
|
||||
|
||||
|
||||
|
||||
+17
-19
@@ -343,24 +343,18 @@ terminated (const) array of 'enum MHD_GNUTLS_CipherAlgorithm'
|
||||
representing the cipher priority order to which the HTTPS
|
||||
daemon should adhere.
|
||||
|
||||
@item MHD_OPTION_KX_PRIORITY
|
||||
Memory pointer to a zero (MHD_GNUTLS_KX_UNKNOWN)
|
||||
terminated (const) array of 'MHD_GNUTLS_KeyExchangeAlgorithm'
|
||||
representing the key exchange algorithm priority order to which
|
||||
the HTTPS daemon should adhere.
|
||||
|
||||
@item MHD_OPTION_CERT_TYPE
|
||||
Indicate which type of certificate this server will use,
|
||||
followed by a value of type 'enum MHD_GNUTLS_CertificateType'.
|
||||
|
||||
@item MHD_OPTION_MAC_ALGO
|
||||
Specify the mac algorithm used by server.
|
||||
The argument should be of type "enum MHD_GNUTLS_MacAlgorithm"
|
||||
|
||||
@item MHD_OPTION_TLS_COMP_ALGO
|
||||
Compression algorithm used by server. Should be followed by an
|
||||
option of type 'enum MHD_GNUTLS_CompressionMethod'.
|
||||
|
||||
@item MHD_OPTION_EXTERNAL_LOGGER
|
||||
Use the given function for logging error messages.
|
||||
This option must be followed by two arguments; the
|
||||
first must be a pointer to a function
|
||||
of type 'void fun(void * arg, const char * fmt, va_list ap)'
|
||||
and the second a pointer of type 'void*' which will
|
||||
be passed as the "arg" argument to "fun".
|
||||
|
||||
Note that MHD will not generate any log messages
|
||||
if it was compiled without the "--enable-messages"
|
||||
flag being set and the MHD_USE_DEBUG flag being set,
|
||||
even if this argument is used.
|
||||
@end table
|
||||
@end deftp
|
||||
|
||||
@@ -934,7 +928,11 @@ responce and we finally destroy it only when the daemon shuts down.
|
||||
|
||||
@deftypefun int MHD_queue_response (struct MHD_Connection *connection, unsigned int status_code, struct MHD_Response *response)
|
||||
Queue a response to be transmitted to the client as soon as possible
|
||||
(increment the reference counter).
|
||||
but only after MHD_AccessHandlerCallback returns. This function
|
||||
checks that it is legal to queue a response at this time for the
|
||||
given connection. It also increments the internal reference
|
||||
counter for the response object (the counter will be decremented
|
||||
automatically once the response has been transmitted).
|
||||
|
||||
@table @var
|
||||
@item connection
|
||||
|
||||
@@ -208,7 +208,7 @@ MHD_lookup_connection_value (struct MHD_Connection *connection,
|
||||
|
||||
/**
|
||||
* Queue a response to be transmitted to the client (as soon as
|
||||
* possible).
|
||||
* possible but after MHD_AccessHandlerCallback returns).
|
||||
*
|
||||
* @param connection the connection identifying the client
|
||||
* @param status_code HTTP status code (i.e. 200 for OK)
|
||||
|
||||
@@ -834,6 +834,10 @@ MHD_start_daemon_va (unsigned int options,
|
||||
retVal->max_connections = MHD_MAX_CONNECTIONS_DEFAULT;
|
||||
retVal->pool_size = MHD_POOL_SIZE_DEFAULT;
|
||||
retVal->connection_timeout = 0; /* no timeout */
|
||||
#if HAVE_MESSAGES
|
||||
retVal->custom_error_log = (void(*)(void*,const char *,va_list)) &vfprintf;
|
||||
retVal->custom_error_log_cls = stderr;
|
||||
#endif
|
||||
#if HTTPS_SUPPORT
|
||||
if (options & MHD_USE_SSL)
|
||||
{
|
||||
@@ -891,6 +895,14 @@ MHD_start_daemon_va (unsigned int options,
|
||||
_set_priority (&retVal->priority_cache->cipher,
|
||||
va_arg (ap, const int *));
|
||||
break;
|
||||
#endif
|
||||
case MHD_OPTION_EXTERNAL_LOGGER:
|
||||
#if HAVE_MESSAGES
|
||||
retVal->custom_error_log = va_arg(ap, void (*)(void*cls, const char *, va_list));
|
||||
retVal->custom_error_log_cls = va_arg(ap, void *);
|
||||
#else
|
||||
va_arg(ap, void (*)(void*cls, const char *,...));
|
||||
va_arg(ap, void *);
|
||||
#endif
|
||||
default:
|
||||
#if HAVE_MESSAGES
|
||||
|
||||
@@ -102,7 +102,9 @@ MHD_DLOG (const struct MHD_Daemon *daemon, const char *format, ...)
|
||||
if ((daemon->options & MHD_USE_DEBUG) == 0)
|
||||
return;
|
||||
va_start (va, format);
|
||||
VFPRINTF (stderr, format, va);
|
||||
daemon->custom_error_log(daemon->custom_error_log_cls,
|
||||
format,
|
||||
va);
|
||||
va_end (va);
|
||||
}
|
||||
#endif
|
||||
|
||||
+406
-317
@@ -66,12 +66,26 @@ void MHD_http_unescape (char *val);
|
||||
*/
|
||||
struct MHD_HTTP_Header
|
||||
{
|
||||
/**
|
||||
* Headers are kept in a linked list.
|
||||
*/
|
||||
struct MHD_HTTP_Header *next;
|
||||
|
||||
/**
|
||||
* The name of the header (key), without
|
||||
* the colon.
|
||||
*/
|
||||
char *header;
|
||||
|
||||
/**
|
||||
* The value of the header.
|
||||
*/
|
||||
char *value;
|
||||
|
||||
/**
|
||||
* Type of the header (where in the HTTP
|
||||
* protocol is this header from).
|
||||
*/
|
||||
enum MHD_ValueKind kind;
|
||||
|
||||
};
|
||||
@@ -82,68 +96,68 @@ struct MHD_HTTP_Header
|
||||
struct MHD_Response
|
||||
{
|
||||
|
||||
/**
|
||||
* Headers to send for the response. Initially
|
||||
* the linked list is created in inverse order;
|
||||
* the order should be inverted before sending!
|
||||
*/
|
||||
/**
|
||||
* Headers to send for the response. Initially
|
||||
* the linked list is created in inverse order;
|
||||
* the order should be inverted before sending!
|
||||
*/
|
||||
struct MHD_HTTP_Header *first_header;
|
||||
|
||||
/**
|
||||
* Buffer pointing to data that we are supposed
|
||||
* to send as a response.
|
||||
*/
|
||||
/**
|
||||
* Buffer pointing to data that we are supposed
|
||||
* to send as a response.
|
||||
*/
|
||||
char *data;
|
||||
|
||||
/**
|
||||
* Closure to give to the content reader
|
||||
* free callback.
|
||||
*/
|
||||
/**
|
||||
* Closure to give to the content reader
|
||||
* free callback.
|
||||
*/
|
||||
void *crc_cls;
|
||||
|
||||
/**
|
||||
* How do we get more data? NULL if we are
|
||||
* given all of the data up front.
|
||||
*/
|
||||
/**
|
||||
* How do we get more data? NULL if we are
|
||||
* given all of the data up front.
|
||||
*/
|
||||
MHD_ContentReaderCallback crc;
|
||||
|
||||
/**
|
||||
* NULL if data must not be freed, otherwise
|
||||
* either user-specified callback or "&free".
|
||||
*/
|
||||
/**
|
||||
* NULL if data must not be freed, otherwise
|
||||
* either user-specified callback or "&free".
|
||||
*/
|
||||
MHD_ContentReaderFreeCallback crfc;
|
||||
|
||||
/**
|
||||
* Mutex to synchronize access to data/size and
|
||||
* reference counts.
|
||||
*/
|
||||
/**
|
||||
* Mutex to synchronize access to data/size and
|
||||
* reference counts.
|
||||
*/
|
||||
pthread_mutex_t mutex;
|
||||
|
||||
/**
|
||||
* Reference count for this response. Free
|
||||
* once the counter hits zero.
|
||||
*/
|
||||
/**
|
||||
* Reference count for this response. Free
|
||||
* once the counter hits zero.
|
||||
*/
|
||||
unsigned int reference_count;
|
||||
|
||||
/**
|
||||
* Set to -1 if size is not known.
|
||||
*/
|
||||
/**
|
||||
* Set to -1 if size is not known.
|
||||
*/
|
||||
size_t total_size;
|
||||
|
||||
/**
|
||||
* Size of data.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Size of data.
|
||||
*/
|
||||
size_t data_size;
|
||||
|
||||
/**
|
||||
* Size of the data buffer.
|
||||
*/
|
||||
/**
|
||||
* Size of the data buffer.
|
||||
*/
|
||||
size_t data_buffer_size;
|
||||
|
||||
/**
|
||||
* At what offset in the stream is the
|
||||
* beginning of data located?
|
||||
*/
|
||||
|
||||
/**
|
||||
* At what offset in the stream is the
|
||||
* beginning of data located?
|
||||
*/
|
||||
size_t data_start;
|
||||
|
||||
};
|
||||
@@ -164,124 +178,124 @@ struct MHD_Response
|
||||
*/
|
||||
enum MHD_CONNECTION_STATE
|
||||
{
|
||||
/**
|
||||
* Connection just started (no headers received).
|
||||
* Waiting for the line with the request type, URL and version.
|
||||
*/
|
||||
/**
|
||||
* Connection just started (no headers received).
|
||||
* Waiting for the line with the request type, URL and version.
|
||||
*/
|
||||
MHD_CONNECTION_INIT = 0,
|
||||
|
||||
/**
|
||||
* 1: We got the URL (and request type and version). Wait for a header line.
|
||||
*/
|
||||
/**
|
||||
* 1: We got the URL (and request type and version). Wait for a header line.
|
||||
*/
|
||||
MHD_CONNECTION_URL_RECEIVED = MHD_CONNECTION_INIT + 1,
|
||||
|
||||
/**
|
||||
* 2: We got part of a multi-line request header. Wait for the rest.
|
||||
*/
|
||||
/**
|
||||
* 2: We got part of a multi-line request header. Wait for the rest.
|
||||
*/
|
||||
MHD_CONNECTION_HEADER_PART_RECEIVED = MHD_CONNECTION_URL_RECEIVED + 1,
|
||||
|
||||
/**
|
||||
* 3: We got the request headers. Process them.
|
||||
*/
|
||||
/**
|
||||
* 3: We got the request headers. Process them.
|
||||
*/
|
||||
MHD_CONNECTION_HEADERS_RECEIVED = MHD_CONNECTION_HEADER_PART_RECEIVED + 1,
|
||||
|
||||
/**
|
||||
* 4: We have processed the request headers. Send 100 continue.
|
||||
*/
|
||||
/**
|
||||
* 4: We have processed the request headers. Send 100 continue.
|
||||
*/
|
||||
MHD_CONNECTION_HEADERS_PROCESSED = MHD_CONNECTION_HEADERS_RECEIVED + 1,
|
||||
|
||||
/**
|
||||
* 5: We have processed the headers and need to send 100 CONTINUE.
|
||||
*/
|
||||
/**
|
||||
* 5: We have processed the headers and need to send 100 CONTINUE.
|
||||
*/
|
||||
MHD_CONNECTION_CONTINUE_SENDING = MHD_CONNECTION_HEADERS_PROCESSED + 1,
|
||||
|
||||
/**
|
||||
* 6: We have sent 100 CONTINUE (or do not need to). Read the message body.
|
||||
*/
|
||||
/**
|
||||
* 6: We have sent 100 CONTINUE (or do not need to). Read the message body.
|
||||
*/
|
||||
MHD_CONNECTION_CONTINUE_SENT = MHD_CONNECTION_CONTINUE_SENDING + 1,
|
||||
|
||||
/**
|
||||
* 7: We got the request body. Wait for a line of the footer.
|
||||
*/
|
||||
/**
|
||||
* 7: We got the request body. Wait for a line of the footer.
|
||||
*/
|
||||
MHD_CONNECTION_BODY_RECEIVED = MHD_CONNECTION_CONTINUE_SENT + 1,
|
||||
|
||||
/**
|
||||
* 8: We got part of a line of the footer. Wait for the
|
||||
* rest.
|
||||
*/
|
||||
/**
|
||||
* 8: We got part of a line of the footer. Wait for the
|
||||
* rest.
|
||||
*/
|
||||
MHD_CONNECTION_FOOTER_PART_RECEIVED = MHD_CONNECTION_BODY_RECEIVED + 1,
|
||||
|
||||
/**
|
||||
* 9: We received the entire footer. Wait for a response to be queued
|
||||
* and prepare the response headers.
|
||||
*/
|
||||
|
||||
/**
|
||||
* 9: We received the entire footer. Wait for a response to be queued
|
||||
* and prepare the response headers.
|
||||
*/
|
||||
MHD_CONNECTION_FOOTERS_RECEIVED = MHD_CONNECTION_FOOTER_PART_RECEIVED + 1,
|
||||
|
||||
/**
|
||||
* 10: We have prepared the response headers in the writ buffer.
|
||||
* Send the response headers.
|
||||
*/
|
||||
/**
|
||||
* 10: We have prepared the response headers in the writ buffer.
|
||||
* Send the response headers.
|
||||
*/
|
||||
MHD_CONNECTION_HEADERS_SENDING = MHD_CONNECTION_FOOTERS_RECEIVED + 1,
|
||||
|
||||
/**
|
||||
* 11: We have sent the response headers. Get ready to send the body.
|
||||
*/
|
||||
/**
|
||||
* 11: We have sent the response headers. Get ready to send the body.
|
||||
*/
|
||||
MHD_CONNECTION_HEADERS_SENT = MHD_CONNECTION_HEADERS_SENDING + 1,
|
||||
|
||||
/**
|
||||
* 12: We are ready to send a part of a non-chunked body. Send it.
|
||||
*/
|
||||
/**
|
||||
* 12: We are ready to send a part of a non-chunked body. Send it.
|
||||
*/
|
||||
MHD_CONNECTION_NORMAL_BODY_READY = MHD_CONNECTION_HEADERS_SENT + 1,
|
||||
|
||||
/**
|
||||
* 13: We are waiting for the client to provide more
|
||||
* data of a non-chunked body.
|
||||
*/
|
||||
/**
|
||||
* 13: We are waiting for the client to provide more
|
||||
* data of a non-chunked body.
|
||||
*/
|
||||
MHD_CONNECTION_NORMAL_BODY_UNREADY = MHD_CONNECTION_NORMAL_BODY_READY + 1,
|
||||
|
||||
/**
|
||||
* 14: We are ready to send a chunk.
|
||||
*/
|
||||
/**
|
||||
* 14: We are ready to send a chunk.
|
||||
*/
|
||||
MHD_CONNECTION_CHUNKED_BODY_READY = MHD_CONNECTION_NORMAL_BODY_UNREADY + 1,
|
||||
|
||||
/**
|
||||
* 15: We are waiting for the client to provide a chunk of the body.
|
||||
*/
|
||||
/**
|
||||
* 15: We are waiting for the client to provide a chunk of the body.
|
||||
*/
|
||||
MHD_CONNECTION_CHUNKED_BODY_UNREADY = MHD_CONNECTION_CHUNKED_BODY_READY + 1,
|
||||
|
||||
/**
|
||||
* 16: We have sent the response body. Prepare the footers.
|
||||
*/
|
||||
/**
|
||||
* 16: We have sent the response body. Prepare the footers.
|
||||
*/
|
||||
MHD_CONNECTION_BODY_SENT = MHD_CONNECTION_CHUNKED_BODY_UNREADY + 1,
|
||||
|
||||
/**
|
||||
* 17: We have prepared the response footer. Send it.
|
||||
*/
|
||||
/**
|
||||
* 17: We have prepared the response footer. Send it.
|
||||
*/
|
||||
MHD_CONNECTION_FOOTERS_SENDING = MHD_CONNECTION_BODY_SENT + 1,
|
||||
|
||||
/**
|
||||
* 18: We have sent the response footer. Shutdown or restart.
|
||||
*/
|
||||
/**
|
||||
* 18: We have sent the response footer. Shutdown or restart.
|
||||
*/
|
||||
MHD_CONNECTION_FOOTERS_SENT = MHD_CONNECTION_FOOTERS_SENDING + 1,
|
||||
|
||||
/**
|
||||
* 19: This connection is closed (no more activity
|
||||
* allowed).
|
||||
*/
|
||||
/**
|
||||
* 19: This connection is closed (no more activity
|
||||
* allowed).
|
||||
*/
|
||||
MHD_CONNECTION_CLOSED = MHD_CONNECTION_FOOTERS_SENT + 1,
|
||||
|
||||
/*
|
||||
* SSL/TLS connection states
|
||||
*/
|
||||
|
||||
/*
|
||||
/**
|
||||
* The initial connection state for all secure connectoins
|
||||
* Handshake messages will be processed in this state & while
|
||||
* in the 'MHD_TLS_HELLO_REQUEST' state
|
||||
*/
|
||||
MHD_TLS_CONNECTION_INIT = MHD_CONNECTION_CLOSED + 1,
|
||||
|
||||
/*
|
||||
/**
|
||||
* This state indicates the server has send a 'Hello Request' to
|
||||
* the client & a renegotiation of the handshake is in progress.
|
||||
*
|
||||
@@ -329,341 +343,416 @@ typedef ssize_t (*TransmitCallback) (struct MHD_Connection * conn,
|
||||
const void *write_to, size_t max_bytes);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* State kept for each HTTP request.
|
||||
*/
|
||||
struct MHD_Connection
|
||||
{
|
||||
|
||||
/**
|
||||
* This is a linked list.
|
||||
*/
|
||||
/**
|
||||
* This is a linked list.
|
||||
*/
|
||||
struct MHD_Connection *next;
|
||||
|
||||
/**
|
||||
* Reference to the MHD_Daemon struct.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Reference to the MHD_Daemon struct.
|
||||
*/
|
||||
struct MHD_Daemon *daemon;
|
||||
|
||||
/**
|
||||
* Linked list of parsed headers.
|
||||
*/
|
||||
/**
|
||||
* Linked list of parsed headers.
|
||||
*/
|
||||
struct MHD_HTTP_Header *headers_received;
|
||||
|
||||
/**
|
||||
* Response to transmit (initially NULL).
|
||||
*/
|
||||
/**
|
||||
* Response to transmit (initially NULL).
|
||||
*/
|
||||
struct MHD_Response *response;
|
||||
|
||||
/**
|
||||
* The memory pool is created whenever we first read
|
||||
* from the TCP stream and destroyed at the end of
|
||||
* each request (and re-created for the next request).
|
||||
* In the meantime, this pointer is NULL. The
|
||||
* pool is used for all connection-related data
|
||||
* except for the response (which maybe shared between
|
||||
* connections) and the IP address (which persists
|
||||
* across individual requests).
|
||||
*/
|
||||
/**
|
||||
* The memory pool is created whenever we first read
|
||||
* from the TCP stream and destroyed at the end of
|
||||
* each request (and re-created for the next request).
|
||||
* In the meantime, this pointer is NULL. The
|
||||
* pool is used for all connection-related data
|
||||
* except for the response (which maybe shared between
|
||||
* connections) and the IP address (which persists
|
||||
* across individual requests).
|
||||
*/
|
||||
struct MemoryPool *pool;
|
||||
|
||||
/**
|
||||
* We allow the main application to associate some
|
||||
* pointer with the connection. Here is where we
|
||||
* store it. (MHD does not know or care what it
|
||||
* is).
|
||||
*/
|
||||
/**
|
||||
* We allow the main application to associate some
|
||||
* pointer with the connection. Here is where we
|
||||
* store it. (MHD does not know or care what it
|
||||
* is).
|
||||
*/
|
||||
void *client_context;
|
||||
|
||||
/**
|
||||
* Request method. Should be GET/POST/etc. Allocated
|
||||
* in pool.
|
||||
*/
|
||||
/**
|
||||
* Request method. Should be GET/POST/etc. Allocated
|
||||
* in pool.
|
||||
*/
|
||||
char *method;
|
||||
|
||||
/**
|
||||
* Requested URL (everything after "GET" only). Allocated
|
||||
* in pool.
|
||||
*/
|
||||
/**
|
||||
* Requested URL (everything after "GET" only). Allocated
|
||||
* in pool.
|
||||
*/
|
||||
char *url;
|
||||
|
||||
/**
|
||||
* HTTP version string (i.e. http/1.1). Allocated
|
||||
* in pool.
|
||||
*/
|
||||
/**
|
||||
* HTTP version string (i.e. http/1.1). Allocated
|
||||
* in pool.
|
||||
*/
|
||||
char *version;
|
||||
|
||||
/**
|
||||
* Buffer for reading requests. Allocated
|
||||
* in pool. Actually one byte larger than
|
||||
* read_buffer_size (if non-NULL) to allow for
|
||||
* 0-termination.
|
||||
*/
|
||||
/**
|
||||
* Buffer for reading requests. Allocated
|
||||
* in pool. Actually one byte larger than
|
||||
* read_buffer_size (if non-NULL) to allow for
|
||||
* 0-termination.
|
||||
*/
|
||||
char *read_buffer;
|
||||
|
||||
/**
|
||||
* Buffer for writing response (headers only). Allocated
|
||||
* in pool.
|
||||
*/
|
||||
/**
|
||||
* Buffer for writing response (headers only). Allocated
|
||||
* in pool.
|
||||
*/
|
||||
char *write_buffer;
|
||||
|
||||
/**
|
||||
* Last incomplete header line during parsing of headers.
|
||||
* Allocated in pool. Only valid if state is
|
||||
* either HEADER_PART_RECEIVED or FOOTER_PART_RECEIVED.
|
||||
*/
|
||||
/**
|
||||
* Last incomplete header line during parsing of headers.
|
||||
* Allocated in pool. Only valid if state is
|
||||
* either HEADER_PART_RECEIVED or FOOTER_PART_RECEIVED.
|
||||
*/
|
||||
char *last;
|
||||
|
||||
/**
|
||||
* Position after the colon on the last incomplete header
|
||||
* line during parsing of headers.
|
||||
* Allocated in pool. Only valid if state is
|
||||
* either HEADER_PART_RECEIVED or FOOTER_PART_RECEIVED.
|
||||
*/
|
||||
/**
|
||||
* Position after the colon on the last incomplete header
|
||||
* line during parsing of headers.
|
||||
* Allocated in pool. Only valid if state is
|
||||
* either HEADER_PART_RECEIVED or FOOTER_PART_RECEIVED.
|
||||
*/
|
||||
char *colon;
|
||||
|
||||
/**
|
||||
* Foreign address (of length addr_len). MALLOCED (not
|
||||
* in pool!).
|
||||
*/
|
||||
/**
|
||||
* Foreign address (of length addr_len). MALLOCED (not
|
||||
* in pool!).
|
||||
*/
|
||||
struct sockaddr_in *addr;
|
||||
|
||||
/**
|
||||
* Thread for this connection (if we are using
|
||||
* one thread per connection).
|
||||
*/
|
||||
/**
|
||||
* Thread for this connection (if we are using
|
||||
* one thread per connection).
|
||||
*/
|
||||
pthread_t pid;
|
||||
|
||||
/**
|
||||
* Size of read_buffer (in bytes). This value indicates
|
||||
* how many bytes we're willing to read into the buffer;
|
||||
* the real buffer is one byte longer to allow for
|
||||
* adding zero-termination (when needed).
|
||||
*/
|
||||
/**
|
||||
* Size of read_buffer (in bytes). This value indicates
|
||||
* how many bytes we're willing to read into the buffer;
|
||||
* the real buffer is one byte longer to allow for
|
||||
* adding zero-termination (when needed).
|
||||
*/
|
||||
size_t read_buffer_size;
|
||||
|
||||
/**
|
||||
* Position where we currently append data in
|
||||
* read_buffer (last valid position).
|
||||
*/
|
||||
/**
|
||||
* Position where we currently append data in
|
||||
* read_buffer (last valid position).
|
||||
*/
|
||||
size_t read_buffer_offset;
|
||||
|
||||
/**
|
||||
* Size of write_buffer (in bytes).
|
||||
*/
|
||||
/**
|
||||
* Size of write_buffer (in bytes).
|
||||
*/
|
||||
size_t write_buffer_size;
|
||||
|
||||
/**
|
||||
* Offset where we are with sending from write_buffer.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Offset where we are with sending from write_buffer.
|
||||
*/
|
||||
size_t write_buffer_send_offset;
|
||||
|
||||
/**
|
||||
* Last valid location in write_buffer (where do we
|
||||
* append and up to where is it safe to send?)
|
||||
*/
|
||||
/**
|
||||
* Last valid location in write_buffer (where do we
|
||||
* append and up to where is it safe to send?)
|
||||
*/
|
||||
size_t write_buffer_append_offset;
|
||||
|
||||
/**
|
||||
* How many more bytes of the body do we expect
|
||||
* to read? "-1" for unknown.
|
||||
*/
|
||||
/**
|
||||
* How many more bytes of the body do we expect
|
||||
* to read? "-1" for unknown.
|
||||
*/
|
||||
size_t remaining_upload_size;
|
||||
|
||||
/**
|
||||
* Current write position in the actual response
|
||||
* (excluding headers, content only; should be 0
|
||||
* while sending headers).
|
||||
*/
|
||||
/**
|
||||
* Current write position in the actual response
|
||||
* (excluding headers, content only; should be 0
|
||||
* while sending headers).
|
||||
*/
|
||||
size_t response_write_position;
|
||||
|
||||
/**
|
||||
* Position in the 100 CONTINUE message that
|
||||
* we need to send when receiving http 1.1 requests.
|
||||
*/
|
||||
/**
|
||||
* Position in the 100 CONTINUE message that
|
||||
* we need to send when receiving http 1.1 requests.
|
||||
*/
|
||||
size_t continue_message_write_offset;
|
||||
|
||||
/**
|
||||
* Length of the foreign address.
|
||||
*/
|
||||
/**
|
||||
* Length of the foreign address.
|
||||
*/
|
||||
socklen_t addr_len;
|
||||
|
||||
/**
|
||||
* Last time this connection had any activity
|
||||
* (reading or writing).
|
||||
*/
|
||||
/**
|
||||
* Last time this connection had any activity
|
||||
* (reading or writing).
|
||||
*/
|
||||
time_t last_activity;
|
||||
|
||||
/**
|
||||
* Socket for this connection. Set to -1 if
|
||||
* this connection has died (daemon should clean
|
||||
* up in that case).
|
||||
*/
|
||||
/**
|
||||
* Socket for this connection. Set to -1 if
|
||||
* this connection has died (daemon should clean
|
||||
* up in that case).
|
||||
*/
|
||||
int socket_fd;
|
||||
|
||||
/**
|
||||
* Has this socket been closed for reading (i.e.
|
||||
* other side closed the connection)? If so,
|
||||
* we must completely close the connection once
|
||||
* we are done sending our response (and stop
|
||||
* trying to read from this socket).
|
||||
*/
|
||||
/**
|
||||
* Has this socket been closed for reading (i.e.
|
||||
* other side closed the connection)? If so,
|
||||
* we must completely close the connection once
|
||||
* we are done sending our response (and stop
|
||||
* trying to read from this socket).
|
||||
*/
|
||||
int read_closed;
|
||||
|
||||
/**
|
||||
* State in the FSM for this connection.
|
||||
*/
|
||||
/**
|
||||
* State in the FSM for this connection.
|
||||
*/
|
||||
enum MHD_CONNECTION_STATE state;
|
||||
|
||||
/**
|
||||
* HTTP response code. Only valid if response object
|
||||
* is already set.
|
||||
*/
|
||||
/**
|
||||
* HTTP response code. Only valid if response object
|
||||
* is already set.
|
||||
*/
|
||||
unsigned int responseCode;
|
||||
|
||||
/**
|
||||
* Set to MHD_YES if the response's content reader
|
||||
* callback failed to provide data the last time
|
||||
* we tried to read from it. In that case, the
|
||||
* write socket should be marked as unready until
|
||||
* the CRC call succeeds.
|
||||
*/
|
||||
/**
|
||||
* Set to MHD_YES if the response's content reader
|
||||
* callback failed to provide data the last time
|
||||
* we tried to read from it. In that case, the
|
||||
* write socket should be marked as unready until
|
||||
* the CRC call succeeds.
|
||||
*/
|
||||
int response_unready;
|
||||
|
||||
/**
|
||||
* Are we sending with chunked encoding?
|
||||
*/
|
||||
/**
|
||||
* Are we sending with chunked encoding?
|
||||
*/
|
||||
int have_chunked_response;
|
||||
|
||||
/**
|
||||
* Are we receiving with chunked encoding? This will be set to
|
||||
* MHD_YES after we parse the headers and are processing the body
|
||||
* with chunks. After we are done with the body and we are
|
||||
* processing the footers; once the footers are also done, this will
|
||||
* be set to MHD_NO again (before the final call to the handler).
|
||||
*/
|
||||
/**
|
||||
* Are we receiving with chunked encoding? This will be set to
|
||||
* MHD_YES after we parse the headers and are processing the body
|
||||
* with chunks. After we are done with the body and we are
|
||||
* processing the footers; once the footers are also done, this will
|
||||
* be set to MHD_NO again (before the final call to the handler).
|
||||
*/
|
||||
int have_chunked_upload;
|
||||
|
||||
/**
|
||||
* If we are receiving with chunked encoding, where are we right
|
||||
* now? Set to 0 if we are waiting to receive the chunk size;
|
||||
* otherwise, this is the size of the current chunk. A value of
|
||||
* zero is also used when we're at the end of the chunks.
|
||||
*/
|
||||
/**
|
||||
* If we are receiving with chunked encoding, where are we right
|
||||
* now? Set to 0 if we are waiting to receive the chunk size;
|
||||
* otherwise, this is the size of the current chunk. A value of
|
||||
* zero is also used when we're at the end of the chunks.
|
||||
*/
|
||||
unsigned int current_chunk_size;
|
||||
|
||||
/**
|
||||
* If we are receiving with chunked encoding, where are we currently
|
||||
* with respect to the current chunk (at what offset / position)?
|
||||
*/
|
||||
/**
|
||||
* If we are receiving with chunked encoding, where are we currently
|
||||
* with respect to the current chunk (at what offset / position)?
|
||||
*/
|
||||
unsigned int current_chunk_offset;
|
||||
|
||||
/* handlers used for processing read, write & idle connection operations */
|
||||
|
||||
/**
|
||||
* Handler used for processing read connection operations
|
||||
*/
|
||||
int (*read_handler) (struct MHD_Connection * connection);
|
||||
|
||||
/**
|
||||
* Handler used for processing write connection operations
|
||||
*/
|
||||
int (*write_handler) (struct MHD_Connection * connection);
|
||||
|
||||
/**
|
||||
* Handler used for processing idle connection operations
|
||||
*/
|
||||
int (*idle_handler) (struct MHD_Connection * connection);
|
||||
|
||||
/**
|
||||
* Function used for reading HTTP request stream.
|
||||
*/
|
||||
ReceiveCallback recv_cls;
|
||||
|
||||
/**
|
||||
* Function used for writing HTTP response stream.
|
||||
*/
|
||||
TransmitCallback send_cls;
|
||||
|
||||
#if HTTPS_SUPPORT
|
||||
/* TODO rename as this might be an SSL connection */
|
||||
/**
|
||||
* State required for HTTPS/SSL/TLS support.
|
||||
*/
|
||||
MHD_gtls_session_t tls_session;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* State kept for each MHD daemon.
|
||||
*/
|
||||
struct MHD_Daemon
|
||||
{
|
||||
|
||||
/**
|
||||
* Callback function for all requests.
|
||||
*/
|
||||
/**
|
||||
* Callback function for all requests.
|
||||
*/
|
||||
MHD_AccessHandlerCallback default_handler;
|
||||
|
||||
/**
|
||||
* Closure argument to default_handler.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Closure argument to default_handler.
|
||||
*/
|
||||
void *default_handler_cls;
|
||||
|
||||
/**
|
||||
* Linked list of our current connections.
|
||||
*/
|
||||
/**
|
||||
* Linked list of our current connections.
|
||||
*/
|
||||
struct MHD_Connection *connections;
|
||||
|
||||
/**
|
||||
* Function to call to check if we should
|
||||
* accept or reject an incoming request.
|
||||
* May be NULL.
|
||||
*/
|
||||
MHD_AcceptPolicyCallback apc;
|
||||
|
||||
/**
|
||||
* Closure argument to apc.
|
||||
*/
|
||||
void *apc_cls;
|
||||
|
||||
/**
|
||||
* Function to call when we are done processing
|
||||
* a particular request. May be NULL.
|
||||
*/
|
||||
MHD_RequestCompletedCallback notify_completed;
|
||||
|
||||
/**
|
||||
* Closure argument to notify_completed.
|
||||
*/
|
||||
void *notify_completed_cls;
|
||||
|
||||
/**
|
||||
* Function to call with the full URI at the
|
||||
* beginning of request processing. May be NULL.
|
||||
* <p>
|
||||
* Returns the initial pointer to internal state
|
||||
* kept by the client for the request.
|
||||
*/
|
||||
void *(*uri_log_callback) (void *cls, const char *uri);
|
||||
|
||||
/**
|
||||
* Closure argument to uri_log_callback.
|
||||
*/
|
||||
void *uri_log_callback_cls;
|
||||
|
||||
/**
|
||||
* PID of the select thread (if we have internal select)
|
||||
*/
|
||||
#if HAVE_MESSAGES
|
||||
/**
|
||||
* Function for logging error messages (if we
|
||||
* support error reporting).
|
||||
*/
|
||||
void (*custom_error_log) (void *cls, const char *fmt, va_list va);
|
||||
|
||||
/**
|
||||
* Closure argument to custom_error_log.
|
||||
*/
|
||||
void *custom_error_log_cls;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* PID of the select thread (if we have internal select)
|
||||
*/
|
||||
pthread_t pid;
|
||||
|
||||
/**
|
||||
* Listen socket.
|
||||
*/
|
||||
/**
|
||||
* Listen socket.
|
||||
*/
|
||||
int socket_fd;
|
||||
|
||||
/**
|
||||
* Are we shutting down?
|
||||
*/
|
||||
|
||||
/**
|
||||
* Are we shutting down?
|
||||
*/
|
||||
int shutdown;
|
||||
|
||||
/**
|
||||
* Size of the per-connection memory pools.
|
||||
*/
|
||||
/**
|
||||
* Size of the per-connection memory pools.
|
||||
*/
|
||||
unsigned int pool_size;
|
||||
|
||||
/**
|
||||
* Limit on the number of parallel connections.
|
||||
*/
|
||||
/**
|
||||
* Limit on the number of parallel connections.
|
||||
*/
|
||||
unsigned int max_connections;
|
||||
|
||||
/**
|
||||
* After how many seconds of inactivity should
|
||||
* connections time out? Zero for no timeout.
|
||||
*/
|
||||
/**
|
||||
* After how many seconds of inactivity should
|
||||
* connections time out? Zero for no timeout.
|
||||
*/
|
||||
unsigned int connection_timeout;
|
||||
|
||||
/**
|
||||
* Maximum number of connections per IP, or 0 for
|
||||
* unlimited.
|
||||
*/
|
||||
/**
|
||||
* Maximum number of connections per IP, or 0 for
|
||||
* unlimited.
|
||||
*/
|
||||
unsigned int per_ip_connection_limit;
|
||||
|
||||
/**
|
||||
* Daemon's options.
|
||||
*/
|
||||
/**
|
||||
* Daemon's options.
|
||||
*/
|
||||
enum MHD_OPTION options;
|
||||
|
||||
/**
|
||||
* Listen port.
|
||||
*/
|
||||
/**
|
||||
* Listen port.
|
||||
*/
|
||||
unsigned short port;
|
||||
|
||||
#if HTTPS_SUPPORT
|
||||
/**
|
||||
* What kind of credentials are we offering
|
||||
* for SSL/TLS?
|
||||
*/
|
||||
enum MHD_GNUTLS_CredentialsType cred_type;
|
||||
|
||||
/* server x509 credintials */
|
||||
/**
|
||||
* Server x509 credentials
|
||||
*/
|
||||
MHD_gtls_cert_credentials_t x509_cred;
|
||||
|
||||
/* cipher priority cache */
|
||||
/**
|
||||
* Cipher priority cache
|
||||
*/
|
||||
MHD_gnutls_priority_t priority_cache;
|
||||
|
||||
/* Diffie-Hellman parameters */
|
||||
/**
|
||||
* Diffie-Hellman parameters
|
||||
*/
|
||||
MHD_gtls_dh_params_t dh_params;
|
||||
|
||||
/**
|
||||
* Pointer to our SSL/TLS key (in ASCII) in memory.
|
||||
*/
|
||||
const char *https_mem_key;
|
||||
|
||||
/**
|
||||
* Pointer to our SSL/TLS certificate (in ASCII) in memory.
|
||||
*/
|
||||
const char *https_mem_cert;
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -411,6 +411,21 @@ enum MHD_OPTION
|
||||
* daemon should adhere.
|
||||
*/
|
||||
MHD_OPTION_CIPHER_ALGORITHM = 12,
|
||||
|
||||
/**
|
||||
* Use the given function for logging error messages.
|
||||
* This option must be followed by two arguments; the
|
||||
* first must be a pointer to a function
|
||||
* of type "void fun(void * arg, const char * fmt, va_list ap)"
|
||||
* and the second a pointer "void*" which will
|
||||
* be passed as the "arg" argument to "fun".
|
||||
* <p>
|
||||
* Note that MHD will not generate any log messages
|
||||
* if it was compiled without the "--enable-messages"
|
||||
* flag being set.
|
||||
*/
|
||||
MHD_OPTION_EXTERNAL_LOGGER = 13,
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -910,13 +925,14 @@ MHD_set_connection_value (struct MHD_Connection *connection,
|
||||
* @param key the header to look for
|
||||
* @return NULL if no such item was found
|
||||
*/
|
||||
const char *MHD_lookup_connection_value (struct MHD_Connection *connection,
|
||||
enum MHD_ValueKind kind,
|
||||
const char *key);
|
||||
const char *
|
||||
MHD_lookup_connection_value (struct MHD_Connection *connection,
|
||||
enum MHD_ValueKind kind,
|
||||
const char *key);
|
||||
|
||||
/**
|
||||
* Queue a response to be transmitted to the client (as soon as
|
||||
* possible).
|
||||
* possible but after MHD_AccessHandlerCallback returns).
|
||||
*
|
||||
* @param connection the connection identifying the client
|
||||
* @param status_code HTTP status code (i.e. 200 for OK)
|
||||
|
||||
Reference in New Issue
Block a user