mirror of
https://git.gnunet.org/libmicrohttpd.git
synced 2026-09-25 04:09:31 +03:00
fixing misc build issues, mostly in the new src/lib/
This commit is contained in:
@@ -43,3 +43,4 @@ po/configure.acT
|
||||
po/Makevars.template
|
||||
po/POTFILES
|
||||
po/configargs.stamp
|
||||
**~
|
||||
|
||||
+655
-14
@@ -74,6 +74,57 @@
|
||||
#define MICROHTTPD2_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#if 0 /* keep Emacsens' auto-indent happy */
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* While we generally would like users to use a configure-driven
|
||||
build process which detects which headers are present and
|
||||
hence works on any platform, we use "standard" includes here
|
||||
to build out-of-the-box for beginning users on common systems.
|
||||
|
||||
If generic headers don't work on your platform, include headers
|
||||
which define 'va_list', 'size_t', 'ssize_t', 'intptr_t',
|
||||
'uint16_t', 'uint32_t', 'uint64_t', 'off_t', 'struct sockaddr',
|
||||
'socklen_t', 'fd_set' and "#define MHD_PLATFORM_H" before
|
||||
including "microhttpd.h". Then the following "standard"
|
||||
includes won't be used (which might be a good idea, especially
|
||||
on platforms where they do not exist).
|
||||
*/
|
||||
#ifndef MHD_PLATFORM_H
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
#include <ws2tcpip.h>
|
||||
#if defined(_MSC_FULL_VER) && !defined (_SSIZE_T_DEFINED)
|
||||
#define _SSIZE_T_DEFINED
|
||||
typedef intptr_t ssize_t;
|
||||
#endif /* !_SSIZE_T_DEFINED */
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__CYGWIN__) && !defined(_SYS_TYPES_FD_SET)
|
||||
/* Do not define __USE_W32_SOCKETS under Cygwin! */
|
||||
#error Cygwin with winsock fd_set is not supported
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Current version of the library.
|
||||
* 0x01093001 = 1.9.30-1.
|
||||
*/
|
||||
#define MHD_VERSION 0x01000000
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Representation of 'bool' in the public API as stdbool.h may not
|
||||
* always be available.
|
||||
@@ -95,6 +146,144 @@ enum MHD_Bool
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Constant used to indicate unknown size (use when
|
||||
* creating a response).
|
||||
*/
|
||||
#ifdef UINT64_MAX
|
||||
#define MHD_SIZE_UNKNOWN UINT64_MAX
|
||||
#else
|
||||
#define MHD_SIZE_UNKNOWN ((uint64_t) -1LL)
|
||||
#endif
|
||||
|
||||
#ifdef SIZE_MAX
|
||||
#define MHD_CONTENT_READER_END_OF_STREAM SIZE_MAX
|
||||
#define MHD_CONTENT_READER_END_WITH_ERROR (SIZE_MAX - 1)
|
||||
#else
|
||||
#define MHD_CONTENT_READER_END_OF_STREAM ((size_t) -1LL)
|
||||
#define MHD_CONTENT_READER_END_WITH_ERROR (((size_t) -1LL) - 1)
|
||||
#endif
|
||||
|
||||
#ifndef _MHD_EXTERN
|
||||
#if defined(_WIN32) && defined(MHD_W32LIB)
|
||||
#define _MHD_EXTERN extern
|
||||
#elif defined (_WIN32) && defined(MHD_W32DLL)
|
||||
/* Define MHD_W32DLL when using MHD as W32 .DLL to speed up linker a little */
|
||||
#define _MHD_EXTERN __declspec(dllimport)
|
||||
#else
|
||||
#define _MHD_EXTERN extern
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef MHD_SOCKET_DEFINED
|
||||
/**
|
||||
* MHD_socket is type for socket FDs
|
||||
*/
|
||||
#if !defined(_WIN32) || defined(_SYS_TYPES_FD_SET)
|
||||
#define MHD_POSIX_SOCKETS 1
|
||||
typedef int MHD_socket;
|
||||
#define MHD_INVALID_SOCKET (-1)
|
||||
#else /* !defined(_WIN32) || defined(_SYS_TYPES_FD_SET) */
|
||||
#define MHD_WINSOCK_SOCKETS 1
|
||||
#include <winsock2.h>
|
||||
typedef SOCKET MHD_socket;
|
||||
#define MHD_INVALID_SOCKET (INVALID_SOCKET)
|
||||
#endif /* !defined(_WIN32) || defined(_SYS_TYPES_FD_SET) */
|
||||
#define MHD_SOCKET_DEFINED 1
|
||||
#endif /* MHD_SOCKET_DEFINED */
|
||||
|
||||
/**
|
||||
* Define MHD_NO_DEPRECATION before including "microhttpd.h" to disable deprecation messages
|
||||
*/
|
||||
#ifdef MHD_NO_DEPRECATION
|
||||
#define _MHD_DEPR_MACRO(msg)
|
||||
#define _MHD_NO_DEPR_IN_MACRO 1
|
||||
#define _MHD_DEPR_IN_MACRO(msg)
|
||||
#define _MHD_NO_DEPR_FUNC 1
|
||||
#define _MHD_DEPR_FUNC(msg)
|
||||
#endif /* MHD_NO_DEPRECATION */
|
||||
|
||||
#ifndef _MHD_DEPR_MACRO
|
||||
#if defined(_MSC_FULL_VER) && _MSC_VER+0 >= 1500
|
||||
/* VS 2008 or later */
|
||||
/* Stringify macros */
|
||||
#define _MHD_INSTRMACRO(a) #a
|
||||
#define _MHD_STRMACRO(a) _MHD_INSTRMACRO(a)
|
||||
/* deprecation message */
|
||||
#define _MHD_DEPR_MACRO(msg) __pragma(message(__FILE__ "(" _MHD_STRMACRO(__LINE__)"): warning: " msg))
|
||||
#define _MHD_DEPR_IN_MACRO(msg) _MHD_DEPR_MACRO(msg)
|
||||
#elif defined(__clang__) || defined (__GNUC_PATCHLEVEL__)
|
||||
/* clang or GCC since 3.0 */
|
||||
#define _MHD_GCC_PRAG(x) _Pragma (#x)
|
||||
#if (defined(__clang__) && (__clang_major__+0 >= 5 || \
|
||||
(!defined(__apple_build_version__) && (__clang_major__+0 > 3 || (__clang_major__+0 == 3 && __clang_minor__ >= 3))))) || \
|
||||
__GNUC__+0 > 4 || (__GNUC__+0 == 4 && __GNUC_MINOR__+0 >= 8)
|
||||
/* clang >= 3.3 (or XCode's clang >= 5.0) or
|
||||
GCC >= 4.8 */
|
||||
#define _MHD_DEPR_MACRO(msg) _MHD_GCC_PRAG(GCC warning msg)
|
||||
#define _MHD_DEPR_IN_MACRO(msg) _MHD_DEPR_MACRO(msg)
|
||||
#else /* older clang or GCC */
|
||||
/* clang < 3.3, XCode's clang < 5.0, 3.0 <= GCC < 4.8 */
|
||||
#define _MHD_DEPR_MACRO(msg) _MHD_GCC_PRAG(message msg)
|
||||
#if (defined(__clang__) && (__clang_major__+0 > 2 || (__clang_major__+0 == 2 && __clang_minor__ >= 9))) /* FIXME: clang >= 2.9, earlier versions not tested */
|
||||
/* clang handles inline pragmas better than GCC */
|
||||
#define _MHD_DEPR_IN_MACRO(msg) _MHD_DEPR_MACRO(msg)
|
||||
#endif /* clang >= 2.9 */
|
||||
#endif /* older clang or GCC */
|
||||
/* #elif defined(SOMEMACRO) */ /* add compiler-specific macros here if required */
|
||||
#endif /* clang || GCC >= 3.0 */
|
||||
#endif /* !_MHD_DEPR_MACRO */
|
||||
|
||||
#ifndef _MHD_DEPR_MACRO
|
||||
#define _MHD_DEPR_MACRO(msg)
|
||||
#endif /* !_MHD_DEPR_MACRO */
|
||||
|
||||
#ifndef _MHD_DEPR_IN_MACRO
|
||||
#define _MHD_NO_DEPR_IN_MACRO 1
|
||||
#define _MHD_DEPR_IN_MACRO(msg)
|
||||
#endif /* !_MHD_DEPR_IN_MACRO */
|
||||
|
||||
#ifndef _MHD_DEPR_FUNC
|
||||
#if defined(_MSC_FULL_VER) && _MSC_VER+0 >= 1400
|
||||
/* VS 2005 or later */
|
||||
#define _MHD_DEPR_FUNC(msg) __declspec(deprecated(msg))
|
||||
#elif defined(_MSC_FULL_VER) && _MSC_VER+0 >= 1310
|
||||
/* VS .NET 2003 deprecation do not support custom messages */
|
||||
#define _MHD_DEPR_FUNC(msg) __declspec(deprecated)
|
||||
#elif (__GNUC__+0 >= 5) || (defined (__clang__) && \
|
||||
(__clang_major__+0 > 2 || (__clang_major__+0 == 2 && __clang_minor__ >= 9))) /* FIXME: earlier versions not tested */
|
||||
/* GCC >= 5.0 or clang >= 2.9 */
|
||||
#define _MHD_DEPR_FUNC(msg) __attribute__((deprecated(msg)))
|
||||
#elif defined (__clang__) || __GNUC__+0 > 3 || (__GNUC__+0 == 3 && __GNUC_MINOR__+0 >= 1)
|
||||
/* 3.1 <= GCC < 5.0 or clang < 2.9 */
|
||||
/* old GCC-style deprecation do not support custom messages */
|
||||
#define _MHD_DEPR_FUNC(msg) __attribute__((__deprecated__))
|
||||
/* #elif defined(SOMEMACRO) */ /* add compiler-specific macros here if required */
|
||||
#endif /* clang < 2.9 || GCC >= 3.1 */
|
||||
#endif /* !_MHD_DEPR_FUNC */
|
||||
|
||||
#ifndef _MHD_DEPR_FUNC
|
||||
#define _MHD_NO_DEPR_FUNC 1
|
||||
#define _MHD_DEPR_FUNC(msg)
|
||||
#endif /* !_MHD_DEPR_FUNC */
|
||||
|
||||
/**
|
||||
* Not all architectures and `printf()`'s support the `long long` type.
|
||||
* This gives the ability to replace `long long` with just a `long`,
|
||||
* standard `int` or a `short`.
|
||||
*/
|
||||
#ifndef MHD_UNSIGNED_LONG_LONG
|
||||
#define MHD_UNSIGNED_LONG_LONG unsigned long long
|
||||
#endif
|
||||
/**
|
||||
* Format string for printing a variable of type #MHD_LONG_LONG.
|
||||
* You should only redefine this if you also define #MHD_LONG_LONG.
|
||||
*/
|
||||
#ifndef MHD_UNSIGNED_LONG_LONG_PRINTF
|
||||
#define MHD_UNSIGNED_LONG_LONG_PRINTF "%llu"
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @brief Handle for a connection / HTTP request.
|
||||
*
|
||||
@@ -111,6 +300,14 @@ enum MHD_Bool
|
||||
struct MHD_Request;
|
||||
|
||||
|
||||
/**
|
||||
* A connection corresponds to the network/stream abstraction.
|
||||
* A single network (i.e. TCP) stream may be used for multiple
|
||||
* requests, which in HTTP/1.1 must be processed sequentially.
|
||||
*/
|
||||
struct MHD_Connection;
|
||||
|
||||
|
||||
/**
|
||||
* Return values for reporting errors, also used
|
||||
* for logging.
|
||||
@@ -164,7 +361,7 @@ enum MHD_StatusCode
|
||||
* The application requested a TLS cipher suite which is not
|
||||
* supported by the selected backend.
|
||||
*/
|
||||
MHD_SC_TLS_CIPHERS_INVALID = 50002
|
||||
MHD_SC_TLS_CIPHERS_INVALID = 50002,
|
||||
|
||||
/**
|
||||
* The application attempted to setup TLS paramters before
|
||||
@@ -300,6 +497,19 @@ enum MHD_StatusCode
|
||||
*/
|
||||
MHD_SC_THREAD_POOL_CREATE_MUTEX_FAILURE = 50027,
|
||||
|
||||
/**
|
||||
* There was an attempt to upgrade a connection on
|
||||
* a daemon where upgrades are disallowed.
|
||||
*/
|
||||
MHD_SC_UPGRADE_ON_DAEMON_WITH_UPGRADE_DISALLOWED = 50028,
|
||||
|
||||
/**
|
||||
* Queueing a response failed because the respective
|
||||
* daemon is already too deep inside of the shutdown
|
||||
* activity and the reponse cannot be sent any longer.
|
||||
*/
|
||||
MHD_SC_DAEMON_ALREADY_SHUTDOWN = 50029,
|
||||
|
||||
/**
|
||||
* We failed to initialize the main thread for listening.
|
||||
*/
|
||||
@@ -1069,8 +1279,9 @@ MHD_daemon_gnutls_credentials (struct MHD_Daemon *daemon,
|
||||
*
|
||||
* @param daemon daemon to configure callback for
|
||||
* @param cb must be of type `gnutls_certificate_retrieve_function2 *`.
|
||||
* @return #MHD_SC_OK on success
|
||||
*/
|
||||
_MHD_EXTERN void
|
||||
_MHD_EXTERN enum MHD_StatusCode
|
||||
MHD_daemon_gnutls_key_and_cert_from_callback (struct MHD_Daemon *daemon,
|
||||
void *cb);
|
||||
|
||||
@@ -1174,9 +1385,9 @@ MHD_daemon_accept_policy (struct MHD_Daemon *daemon,
|
||||
* @return value to set for the "request_context" of @a request
|
||||
*/
|
||||
typedef void *
|
||||
(MHD_EarlyUriLogCallback)(void *cls,
|
||||
const char *uri,
|
||||
struct MHD_Request *request);
|
||||
(*MHD_EarlyUriLogCallback)(void *cls,
|
||||
const char *uri,
|
||||
struct MHD_Request *request);
|
||||
|
||||
|
||||
/**
|
||||
@@ -1194,6 +1405,29 @@ MHD_daemon_set_early_uri_logger (struct MHD_Daemon *daemon,
|
||||
void *cb_cls);
|
||||
|
||||
|
||||
/**
|
||||
* The `enum MHD_ConnectionNotificationCode` specifies types
|
||||
* of connection notifications.
|
||||
* @ingroup request
|
||||
*/
|
||||
enum MHD_ConnectionNotificationCode
|
||||
{
|
||||
|
||||
/**
|
||||
* A new connection has been started.
|
||||
* @ingroup request
|
||||
*/
|
||||
MHD_CONNECTION_NOTIFY_STARTED = 0,
|
||||
|
||||
/**
|
||||
* A connection is closed.
|
||||
* @ingroup request
|
||||
*/
|
||||
MHD_CONNECTION_NOTIFY_CLOSED = 1
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Signature of the callback used by MHD to notify the
|
||||
* application about started/stopped connections
|
||||
@@ -1214,9 +1448,9 @@ MHD_daemon_set_early_uri_logger (struct MHD_Daemon *daemon,
|
||||
* @ingroup request
|
||||
*/
|
||||
typedef void
|
||||
(*MHD_ConnectionCompletedCallback) (void *cls,
|
||||
struct MHD_Connection *connection,
|
||||
enum MHD_ConnectionNotificationCode toe);
|
||||
(*MHD_NotifyConnectionCallback) (void *cls,
|
||||
struct MHD_Connection *connection,
|
||||
enum MHD_ConnectionNotificationCode toe);
|
||||
|
||||
|
||||
/**
|
||||
@@ -1310,9 +1544,9 @@ MHD_daemon_connection_default_timeout (struct MHD_Daemon *daemon,
|
||||
* @return number of characters in @a s (excluding 0-terminator)
|
||||
*/
|
||||
typedef size_t
|
||||
MHD_UnescapeCallback (void *cls,
|
||||
struct MHD_Request *req,
|
||||
char *s);
|
||||
(*MHD_UnescapeCallback) (void *cls,
|
||||
struct MHD_Request *req,
|
||||
char *s);
|
||||
|
||||
|
||||
/**
|
||||
@@ -1377,6 +1611,69 @@ MHD_connection_set_timeout (struct MHD_Connection *connection,
|
||||
|
||||
/* **************** Request handling functions ***************** */
|
||||
|
||||
|
||||
/**
|
||||
* The `enum MHD_ValueKind` specifies the source of
|
||||
* the key-value pairs in the HTTP protocol.
|
||||
*/
|
||||
enum MHD_ValueKind
|
||||
{
|
||||
|
||||
/**
|
||||
* HTTP header (request/response).
|
||||
*/
|
||||
MHD_HEADER_KIND = 1,
|
||||
|
||||
/**
|
||||
* Cookies. Note that the original HTTP header containing
|
||||
* the cookie(s) will still be available and intact.
|
||||
*/
|
||||
MHD_COOKIE_KIND = 2,
|
||||
|
||||
/**
|
||||
* POST data. This is available only if a content encoding
|
||||
* supported by MHD is used (currently only URL encoding),
|
||||
* and only if the posted content fits within the available
|
||||
* memory pool. Note that in that case, the upload data
|
||||
* given to the #MHD_AccessHandlerCallback will be
|
||||
* empty (since it has already been processed).
|
||||
*/
|
||||
MHD_POSTDATA_KIND = 4,
|
||||
|
||||
/**
|
||||
* GET (URI) arguments.
|
||||
*/
|
||||
MHD_GET_ARGUMENT_KIND = 8,
|
||||
|
||||
/**
|
||||
* HTTP footer (only for HTTP 1.1 chunked encodings).
|
||||
*/
|
||||
MHD_FOOTER_KIND = 16
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Iterator over key-value pairs. This iterator can be used to
|
||||
* iterate over all of the cookies, headers, or POST-data fields of a
|
||||
* request, and also to iterate over the headers that have been added
|
||||
* to a response.
|
||||
*
|
||||
* @param cls closure
|
||||
* @param kind kind of the header we are looking at
|
||||
* @param key key for the value, can be an empty string
|
||||
* @param value corresponding value, can be NULL
|
||||
* @return #MHD_YES to continue iterating,
|
||||
* #MHD_NO to abort the iteration
|
||||
* @ingroup request
|
||||
*/
|
||||
typedef int
|
||||
(*MHD_KeyValueIterator) (void *cls,
|
||||
enum MHD_ValueKind kind,
|
||||
const char *key,
|
||||
const char *value);
|
||||
|
||||
|
||||
/**
|
||||
* Get all of the headers from the request.
|
||||
*
|
||||
@@ -1595,6 +1892,14 @@ MHD_request_resume (struct MHD_Request *request);
|
||||
/* **************** Response manipulation functions ***************** */
|
||||
|
||||
|
||||
/**
|
||||
* Data transmitted in response to an HTTP request.
|
||||
* Usually the final action taken in response to
|
||||
* receiving a request.
|
||||
*/
|
||||
struct MHD_Response;
|
||||
|
||||
|
||||
/**
|
||||
* Converts a @a response to an action. If @a consume
|
||||
* is set, the reference to the @a response is consumed
|
||||
@@ -1614,7 +1919,7 @@ MHD_request_resume (struct MHD_Request *request);
|
||||
*/
|
||||
_MHD_EXTERN struct MHD_Action *
|
||||
MHD_action_from_response (struct MHD_Response *response,
|
||||
enum MHD_bool destroy_after_use);
|
||||
enum MHD_Bool destroy_after_use);
|
||||
|
||||
|
||||
/**
|
||||
@@ -1628,9 +1933,67 @@ _MHD_EXTERN void
|
||||
MHD_response_option_v10_only (struct MHD_Response *response);
|
||||
|
||||
|
||||
/**
|
||||
* The `enum MHD_RequestTerminationCode` specifies reasons
|
||||
* why a request has been terminated (or completed).
|
||||
* @ingroup request
|
||||
*/
|
||||
enum MHD_RequestTerminationCode
|
||||
{
|
||||
|
||||
/**
|
||||
* We finished sending the response.
|
||||
* @ingroup request
|
||||
*/
|
||||
MHD_REQUEST_TERMINATED_COMPLETED_OK = 0,
|
||||
|
||||
/**
|
||||
* Error handling the connection (resources
|
||||
* exhausted, other side closed connection,
|
||||
* application error accepting request, etc.)
|
||||
* @ingroup request
|
||||
*/
|
||||
MHD_REQUEST_TERMINATED_WITH_ERROR = 1,
|
||||
|
||||
/**
|
||||
* No activity on the connection for the number
|
||||
* of seconds specified using
|
||||
* #MHD_OPTION_CONNECTION_TIMEOUT.
|
||||
* @ingroup request
|
||||
*/
|
||||
MHD_REQUEST_TERMINATED_TIMEOUT_REACHED = 2,
|
||||
|
||||
/**
|
||||
* We had to close the session since MHD was being
|
||||
* shut down.
|
||||
* @ingroup request
|
||||
*/
|
||||
MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN = 3,
|
||||
|
||||
/**
|
||||
* We tried to read additional data, but the other side closed the
|
||||
* connection. This error is similar to
|
||||
* #MHD_REQUEST_TERMINATED_WITH_ERROR, but specific to the case where
|
||||
* the connection died because the other side did not send expected
|
||||
* data.
|
||||
* @ingroup request
|
||||
*/
|
||||
MHD_REQUEST_TERMINATED_READ_ERROR = 4,
|
||||
|
||||
/**
|
||||
* The client terminated the connection by closing the socket
|
||||
* for writing (TCP half-closed); MHD aborted sending the
|
||||
* response according to RFC 2616, section 8.1.4.
|
||||
* @ingroup request
|
||||
*/
|
||||
MHD_REQUEST_TERMINATED_CLIENT_ABORT = 5
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Signature of the callback used by MHD to notify the
|
||||
* application about completed requests.
|
||||
* Signature of the callback used by MHD to notify the application
|
||||
* about completed requests.
|
||||
*
|
||||
* @param cls client-defined closure
|
||||
* @param toe reason for request termination
|
||||
@@ -1659,6 +2022,69 @@ MHD_response_option_termination_callback (struct MHD_Response *response,
|
||||
void *termination_cb_cls);
|
||||
|
||||
|
||||
/**
|
||||
* Callback used by libmicrohttpd in order to obtain content. The
|
||||
* callback is to copy at most @a max bytes of content into @a buf. The
|
||||
* total number of bytes that has been placed into @a buf should be
|
||||
* returned.
|
||||
*
|
||||
* Note that returning zero will cause libmicrohttpd to try again.
|
||||
* Thus, returning zero should only be used in conjunction
|
||||
* with MHD_suspend_connection() to avoid busy waiting.
|
||||
*
|
||||
* @param cls extra argument to the callback
|
||||
* @param pos position in the datastream to access;
|
||||
* note that if a `struct MHD_Response` object is re-used,
|
||||
* it is possible for the same content reader to
|
||||
* be queried multiple times for the same data;
|
||||
* however, if a `struct MHD_Response` is not re-used,
|
||||
* libmicrohttpd guarantees that "pos" will be
|
||||
* the sum of all non-negative return values
|
||||
* obtained from the content reader so far.
|
||||
* @param buf where to copy the data
|
||||
* @param max maximum number of bytes to copy to @a buf (size of @a buf)
|
||||
* @return number of bytes written to @a buf;
|
||||
* 0 is legal unless we are running in internal select mode (since
|
||||
* this would cause busy-waiting); 0 in external select mode
|
||||
* will cause this function to be called again once the external
|
||||
* select calls MHD again;
|
||||
* #MHD_CONTENT_READER_END_OF_STREAM (-1) for the regular
|
||||
* end of transmission (with chunked encoding, MHD will then
|
||||
* terminate the chunk and send any HTTP footers that might be
|
||||
* present; without chunked encoding and given an unknown
|
||||
* response size, MHD will simply close the connection; note
|
||||
* that while returning #MHD_CONTENT_READER_END_OF_STREAM is not technically
|
||||
* legal if a response size was specified, MHD accepts this
|
||||
* and treats it just as #MHD_CONTENT_READER_END_WITH_ERROR;
|
||||
* #MHD_CONTENT_READER_END_WITH_ERROR (-2) to indicate a server
|
||||
* error generating the response; this will cause MHD to simply
|
||||
* close the connection immediately. If a response size was
|
||||
* given or if chunked encoding is in use, this will indicate
|
||||
* an error to the client. Note, however, that if the client
|
||||
* does not know a response size and chunked encoding is not in
|
||||
* use, then clients will not be able to tell the difference between
|
||||
* #MHD_CONTENT_READER_END_WITH_ERROR and #MHD_CONTENT_READER_END_OF_STREAM.
|
||||
* This is not a limitation of MHD but rather of the HTTP protocol.
|
||||
*/
|
||||
typedef ssize_t
|
||||
(*MHD_ContentReaderCallback) (void *cls,
|
||||
uint64_t pos,
|
||||
char *buf,
|
||||
size_t max);
|
||||
|
||||
|
||||
/**
|
||||
* This method is called by libmicrohttpd if we are done with a
|
||||
* content reader. It should be used to free resources associated
|
||||
* with the content reader.
|
||||
*
|
||||
* @param cls closure
|
||||
* @ingroup response
|
||||
*/
|
||||
typedef void
|
||||
(*MHD_ContentReaderFreeCallback) (void *cls);
|
||||
|
||||
|
||||
/**
|
||||
* Create a response action. The response object can be extended with
|
||||
* header information and then be used any number of times.
|
||||
@@ -2505,4 +2931,219 @@ MHD_daemon_get_information_sz (struct MHD_Daemon *daemon,
|
||||
MHD_daemon_get_information_sz((daemon), (info_type), (return_value), sizeof(union MHD_DaemonInformation));
|
||||
|
||||
|
||||
/**
|
||||
* Callback for serious error condition. The default action is to print
|
||||
* an error message and `abort()`.
|
||||
*
|
||||
* @param cls user specified value
|
||||
* @param file where the error occured
|
||||
* @param line where the error occured
|
||||
* @param reason error detail, may be NULL
|
||||
* @ingroup logging
|
||||
*/
|
||||
typedef void
|
||||
(*MHD_PanicCallback) (void *cls,
|
||||
const char *file,
|
||||
unsigned int line,
|
||||
const char *reason);
|
||||
|
||||
|
||||
/**
|
||||
* Sets the global error handler to a different implementation. @a cb
|
||||
* will only be called in the case of typically fatal, serious
|
||||
* internal consistency issues. These issues should only arise in the
|
||||
* case of serious memory corruption or similar problems with the
|
||||
* architecture. While @a cb is allowed to return and MHD will then
|
||||
* try to continue, this is never safe.
|
||||
*
|
||||
* The default implementation that is used if no panic function is set
|
||||
* simply prints an error message and calls `abort()`. Alternative
|
||||
* implementations might call `exit()` or other similar functions.
|
||||
*
|
||||
* @param cb new error handler
|
||||
* @param cls passed to @a cb
|
||||
* @ingroup logging
|
||||
*/
|
||||
_MHD_EXTERN void
|
||||
MHD_set_panic_func (MHD_PanicCallback cb,
|
||||
void *cls);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Types of information about MHD features,
|
||||
* used by #MHD_is_feature_supported().
|
||||
*/
|
||||
enum MHD_Feature
|
||||
{
|
||||
/**
|
||||
* Get whether messages are supported. If supported then in debug
|
||||
* mode messages can be printed to stderr or to external logger.
|
||||
*/
|
||||
MHD_FEATURE_MESSAGES = 1,
|
||||
|
||||
/**
|
||||
* Get whether HTTPS is supported. If supported then flag
|
||||
* #MHD_USE_TLS and options #MHD_OPTION_HTTPS_MEM_KEY,
|
||||
* #MHD_OPTION_HTTPS_MEM_CERT, #MHD_OPTION_HTTPS_MEM_TRUST,
|
||||
* #MHD_OPTION_HTTPS_MEM_DHPARAMS, #MHD_OPTION_HTTPS_CRED_TYPE,
|
||||
* #MHD_OPTION_HTTPS_PRIORITIES can be used.
|
||||
*/
|
||||
MHD_FEATURE_TLS = 2,
|
||||
|
||||
/**
|
||||
* Get whether option #MHD_OPTION_HTTPS_CERT_CALLBACK is
|
||||
* supported.
|
||||
*/
|
||||
MHD_FEATURE_HTTPS_CERT_CALLBACK = 3,
|
||||
|
||||
/**
|
||||
* Get whether IPv6 is supported. If supported then flag
|
||||
* #MHD_USE_IPv6 can be used.
|
||||
*/
|
||||
MHD_FEATURE_IPv6 = 4,
|
||||
|
||||
/**
|
||||
* Get whether IPv6 without IPv4 is supported. If not supported
|
||||
* then IPv4 is always enabled in IPv6 sockets and
|
||||
* flag #MHD_USE_DUAL_STACK if always used when #MHD_USE_IPv6 is
|
||||
* specified.
|
||||
*/
|
||||
MHD_FEATURE_IPv6_ONLY = 5,
|
||||
|
||||
/**
|
||||
* Get whether `poll()` is supported. If supported then flag
|
||||
* #MHD_USE_POLL can be used.
|
||||
*/
|
||||
MHD_FEATURE_POLL = 6,
|
||||
|
||||
/**
|
||||
* Get whether `epoll()` is supported. If supported then Flags
|
||||
* #MHD_USE_EPOLL and
|
||||
* #MHD_USE_EPOLL_INTERNAL_THREAD can be used.
|
||||
*/
|
||||
MHD_FEATURE_EPOLL = 7,
|
||||
|
||||
/**
|
||||
* Get whether shutdown on listen socket to signal other
|
||||
* threads is supported. If not supported flag
|
||||
* #MHD_USE_ITC is automatically forced.
|
||||
*/
|
||||
MHD_FEATURE_SHUTDOWN_LISTEN_SOCKET = 8,
|
||||
|
||||
/**
|
||||
* Get whether socketpair is used internally instead of pipe to
|
||||
* signal other threads.
|
||||
*/
|
||||
MHD_FEATURE_SOCKETPAIR = 9,
|
||||
|
||||
/**
|
||||
* Get whether TCP Fast Open is supported. If supported then
|
||||
* flag #MHD_USE_TCP_FASTOPEN and option
|
||||
* #MHD_OPTION_TCP_FASTOPEN_QUEUE_SIZE can be used.
|
||||
*/
|
||||
MHD_FEATURE_TCP_FASTOPEN = 10,
|
||||
|
||||
/**
|
||||
* Get whether HTTP Basic authorization is supported. If supported
|
||||
* then functions #MHD_basic_auth_get_username_password and
|
||||
* #MHD_queue_basic_auth_fail_response can be used.
|
||||
*/
|
||||
MHD_FEATURE_BASIC_AUTH = 11,
|
||||
|
||||
/**
|
||||
* Get whether HTTP Digest authorization is supported. If
|
||||
* supported then options #MHD_OPTION_DIGEST_AUTH_RANDOM,
|
||||
* #MHD_OPTION_NONCE_NC_SIZE and
|
||||
* #MHD_digest_auth_check() can be used.
|
||||
*/
|
||||
MHD_FEATURE_DIGEST_AUTH = 12,
|
||||
|
||||
/**
|
||||
* Get whether postprocessor is supported. If supported then
|
||||
* functions #MHD_create_post_processor(), #MHD_post_process() and
|
||||
* #MHD_destroy_post_processor() can
|
||||
* be used.
|
||||
*/
|
||||
MHD_FEATURE_POSTPROCESSOR = 13,
|
||||
|
||||
/**
|
||||
* Get whether password encrypted private key for HTTPS daemon is
|
||||
* supported. If supported then option
|
||||
* ::MHD_OPTION_HTTPS_KEY_PASSWORD can be used.
|
||||
*/
|
||||
MHD_FEATURE_HTTPS_KEY_PASSWORD = 14,
|
||||
|
||||
/**
|
||||
* Get whether reading files beyond 2 GiB boundary is supported.
|
||||
* If supported then #MHD_create_response_from_fd(),
|
||||
* #MHD_create_response_from_fd64 #MHD_create_response_from_fd_at_offset()
|
||||
* and #MHD_create_response_from_fd_at_offset64() can be used with sizes and
|
||||
* offsets larger than 2 GiB. If not supported value of size+offset is
|
||||
* limited to 2 GiB.
|
||||
*/
|
||||
MHD_FEATURE_LARGE_FILE = 15,
|
||||
|
||||
/**
|
||||
* Get whether MHD set names on generated threads.
|
||||
*/
|
||||
MHD_FEATURE_THREAD_NAMES = 16,
|
||||
|
||||
/**
|
||||
* Get whether HTTP "Upgrade" is supported.
|
||||
* If supported then #MHD_ALLOW_UPGRADE, #MHD_upgrade_action() and
|
||||
* #MHD_create_response_for_upgrade() can be used.
|
||||
*/
|
||||
MHD_FEATURE_UPGRADE = 17,
|
||||
|
||||
/**
|
||||
* Get whether it's safe to use same FD for multiple calls of
|
||||
* #MHD_create_response_from_fd() and whether it's safe to use single
|
||||
* response generated by #MHD_create_response_from_fd() with multiple
|
||||
* connections at same time.
|
||||
* If #MHD_is_feature_supported() return #MHD_NO for this feature then
|
||||
* usage of responses with same file FD in multiple parallel threads may
|
||||
* results in incorrect data sent to remote client.
|
||||
* It's always safe to use same file FD in multiple responses if MHD
|
||||
* is run in any single thread mode.
|
||||
*/
|
||||
MHD_FEATURE_RESPONSES_SHARED_FD = 18,
|
||||
|
||||
/**
|
||||
* Get whether MHD support automatic detection of bind port number.
|
||||
* @sa #MHD_DAEMON_INFO_BIND_PORT
|
||||
*/
|
||||
MHD_FEATURE_AUTODETECT_BIND_PORT = 19,
|
||||
|
||||
/**
|
||||
* Get whether MHD support SIGPIPE suppression.
|
||||
* If SIGPIPE suppression is not supported, application must handle
|
||||
* SIGPIPE signal by itself.
|
||||
*/
|
||||
MHD_FEATURE_AUTOSUPPRESS_SIGPIPE = 20,
|
||||
|
||||
/**
|
||||
* Get whether MHD use system's sendfile() function to send
|
||||
* file-FD based responses over non-TLS connections.
|
||||
* @note Since v0.9.56
|
||||
*/
|
||||
MHD_FEATURE_SENDFILE = 21
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get information about supported MHD features.
|
||||
* Indicate that MHD was compiled with or without support for
|
||||
* particular feature. Some features require additional support
|
||||
* by kernel. Kernel support is not checked by this function.
|
||||
*
|
||||
* @param feature type of requested information
|
||||
* @return #MHD_YES if feature is supported by MHD, #MHD_NO if
|
||||
* feature is not supported or feature is unknown.
|
||||
* @ingroup specialized
|
||||
*/
|
||||
_MHD_EXTERN enum MHD_Bool
|
||||
MHD_is_feature_supported (enum MHD_Feature feature);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -87,7 +87,7 @@ struct MHD_TLS_Plugin
|
||||
* @return NULL on errors (in particular, invalid cipher suite)
|
||||
*/
|
||||
typedef struct MHD_TLS_Plugin *
|
||||
MHD_TLS_PluginInit (const char *ciphers);
|
||||
(*MHD_TLS_PluginInit) (const char *ciphers);
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -31,13 +31,15 @@
|
||||
*
|
||||
* @param cls NULL
|
||||
* @param request the request to apply the action to
|
||||
* @return #MHD_SC_OK on success
|
||||
*/
|
||||
static void
|
||||
static enum MHD_StatusCode
|
||||
cont_action (void *cls,
|
||||
struct MHD_Request *request)
|
||||
{
|
||||
/* not sure yet, but this function body may
|
||||
just legitimately stay empty... */
|
||||
return MHD_SC_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -49,7 +51,7 @@ cont_action (void *cls,
|
||||
struct MHD_Action *
|
||||
MHD_action_continue (void)
|
||||
{
|
||||
static MHD_Action acont = {
|
||||
static struct MHD_Action acont = {
|
||||
.action = &cont_action,
|
||||
.action_cls = NULL
|
||||
};
|
||||
|
||||
@@ -31,27 +31,30 @@
|
||||
*
|
||||
* @param cls the `struct MHD_Response`
|
||||
* @param request the request we are processing
|
||||
* @return #MHD_SC_OK on success
|
||||
*/
|
||||
static void
|
||||
static enum MHD_StatusCode
|
||||
response_action (void *cls,
|
||||
struct MHD_Request *request)
|
||||
{
|
||||
struct MHD_Response *response = cls;
|
||||
struct MHD_Daemon *daemon = response->daemon;
|
||||
struct MHD_Daemon *daemon = request->daemon;
|
||||
|
||||
/* If daemon was shut down in parallel,
|
||||
* response will be aborted now or on later stage. */
|
||||
if (daemon->shutdown)
|
||||
return MHD_YES; /* If daemon was shut down in parallel,
|
||||
* response will be aborted now or on later stage. */
|
||||
return MHD_SC_DAEMON_ALREADY_SHUTDOWN;
|
||||
|
||||
#ifdef UPGRADE_SUPPORT
|
||||
if ( (NULL != response->upgrade_handler) &&
|
||||
(0 == (daemon->options & MHD_ALLOW_UPGRADE)) )
|
||||
daemon->disallow_upgrade )
|
||||
{
|
||||
#ifdef HAVE_MESSAGES
|
||||
MHD_DLOG (daemon,
|
||||
MHD_SC_UPGRADE_ON_DAEMON_WITH_UPGRADE_DISALLOWED,
|
||||
_("Attempted 'upgrade' connection on daemon without MHD_ALLOW_UPGRADE option!\n"));
|
||||
#endif
|
||||
return MHD_NO;
|
||||
return MHD_SC_UPGRADE_ON_DAEMON_WITH_UPGRADE_DISALLOWED;
|
||||
}
|
||||
#endif /* UPGRADE_SUPPORT */
|
||||
request->response = response;
|
||||
@@ -66,9 +69,7 @@ response_action (void *cls,
|
||||
request->resp_sender = MHD_resp_sender_sendfile;
|
||||
#endif /* _MHD_HAVE_SENDFILE */
|
||||
|
||||
if ( ( (NULL != request->method) &&
|
||||
(MHD_str_equal_caseless_ (request->method,
|
||||
MHD_HTTP_METHOD_HEAD)) ) ||
|
||||
if ( (MHD_METHOD_HEAD == request->method) ||
|
||||
(MHD_HTTP_OK > response->status_code) ||
|
||||
(MHD_HTTP_NO_CONTENT == response->status_code) ||
|
||||
(MHD_HTTP_NOT_MODIFIED == response->status_code) )
|
||||
@@ -79,19 +80,17 @@ response_action (void *cls,
|
||||
request->response_write_position = response->total_size;
|
||||
}
|
||||
if ( (MHD_REQUEST_HEADERS_PROCESSED == request->state) &&
|
||||
(NULL != connection->method) &&
|
||||
( (MHD_str_equal_caseless_ (request->method,
|
||||
MHD_HTTP_METHOD_POST)) ||
|
||||
(MHD_str_equal_caseless_ (request->method,
|
||||
MHD_HTTP_METHOD_PUT))) )
|
||||
(MHD_METHOD_POST == request->method) ||
|
||||
(MHD_METHOD_PUT == request->method) )
|
||||
{
|
||||
/* response was queued "early", refuse to read body / footers or
|
||||
further requests! */
|
||||
connection->read_closed = true;
|
||||
request->state = MHD_CONNECTION_FOOTERS_RECEIVED;
|
||||
request->connection->read_closed = true;
|
||||
request->state = MHD_REQUEST_FOOTERS_RECEIVED;
|
||||
}
|
||||
if (! request->in_idle)
|
||||
(void) MHD_connection_handle_idle (connection);
|
||||
(void) MHD_connection_handle_idle (request->connection);
|
||||
return MHD_SC_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -114,7 +113,7 @@ response_action (void *cls,
|
||||
*/
|
||||
_MHD_EXTERN struct MHD_Action *
|
||||
MHD_action_from_response (struct MHD_Response *response,
|
||||
enum MHD_bool destroy_after_use)
|
||||
enum MHD_Bool destroy_after_use)
|
||||
{
|
||||
response->action.action = &response_action;
|
||||
response->action.action_cls = response;
|
||||
|
||||
@@ -51,8 +51,9 @@ struct UploadAction
|
||||
* function we are to call for upload data
|
||||
* @param request the request for which we are to process
|
||||
* upload data
|
||||
* @return #MHD_SC_OK on success
|
||||
*/
|
||||
static void
|
||||
static enum MHD_StatusCode
|
||||
upload_action (void *cls,
|
||||
struct MHD_Request *request)
|
||||
{
|
||||
@@ -60,6 +61,7 @@ upload_action (void *cls,
|
||||
|
||||
(void) ua;
|
||||
// FIXME: implement!
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -79,11 +81,11 @@ MHD_action_process_upload (MHD_UploadCallback uc,
|
||||
|
||||
if (NULL == (ua = malloc (sizeof (struct UploadAction))))
|
||||
return NULL;
|
||||
ua->action = &upload_action;
|
||||
ua->action_cls = ua;
|
||||
ua->action.action = &upload_action;
|
||||
ua->action.action_cls = ua;
|
||||
ua->uc = uc;
|
||||
ua->uc_cls = uc_cls;
|
||||
return ua;
|
||||
return &ua->action;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -31,11 +31,13 @@
|
||||
*
|
||||
* @param cls NULL
|
||||
* @param request the request to apply the action to
|
||||
* @return #MHD_SC_OK on success
|
||||
*/
|
||||
static void
|
||||
static enum MHD_StatusCode
|
||||
suspend_action (void *cls,
|
||||
struct MHD_Request *request)
|
||||
{
|
||||
struct MHD_Connection *connection = request->connection;
|
||||
struct MHD_Daemon *daemon = connection->daemon;
|
||||
|
||||
MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
|
||||
@@ -44,7 +46,7 @@ suspend_action (void *cls,
|
||||
/* suspending again while we didn't even complete resuming yet */
|
||||
connection->resuming = false;
|
||||
MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
|
||||
return;
|
||||
return MHD_SC_OK;
|
||||
}
|
||||
if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
|
||||
{
|
||||
@@ -88,6 +90,7 @@ suspend_action (void *cls,
|
||||
}
|
||||
#endif
|
||||
MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
|
||||
return MHD_SC_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ MHD_connection_set_timeout (struct MHD_Connection *connection,
|
||||
connection->connection_timeout = (time_t) timeout_s;
|
||||
return;
|
||||
}
|
||||
|
||||
MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
|
||||
if (! connection->suspended)
|
||||
{
|
||||
|
||||
+32
-31
@@ -23,6 +23,7 @@
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "internal.h"
|
||||
#include <dlfcn.h>
|
||||
|
||||
|
||||
/**
|
||||
@@ -150,7 +151,7 @@ MHD_daemon_tcp_fastopen (struct MHD_Daemon *daemon,
|
||||
unsigned int queue_length)
|
||||
{
|
||||
daemon->fast_open_method = fom;
|
||||
daemon->fast_open_queue_length = queue_length;
|
||||
daemon->fo_queue_length = queue_length;
|
||||
switch (fom)
|
||||
{
|
||||
case MHD_FOM_DISABLE:
|
||||
@@ -204,7 +205,6 @@ MHD_daemon_bind_socket_address (struct MHD_Daemon *daemon,
|
||||
const struct sockaddr *sa,
|
||||
size_t sa_len)
|
||||
{
|
||||
daemon->sa_given = true;
|
||||
memcpy (&daemon->listen_sa,
|
||||
sa,
|
||||
sa_len);
|
||||
@@ -338,37 +338,37 @@ MHD_daemon_set_tls_backend (struct MHD_Daemon *daemon,
|
||||
const char *ciphers)
|
||||
{
|
||||
#ifndef HTTPS_SUPPORT
|
||||
return MHD_TLS_DISABLED;
|
||||
return MHD_SC_TLS_DISABLED;
|
||||
#else
|
||||
char filename[1024];
|
||||
int res;
|
||||
MHD_TLS_PluginInit init;
|
||||
|
||||
/* todo: .dll on W32? */
|
||||
res = MHD_snprintf (filename,
|
||||
sizeof (filename),
|
||||
"%s/libmicrohttpd_tls_%s.so",
|
||||
MHD_PLUGIN_INSTALL_PREFIX,
|
||||
tls_backend);
|
||||
res = MHD_snprintf_ (filename,
|
||||
sizeof (filename),
|
||||
"%s/libmicrohttpd_tls_%s.so",
|
||||
MHD_PLUGIN_INSTALL_PREFIX,
|
||||
tls_backend);
|
||||
if (0 >= res)
|
||||
return MHD_BACKEND_UNSUPPORTED; /* string too long? */
|
||||
return MHD_SC_TLS_BACKEND_UNSUPPORTED; /* string too long? */
|
||||
if (NULL ==
|
||||
(daemon->tls_backend_lib = dlopen (filename,
|
||||
RTLD_NOW | RTLD_LOCAL)))
|
||||
return MHD_BACKEND_UNSUPPORTED; /* plugin not found */
|
||||
return MHD_SC_BACKEND_UNSUPPORTED; /* plugin not found */
|
||||
if (NULL == (init = dlsym (daemon->tls_backend_lib,
|
||||
"MHD_TLS_init_" MHD_TLS_ABI_VERSION_STR)))
|
||||
|
||||
{
|
||||
dlclose (daemon->tls_backend_lib);
|
||||
daemon->tls_backend_lib = NULL;
|
||||
return MHD_BACKEND_UNSUPPORTED; /* possibly wrong version installed */
|
||||
return MHD_SC_BACKEND_UNSUPPORTED; /* possibly wrong version installed */
|
||||
}
|
||||
if (NULL == (daemon->tls_backend = init (ciphers)))
|
||||
if (NULL == (daemon->tls_api = init (ciphers)))
|
||||
{
|
||||
dlclose (daemon->tls_backend_lib);
|
||||
daemon->tls_backend_lib = NULL;
|
||||
return MHD_CIPHERS_INVALID; /* possibly wrong version installed */
|
||||
return MHD_SC_CIPHERS_INVALID; /* possibly wrong version installed */
|
||||
}
|
||||
return MHD_SC_OK;
|
||||
#endif
|
||||
@@ -396,8 +396,8 @@ MHD_daemon_tls_key_and_cert_from_memory (struct MHD_Daemon *daemon,
|
||||
{
|
||||
struct MHD_TLS_Plugin *plugin;
|
||||
|
||||
if (NULL == (plugin = daemon->tls_backend))
|
||||
return MHD_TLS_BACKEND_UNINITIALIZED;
|
||||
if (NULL == (plugin = daemon->tls_api))
|
||||
return MHD_SC_TLS_BACKEND_UNINITIALIZED;
|
||||
return plugin->init_kcp (plugin->cls,
|
||||
mem_key,
|
||||
mem_cert,
|
||||
@@ -420,8 +420,8 @@ MHD_daemon_tls_mem_dhparams (struct MHD_Daemon *daemon,
|
||||
{
|
||||
struct MHD_TLS_Plugin *plugin;
|
||||
|
||||
if (NULL == (plugin = daemon->tls_backend))
|
||||
return MHD_TLS_BACKEND_UNINITIALIZED;
|
||||
if (NULL == (plugin = daemon->tls_api))
|
||||
return MHD_SC_TLS_BACKEND_UNINITIALIZED;
|
||||
return plugin->init_dhparams (plugin->cls,
|
||||
dh);
|
||||
}
|
||||
@@ -442,8 +442,8 @@ MHD_daemon_tls_mem_trust (struct MHD_Daemon *daemon,
|
||||
{
|
||||
struct MHD_TLS_Plugin *plugin;
|
||||
|
||||
if (NULL == (plugin = daemon->tls_backend))
|
||||
return MHD_TLS_BACKEND_UNINITIALIZED;
|
||||
if (NULL == (plugin = daemon->tls_api))
|
||||
return MHD_SC_TLS_BACKEND_UNINITIALIZED;
|
||||
return plugin->init_mem_trust (plugin->cls,
|
||||
mem_trust);
|
||||
}
|
||||
@@ -462,9 +462,9 @@ MHD_daemon_gnutls_credentials (struct MHD_Daemon *daemon,
|
||||
{
|
||||
struct MHD_TLS_Plugin *plugin;
|
||||
|
||||
if (NULL == (plugin = daemon->tls_backend))
|
||||
return MHD_TLS_BACKEND_UNINITIALIZED;
|
||||
return MHD_TLS_BACKEND_OPERATION_UNSUPPORTED;
|
||||
if (NULL == (plugin = daemon->tls_api))
|
||||
return MHD_SC_TLS_BACKEND_UNINITIALIZED;
|
||||
return MHD_SC_TLS_BACKEND_OPERATION_UNSUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
@@ -483,16 +483,17 @@ MHD_daemon_gnutls_credentials (struct MHD_Daemon *daemon,
|
||||
*
|
||||
* @param daemon daemon to configure callback for
|
||||
* @param cb must be of type `gnutls_certificate_retrieve_function2 *`.
|
||||
* @return #MHD_SC_OK on success
|
||||
*/
|
||||
void
|
||||
enum MHD_StatusCode
|
||||
MHD_daemon_gnutls_key_and_cert_from_callback (struct MHD_Daemon *daemon,
|
||||
void *cb)
|
||||
{
|
||||
struct MHD_TLS_Plugin *plugin;
|
||||
|
||||
if (NULL == (plugin = daemon->tls_backend))
|
||||
return MHD_TLS_BACKEND_UNINITIALIZED;
|
||||
return MHD_TLS_BACKEND_OPERATION_UNSUPPORTED;
|
||||
if (NULL == (plugin = daemon->tls_api))
|
||||
return MHD_SC_TLS_BACKEND_UNINITIALIZED;
|
||||
return MHD_SC_TLS_BACKEND_OPERATION_UNSUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
@@ -544,8 +545,8 @@ MHD_daemon_set_early_uri_logger (struct MHD_Daemon *daemon,
|
||||
MHD_EarlyUriLogCallback cb,
|
||||
void *cb_cls)
|
||||
{
|
||||
daemon->early_uri_logger_cb = cb;
|
||||
daemon->early_uri_logger_cb_cls = cb_cls;
|
||||
daemon->early_uri_logger = cb;
|
||||
daemon->early_uri_logger_cls = cb_cls;
|
||||
}
|
||||
|
||||
|
||||
@@ -710,7 +711,7 @@ MHD_daemon_digest_auth_nc_length (struct MHD_Daemon *daemon,
|
||||
MHD_DLOG (daemon,
|
||||
_("Specified value for NC_SIZE too large\n"));
|
||||
#endif
|
||||
return MHD_DIGEST_AUTH_NC_LENGTH_TOO_BIG;
|
||||
return MHD_SC_DIGEST_AUTH_NC_LENGTH_TOO_BIG;
|
||||
}
|
||||
if (0 < nc_length)
|
||||
{
|
||||
@@ -725,13 +726,13 @@ MHD_daemon_digest_auth_nc_length (struct MHD_Daemon *daemon,
|
||||
_("Failed to allocate memory for nonce-nc map: %s\n"),
|
||||
MHD_strerror_ (errno));
|
||||
#endif
|
||||
return MHD_DIGEST_AUTH_NC_ALLOCATION_FAILURE;
|
||||
return MHD_SC_DIGEST_AUTH_NC_ALLOCATION_FAILURE;
|
||||
}
|
||||
}
|
||||
daemon->digest_nc_length = nc_length;
|
||||
return MHD_SC_OK;
|
||||
#else
|
||||
return MHD_DIGEST_AUTH_NOT_SUPPORTED_BY_BUILD;
|
||||
return MHD_SC_DIGEST_AUTH_NOT_SUPPORTED_BY_BUILD;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -643,9 +643,9 @@ setup_thread_pool (struct MHD_Daemon *daemon)
|
||||
/* Coarse-grained count of connections per thread (note error
|
||||
* due to integer division). Also keep track of how many
|
||||
* connections are leftover after an equal split. */
|
||||
unsigned int conns_per_thread = daemon->connection_limit
|
||||
unsigned int conns_per_thread = daemon->global_connection_limit
|
||||
/ daemon->threading_model;
|
||||
unsigned int leftover_conns = daemon->connection_limit
|
||||
unsigned int leftover_conns = daemon->global_connection_limit
|
||||
% daemon->threading_model;
|
||||
unsigned int i;
|
||||
enum MHD_StatusCode sc;
|
||||
@@ -674,9 +674,9 @@ setup_thread_pool (struct MHD_Daemon *daemon)
|
||||
/* Divide available connections evenly amongst the threads.
|
||||
* Thread indexes in [0, leftover_conns) each get one of the
|
||||
* leftover connections. */
|
||||
d->connection_limit = conns_per_thread;
|
||||
d->global_connection_limit = conns_per_thread;
|
||||
if (i < leftover_conns)
|
||||
++d->connection_limit;
|
||||
++d->global_connection_limit;
|
||||
|
||||
if (! daemon->disable_itc)
|
||||
{
|
||||
|
||||
@@ -97,6 +97,8 @@ volatile int global_init_count = 0;
|
||||
MHD_MUTEX_STATIC_DEFN_INIT_(global_init_mutex_);
|
||||
#endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Check whether global initialisation was performed
|
||||
|
||||
+27
-24
@@ -92,17 +92,20 @@ MHD_state_to_string (enum MHD_CONNECTION_STATE state)
|
||||
*/
|
||||
void
|
||||
MHD_DLOG (const struct MHD_Daemon *daemon,
|
||||
enum MHD_StatusCode sc,
|
||||
const char *format,
|
||||
...)
|
||||
{
|
||||
va_list va;
|
||||
|
||||
if (0 == (daemon->options & MHD_USE_ERROR_LOG))
|
||||
if (NULL == daemon->logger)
|
||||
return;
|
||||
va_start (va, format);
|
||||
daemon->custom_error_log (daemon->custom_error_log_cls,
|
||||
format,
|
||||
va);
|
||||
va_start (va,
|
||||
format);
|
||||
daemon->logger (daemon->logger_cls,
|
||||
sc,
|
||||
format,
|
||||
va);
|
||||
va_end (va);
|
||||
}
|
||||
#endif
|
||||
@@ -204,9 +207,9 @@ MHD_parse_arguments_ (struct MHD_Connection *connection,
|
||||
{
|
||||
/* last argument, without '=' */
|
||||
MHD_unescape_plus (args);
|
||||
daemon->unescape_callback (daemon->unescape_callback_cls,
|
||||
connection,
|
||||
args);
|
||||
daemon->unescape_cb (daemon->unescape_cb_cls,
|
||||
connection,
|
||||
args);
|
||||
if (MHD_YES != cb (connection,
|
||||
args,
|
||||
NULL,
|
||||
@@ -219,13 +222,13 @@ MHD_parse_arguments_ (struct MHD_Connection *connection,
|
||||
equals[0] = '\0';
|
||||
equals++;
|
||||
MHD_unescape_plus (args);
|
||||
daemon->unescape_callback (daemon->unescape_callback_cls,
|
||||
connection,
|
||||
args);
|
||||
daemon->unescape_cb (daemon->unescape_cb_cls,
|
||||
connection,
|
||||
args);
|
||||
MHD_unescape_plus (equals);
|
||||
daemon->unescape_callback (daemon->unescape_callback_cls,
|
||||
connection,
|
||||
equals);
|
||||
daemon->unescape_cb (daemon->unescape_cb_cls,
|
||||
connection,
|
||||
equals);
|
||||
if (MHD_YES != cb (connection,
|
||||
args,
|
||||
equals,
|
||||
@@ -235,16 +238,16 @@ MHD_parse_arguments_ (struct MHD_Connection *connection,
|
||||
break;
|
||||
}
|
||||
/* amper is non-NULL here */
|
||||
amper[0] = '\0';
|
||||
amper[0] = '\0';d
|
||||
amper++;
|
||||
if ( (NULL == equals) ||
|
||||
(equals >= amper) )
|
||||
{
|
||||
/* got 'foo&bar' or 'foo&bar=val', add key 'foo' with NULL for value */
|
||||
MHD_unescape_plus (args);
|
||||
daemon->unescape_callback (daemon->unescape_callback_cls,
|
||||
connection,
|
||||
args);
|
||||
daemon->unescape_cb (daemon->unescape_cb_cls,
|
||||
connection,
|
||||
args);
|
||||
if (MHD_YES != cb (connection,
|
||||
args,
|
||||
NULL,
|
||||
@@ -260,13 +263,13 @@ MHD_parse_arguments_ (struct MHD_Connection *connection,
|
||||
equals[0] = '\0';
|
||||
equals++;
|
||||
MHD_unescape_plus (args);
|
||||
daemon->unescape_callback (daemon->unescape_callback_cls,
|
||||
connection,
|
||||
args);
|
||||
daemon->unescape_cb (daemon->unescape_cb_cls,
|
||||
connection,
|
||||
args);
|
||||
MHD_unescape_plus (equals);
|
||||
daemon->unescape_callback (daemon->unescape_callback_cls,
|
||||
connection,
|
||||
equals);
|
||||
daemon->unescape_cb (daemon->unescape_cb_cls,
|
||||
connection,
|
||||
equals);
|
||||
if (MHD_YES != cb (connection,
|
||||
args,
|
||||
equals,
|
||||
|
||||
+154
-6
@@ -32,6 +32,8 @@
|
||||
#include "microhttpd2.h"
|
||||
#include "microhttpd_tls.h"
|
||||
#include "mhd_assert.h"
|
||||
#include "mhd_compat.h"
|
||||
#include "memorypool.h"
|
||||
|
||||
#ifdef HTTPS_SUPPORT
|
||||
#include <gnutls/gnutls.h>
|
||||
@@ -67,9 +69,23 @@
|
||||
#include "mhd_threads.h"
|
||||
#include "mhd_locks.h"
|
||||
#include "mhd_sockets.h"
|
||||
#include "mhd_str.h"
|
||||
#include "mhd_itc_types.h"
|
||||
|
||||
|
||||
#ifdef HAVE_MESSAGES
|
||||
/**
|
||||
* fprintf()-like helper function for logging debug
|
||||
* messages.
|
||||
*/
|
||||
void
|
||||
MHD_DLOG (const struct MHD_Daemon *daemon,
|
||||
enum MHD_StatusCode sc,
|
||||
const char *format,
|
||||
...);
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Close FD and abort execution if error is detected.
|
||||
* @param fd the FD to close
|
||||
@@ -344,6 +360,33 @@ struct MHD_HTTP_Header
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* What is this request waiting for?
|
||||
*/
|
||||
enum MHD_RequestEventLoopInfo
|
||||
{
|
||||
/**
|
||||
* We are waiting to be able to read.
|
||||
*/
|
||||
MHD_EVENT_LOOP_INFO_READ = 0,
|
||||
|
||||
/**
|
||||
* We are waiting to be able to write.
|
||||
*/
|
||||
MHD_EVENT_LOOP_INFO_WRITE = 1,
|
||||
|
||||
/**
|
||||
* We are waiting for the application to provide data.
|
||||
*/
|
||||
MHD_EVENT_LOOP_INFO_BLOCK = 2,
|
||||
|
||||
/**
|
||||
* We are finished and are awaiting cleanup.
|
||||
*/
|
||||
MHD_EVENT_LOOP_INFO_CLEANUP = 3
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* State kept for each HTTP request.
|
||||
*/
|
||||
@@ -351,7 +394,7 @@ struct MHD_Request
|
||||
{
|
||||
|
||||
/**
|
||||
* Reference to the MHD_Daemon struct.
|
||||
* Reference to the `struct MHD_Daemon`.
|
||||
*/
|
||||
struct MHD_Daemon *daemon;
|
||||
|
||||
@@ -360,6 +403,12 @@ struct MHD_Request
|
||||
*/
|
||||
struct MHD_Connection *connection;
|
||||
|
||||
/**
|
||||
* Response to return for this request, set once
|
||||
* it is available.
|
||||
*/
|
||||
struct MHD_Response *response;
|
||||
|
||||
/**
|
||||
* Linked list of parsed headers.
|
||||
*/
|
||||
@@ -389,9 +438,10 @@ struct MHD_Request
|
||||
void *client_context;
|
||||
|
||||
/**
|
||||
* Request method. Should be GET/POST/etc. Allocated in pool.
|
||||
* Request method as string. Should be GET/POST/etc. Allocated in
|
||||
* pool.
|
||||
*/
|
||||
char *method;
|
||||
char *method_s;
|
||||
|
||||
/**
|
||||
* Requested URL (everything after "GET" only). Allocated
|
||||
@@ -556,6 +606,11 @@ struct MHD_Request
|
||||
*/
|
||||
enum MHD_REQUEST_STATE state;
|
||||
|
||||
/**
|
||||
* HTTP method, as an enum.
|
||||
*/
|
||||
enum MHD_Method method;
|
||||
|
||||
/**
|
||||
* What is this request waiting for?
|
||||
*/
|
||||
@@ -591,6 +646,54 @@ struct MHD_Request
|
||||
};
|
||||
|
||||
|
||||
#ifdef EPOLL_SUPPORT
|
||||
/**
|
||||
* State of the socket with respect to epoll (bitmask).
|
||||
*/
|
||||
enum MHD_EpollState
|
||||
{
|
||||
|
||||
/**
|
||||
* The socket is not involved with a defined state in epoll() right
|
||||
* now.
|
||||
*/
|
||||
MHD_EPOLL_STATE_UNREADY = 0,
|
||||
|
||||
/**
|
||||
* epoll() told us that data was ready for reading, and we did
|
||||
* not consume all of it yet.
|
||||
*/
|
||||
MHD_EPOLL_STATE_READ_READY = 1,
|
||||
|
||||
/**
|
||||
* epoll() told us that space was available for writing, and we did
|
||||
* not consume all of it yet.
|
||||
*/
|
||||
MHD_EPOLL_STATE_WRITE_READY = 2,
|
||||
|
||||
/**
|
||||
* Is this connection currently in the 'eready' EDLL?
|
||||
*/
|
||||
MHD_EPOLL_STATE_IN_EREADY_EDLL = 4,
|
||||
|
||||
/**
|
||||
* Is this connection currently in the epoll() set?
|
||||
*/
|
||||
MHD_EPOLL_STATE_IN_EPOLL_SET = 8,
|
||||
|
||||
/**
|
||||
* Is this connection currently suspended?
|
||||
*/
|
||||
MHD_EPOLL_STATE_SUSPENDED = 16,
|
||||
|
||||
/**
|
||||
* Is this connection in some error state?
|
||||
*/
|
||||
MHD_EPOLL_STATE_ERROR = 128
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* State kept per HTTP connection.
|
||||
*/
|
||||
@@ -990,7 +1093,11 @@ struct MHD_Daemon
|
||||
*/
|
||||
bool allow_address_reuse;
|
||||
|
||||
|
||||
/**
|
||||
* Are we shutting down?
|
||||
*/
|
||||
volatile bool shutdown;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -1000,10 +1107,11 @@ struct MHD_Daemon
|
||||
*
|
||||
* @param cls action-specfic closure
|
||||
* @param request the request on which the action is to be performed
|
||||
* @return #MHD_SC_OK on success, otherwise an error code
|
||||
*/
|
||||
typedef void
|
||||
typedef enum MHD_StatusCode
|
||||
(*ActionCallback) (void *cls,
|
||||
const struct MHD_Request *request);
|
||||
struct MHD_Request *request);
|
||||
|
||||
|
||||
/**
|
||||
@@ -1153,4 +1261,44 @@ struct MHD_Response
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Callback invoked when iterating over @a key / @a value
|
||||
* argument pairs during parsing.
|
||||
*
|
||||
* @param connection context of the iteration
|
||||
* @param key 0-terminated key string, never NULL
|
||||
* @param value 0-terminated value string, may be NULL
|
||||
* @param kind origin of the key-value pair
|
||||
* @return #MHD_YES on success (continue to iterate)
|
||||
* #MHD_NO to signal failure (and abort iteration)
|
||||
*/
|
||||
typedef int
|
||||
(*MHD_ArgumentIterator_)(struct MHD_Connection *connection,
|
||||
const char *key,
|
||||
const char *value,
|
||||
enum MHD_ValueKind kind);
|
||||
|
||||
|
||||
/**
|
||||
* Parse and unescape the arguments given by the client
|
||||
* as part of the HTTP request URI.
|
||||
*
|
||||
* @param kind header kind to pass to @a cb
|
||||
* @param connection connection to add headers to
|
||||
* @param[in,out] args argument URI string (after "?" in URI),
|
||||
* clobbered in the process!
|
||||
* @param cb function to call on each key-value pair found
|
||||
* @param[out] num_headers set to the number of headers found
|
||||
* @return #MHD_NO on failure (@a cb returned #MHD_NO),
|
||||
* #MHD_YES for success (parsing succeeded, @a cb always
|
||||
* returned #MHD_YES)
|
||||
*/
|
||||
int
|
||||
MHD_parse_arguments_ (struct MHD_Connection *connection,
|
||||
enum MHD_ValueKind kind,
|
||||
char *args,
|
||||
MHD_ArgumentIterator_ cb,
|
||||
unsigned int *num_headers);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
* @author Christian Grothoff
|
||||
* @author Karlson2k (Evgeny Grin)
|
||||
*/
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
/**
|
||||
|
||||
+2
-2
@@ -129,7 +129,7 @@ MHD_response_add_header (struct MHD_Response *response,
|
||||
return add_response_entry (response,
|
||||
MHD_HEADER_KIND,
|
||||
header,
|
||||
content) ? MHD_TRUE : MHD_FALSE;
|
||||
content) ? MHD_YES : MHD_NO;
|
||||
}
|
||||
|
||||
|
||||
@@ -151,7 +151,7 @@ MHD_response_add_trailer (struct MHD_Response *response,
|
||||
return add_response_entry (response,
|
||||
MHD_FOOTER_KIND,
|
||||
footer,
|
||||
content) ? MHD_TRUE : MHD_FALSE;
|
||||
content) ? MHD_YES : MHD_NO;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ MHD_response_from_buffer (enum MHD_HTTP_StatusCode sc,
|
||||
struct MHD_Response *response;
|
||||
void *tmp;
|
||||
|
||||
mhd_assert ( (NULL != data) ||
|
||||
mhd_assert ( (NULL != buffer) ||
|
||||
(0 == size) );
|
||||
if (NULL ==
|
||||
(response = MHD_calloc_ (1,
|
||||
@@ -68,19 +68,19 @@ MHD_response_from_buffer (enum MHD_HTTP_StatusCode sc,
|
||||
return NULL;
|
||||
}
|
||||
memcpy (tmp,
|
||||
data,
|
||||
buffer,
|
||||
size);
|
||||
data = tmp;
|
||||
buffer = tmp;
|
||||
}
|
||||
if (MHD_RESPMEM_PERSISTENT != mode)
|
||||
{
|
||||
response->crfc = &free;
|
||||
response->crc_cls = data;
|
||||
response->crc_cls = buffer;
|
||||
}
|
||||
response->status_code = sc;
|
||||
response->reference_count = 1;
|
||||
response->total_size = size;
|
||||
response->data = data;
|
||||
response->data = buffer;
|
||||
response->data_size = size;
|
||||
return response;
|
||||
}
|
||||
|
||||
@@ -180,7 +180,8 @@ MHD_response_from_fd (enum MHD_HTTP_StatusCode sc,
|
||||
((int64_t) (size + offset) < 0) )
|
||||
return NULL;
|
||||
|
||||
response = MHD_response_from_callback (size,
|
||||
response = MHD_response_from_callback (sc,
|
||||
size,
|
||||
4 * 1024,
|
||||
&file_reader,
|
||||
NULL,
|
||||
@@ -188,7 +189,6 @@ MHD_response_from_fd (enum MHD_HTTP_StatusCode sc,
|
||||
if (NULL == response)
|
||||
return NULL;
|
||||
response->fd = fd;
|
||||
response->status_code = sc;
|
||||
response->fd_off = offset;
|
||||
response->crc_cls = response;
|
||||
return response;
|
||||
|
||||
+2
-2
@@ -65,8 +65,8 @@ MHD_get_version (void)
|
||||
* feature is not supported or feature is unknown.
|
||||
* @ingroup specialized
|
||||
*/
|
||||
_MHD_EXTERN int
|
||||
MHD_is_feature_supported(enum MHD_FEATURE feature)
|
||||
_MHD_EXTERN enum MHD_Bool
|
||||
MHD_is_feature_supported(enum MHD_Feature feature)
|
||||
{
|
||||
switch(feature)
|
||||
{
|
||||
|
||||
@@ -751,10 +751,10 @@ MHD_socket_noninheritable_ (MHD_socket sock);
|
||||
/**
|
||||
* Create a listen socket, with noninheritable flag if possible.
|
||||
*
|
||||
* @param use_ipv6 if set to non-zero IPv6 is used
|
||||
* @param pf protocol family to use
|
||||
* @return created socket or MHD_INVALID_SOCKET in case of errors
|
||||
*/
|
||||
MHD_socket
|
||||
MHD_socket_create_listen_ (bool use_ipv6);
|
||||
MHD_socket_create_listen_ (int pf);
|
||||
|
||||
#endif /* ! MHD_SOCKETS_H */
|
||||
|
||||
Reference in New Issue
Block a user