microhttpd2.h: edits and split

This commit is contained in:
Evgeny Grin (Karlson2k)
2024-03-31 15:26:22 +02:00
parent 05a570b773
commit ba8099ade3
2 changed files with 2117 additions and 1143 deletions
+341
View File
@@ -0,0 +1,341 @@
#ifndef MHD_EXTERN_
# if ! defined(_WIN32)
# define MHD_EXTERN_ extern
# else /* defined(_WIN32) */
# if ! defined(MHD_W32LIB)
# define MHD_EXTERN_ extern
# else /* defined(_WIN32) && efined(MHD_W32LIB) */
/* Define MHD_W32DLL when using MHD as W32 .DLL to speed up linker a little */
# define MHD_EXTERN_ extern __declspec(dllimport)
# endif
# endif
#endif
#ifndef MHD_FIXED_ENUM_
# define MHD_FIXED_ENUM_ /* empty */
#endif /* MHD_FIXED_ENUM_ */
#ifndef MHD_FLAGS_ENUM_
# define MHD_FLAGS_ENUM_ /* empty */
#endif /* MHD_FLAGS_ENUM_ */
#ifndef MHD_FIXED_FLAGS_ENUM_
# define MHD_FIXED_FLAGS_ENUM_ MHD_FIXED_ENUM_ MHD_FLAGS_ENUM_
#endif
#ifndef MHD_FIXED_ENUM_APP_SET_
/* The enum is set by an application to the fixed list of values */
# define MHD_FIXED_ENUM_APP_SET_ MHD_FIXED_ENUM_
#endif
#ifndef MHD_FLAGS_ENUM_APP_SET_
/* The enum is set by an application, it is a bitmap */
# define MHD_FLAGS_ENUM_APP_SET_ MHD_FLAGS_ENUM_
#endif
#ifndef MHD_FIXED_FLAGS_ENUM_APP_SET_
/* The enum is set by an application to the fixed bitmap values */
# define MHD_FIXED_FLAGS_ENUM_APP_SET_ MHD_FIXED_FLAGS_ENUM_
#endif
#ifndef MHD_FIXED_ENUM_MHD_SET_
/* The enum is set by MHD to the fixed list of values */
# define MHD_FIXED_ENUM_MHD_SET_ /* enum can be extended in next MHD versions */
#endif
#ifndef MHD_FLAGS_ENUM_MHD_SET_
/* The enum is set by MHD, it is a bitmap */
# define MHD_FLAGS_ENUM_MHD_SET_ MHD_FLAGS_ENUM_
#endif
#ifndef MHD_FIXED_FLAGS_ENUM_MHD_SET_
/* The enum is set by MHD to the fixed bitmap values */
# define MHD_FIXED_FLAGS_ENUM_MHD_SET_ MHD_FLAGS_ENUM_ /* enum can be extended in next MHD versions */
#endif
#ifndef MHD_FIXED_ENUM_MHD_APP_SET_
/* The enum is set by both MHD and app to the fixed list of values */
# define MHD_FIXED_ENUM_MHD_APP_SET_ /* enum can be extended in next MHD versions */
#endif
#ifndef MHD_FLAGS_ENUM_MHD_APP_SET_
/* The enum is set by both MHD and app, it is a bitmap */
# define MHD_FLAGS_ENUM_MHD_APP_SET_ MHD_FLAGS_ENUM_
#endif
#ifndef MHD_FIXED_FLAGS_ENUM_MHD_APP_SET_
/* The enum is set by both MHD and app to the fixed bitmap values */
# define MHD_FIXED_FLAGS_ENUM_MHD_APP_SET_ MHD_FLAGS_ENUM_ /* enum can be extended in next MHD versions */
#endif
#ifndef MHD_FN_CONST_
# define MHD_FN_CONST_ /* empty */
#endif /* ! MHD_FN_CONST_ */
#ifndef MHD_FN_PURE_
# define MHD_FN_PURE_ /* empty */
#endif /* ! MHD_FN_PURE_ */
#ifndef MHD_FN_MUST_CHECK_RESULT_
# define MHD_FN_MUST_CHECK_RESULT_ /* empty */
#endif /* ! MHD_FN_MUST_CHECK_RESULT_ */
#ifndef MHD_FN_PAR_NONNULL_
# define MHD_FN_PAR_NONNULL_(param_num) /* empty */
#endif /* ! MHD_FN_PAR_NONNULL_ */
#ifndef MHD_FN_PAR_NONNULL_ALL_
# define MHD_FN_PAR_NONNULL_ALL_ /* empty */
#endif /* ! MHD_FN_PAR_NONNULL_ALL_ */
#ifndef MHD_FN_PAR_IN_
# define MHD_FN_PAR_IN_(param_num) /* empty */
#endif /* !MHD_FN_PAR_IN_ */
#ifndef MHD_FN_PAR_IN_SIZE_
# define MHD_FN_PAR_IN_SIZE_(param_num,size_num) /* empty */
#endif /* !MHD_FN_PAR_IN_SIZE_ */
#ifndef MHD_FN_PAR_OUT_
# define MHD_FN_PAR_OUT_(param_num) /* empty */
#endif /* !MHD_FN_PAR_OUT_ */
#ifndef MHD_FN_PAR_OUT_SIZE_
# define MHD_FN_PAR_OUT_SIZE_(param_num,size_num) /* empty */
#endif /* !MHD_FN_PAR_OUT_SIZE_ */
#ifndef MHD_FN_PAR_INOUT_
# define MHD_FN_PAR_INOUT_(param_num) /* empty */
#endif /* !MHD_FN_PAR_INOUT_ */
#ifndef MHD_FN_PAR_INOUT_SIZE_
# define MHD_FN_PAR_INOUT_SIZE_(param_num,size_num) /* empty */
#endif /* !MHD_FN_PAR_INOUT_SIZE_ */
#ifndef MHD_FN_PAR_FD_READ_
# define MHD_FN_PAR_FD_READ_(param_num) /* empty */
#endif /* !MHD_FN_PAR_FD_READ_ */
#ifndef MHD_FN_PAR_CSTR_
# define MHD_FN_PAR_CSTR_(param_num) /* empty */
#endif /* ! MHD_FN_PAR_CSTR_ */
#ifndef MHD_FN_RETURNS_NONNULL_
# define MHD_FN_RETURNS_NONNULL_ /* empty */
#endif /* ! MHD_FN_RETURNS_NONNULL_ */
#ifndef MHD_FN_WARN_UNUSED_RESULT_
# define MHD_FN_WARN_UNUSED_RESULT_ /* empty */
#endif /* ! MHD_FN_WARN_UNUSED_RESULT_ */
/**
* Which threading and polling mode should be used by MHD?
*/
enum MHD_FIXED_ENUM_MHD_SET_ MHD_ThreadingPollingMode
{
/**
* Use an external event loop.
* Application uses #MHD_get_watched_fds()/#MHD_get_watched_fds_update()
* and #MHD_process_watched_fds() with level triggered sockets
* polling (like select() or poll()).
*/
MHD_TM_EXTERNAL_EVENT_LOOP_WFD_LEVEL = 10
,
/**
* Use an external event loop.
* Application uses #MHD_get_watched_fds()/#MHD_get_watched_fds_update()
* and #MHD_process_watched_fds() with edge triggered sockets polling.
*/
MHD_TM_EXTERNAL_EVENT_LOOP_WFD_EDGE = 11
,
};
/* FUTURE:
(with eventually option "number of masters")
MHD_TM_WORKER_THREADS_WITH_MASTER_LISTENER = 3 */
// Alternative style
struct MHD_WatchedFD
{
/**
* The watched socket.
* Ignored if set by application to #MHD_INVALID_SOCKET. TODO: Improve wording
*/
MHD_socket fd;
/**
* Indicates that socket should be watched for specific network state
* (when set by #MHD_get_watched_fds(), #MHD_get_watched_fds_update())
* / the network state of the socket (when used for
* #MHD_process_watched_fds())
*/
enum MHD_FdState state;
};
/**
* Get the full list of the sockets that must be watched by application.
*
* The application may use this function each time to get a full list of
* the sockets for watch or may use #MHD_get_watched_fds_update() to
* get the incremental updates.
*
* // TODO: add introspection reference
*
* @param daemon the daemon to get the list
* @param num_elements the number of elements in @a fds list
* @param[out] wfds the arrays of @a num_elements of sockets to be watched
* by application, the unused elements (if any) at
* the end of the array are filled with
* { MHD_INVALID_SOCKET, MHD_FD_STATE_NONE }
* @param[out] max_wait the pointer to value set to maximum wait time
* for the network events, in microseconds
* @return ::MHD_SC_OK on success,
* error code otherwise
* @ingroup event
*/
MHD_EXTERN_ enum MHD_StatusCode
MHD_get_watched_fds (
struct MHD_Daemon *daemon,
unsigned int num_elements,
struct MHD_WatchedFD wfds[MHD_FN_PAR_DYN_ARR_SIZE_ (num_elements)],
uint_fast64_t *max_wait)
MHD_FN_PAR_NONNULL_ (1)
MHD_FN_PAR_OUT_(3) MHD_FN_PAR_NONNULL_(3)
MHD_FN_PAR_OUT_(4) MHD_FN_PAR_NONNULL_ (4);
enum MHD_WatchedFdAction
{
/**
* New watched FD, to be added to the list
*/
MHD_WFA_ADD = 1
,
/**
* Update watching interest in already watched FD
*/
MHD_WFA_UPDATE = 2
,
/**
* Delete FD from watching list
*/
MHD_WFA_REMOVE = 3
,
/**
* No action. Used to fill the end of the array
* The matching FD is always #MHD_INVALID_SOCKET.
*/
MHD_WFA_NONE = 0
};
struct MHD_WatchedFdUpdate
{
/**
* The required action: add/update/delete
*/
enum MHD_WatchedFdAction action;
/**
* The watched FD to add, update or delete.
*/
struct MHD_WatchedFD watched_fd;
};
/**
* Get the update of the list of the sockets that must be watched
* by application.
* This function provides an update to the list of watched sockets
* since the last call of #MHD_get_watched_fds() or
* #MHD_get_watched_fds_update().
* If this function is called before #MHD_get_watched_fds() then it
* returns full list of sockets to watch with action #MHD_WFA_ADD.
*
* @param daemon the daemon to get the list
* @param num_elements the number of elements in @a fds list
* @param[out] wfdus the arrays of @a num_elements to update the list
* of watched sockets, the unused elements (if any) at
* the end of the array are filled with
* { MHD_WFA_NONE, { MHD_INVALID_SOCKET, MHD_FD_STATE_NONE } }
* @param[out] max_wait the pointer to value set to maximum wait time
* for the network events, in microseconds
* @return ::MHD_SC_OK on success,
* error code otherwise
* @ingroup event
*/
MHD_EXTERN_ enum MHD_StatusCode
MHD_get_watched_fds_update (
struct MHD_Daemon *daemon,
unsigned int num_elements,
struct MHD_WatchedFdUpdate wfdus[MHD_FN_PAR_DYN_ARR_SIZE_ (num_elements)],
uint_fast64_t *max_wait)
MHD_FN_PAR_NONNULL_ (1)
MHD_FN_PAR_OUT_(3) MHD_FN_PAR_NONNULL_(3)
MHD_FN_PAR_OUT_(4) MHD_FN_PAR_NONNULL_ (4);
;
/**
* Perform round of sockets processing, including receiving, sending,
* data processing, sockets closing and other things.
* @param daemon the daemon to process
* @param num_elements the number of elements in the @a fds array
* @param fds the array of watched sockets, must be complete list of
* all watched sockets level sockets triggering used or
* could be just partial list if edge sockets triggering used
* @return ::MHD_SC_OK on success,
* otherwise error code TODO: complete list of error codes
*/
MHD_EXTERN_ enum MHD_StatusCode
MHD_process_watched_fds (
struct MHD_Daemon *daemon,
unsigned int num_elements,
const struct MHD_WatchedFD fds[MHD_FN_PAR_DYN_ARR_SIZE_ (num_elements)])
MHD_FN_PAR_NONNULL_ (1)
MHD_FN_PAR_IN_(3) MHD_FN_PAR_NONNULL_ (3);
// FIXME: convert introspection
/**
* Obtain timeout value for polling function for this daemon.
*
* This function set value to amount of milliseconds for which polling
* function (`select()` or `poll()`) should at most block, not the
* timeout value set for connections.
* It is important to always use this function, even if connection
* timeout is not set, as in some cases MHD may already have more
* data to process on next turn (data pending in TLS buffers,
* connections are already ready with epoll etc.) and returned timeout
* will be zero.
*
* @param[in,out] daemon daemon to query for timeout
* @param[out] timeout set to the timeout (in milliseconds),
* #MHD_WAIT_INDEFINITELY if timeouts are // FIXME: redesigned
* not used (or no connections exist that would
* necessitate the use of a timeout right now)
* @return #MHD_SC_OK on success, otherwise
* an error code
* @ingroup event
*/
MHD_EXTERN_ enum MHD_StatusCode
MHD_daemon_ext_polling_get_max_wait (struct MHD_Daemon *daemon,
uint_fast64_t *timeout)
MHD_FN_PAR_NONNULL_ (1)
MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_OUT_ (2);
// FIXME: gana? table for RFC 7541...
// TODO: extract https://www.rfc-editor.org/rfc/rfc7541.html#appendix-A
enum MHD_PredefinedHeader;
/**
* Get last occurrence of a particular header value under
* the given @a skt.
*
* The pointer to the string in @a value is valid until the response
* is queued. If the data is needed beyond this point, it should be copied.
*
* @param[in,out] request request to get values from
* @param kind what kind of value are we looking for
* @param skt the header to look for based on RFC 7541 Appendix A.
* @param[out] value the found value, the str pointer set to
* NULL if nothing is found
* @return #MHD_SC_OK if found,
* error code otherwise
* @ingroup request
*/
MHD_EXTERN_ enum MHD_StatusCode
MHD_request_lookup_value_by_static_header (struct MHD_Request *request,
enum MHD_ValueKind kind,
enum MHD_PredefinedHeader skt,
struct MHD_StringNullable *value)
MHD_FN_PAR_NONNULL_ (1) MHD_FN_PAR_NONNULL_ (4); // TODO: convert like previous
+1776 -1143
View File
@@ -59,7 +59,7 @@
* really optional, and where applicable avoid having options
* where the default works if nothing is specified
* - simplify API by moving rarely used http_version into
* MHD_request_get_information()
* MHD_request_get_info_fixed()
* - avoid 'int' for MHD_YES/MHD_NO by introducing `enum MHD_Bool`
* - improve terminology by eliminating confusion between
* 'request' and 'connection'
@@ -172,14 +172,10 @@
* TODO:
* - varargs in upgrade is still there and ugly (and not even used!)
* - migrate event loop apis (get fdset, timeout, MHD_run(), etc.)
*
* FIXME: Add to public API internal helpers, like Base64 decoder?
* Keep smaller API for now. Do not export.
*/
#ifndef MICROHTTPD2_H
#define MICROHTTPD2_H
// TODO: Introspection API for lib, daemon, request
// TODO: finish daemon options with recutils
// TODO: finish response options with recutils
@@ -232,7 +228,7 @@ typedef intptr_t ssize_t;
* Current version of the library.
* 0x01093001 = 1.9.30-1.
*/
#define MHD_VERSION 0x02000000
#define MHD_VERSION 0x02000001
/**
* Representation of 'bool' in the public API as stdbool.h may not
@@ -403,20 +399,20 @@ struct MHD_StringNullable
#endif /* ! _MSC_FULL_VER */
#if defined(__STDC_VERSION__) && !defined(__cplusplus)
# define MHD_C_MINV(ver) (__STDC_VERSION__ >= (ver))
# define MHD_C_MINV(version) (__STDC_VERSION__ >= (version))
#else
# define MHD_C_MINV(ver) (0)
# define MHD_C_MINV(version) (0)
#endif
#define MHD_C_MINV_99 MHD_C_MINV(199901)
#ifndef __cplusplus
# define MHD_CPP_MINV(version) (0)
# define MHD_CXX_MINV(version) (0)
#elif !defined(_MSC_FULL_VER) || !defined(_MSVC_LANG)
# define MHD_CPP_MINV(version) ((__cplusplus+0) >= version)
# define MHD_CXX_MINV(version) ((__cplusplus+0) >= version)
#else
# define MHD_CPP_MINV(version) \
# define MHD_CXX_MINV(version) \
((__cplusplus+0) >= version) || ((_MSVC_LANG+0) >= version)
#endif
@@ -536,7 +532,7 @@ struct MHD_StringNullable
# if !defined(MHD_USE_VARARG_MACROS)
# if MHD_C_MINV_99
# define MHD_USE_VARARG_MACROS 1
# elif MHD_CPP_MINV(201103)
# elif MHD_CXX_MINV(201103)
# define MHD_USE_VARARG_MACROS 1
# elif MHD_GNUC_MINV(3,0) && !defined(__STRICT_ANSI__)
/* This may warn in "pedantic" compilation mode */
@@ -589,7 +585,7 @@ struct MHD_StringNullable
# define MHD_INLINE inline
# elif MHD_GNUC_MINV(3,0) && !defined(__STRICT_ANSI__)
# define MHD_INLINE __inline__
# elif defined(MHD_HAS_MSC_EXTENSION) && _MSC_VER >= 1400
# elif defined(MHD_HAS_MSC_EXTENSION) && MHD_MSC_MINV(1400)
# define MHD_INLINE __inline
# else
# define MHD_INLINE /* empty */
@@ -705,9 +701,9 @@ struct MHD_StringNullable
# if MHD_GNUC_MINV(4,8) && ! deifned(__clang__) /* GCC >= 4.8 */
/* Print warning when the macro is processed (if not excluded from processing).
* To be used outside other macros */
# define MHD_DEPR_MACRO_(msg) _Pragma (MHD_MACRO_STR_(GCC warning msg))
# define MHD_DEPR_MACRO_(msg) _Pragma(MHD_MACRO_STR_(GCC warning msg))
/* Print warning message when another macro which includes this macro is used */
# define MHD_DEPR_IN_MACRO_(msg) MHD_DEPR_MACRO_ (msg)
# define MHD_DEPR_IN_MACRO_(msg) MHD_DEPR_MACRO_(msg)
# elif (MHD_CLANG_MINV(3,3) && !defined(__apple_build_version__)) \
|| MHD_CLANG_MINV(5,0)
/* clang >= 3.3 (or XCode's clang >= 5.0) */
@@ -769,22 +765,72 @@ struct MHD_StringNullable
#endif /* !MHD_DEPR_FUNC_ */
#ifdef __has_attribute
# if __has_attribute (flag_enum)
# define MHD_FLAGS_ENUM_ __attribute__((flag_enum))
# endif /* flag_enum */
# if __has_attribute (enum_extensibility)
/* Enum will not be extended */
# define MHD_FIXED_ENUM_ __attribute__((enum_extensibility (closed)))
# endif /* enum_extensibility */
# if __has_attribute (flag_enum)
/* Enum is a bitmap */
# define MHD_FLAGS_ENUM_ __attribute__((flag_enum))
# endif /* flag_enum */
#endif /* __has_attribute */
#ifndef MHD_FLAGS_ENUM_
# define MHD_FLAGS_ENUM_ /* empty */
#endif /* MHD_FLAGS_ENUM_ */
#ifndef MHD_FIXED_ENUM_
# define MHD_FIXED_ENUM_ /* empty */
#endif /* MHD_FIXED_ENUM_ */
#ifndef MHD_FLAGS_ENUM_
# define MHD_FLAGS_ENUM_ /* empty */
#endif /* MHD_FLAGS_ENUM_ */
#ifndef MHD_FIXED_FLAGS_ENUM_
# define MHD_FIXED_FLAGS_ENUM_ MHD_FIXED_ENUM_ MHD_FLAGS_ENUM_
#endif
#ifndef MHD_FIXED_ENUM_APP_SET_
/* The enum is set by an application to the fixed list of values */
# define MHD_FIXED_ENUM_APP_SET_ MHD_FIXED_ENUM_
#endif
#ifndef MHD_FLAGS_ENUM_APP_SET_
/* The enum is set by an application, it is a bitmap */
# define MHD_FLAGS_ENUM_APP_SET_ MHD_FLAGS_ENUM_
#endif
#ifndef MHD_FIXED_FLAGS_ENUM_APP_SET_
/* The enum is set by an application to the fixed bitmap values */
# define MHD_FIXED_FLAGS_ENUM_APP_SET_ MHD_FIXED_FLAGS_ENUM_
#endif
#ifndef MHD_FIXED_ENUM_MHD_SET_
/* The enum is set by MHD to the fixed list of values */
# define MHD_FIXED_ENUM_MHD_SET_ /* enum can be extended in next MHD versions */
#endif
#ifndef MHD_FLAGS_ENUM_MHD_SET_
/* The enum is set by MHD, it is a bitmap */
# define MHD_FLAGS_ENUM_MHD_SET_ MHD_FLAGS_ENUM_
#endif
#ifndef MHD_FIXED_FLAGS_ENUM_MHD_SET_
/* The enum is set by MHD to the fixed bitmap values */
# define MHD_FIXED_FLAGS_ENUM_MHD_SET_ MHD_FLAGS_ENUM_ /* enum can be extended in next MHD versions */
#endif
#ifndef MHD_FIXED_ENUM_MHD_APP_SET_
/* The enum is set by both MHD and app to the fixed list of values */
# define MHD_FIXED_ENUM_MHD_APP_SET_ /* enum can be extended in next MHD versions */
#endif
#ifndef MHD_FLAGS_ENUM_MHD_APP_SET_
/* The enum is set by both MHD and app, it is a bitmap */
# define MHD_FLAGS_ENUM_MHD_APP_SET_ MHD_FLAGS_ENUM_
#endif
#ifndef MHD_FIXED_FLAGS_ENUM_MHD_APP_SET_
/* The enum is set by both MHD and app to the fixed bitmap values */
# define MHD_FIXED_FLAGS_ENUM_MHD_APP_SET_ MHD_FLAGS_ENUM_ /* enum can be extended in next MHD versions */
#endif
#define MHD_FIXED_FLAGS_ENUM_ MHD_FIXED_ENUM_ MHD_FLAGS_ENUM_
/* Define MHD_NO_FUNC_ATTRIBUTES to avoid having function attributes */
#if ! defined(MHD_NO_FUNC_ATTRIBUTES)
@@ -1124,7 +1170,7 @@ struct MHD_Action;
* Values from 50000-59999 indicate MHD server errors.
* Values from 60000-65535 indicate application errors.
*/
enum MHD_StatusCode
enum MHD_FIXED_ENUM_MHD_SET_ MHD_StatusCode
{
/* 00000-level status codes indicate return values
@@ -1714,7 +1760,7 @@ enum MHD_StatusCode
*/
MHD_EXTERN_ const struct MHD_String *
MHD_status_code_to_string (enum MHD_StatusCode code)
MHD_FN_CONST_;
MHD_FN_PURE_;
/**
* HTTP methods explicitly supported by MHD. Note that for
@@ -1734,7 +1780,7 @@ MHD_FN_CONST_;
* Registry Version 2015-05-19
* @{
*/
enum MHD_HTTP_Method
enum MHD_FIXED_ENUM_ MHD_HTTP_Method
{
/**
@@ -1808,7 +1854,7 @@ enum MHD_HTTP_Method
*/
MHD_EXTERN_ const struct MHD_String *
MHD_http_method_to_string (enum MHD_HTTP_Method method)
MHD_FN_CONST_;
MHD_FN_PURE_;
/**
* @defgroup methods HTTP methods
@@ -1911,7 +1957,7 @@ MHD_FN_CONST_;
* @{
*/
enum MHD_HTTP_PostEncoding
enum MHD_FIXED_ENUM_MHD_APP_SET_ MHD_HTTP_PostEncoding
{
/**
* No post encoding / broken data / unknown encoding
@@ -2567,7 +2613,7 @@ MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_INOUT_(1);
* @param[in] daemon daemon to stop
* @ingroup event
*/
MHD_EXTERN_ void // FIXME: enum MHD_StatusCode ?
MHD_EXTERN_ void
MHD_daemon_destroy (struct MHD_Daemon *daemon)
MHD_FN_PAR_NONNULL_ALL_;
@@ -2638,19 +2684,32 @@ struct MHD_DaemonOptionValueSA
const struct sockaddr *sa;
};
enum MHD_DaemonOptionAddrReuse
/**
* Parameter for listen socket binding type
*/
enum MHD_FIXED_ENUM_APP_SET_ MHD_DaemonOptionBindType
{
MHD_DAEMON_OPTION_ADDR_REUSE = 1
/**
* The list socket bind without sharing listen address.
* Default.
*/
MHD_DAEMON_OPTION_BIND_TYPE_NOT_SHARED = 0
,
/* Default. //TODO: add doxy */
MHD_DAEMON_OPTION_ADDR_NO_REUSE = 0
/**
* The list socket bind with sharing listen address.
* Several sockets can bind to the same address.
*/
MHD_DAEMON_OPTION_BIND_TYPE_SHARED = 1
,
/* Ignored on platforms without support for explicit exclusive socket use. */
MHD_DAEMON_OPTION_ADDR_EXCLUSIVE = -1
/**
* The list socket bind to the address in explicit exclusive mode.
* Ignored on platforms without support for explicit exclusive socket use.
*/
MHD_DAEMON_OPTION_BIND_TYPE_EXCLUSIVE = 2
};
enum MHD_DaemonOption
enum MHD_FIXED_ENUM_APP_SET_ MHD_DaemonOption
{
/**
* Not a real option.
@@ -2742,7 +2801,7 @@ enum MHD_DaemonOption
/**
* Possible levels of enforcement for TCP_FASTOPEN.
*/
enum MHD_FastOpenOption
enum MHD_FIXED_ENUM_APP_SET_ MHD_FastOpenOption
{
/**
* Disable use of TCP_FASTOPEN.
@@ -2757,7 +2816,7 @@ enum MHD_FastOpenOption
MHD_FOM_AUTO = 0
,
/**
* If TCP_FASTOPEN is not available, return #MHD_NO.
* Require TCP_FASTOPEN.
* Also causes #MHD_daemon_start() to fail if setting
* the option fails later.
*/
@@ -2793,7 +2852,7 @@ MHD_FN_PAR_NONNULL_ALL_ MHD_FN_MUST_CHECK_RESULT_;
/**
* Address family to be used by MHD.
*/
enum MHD_AddressFamily
enum MHD_FIXED_ENUM_APP_SET_ MHD_AddressFamily
{
/**
* Option not given, do not listen at all
@@ -2845,7 +2904,7 @@ enum MHD_AddressFamily
MHD_EXTERN_ enum MHD_StatusCode
MHD_daemon_bind_port (struct MHD_Daemon *daemon,
enum MHD_AddressFamily af,
uint16_t port)
uint_fast16_t port)
MHD_FN_PAR_NONNULL_ALL_ MHD_FN_MUST_CHECK_RESULT_;
@@ -2909,7 +2968,6 @@ enum MHD_DeamonOptionUInt
};
// ADD - Discussed
/**
* Set unsigned integer MHD option.
*
@@ -2991,7 +3049,7 @@ MHD_FN_PAR_NONNULL_ (1);
/**
* Event loop internal syscalls supported by MHD.
*/
enum MHD_EventLoopSyscall
enum MHD_FIXED_ENUM_APP_SET_ MHD_EventLoopSyscall
{
/**
* Automatic selection of best-available method. This is also the
@@ -3027,7 +3085,7 @@ enum MHD_EventLoopSyscall
* #MHD_SC_FEATURE_NOT_AVAILABLE if this options is not supported on this system
* #MHD_SC_OPTIONS_CONFLICT
*/
MHD_EXTERN_ enum MHD_StatusCode // FIXME - corrected
MHD_EXTERN_ enum MHD_StatusCode
MHD_daemon_event_loop (struct MHD_Daemon *daemon,
enum MHD_EventLoopSyscall els)
MHD_FN_PAR_NONNULL_ (1);
@@ -3037,7 +3095,7 @@ MHD_FN_PAR_NONNULL_ (1);
* Protocol strictness enforced by MHD on clients.
* All levels have different parsing settings for the headers.
*/
enum MHD_ProtocolStrictLevel
enum MHD_FIXED_ENUM_APP_SET_ MHD_ProtocolStrictLevel
{
/* * Basic levels * */
@@ -3122,7 +3180,7 @@ enum MHD_ProtocolStrictLevel
* MHD can be compiled with limited set of strictness levels.
* These values instructs MHD how to apply the request level.
*/
enum MHD_UseStictLevel
enum MHD_FIXED_ENUM_APP_SET_ MHD_UseStictLevel
{
/**
* Use requested level if available or the nearest stricter
@@ -3160,21 +3218,12 @@ MHD_daemon_protocol_strict_level (struct MHD_Daemon *daemon,
enum MHD_UseStictLevel how)
MHD_FN_PAR_NONNULL_ (1);
// FIXME: do we want to keep it as generic API?
// FIXME: other TLS backends will not support it.
// TODO: remove and use low-level from callback
// + TLS ciphers
// + 'application name' for lookup
// of TLS cipher option in configuration file.
// ciphers which ciphers should be used by TLS, default is
// "NORMAL"
MHD_EXTERN_ enum MHD_StatusCode
MHD_daemon_set_option_string (struct MHD_Daemon *daemon,
enum foo,
const char *value)
MHD_FN_PAR_NONNULL_ (1);
// TODO: three options
/**
* Provide TLS key and certificate data in-memory.
*
@@ -3185,7 +3234,7 @@ MHD_FN_PAR_NONNULL_ (1);
* HTTPS daemon. Must be the actual data in-memory, not a filename.
* @param pass passphrase phrase to decrypt 'key.pem', NULL
* if @param mem_key is in cleartext already
* @return #MHD_SC_OK upon success; TODO: define failure modes
* @return #MHD_SC_OK upon success;
*/
MHD_EXTERN_ enum MHD_StatusCode
MHD_daemon_tls_key_and_cert_from_memory (struct MHD_Daemon *daemon,
@@ -3228,7 +3277,7 @@ MHD_FN_PAR_NONNULL_ (1);
/**
* The TLS backend choice
*/
enum MHD_TlsBackend
enum MHD_FIXED_ENUM_APP_SET_ MHD_TlsBackend
{
/**
* TODO add descr
@@ -3278,7 +3327,7 @@ MHD_FN_PAR_NONNULL_ (1);
*/
struct MHD_ServerCredentialsContext;
enum MHD_StatusCode
MHD_EXTERN_ enum MHD_StatusCode
MHD_connection_set_psk (struct MHD_ServerCredentialsContext *mscc,
size_t psk_size,
const /*void? */ char psk[MHD_C99_ (psk_size)]);
@@ -3452,7 +3501,7 @@ MHD_FN_PAR_NONNULL_ (1);
* of connection notifications.
* @ingroup request
*/
enum MHD_ConnectionNotificationCode
enum MHD_FIXED_ENUM_MHD_SET_ MHD_ConnectionNotificationCode
{
/**
@@ -3491,6 +3540,14 @@ struct MHD_ConnectionNotificationData
* The connection handle
*/
struct MHD_Connection *connection;
/**
* The connection-specific application context data (opaque for MHD).
* Initially set to NULL (for connections added by MHD) or set by
* @a connection_cntx parameter for connections added by
* #MHD_daemon_add_connection().
* Modified pointer is remembered by MHD.
*/
void *application_context;
/**
* The code of the event
*/
@@ -3507,7 +3564,7 @@ struct MHD_ConnectionNotificationData
* application about started/stopped network connections
*
* @param cls client-defined closure
* @param data the details about the event
* @param[in,out] data the details about the event
* @see #MHD_daemon_set_notify_connection()
* @ingroup request
*/
@@ -3536,7 +3593,7 @@ MHD_FN_PAR_NONNULL_ (1);
* The type of stream notifications.
* @ingroup request
*/
enum MHD_StreamNotificationCode
enum MHD_FIXED_ENUM_MHD_SET_ MHD_StreamNotificationCode
{
/**
* A new connection has been started.
@@ -3626,7 +3683,6 @@ MHD_daemon_set_notify_stream (struct MHD_Daemon *daemon,
void *nsc_cls)
MHD_FN_PAR_NONNULL_ (1);
// TODO: Sort and assign values
enum MHD_DaemonOptionSizet
{
/**
@@ -3639,16 +3695,6 @@ enum MHD_DaemonOptionSizet
* with internal parsing information).
*/
MHD_DAEMON_OPTION_SIZET_CONN_MEM_LIMIT,
// FIXME: remove this option completely and manage it in MHD?
// Users do not have clear understanding of what is it and why is it needed/
// TODO: remove for now
/**
* The step in which read buffer is incremented when needed.
* If initial half size of the connection's memory region is not enough
* for message header and initial part of the request context/body then
* buffer is increased by this size.
*/
MHD_DAEMON_OPTION_SIZET_CONN_INCR_SIZE,
/**
* Desired size of the stack for threads created by MHD.
* Use 0 for system default, which is also MHD default.
@@ -3658,7 +3704,6 @@ enum MHD_DaemonOptionSizet
MHD_DAEMON_OPTION_SIZET_STACK_SIZE,
};
// FIXME: finish
MHD_EXTERN_ void
MHD_daemon_option_set_sizet (struct MHD_Daemon *daemon,
enum MHD_DaemonOptionSizet option,
@@ -3850,7 +3895,7 @@ MHD_RESTORE_WARN_UNUSED_FUNC_
* use MHD_OPTIONS_ARRAY_MAX_SIZE if options processing
* must stop only at zero-termination option
* @return ::MHD_SC_OK on success,
* error code otherwise // TODO: add the full list
* error code otherwise
*/
MHD_EXTERN_ enum MHD_StatusCode
MHD_daemon_options_set(struct MHD_Daemon *daemon,
@@ -3865,7 +3910,7 @@ MHD_FN_PAR_NONNULL_ALL_;
* @param daemon the daemon to set the option
* @param[in] options the pointer to the option
* @return ::MHD_SC_OK on success,
* error code otherwise // TODO: add the full list
* error code otherwise
*/
#define MHD_daemon_option_set(daemon, option_ptr) \
MHD_daemon_options_set(daemon, options_ptr, 1)
@@ -3888,7 +3933,7 @@ MHD_NOWARN_VARIADIC_MACROS_
* @param ... the list of the options, each option must be created
* by helpers MHD_DAEMON_OPTION_NameOfOption(option_value)
* @return ::MHD_SC_OK on success,
* error code otherwise // TODO: add the full list
* error code otherwise
*/
# define MHD_DAEMON_OPTIONS_SET(daemon,...) \
MHD_NOWARN_COMPOUND_LITERALS_ \
@@ -3916,7 +3961,7 @@ extern "C"
* @param ... the list of the options, each option must be created
* by helpers MHD_D_OPTION_NameOfOption(option_value)
* @return ::MHD_SC_OK on success,
* error code otherwise // TODO: add the full list
* error code otherwise
*/
# define MHD_DAEMON_OPTIONS_SET(daemon,...) \
MHD_NOWARN_CPP_INIT_LIST_ \
@@ -3936,56 +3981,39 @@ MHD_RESTORE_WARN_VARIADIC_MACROS_
/**
* Which threading and polling mode should be used by MHD?
*/
enum MHD_ThreadingPollingMode
enum MHD_FIXED_ENUM_APP_SET_ MHD_ThreadingPollingMode
{
/**
* The daemon has no internal threads.
* The application periodically calls #MHD_daemon_process_blocking(), where
* MHD internally checks all sockets automatically.
* This is the default. // FIXME: keep as default?
* This is the default.
*/
MHD_TM_EXTERNAL_PERIODIC = 0
,
// FIXME: updated-2
/**
* Use an external event loop.
* Application uses #MHD_set_external_event_loop() and level
* triggered sockets polling (like select() or poll()).
* Use an external event loop with level triggers.
* Application uses #MHD_SocketRegistrationUpdateCallback, level triggered
* sockets polling (like select() or poll()) and #MHD_daemon_event_update().
*/
MHD_TM_EXTERNAL_EVENT_LOOP_CB_LEVEL = 8
,
/**
* Use an external event loop.
* Application uses #MHD_set_external_event_loop() and edge
* triggered sockets polling.
* Use an external event loop with edge triggers.
* Application uses #MHD_SocketRegistrationUpdateCallback, edge triggered
* sockets polling (like select() or poll()) and #MHD_daemon_event_update().
*/
MHD_TM_EXTERNAL_EVENT_LOOP_CB_EDGE = 9
,
/**
* Use an external event loop.
* Application uses #MHD_get_watched_fds()/#MHD_get_watched_fds_update()
* and #MHD_process_watched_fds() with level triggered sockets
* polling (like select() or poll()).
*/
MHD_TM_EXTERNAL_EVENT_LOOP_WFD_LEVEL = 10
,
/**
* Use an external event loop.
* Application uses #MHD_get_watched_fds()/#MHD_get_watched_fds_update()
* and #MHD_process_watched_fds() with edge triggered sockets polling.
*/
MHD_TM_EXTERNAL_EVENT_LOOP_WFD_EDGE = 11
,
/**
* The daemon has no internal threads.
* Application uses // TODO: add introspection reference
* to get single FD that triggered when any MHD even happens.
* Application uses #MHD_DAEMON_INFO_FIXED_AGGREAGATE_FD to get single FD
* that triggered when any MHD event happens.
* This FD can be watched as aggregate indicator for all MHD events.
* This mode is available only on selected platforms (currently
* GNU/Linux only).
* GNU/Linux only), see #MHD_LIB_INFO_FIXED_HAS_AGGREGATE_FD.
* When the FD is triggered, #MHD_daemon_process_nonblocking() should
* be called.
* // TODO: introspection
*/
MHD_TM_EXTERNAL_SINGLE_FD_WATCH = 12
,
@@ -3997,16 +4025,10 @@ enum MHD_ThreadingPollingMode
* If #MHD_DAEMON_OPTION_UINT_NUM_WORKERS used with value more
* than one, then that number of worker threads and distributed
* processing of requests among the workers.
*
* If this mode is specified, #MHD_daemon_run() and
* #MHD_daemon_run_from_select() cannot be used.
*/
MHD_TM_WORKER_THREADS = 16
,
// FIXME: could be unavailable for HTTP/2 and /3. Streams must be
// multiplexed. Multiplexing from several threads looks overcomplicated.
// TODO: update doxy
/**
* MHD should create its own thread for listening and furthermore create
* additional threads per every connection. Use this if handling requests
@@ -4034,9 +4056,6 @@ MHD_daemon_set_threading_mode (struct MHD_Daemon *daemon,
MHD_FN_PAR_NONNULL_ (1);
// thread safety?
// -> introspection API to return the FD
/**
* The network status of the socket.
* When set by MHD (by #MHD_get_watched_fds(), #MHD_get_watched_fds_update() and
@@ -4050,8 +4069,7 @@ MHD_FN_PAR_NONNULL_ (1);
* #MHD_FD_STATE_SEND, #MHD_FD_STATE_EXCEPT.
* @ingroup event
*/
MHD_FIXED_FLAGS_ENUM_
enum MHD_FdState
enum MHD_FIXED_ENUM_ MHD_FdState
{
/**
* The socket is not ready for receiving or sending and
@@ -4180,114 +4198,16 @@ enum MHD_FdState
MHD_FD_STATE_CLEAR ((var),MHD_FD_STATE_EXCEPT)
#if 0 /* Christian's idea, finalised */
/* Does not need MHD to iterate over all the sockets/connections to check for
* updates.
* For one million sockets it requires up to one million calls each round to
* update the socket statuses.
*/
/**
* The context data to used for #MHD_EventCallback,
* identifies the socket for MHD.
*/
struct MHD_EventCallbackContext;
/**
* The callback function provided by MHD.
* This callback must be called for every socket with new monitoring state
* to update the state of the socket.
* @param ecb_data the context data provided via
* #MHD_SocketRegistrationUpdateCallback() parameter
* @param fd_state the current state of the socket
*/
typedef void
(MHD_FN_PAR_NONNULL_(1)
*MHD_EventCallback) (struct MHD_EventCallbackContext *ecb_cntx,
enum MHD_FdState fd_state);
/* Define MHD_APP_SOCKET_CNTX_TYPE to the socket context type before
* including this header.
* This is optional, but improves the types safety.
* For example:
* #define MHD_APP_SOCKET_CNTX_TYPE struct my_structure
*/
#ifndef MHD_APP_SOCKET_CNTX_TYPE
# define MHD_APP_SOCKET_CNTX_TYPE void
#endif
/**
* The callback for registration/de-registration of the sockets to watch.
*
* This callback must not call #MHD_daemon_destroy(), #MHD_daemon_quiesce(),
* #MHD_daemon_add_connection().
*
* @param cls the closure
* @param fd the socket to watch
* @param watch_for the states of the @a fd to watch, if set to
* #MHD_FD_STATE_NONE the socket must be de-registred
* @param app_cntx_old the old application defined context for the socket,
* NULL if @a fd socket was not registered before
* @param ecb the function provided by MHD to update the status of the socket
* @param ecb_cntx the context handle to be used with @a ecb
* @return NULL if error (to connection will be closed),
* or the new socket context
* @ingroup event
*/
typedef MHD_APP_SOCKET_CNTX_TYPE *
(*MHD_SocketRegistrationUpdateCallback)(
void *cls,
MHD_socket fd,
enum MHD_FdState watch_for,
MHD_APP_SOCKET_CNTX_TYPE *app_cntx_old,
MHD_EventCallback ecb,
struct MHD_EventCallbackContext *ecb_cntx);
/**
* Perform sockets registration, process registered network events.
*
* This function first processes all registred network evetns (if any) and
* then calls #MHD_SocketRegistrationUpdateCallback callback for every socket
* that need to be added/updated/removed.
*
* @param daemon the daemon handle
* @return MHD_SC_OK on success,
* error code otherwise
*/
MHD_EXTERN_ enum MHD_StatusCode
MHD_deamon_process_reg_events(struct MHD_Daemon *daemon)
MHD_FN_PAR_NONNULL_(1);
#else /* Almost the same idea, but with ability to make a group updates */
/* Changes:
* + status update callback replaced with function
* + status update accepts array of updates
*/
/**
* The context data to used to provide update of the socket state
* The context data to be used for updates of the socket state
*/
struct MHD_EventUpdateContext;
/**
* The parameter type used for #MHD_EventCallback
*/
struct MHD_EventUpdateData
{
/**
* The context provided via #MHD_SocketRegistrationUpdateCallback,
* identifies the socket for MHD.
*/
struct MHD_EventUpdateContext cntx;
/**
* The actual state of the socket
*/
enum MHD_FdState fd_state;
};
/* Define MHD_APP_SOCKET_CNTX_TYPE to the socket context type before
* including this header.
@@ -4312,234 +4232,63 @@ struct MHD_EventUpdateData
* @param app_cntx_old the old application defined context for the socket,
* NULL if @a fd socket was not registered before
* @param ecb_cntx the context handle to be used
* with #MHD_daemon_events_update()
* with #MHD_daemon_event_update()
* @return NULL if error (to connection will be closed),
* or the new socket context
* @ingroup event
*/
typedef MHD_APP_SOCKET_CNTX_TYPE *
(*MHD_SocketRegistrationUpdateCallback)(
(MHD_FN_PAR_NONNULL_(5)
*MHD_SocketRegistrationUpdateCallback)(
void *cls,
MHD_socket fd,
enum MHD_FdState watch_for,
MHD_APP_SOCKET_CNTX_TYPE *app_cntx_old,
struct MHD_EventUpdateContext *ecb_cntx); // Removed callback pointer
struct MHD_EventUpdateContext *ecb_cntx);
/**
* Update the sockets state.
* Must be called for every socket that got state updated.
* For #MHD_TM_EXTERNAL_EVENT_LOOP_CB_LEVEL mode should be called for each
* socket.
* Available only for daemons stated in #MHD_TM_EXTERNAL_EVENT_LOOP_CB_LEVEL or
* #MHD_TM_EXTERNAL_EVENT_LOOP_CB_EDGE modes.
* @param daemon the daemon handle
* @param num_elements the number of elements in @a updates array
* @param updates the array of the structures with updates
* of the socket states
* @param ecb_cntx the context handle provided
* for #MHD_SocketRegistrationUpdateCallback
* @param fd_current_state the current state of the socket
*/
MHD_EXTERN_ void
MHD_daemon_events_update (
MHD_daemon_event_update (
struct MHD_Daemon *daemon,
size_t num_elements,
struct MHD_EventCallbackData updates[MHD_FN_PAR_DYN_ARR_SIZE_(num_elements)])
MHD_FN_PAR_NONNULL_(1) MHD_FN_PAR_NONNULL_(3);
struct MHD_EventUpdateContext *ecb_cntx,
enum MHD_FdState fd_current_state)
MHD_FN_PAR_NONNULL_(1) MHD_FN_PAR_NONNULL_(2);
/**
* Update the sockets state.
* @param daemon the daemon handle
* @param update the update of the socket states
*/
#define MHD_daemon_event_update(daemon,update) \
MHD_daemon_events_update(daemon, 1, update)
/**
* Perform sockets registration, process registered network events.
*
* This function first processes all registered (by MHD_daemon_events_update())
* This function first processes all registered (by MHD_daemon_event_update())
* network events (if any) and then calls #MHD_SocketRegistrationUpdateCallback
* callback for every socket that needs to be added/updated/removed.
*
* Available only for daemons stated in #MHD_TM_EXTERNAL_EVENT_LOOP_CB_LEVEL or
* #MHD_TM_EXTERNAL_EVENT_LOOP_CB_EDGE modes.
*
* @param daemon the daemon handle
* @param[out] next_max_wait the optional pointer to receive the next maximum
* wait time in microseconds to be used for sockets
* polling function, can be NULL
* @return MHD_SC_OK on success,
* error code otherwise
*/
MHD_EXTERN_ enum MHD_StatusCode
MHD_deamon_process_reg_events(struct MHD_Daemon *daemon)
MHD_deamon_process_reg_events(struct MHD_Daemon *daemon,
uint_fast64_t *next_max_wait)
MHD_FN_PAR_NONNULL_(1);
#endif /* Modified idea */
// Alternative style
struct MHD_WatchedFD
{
/**
* The watched socket.
* Ignored if set by application to #MHD_INVALID_SOCKET. TODO: Improve wording
*/
MHD_socket fd;
/**
* Indicates that socket should be watched for specific network state
* (when set by #MHD_get_watched_fds(), #MHD_get_watched_fds_update())
* / the network state of the socket (when used for
* #MHD_process_watched_fds())
*/
enum MHD_FdState state;
};
/**
* Get the full list of the sockets that must be watched by application.
*
* The application may use this function each time to get a full list of
* the sockets for watch or may use #MHD_get_watched_fds_update() to
* get the incremental updates.
*
* // TODO: add introspection reference
*
* @param daemon the daemon to get the list
* @param num_elements the number of elements in @a fds list
* @param[out] wfds the arrays of @a num_elements of sockets to be watched
* by application, the unused elements (if any) at
* the end of the array are filled with
* { MHD_INVALID_SOCKET, MHD_FD_STATE_NONE }
* @param[out] max_wait the pointer to value set to maximum wait time
* for the network events, in microseconds
* @return ::MHD_SC_OK on success,
* error code otherwise
* @ingroup event
*/
MHD_EXTERN_ enum MHD_StatusCode
MHD_get_watched_fds (
struct MHD_Daemon *daemon,
unsigned int num_elements,
struct MHD_WatchedFD wfds[MHD_FN_PAR_DYN_ARR_SIZE_(num_elements)],
uint_fast64_t *max_wait)
MHD_FN_PAR_NONNULL_ (1)
MHD_FN_PAR_OUT_(3) MHD_FN_PAR_NONNULL_(3)
MHD_FN_PAR_OUT_(4) MHD_FN_PAR_NONNULL_(4);
enum MHD_WatchedFdAction
{
/**
* New watched FD, to be added to the list
*/
MHD_WFA_ADD = 1
,
/**
* Update watching interest in already watched FD
*/
MHD_WFA_UPDATE = 2
,
/**
* Delete FD from watching list
*/
MHD_WFA_REMOVE = 3
,
/**
* No action. Used to fill the end of the array
* The matching FD is always #MHD_INVALID_SOCKET.
*/
MHD_WFA_NONE = 0
};
struct MHD_WatchedFdUpdate
{
/**
* The required action: add/update/delete
*/
enum MHD_WatchedFdAction action;
/**
* The watched FD to add, update or delete.
*/
struct MHD_WatchedFD watched_fd;
};
/**
* Get the update of the list of the sockets that must be watched
* by application.
* This function provides an update to the list of watched sockets
* since the last call of #MHD_get_watched_fds() or
* #MHD_get_watched_fds_update().
* If this function is called before #MHD_get_watched_fds() then it
* returns full list of sockets to watch with action #MHD_WFA_ADD.
*
* @param daemon the daemon to get the list
* @param num_elements the number of elements in @a fds list
* @param[out] wfdus the arrays of @a num_elements to update the list
* of watched sockets, the unused elements (if any) at
* the end of the array are filled with
* { MHD_WFA_NONE, { MHD_INVALID_SOCKET, MHD_FD_STATE_NONE } }
* @param[out] max_wait the pointer to value set to maximum wait time
* for the network events, in microseconds
* @return ::MHD_SC_OK on success,
* error code otherwise
* @ingroup event
*/
MHD_EXTERN_ enum MHD_StatusCode
MHD_get_watched_fds_update (
struct MHD_Daemon *daemon,
unsigned int num_elements,
struct MHD_WatchedFdUpdate wfdus[MHD_FN_PAR_DYN_ARR_SIZE_(num_elements)],
uint_fast64_t *max_wait)
MHD_FN_PAR_NONNULL_ (1)
MHD_FN_PAR_OUT_(3) MHD_FN_PAR_NONNULL_(3)
MHD_FN_PAR_OUT_(4) MHD_FN_PAR_NONNULL_(4);
;
/**
* Perform round of sockets processing, including receiving, sending,
* data processing, sockets closing and other things.
* @param daemon the daemon to process
* @param num_elements the number of elements in the @a fds array
* @param fds the array of watched sockets, must be complete list of
* all watched sockets level sockets triggering used or
* could be just partial list if edge sockets triggering used
* @return ::MHD_SC_OK on success,
* otherwise error code TODO: complete list of error codes
*/
MHD_EXTERN_ enum MHD_StatusCode
MHD_process_watched_fds (
struct MHD_Daemon *daemon,
unsigned int num_elements,
const struct MHD_WatchedFD fds[MHD_FN_PAR_DYN_ARR_SIZE_ (num_elements)])
MHD_FN_PAR_NONNULL_ (1)
MHD_FN_PAR_IN_(3) MHD_FN_PAR_NONNULL_(3);
// FIXME: convert introspecition
/**
* Obtain timeout value for polling function for this daemon.
*
* This function set value to amount of milliseconds for which polling
* function (`select()` or `poll()`) should at most block, not the
* timeout value set for connections.
* It is important to always use this function, even if connection
* timeout is not set, as in some cases MHD may already have more
* data to process on next turn (data pending in TLS buffers,
* connections are already ready with epoll etc.) and returned timeout
* will be zero.
*
* @param[in,out] daemon daemon to query for timeout
* @param[out] timeout set to the timeout (in milliseconds),
* #MHD_WAIT_INDEFINITELY if timeouts are // FIXME: redesigned
* not used (or no connections exist that would
* necessitate the use of a timeout right now)
* @return #MHD_SC_OK on success, otherwise
* an error code
* @ingroup event
*/
MHD_EXTERN_ enum MHD_StatusCode
MHD_daemon_ext_polling_get_max_wait (struct MHD_Daemon *daemon,
uint_fast64_t *timeout)
MHD_FN_PAR_NONNULL_ (1)
MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_OUT_(2);
#ifdef alterantive
// FIXME: how to return error? For example, unsupported mode
uint64_t
MHD_daemon_external_event_loop_get_max_wait (struct MHD_Daemon *d);
#endif
/**
* Run websever operation with possible blocking.
@@ -4586,7 +4335,6 @@ MHD_daemon_process_blocking (struct MHD_Daemon *daemon,
uint_fast64_t microsec)
MHD_FN_PAR_NONNULL_(1);
// TODO: introscpection for timeout
/**
* Run webserver operations (without blocking unless in client
* callbacks).
@@ -4630,8 +4378,8 @@ MHD_FN_PAR_NONNULL_(1);
* to receive an HTTP request from this socket next).
* @param[in] addr IP address of the client
* @param addrlen number of bytes in @a addr
* @param connection_cls meta data the application wants to
* associate with the new connection object
* @param connection_cntx meta data the application wants to
* associate with the new connection object
* @return #MHD_SC_OK on success
* error on failure
* @ingroup specialized
@@ -4641,14 +4389,14 @@ MHD_daemon_add_connection (struct MHD_Daemon *daemon,
MHD_socket client_socket,
size_t addrlen,
const struct sockaddr *addr,
void *connection_cls)
void *connection_cntx)
MHD_FN_PAR_NONNULL_ (1)
MHD_FN_PAR_IN_SIZE_(4,3);
/* ********************* connection options ************** */
enum MHD_ConnectionOption
enum MHD_FIXED_ENUM_APP_SET_ MHD_ConnectionOption
{
/**
* Not a real option.
@@ -4763,7 +4511,7 @@ MHD_RESTORE_WARN_UNUSED_FUNC_
* use MHD_OPTIONS_ARRAY_MAX_SIZE if options processing
* must stop only at zero-termination option
* @return ::MHD_SC_OK on success,
* error code otherwise // TODO: add the full list
* error code otherwise
*/
MHD_EXTERN_ enum MHD_StatusCode
MHD_connection_options_set(
@@ -4779,7 +4527,7 @@ MHD_FN_PAR_NONNULL_ALL_;
* @param connection the connection to set the options
* @param[in] options the pointer to the option
* @return ::MHD_SC_OK on success,
* error code otherwise // TODO: add the full list
* error code otherwise
*/
#define MHD_connection_option_set(connection, option_ptr) \
MHD_connection_options_set(connection, options_ptr, 1)
@@ -4801,7 +4549,7 @@ MHD_NOWARN_VARIADIC_MACROS_
* @param ... the list of the options, each option must be created
* by helpers MHD_C_OPTION_NameOfOption(option_value)
* @return ::MHD_SC_OK on success,
* error code otherwise // TODO: add the full list
* error code otherwise
*/
# define MHD_CONNECTION_OPTIONS_SET(connection,...) \
MHD_NOWARN_COMPOUND_LITERALS_ \
@@ -4828,7 +4576,7 @@ extern "C"
* @param ... the list of the options, each option must be created
* by helpers MHD_C_OPTION_NameOfOption(option_value)
* @return ::MHD_SC_OK on success,
* error code otherwise // TODO: add the full list
* error code otherwise
*/
# define MHD_CONNECTION_OPTIONS_SET(daemon,...) \
MHD_NOWARN_CPP_INIT_LIST_ \
@@ -5020,34 +4768,6 @@ MHD_FN_PAR_NONNULL_ (1)
MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_CSTR_(3);
// FIXME: gana? table for RFC 7541...
// TODO: extract https://www.rfc-editor.org/rfc/rfc7541.html#appendix-A
enum MHD_PredefinedHeader;
// FIXME: Updated
/**
* Get last occurrence of a particular header value under
* the given @a skt.
*
* The pointer to the string in @a value is valid until the response
* is queued. If the data is needed beyond this point, it should be copied.
*
* @param[in,out] request request to get values from
* @param kind what kind of value are we looking for
* @param skt the header to look for based on RFC 7541 Appendix A.
* @param[out] value the found value, the str pointer set to
* NULL if nothing is found
* @return #MHD_SC_OK if found,
* // FIXME: add error codes
* @ingroup request
*/
MHD_EXTERN_ enum MHD_StatusCode
MHD_request_lookup_value_by_static_header (struct MHD_Request *request,
enum MHD_ValueKind kind,
enum MHD_PredefinedHeader skt,
struct MHD_StringNullable *value)
MHD_FN_PAR_NONNULL_ (1) MHD_FN_PAR_NONNULL_ (4); // TODO: convert like previous
/**
* @defgroup httpcode HTTP response codes.
@@ -5055,9 +4775,7 @@ MHD_FN_PAR_NONNULL_ (1) MHD_FN_PAR_NONNULL_ (4); // TODO: convert like previous
* @{
*/
/* See http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml */
// Use GANA!
// FIXME: Discuss GANA. Not clear how to use automatic substitution for missing entries
enum MHD_HTTP_StatusCode
enum MHD_FIXED_ENUM_APP_SET_ MHD_HTTP_StatusCode
{
MHD_HTTP_STATUS_CONTINUE = 100
@@ -5203,7 +4921,7 @@ enum MHD_HTTP_StatusCode
*/
MHD_EXTERN_ const struct MHD_String *
MHD_HTTP_status_code_to_string (enum MHD_HTTP_StatusCode code)
MHD_FN_CONST_;
MHD_FN_PURE_;
/** @} */ /* end of group httpcode */
@@ -5214,9 +4932,7 @@ MHD_FN_CONST_;
* HTTP header.
* @{
*/
// Again: GANA?
// FIXME: Discuss GANA. Just a few entries so far.
enum MHD_HTTP_ProtocolVersion
enum MHD_FIXED_ENUM_MHD_SET_ MHD_HTTP_ProtocolVersion
{
MHD_HTTP_VERSION_INVALID = 0
,
@@ -5241,10 +4957,8 @@ enum MHD_HTTP_ProtocolVersion
*/
MHD_EXTERN_ const struct MHD_String *
MHD_protocol_version_to_string (enum MHD_HTTP_ProtocolVersion pv)
MHD_FN_CONST_;
MHD_FN_PURE_;
// FIXME: remove completely, usable only for HTTP/1.x, no practical use with the new API
// Reminder:
/**
* HTTP/1.0 identification string
*/
@@ -5263,7 +4977,7 @@ MHD_FN_CONST_;
* HTTP/3 identification string.
* Not used by the HTTP protocol, useful for logs and similar proposes.
*/
#define MHD_HTTP_VERSION_3 "HTTP/3" // FIXME: not defined anywhere
#define MHD_HTTP_VERSION_3 "HTTP/3"
/** @} */ /* end of group versions */
@@ -5274,12 +4988,6 @@ MHD_FN_CONST_;
* function on a request that was not previously suspended will
* result in undefined behaviour.
*
* // FIXME: race conditions when request is resuming automatically
* // FIXME: what if request was already resumed? resumed in parallel? resumed and already closed?
* // FIXME: solutions:
* // FIXME: + disallow manual resume if resume timer set
* // FIXME: + put resumed and finished connection into special delayed cleanup list (worse, what's the delay?)
*
* If you are using this function in ``external'' select mode, you must
* make sure to run #MHD_run() afterwards (before again calling
* #MHD_get_fdset(), as otherwise the change may not be reflected in
@@ -5375,7 +5083,6 @@ MHD_action_from_response (struct MHD_Request *request,
/**
* Flags for special handling of responses.
*/
// FIXME: extended, sorted
enum MHD_ResponseOptionBool
{
/**
@@ -5460,8 +5167,8 @@ enum MHD_ResponseOptionBool
* This flag is primarily intended to be used when automatic "Content-Length"
* header is undesirable in response to HEAD requests.
*/
MHD_RESP_OPT_BOOL_HEAD_ONLY_RESPONSE = 81 // FIXME: replace with special "create" function?
} MHD_FIXED_FLAGS_ENUM_;
MHD_RESP_OPT_BOOL_HEAD_ONLY_RESPONSE = 81
};
// FIXME: use the same approach as for the daemon
@@ -5492,12 +5199,12 @@ struct MHD_ResponseOptionBoolSet
* @param max_num_options the maximum number of elements to read
* from @a options_array, ignored if set to SIZE_MAX
* @return #MHD_SC_OK if found,
* // FIXME: add error codes
* error code otherwise
*/
MHD_EXTERN_ enum MHD_StatusCode
MHD_response_set_options_bool (struct MHD_Response *response,
struct MHD_ResponseOptionBoolSet *options_array,
size_t max_num_options) // FIXME: another sequence, as intended
size_t max_num_options)
MHD_FN_PAR_NONNULL_ALL_;
@@ -5507,7 +5214,7 @@ MHD_FN_PAR_NONNULL_ALL_;
* why a request has been terminated (or completed).
* @ingroup request
*/
enum MHD_RequestTerminationCode
enum MHD_FIXED_ENUM_MHD_SET_ MHD_RequestTerminationCode
{
/**
@@ -5561,7 +5268,33 @@ enum MHD_RequestTerminationCode
* @ingroup request
*/
MHD_REQUEST_TERMINATED_CONNECTION_ERROR = 7
};
/**
* Additional information about request termination
*/
union MHD_RequestTerminationDetail
{
/**
* Reserved member.
* Do not use.
*/
void *reserved;
};
/**
* Request termination data structure
*/
struct MHD_RequestTerminationData
{
/**
* The code of the event
*/
enum MHD_RequestTerminationCode code;
/**
* Detailed information about termination event
*/
union MHD_RequestTerminationDetail details;
};
@@ -5570,7 +5303,7 @@ enum MHD_RequestTerminationCode
* about completed requests.
*
* @param cls client-defined closure
* @param reqtc the reason for request termination
* @param data the details about the event
* @param request_context request context value, as originally
* returned by the #MHD_EarlyUriLogCallback
* @see #MHD_option_request_completion()
@@ -5578,7 +5311,7 @@ enum MHD_RequestTerminationCode
*/
typedef void
(*MHD_RequestTerminationCallback) (void *cls,
enum MHD_RequestTerminationCode reqtc, // TODO: extend with struct
struct MHD_RequestTerminationData *data,
void *request_context);
@@ -5597,35 +5330,6 @@ MHD_response_set_option_termination_callback (
void *termination_cb_cls)
MHD_FN_PAR_NONNULL_ (1);
// FIXME: remove?
enum MHD_DynContCreatorActionType
{
/**
* Continue with response content
*/
MHD_DYN_CONT_CREATOR_ACT_CONTINUE = 0
,
/**
* The final chunk of content is created
*/
MHD_DYN_CONT_CREATOR_ACT_FINISHED = 1
,
/**
* Error creating the content.
* The request will be closed in a hard way.
*/
MHD_DYN_CONT_CREATOR_ACT_ERROR_STOP = 2
,
/**
* Suspend content creation.
* // TODO: describe
*/
MHD_DYN_CONT_CREATOR_ACT_SUSPEND = 3
};
/**
* This method is called by libmicrohttpd when response with dynamic content
@@ -5718,7 +5422,6 @@ MHD_FN_PAR_CSTR_(4);
* are copied and does not need to be valid after return from
* this function),
* can be NULL if @a num_footers is zero
* ignored if chunked encoding is not used // FIXME: throw error?
* @return the pointer to the action if succeed,
* NULL (equivalent of MHD_DCC_action_abort())in case of any error
*/
@@ -5744,7 +5447,8 @@ MHD_FN_PAR_NONNULL_ (1);
*/
MHD_EXTERN_ const struct MHD_DynamicContentCreatorAction *
MHD_DCC_action_suspend (struct MHD_DynamicContentCreatorContext *ctx)
MHD_FN_PAR_NONNULL_ (1);
MHD_FN_PAR_NONNULL_ (1)
MHD_FN_RETURNS_NONNULL_;
/**
* Set action to "stop with error".
@@ -5754,7 +5458,6 @@ MHD_FN_PAR_NONNULL_ (1);
#define MHD_DCC_action_abort(ctx) \
MHD_STATIC_CAST_(const struct MHD_DynamicContentCreatorAction *, NULL)
// FIXME: Updated
/**
* Callback used by libmicrohttpd in order to obtain content. The
* callback is to copy at most @a max bytes of content into @a buf or
@@ -5782,7 +5485,7 @@ typedef const struct MHD_DynamicContentCreatorAction *
(MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_NONNULL_ (4)
*MHD_DynamicContentCreator)(void *dyn_cont_cls,
struct MHD_DynamicContentCreatorContext *ctx,
uint64_t pos,
uint_fast64_t pos,
void *buf,
size_t max);
@@ -5848,8 +5551,7 @@ MHD_FN_PAR_IN_SIZE_(3,2);
* Create a response object. The response object can be extended with
* header information.
*
* @param sc status code to use for the response;
* #MHD_HTTP_NO_CONTENT is only valid if @a size is 0; // FIXME: remove comment? Too many statuses without body
* @param sc status code to use for the response
* @param size the size of the data portion of the response
* @param buffer the @a size bytes containing the response's data portion,
* an internal copy will be made, there is no need to
@@ -6141,7 +5843,7 @@ typedef const struct MHD_Action *
const struct MHD_String *content_type,
const struct MHD_String *encoding,
const void *data,
uint64_t off,
uint_fast64_t off,
size_t size);
@@ -6286,7 +5988,7 @@ MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_(3);
* the final set of actions is yet to be decided. This is just an
* idea for what we might want.
*/
enum MHD_UpgradeOperation
enum MHD_FIXED_ENUM_APP_SET_ MHD_UpgradeOperation
{
/**
@@ -6294,8 +5996,24 @@ enum MHD_UpgradeOperation
*/
MHD_UPGRADE_OPERATION_CLOSE = 0
,
MHD_UPGRADE_OPERATION_DRAIN_FLUSH_AFTER_SEND = 1
/**
* Turn on flushing the network buffers after each data piece.
*/
MHD_UPGRADE_OPERATION_DISABLE_NETWORK_BUFFERING = 1
,
/**
* Turn on normal data buffering (default).
*/
MHD_UPGRADE_OPERATION_ENABLE_NETWORK_BUFFERING = 2
,
/* * Sentinel * */
/**
* The sentinel value.
* This value enforces specific underlying integer type for the enum.
* Do not use.
*/
MHD_UPGRADE_OPERATION_SENTINEL = 65535
};
@@ -6306,8 +6024,6 @@ enum MHD_UpgradeOperation
*/
struct MHD_UpgradeHandle;
// TODO: re-recheck
// FIXME: no need for action
/**
* This connection-specific callback is provided by MHD to
* applications (unusual) during the #MHD_UpgradeHandler.
@@ -6377,7 +6093,7 @@ typedef void
(*MHD_UpgradeHandler)(void *cls,
struct MHD_Request *request,
size_t extra_in_size,
const char *extra_in, // TODO
const char *extra_in,
MHD_socket sock,
struct MHD_UpgradeHandle *urh);
@@ -6387,10 +6103,8 @@ typedef void
* responses, for example to implement WebSockets. After sending the
* response, control over the data stream is given to the callback (which
* can then, for example, start some bi-directional communication).
* If the response is queued for multiple connections, the callback
* will be called for each connection. The callback
* will ONLY be called after the response header was successfully passed
* to the OS; if there are communication errors before, the usual MHD
* The callback will ONLY be called after the response header was successfully
* passed to the OS; if there are communication errors before, the usual MHD
* connection error handling code will be performed.
*
* MHD will automatically set the correct HTTP status
@@ -6398,11 +6112,7 @@ typedef void
* Setting correct HTTP headers for the upgrade must be done
* manually (this way, it is possible to implement most existing
* WebSocket versions using this API; in fact, this API might be useful
* for any protocol switch, not just WebSockets). Note that
* draft-ietf-hybi-thewebsocketprotocol-00 cannot be implemented this
* way as the header "HTTP/1.1 101 WebSocket Protocol Handshake"
* cannot be generated; instead, MHD will always produce "HTTP/1.1 101
* Switching Protocols" (if the response code 101 is used).
* for any protocol switch, not just WebSockets).
*
* As usual, the response object can be extended with header
* information and then be used any number of times (as long as the
@@ -6411,13 +6121,21 @@ typedef void
* @param request the request to create action for
* @param upgrade_handler function to call with the "upgraded" socket
* @param upgrade_handler_cls closure for @a upgrade_handler
* @param num_headers number of elements in the @a headers array,
* must be zero if @a headers is NULL
* @param headers the optional pointer to the array of the headers (the strings
* are copied and does not need to be valid after return from
* this function),
* can be NULL if @a num_headers is zero
* @return NULL on error (i.e. invalid arguments, out of memory)
*/
MHD_EXTERN_ struct MHD_Action *
MHD_action_upgrade (struct MHD_Request *request, // TODO: fix the name
MHD_action_upgrade (struct MHD_Request *request,
MHD_UpgradeHandler upgrade_handler,
void *upgrade_handler_cls)
MHD_FN_PAR_NONNULL_ (1) MHD_FN_PAR_NONNULL_ (2);
void *upgrade_handler_cls,
size_t num_headers,
const struct MHD_NameValueCStr *headers)
MHD_FN_PAR_NONNULL_ (1);
/* ********************** (e) Client auth ********************** */
@@ -6452,7 +6170,7 @@ MHD_FN_PAR_NONNULL_ (1) MHD_FN_PAR_NONNULL_ (2);
*
* @warning Not used directly by MHD API.
*/
enum MHD_DigestBaseAlgo
enum MHD_FIXED_ENUM_MHD_APP_SET_ MHD_DigestBaseAlgo
{
/**
* Invalid hash algorithm value
@@ -6476,7 +6194,7 @@ enum MHD_DigestBaseAlgo
* As specified by FIPS PUB 180-4
*/
MHD_DIGEST_BASE_ALGO_SHA512_256 = (1 << 2)
} MHD_FIXED_FLAGS_ENUM_;
};
/**
* The flag indicating non-session algorithm types,
@@ -6493,7 +6211,7 @@ enum MHD_DigestBaseAlgo
/**
* Digest algorithm identification
*/
enum MHD_DigestAuthAlgo
enum MHD_FIXED_ENUM_MHD_APP_SET_ MHD_DigestAuthAlgo
{
/**
* Unknown or wrong algorithm type.
@@ -6565,10 +6283,8 @@ MHD_FN_CONST_;
*
* #MHD_DigestAuthAlgo always can be casted to #MHD_DigestAuthMultiAlgo, but
* not vice versa.
*
* @note Available since #MHD_VERSION 0x00097701
*/
enum MHD_DigestAuthMultiAlgo
enum MHD_FIXED_ENUM_MHD_APP_SET_ MHD_DigestAuthMultiAlgo
{
/**
* Unknown or wrong algorithm type.
@@ -6796,7 +6512,7 @@ MHD_FN_PAR_OUT_SIZE_(4,3);
* * (value >= MHD_DIGEST_AUTH_UNAME_TYPE_STANDARD) is true if username is
* provided in clear text (no userhash matching is needed)
*/
enum MHD_DigestAuthUsernameType
enum MHD_FIXED_ENUM_MHD_SET_ MHD_DigestAuthUsernameType
{
/**
* No username parameter in in Digest Authorization header.
@@ -6833,12 +6549,12 @@ enum MHD_DigestAuthUsernameType
* * 'username' is not hexadecimal string, while 'userhash' set to 'true'
*/
MHD_DIGEST_AUTH_UNAME_TYPE_INVALID = (1 << 0)
} MHD_FIXED_ENUM_;
};
/**
* The QOP ('quality of protection') types.
*/
enum MHD_DigestAuthQOP
enum MHD_FIXED_ENUM_MHD_APP_SET_ MHD_DigestAuthQOP
{
/**
* Invalid/unknown QOP.
@@ -6867,7 +6583,7 @@ enum MHD_DigestAuthQOP
* Not supported by MHD for authentication.
*/
MHD_DIGEST_AUTH_QOP_AUTH_INT = 1 << 2
} MHD_FIXED_FLAGS_ENUM_;
};
/**
* The QOP ('quality of protection') types, multiple selection.
@@ -6875,7 +6591,7 @@ enum MHD_DigestAuthQOP
* #MHD_DigestAuthQOP always can be casted to #MHD_DigestAuthMultiQOP, but
* not vice versa.
*/
enum MHD_DigestAuthMultiQOP
enum MHD_FIXED_ENUM_MHD_APP_SET_ MHD_DigestAuthMultiQOP
{
/**
* Invalid/unknown QOP.
@@ -6919,7 +6635,7 @@ enum MHD_DigestAuthMultiQOP
*/
MHD_DIGEST_AUTH_MULT_QOP_AUTH_ANY =
MHD_DIGEST_AUTH_QOP_AUTH | MHD_DIGEST_AUTH_QOP_AUTH_INT
} MHD_FIXED_ENUM_;
};
/**
* The invalid value of 'nc' parameter in client Digest Authorization header.
@@ -6929,19 +6645,13 @@ enum MHD_DigestAuthMultiQOP
/**
* Information from Digest Authorization client's header.
*
* All buffers pointed by any struct members are freed when #MHD_free() is
* called for pointer to this structure.
*
* Application may modify buffers as needed until #MHD_free() is called for
* pointer to this structure
* @see #MHD_REQUEST_INFO_DYNAMIC_DAUTH_REQ_INFO
*/
struct MHD_DigestAuthInfo
{
/**
* The algorithm as defined by client.
* Set automatically to MD5 if not specified by client.
* @warning Do not be confused with #MHD_DigestAuthAlgorithm,
* which uses other values!
*/
enum MHD_DigestAuthAlgo algo;
@@ -6956,32 +6666,26 @@ struct MHD_DigestAuthInfo
* If extended notation is used, this string is pct-decoded string
* with charset and language tag removed (i.e. it is original username
* extracted from the extended notation).
* When userhash is used by the client, this member is NULL and
* When userhash is used by the client, the string pointer is NULL and
* @a userhash_hex and @a userhash_bin are set.
* The buffer pointed by the @a username becomes invalid when the pointer
* to the structure is freed by #MHD_free(). // FIXME: remove?
*/
struct MHD_String username;
struct MHD_StringNullable username;
/**
* The userhash string.
* Valid only if username type is userhash.
* This is unqoted string without decoding of the hexadecimal
* digits (as provided by the client).
* The buffer pointed by the @a userhash_hex becomes invalid when the pointer
* to the structure is freed by #MHD_free().
* @sa #MHD_digest_auth_calc_userhash_hex()
*/
struct MHD_String userhash_hex;
struct MHD_StringNullable userhash_hex;
/**
* The userhash decoded to binary form.
* Used only if username type is userhash, always NULL otherwise.
* When not NULL, this points to binary sequence @a userhash_hex_len /2 bytes
* When not NULL, this points to binary sequence @a userhash_bin_size bytes
* long.
* The valid size should be #MHD_digest_get_hash_size(algo) bytes.
* The buffer pointed by the @a userhash_bin becomes invalid when the pointer
* to the structure is freed by #MHD_free().
* @warning This is a binary data, no zero termination.
* @warning To avoid buffer overruns, always check the size of the data before
* use, because @a userhash_bin can point even to zero-sized
@@ -6991,20 +6695,22 @@ struct MHD_DigestAuthInfo
uint8_t *userhash_bin;
/**
* The 'opaque' parameter value, as specified by client.
* NULL if not specified by client.
* The buffer pointed by the @a opaque becomes invalid when the pointer
* to the structure is freed by #MHD_free().
* The size of the data pointed by @a userhash_bin.
* Always zero when @a userhash_bin is NULL.
*/
struct MHD_String opaque;
size_t userhash_bin_size;
/**
* The 'opaque' parameter value, as specified by client.
* If not specified by client then string pointer is NULL.
*/
struct MHD_StringNullable opaque;
/**
* The 'realm' parameter value, as specified by client.
* NULL if not specified by client.
* The buffer pointed by the @a realm becomes invalid when the pointer
* to the structure is freed by #MHD_free().
* If not specified by client then string pointer is NULL.
*/
struct MHD_String realm;
struct MHD_StringNull realm;
/**
* The 'qop' parameter value.
@@ -7030,41 +6736,20 @@ struct MHD_DigestAuthInfo
* If not specified by client or does not have hexadecimal digits only, the
* value is #MHD_DIGEST_AUTH_INVALID_NC_VALUE.
*/
uint32_t nc;
uint_fast32_t nc;
};
// TODO: replace with introspection with possible failure for out-of-memory
/**
* Get information about Digest Authorization client's header.
*
* @param connection The MHD connection structure
* @return NULL if no valid Digest Authorization header is used in the request;
* a pointer to the structure with information if the valid request
* header found, free using #MHD_free().
* @sa #MHD_digest_auth_get_username()
* @ingroup authentication
*/
MHD_EXTERN_ struct MHD_DigestAuthInfo *
MHD_digest_auth_get_request_info (struct MHD_Request *request)
MHD_FN_PAR_NONNULL_ALL_;
/**
* Information from Digest Authorization client's header.
*
* All buffers pointed by any struct members are freed when #MHD_free() is
* called for pointer to this structure.
*
* Application may modify buffers as needed until #MHD_free() is called for
* pointer to this structure
* @see #MHD_REQUEST_INFO_DYNAMIC_DAUTH_USERNAME_INFO
*/
struct MHD_DigestAuthUsernameInfo
{
/**
* The algorithm as defined by client.
* Set automatically to MD5 if not specified by client.
* @warning Do not be confused with #MHD_DigestAuthAlgorithm,
* which uses other values!
*/
enum MHD_DigestAuthAlgo algo;
@@ -7117,32 +6802,13 @@ struct MHD_DigestAuthUsernameInfo
};
// TODO: replace with introspection with possible failure for out-of-memory
/**
* Get the username from Digest Authorization client's header.
*
* @param connection The MHD connection structure
* @return NULL if no valid Digest Authorization header is used in the request,
* or no username parameter is present in the header, or username is
* provided incorrectly by client (see description for
* #MHD_DIGEST_AUTH_UNAME_TYPE_INVALID);
* a pointer structure with information if the valid request header
* found, free using #MHD_free().
* @sa #MHD_digest_auth_get_request_info() provides more complete information
* @ingroup authentication
*/
MHD_EXTERN_ struct MHD_DigestAuthUsernameInfo *
MHD_digest_auth_get_username (struct MHD_Connection *connection)
MHD_FN_PAR_NONNULL_ALL_;
/**
* The result of digest authentication of the client.
*
* All error values are zero or negative.
* // TODO: renumber
*/
enum MHD_DigestAuthResult
enum MHD_FIXED_ENUM_MHD_SET_ MHD_DigestAuthResult
{
/**
* Authentication OK.
@@ -7364,7 +7030,7 @@ MHD_digest_auth_check_digest (struct MHD_Request *request,
const void *userdigest,
size_t userdigest_size,
unsigned int nonce_timeout,
uint32_t max_nc,
uint_fast32_t max_nc,
enum MHD_DigestAuthMultiQOP mqop,
enum MHD_DigestAuthMultiAlgo malgo)
MHD_FN_PAR_NONNULL_ALL_
@@ -7451,8 +7117,8 @@ MHD_FN_PAR_CSTR_(3) MHD_FN_PAR_CSTR_(4) MHD_FN_PAR_NONNULL_ (5);
/**
* Constant to indicate that the nonce of the provided
* authentication code was wrong.
* Used as return code by #MHD_digest_auth_check(), #MHD_digest_auth_check2(), // TODO: remove old references
* #MHD_digest_auth_check_digest(), #MHD_digest_auth_check_digest2().
* Used as return code by #MHD_digest_auth_check(),
* #MHD_digest_auth_check_digest()
* @ingroup authentication
*/
#define MHD_INVALID_NONCE -1
@@ -7461,58 +7127,22 @@ MHD_FN_PAR_CSTR_(3) MHD_FN_PAR_CSTR_(4) MHD_FN_PAR_NONNULL_ (5);
/**
* Information decoded from Basic Authentication client's header.
*
* The username and the password are technically allowed to have binary zeros,
* username_len and password_len could be used to detect such situations.
*
* The buffers pointed by username and password members are freed
* when #MHD_free() is called for pointer to this structure.
*
* Application may modify buffers as needed until #MHD_free() is called for
* pointer to this structure
* @see #MHD_REQUEST_INFO_DYNAMIC_BAUTH_REQ_INFO
*/
struct MHD_BasicAuthInfo
{
/**
* The username, cannot be NULL.
* The buffer pointed by the @a username becomes invalid when the pointer
* to the structure is freed by #MHD_free().
* The username
*/
char *username;
struct MHD_String username;
/**
* The length of the @a username, not including zero-termination
* The password, string pointer may be NULL if password is not encoded
* by the client.
*/
size_t username_len;
/**
* The password, may be NULL if password is not encoded by the client.
* The buffer pointed by the @a password becomes invalid when the pointer
* to the structure is freed by #MHD_free().
*/
char *password;
/**
* The length of the @a password, not including zero-termination;
* when the @a password is NULL, the length is always zero.
*/
size_t password_len;
struct MHD_StringNullable password;
};
// TODO: convert to introspection
/**
* Get the username and password from the Basic Authorisation header
* sent by the client
*
* @param connection the MHD connection structure
* @return NULL if no valid Basic Authentication header is present in
* current request, or
* pointer to structure with username and password, which must be
* freed by #MHD_free().
* @ingroup authentication
*/
MHD_EXTERN_ struct MHD_BasicAuthInfo *
MHD_basic_auth_get_username_password3 (struct MHD_Connection *connection);
/**
* Send a response to request basic authentication from the client.
*
@@ -7542,426 +7172,1616 @@ MHD_queue_basic_auth_required_response (struct MHD_Connection *connection,
/* ********************** (f) Introspection ********************** */
/**
* Select which member of the `struct ConnectionInformation`
* union is desired to be returned by #MHD_connection_get_info().
* Types of information about MHD,
* used by #MHD_lib_get_info_fixed_sz().
* This information is not changed at run-time.
*/
enum MHD_ConnectionInformationType
enum MHD_FIXED_ENUM_APP_SET_ MHD_LibInfoFixed
{
/* * Basic MHD information * */
/**
* Get the MHD version as a number.
* The result is placed in @a v_uint32 member.
*/
MHD_LIB_INFO_FIXED_VERSION_NUM = 0
,
/**
* Get the MHD version as a string.
* The result is placed in @a v_string member.
*/
MHD_LIB_INFO_FIXED_VERSION_STR = 1
,
/* * Basic MHD features, buid-time configurable * */
/* These features should be always available unless the library was
* not compiled specifically for some embedded project.
* Exceptions are marked explicitly in the description. */
/**
* Get whether messages are supported. If supported then in debug
* mode messages can be printed to stderr or to external logger.
* The result is placed in @a v_bool member.
*/
MHD_LIB_INFO_FIXED_HAS_MESSAGES = 11
,
/**
* Get whether MHD supports threads.
* The result is placed in @a v_bool member.
*/
MHD_LIB_INFO_FIXED_HAS_THREADS = 12
,
/**
* Get whether MHD was built with asserts enabled.
* Enabled only on special debug builds.
* For debug builds the error log is always enabled.
* The result is placed in @a v_bool member.
*/
MHD_LIB_INFO_FIXED_HAS_DEBUG = 13
,
/**
* Get whether automatic parsing of HTTP Cookie header is supported.
* If disabled, no #MHD_COOKIE_KIND will be generated by MHD.
* The result is placed in @a v_bool member.
*/
MHD_LIB_INFO_FIXED_HAS_COOKIE_PARSING = 14
,
/**
* Get whether postprocessor is supported. If supported then
* functions #MHD_create_post_processor(), #MHD_post_process() and
* #MHD_destroy_post_processor() can
* be used.
* The result is placed in @a v_bool member.
*/
MHD_LIB_INFO_FIXED_HAS_POSTPROCESSOR = 15
,
/**
* Get whether HTTP "Upgrade" is supported.
* If supported then #MHD_ALLOW_UPGRADE, #MHD_upgrade_action() and
* #MHD_create_response_for_upgrade() can be used.
* The result is placed in @a v_bool member.
*/
MHD_LIB_INFO_FIXED_HAS_UPGRADE = 16
,
/**
* 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.
* The result is placed in @a v_bool member.
*/
MHD_LIB_INFO_FIXED_HAS_BASIC_AUTH = 20
,
/**
* 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.
* The result is placed in @a v_bool member.
*/
MHD_LIB_INFO_FIXED_HAS_DIGEST_AUTH = 21
,
/**
* Get whether the early version the Digest Authorization (RFC 2069) is
* supported (digest authorisation without QOP parameter).
* Since #MHD_VERSION 0x00097701 it is always supported if Digest Auth
* module is built.
* The result is placed in @a v_bool member.
*/
MHD_LIB_INFO_FIXED_HAS_DIGEST_AUTH_RFC2069 = 22
,
/**
* Get whether the MD5-based hashing algorithms are supported for Digest
* Authorization and the type of the implementation if supported.
* Currently it is always supported if Digest Auth module is built
* unless manually disabled in a custom build.
* The result is placed in @a v_d_algo member.
*/
MHD_LIB_INFO_FIXED_TYPE_DIGEST_AUTH_MD5 = 23
,
/**
* Get whether the SHA-256-based hashing algorithms are supported for Digest
* Authorization and the type of the implementation if supported.
* Currently it is always supported if Digest Auth module is built
* unless manually disabled in a custom build.
* The result is placed in @a v_d_algo member.
*/
MHD_LIB_INFO_FIXED_TYPE_DIGEST_AUTH_SHA256 = 24
,
/**
* Get whether the SHA-512/256-based hashing algorithms are supported
* Authorization and the type of the implementation if supported.
* Currently it is always supported if Digest Auth module is built
* unless manually disabled in a custom build.
* The result is placed in @a v_d_algo member.
*/
MHD_LIB_INFO_FIXED_TYPE_DIGEST_AUTH_SHA512_256 = 25
,
/**
* Get whether QOP with value 'auth-int' (authentication with integrity
* protection) is supported for Digest Authorization.
* Currently it is always not supported.
* The result is placed in @a v_bool member.
*/
MHD_LIB_INFO_FIXED_HAS_DIGEST_AUTH_AUTH_INT = 28
,
/**
* Get whether 'session' algorithms (like 'MD5-sess') are supported for Digest
* Authorization.
* Currently it is always not supported.
* The result is placed in @a v_bool member.
*/
MHD_LIB_INFO_FIXED_HAS_DIGEST_AUTH_ALGO_SESSION = 29
,
/**
* Get whether 'userhash' is supported for Digest Authorization.
* Currently it is always supported if Digest Auth module is built.
* The result is placed in @a v_bool member.
*/
MHD_LIB_INFO_FIXED_HAS_DIGEST_AUTH_USERHASH = 30
,
/* * Platform-dependent features, some are configurable at build-time * */
/* These features depends on the platform, third-party libraries and
* the toolchain.
* Some of the features can be disabled or selected at build-time. */
/**
* Get supported sockets polling function/techniques.
* The result is placed in @a v_polling member.
*/
MHD_LIB_INFO_FIXED_TYPE_SOCKETS_POLLING = 50
,
/**
* Get whether aggregate FD external polling is supported.
* The result is placed in @a v_polling member.
*/
MHD_LIB_INFO_FIXED_HAS_AGGREGATE_FD = 51
,
/**
* Get whether IPv6 is supported on the platform and whether IPv6 without IPv4
* can be used.
* The result is placed in @a v_ipv6 member.
* @note The platform may have disabled IPv6 at run-time, it is not checked
* by this information type.
*/
MHD_LIB_INFO_FIXED_TYPE_IPv6 = 52
,
/**
* 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.
* The result is placed in @a v_bool member.
*/
MHD_LIB_INFO_FIXED_HAS_TCP_FASTOPEN = 53
,
/**
* Get whether MHD support automatic detection of bind port number.
* @sa #MHD_DAEMON_INFO_BIND_PORT
* The result is placed in @a v_bool member.
*/
MHD_LIB_INFO_FIXED_HAS_AUTODETECT_BIND_PORT = 54
,
/**
* Get whether MHD use system's sendfile() function to send
* file-FD based responses over non-TLS connections.
* The result is placed in @a v_bool member.
*/
MHD_LIB_INFO_FIXED_HAS_SENDFILE = 55
,
/**
* Get whether MHD supports automatic SIGPIPE suppression.
* If SIGPIPE suppression is not supported, application must handle
* SIGPIPE signal by itself.
* The result is placed in @a v_bool member.
*/
MHD_LIB_INFO_FIXED_HAS_AUTOSUPPRESS_SIGPIPE = 60
,
/**
* Get whether MHD sets names on generated threads.
* The result is placed in @a v_bool member.
*/
MHD_LIB_INFO_FIXED_HAS_THREAD_NAMES = 61
,
/**
* Get the type of supported inter-thread communication.
* The result is placed in @a v_itc member.
*/
MHD_LIB_INFO_FIXED_TYPE_ITC = 62
,
/**
* 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.
* The result is placed in @a v_bool member.
*/
MHD_LIB_INFO_FIXED_HAS_LARGE_FILE = 63
,
/* * Platform-dependent features, some set on startup and some are
* configurable at build-time * */
/* These features depends on the platform, third-party libraries availability
* and configuration. The features can be enabled/disabled during startup
* of the library depending on conditions.
* Some of the features can be disabled or selected at build-time. */
/**
* Get whether HTTPS is supported and type of TLS backend(s) available if
* HTTPS is supported.
* The result is placed in @a v_tls member.
*/
MHD_LIB_INFO_FIXED_TYPE_TLS = 100
,
/**
* Get whether option #MHD_OPTION_HTTPS_CERT_CALLBACK is
* supported.
* The result is placed in @a v_bool member.
*/
MHD_LIB_INFO_FIXED_HAS_TLS_CERT_CALLBACK = 101
,
/**
* Get whether password encrypted private key for HTTPS daemon is
* supported. If supported then option
* ::MHD_OPTION_HTTPS_KEY_PASSWORD can be used.
* The result is placed in @a v_bool member.
*/
MHD_LIB_INFO_FIXED_HAS_TLS_KEY_PASSWORD = 102
,
/**
* Get whether option #MHD_OPTION_HTTPS_CERT_CALLBACK2 is
* supported.
* The result is placed in @a v_bool member.
*/
MHD_LIB_INFO_FIXED_HAS_TLS_CERT_CALLBACK2 = 103
,
/* * Sentinel * */
/**
* The sentinel value.
* This value enforces specific underlying integer type for the enum.
* Do not use.
*/
MHD_LIB_INFO_FIXED_SENTINEL = 65535
};
/**
* The type of the data for digest algorithm implementations.
*/
enum MHD_FIXED_ENUM_MHD_SET_ MHD_LibInfoFixedDigestAlgoType
{
/**
* What cipher algorithm is being used.
* Takes no extra arguments.
* @ingroup request
* The algorithm is not implemented or disabled at the build time.
*/
MHD_CONNECTION_INFORMATION_CIPHER_ALGO,
MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_NOT_AVAILABLE = 0
,
/**
*
* Takes no extra arguments.
* @ingroup request
* The algorithm is implemented by MHD internal code.
*/
MHD_CONNECTION_INFORMATION_PROTOCOL,
MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_BUILT_IN = 1
,
/**
* Obtain IP address of the client. Takes no extra arguments.
* Returns essentially a `struct sockaddr **` (since the API returns
* a `union MHD_ConnectionInfo *` and that union contains a `struct
* sockaddr *`).
* @ingroup request
* The algorithm is implemented by external code that never fails.
*/
MHD_CONNECTION_INFORMATION_CLIENT_ADDRESS,
MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_EXTERNAL_NEVER_FAIL = 2
,
/**
* Get the gnuTLS session handle.
* @ingroup request
* The algorithm is implemented by external code that may hypothetically fail.
*/
MHD_CONNECTION_INFORMATION_GNUTLS_SESSION,
MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_EXTERNAL_MAY_FAIL = 3
};
/**
* The types of the sockets polling functions/techniques supported
*/
struct MHD_LibInfoFixedPollingFunc
{
/**
* Get the gnuTLS client certificate handle. Dysfunctional (never
* implemented, deprecated). Use #MHD_CONNECTION_INFORMATION_GNUTLS_SESSION
* to get the `gnutls_session_t` and then call
* gnutls_certificate_get_peers().
* select() function for sockets polling
*/
MHD_CONNECTION_INFORMATION_GNUTLS_CLIENT_CERT,
enum MHD_Bool func_select;
/**
* Get the `struct MHD_Daemon *` responsible for managing this connection.
* @ingroup request
* poll() function for sockets polling
*/
MHD_CONNECTION_INFORMATION_DAEMON,
enum MHD_Bool func_poll;
/**
* Request the file descriptor for the connection socket.
* No extra arguments should be passed.
* @ingroup request
* epoll technique for sockets polling
*/
MHD_CONNECTION_INFORMATION_CONNECTION_FD,
enum MHD_Bool tech_epoll;
};
/**
* The types of IPv6 supported
*/
enum MHD_FIXED_ENUM_MHD_SET_ MHD_LibInfoFixedIPv6Type
{
/**
* Returns the client-specific pointer to a `void *` that was (possibly)
* set during a #MHD_NotifyConnectionCallback when the socket was
* first accepted. Note that this is NOT the same as the "req_cls"
* argument of the #MHD_AccessHandlerCallback. The "req_cls" is
* fresh for each HTTP request, while the "socket_context" is fresh
* for each socket.
* IPv6 is not supported by this MHD build
*/
MHD_CONNECTION_INFORMATION_SOCKET_CONTEXT,
MHD_LIB_INFO_FIXED_IPV6_TYPE_NONE = 0
,
/**
* Get connection timeout
* @ingroup request
* IPv6 is supported only as "dual stack".
* IPv4 connections can be received by IPv6 listen socket.
*/
MHD_CONNECTION_INFORMATION_CONNECTION_TIMEOUT,
MHD_LIB_INFO_FIXED_IPV6_TYPE_DUAL_ONLY = 1
,
/**
* Check whether the connection is suspended.
* @ingroup request
* IPv6 is supported as IPv6-only or as "dual stack".
*/
MHD_CONNECTION_INFORMATION_CONNECTION_SUSPENDED
MHD_LIB_INFO_FIXED_IPV6_TYPE_BOTH = 2
};
/**
* The types of inter-thread communication
* @note the enum can be extended in future versions with new values
*/
enum MHD_FIXED_ENUM_MHD_SET_ MHD_LibInfoFixedITCType
{
/**
* The pair of sockets are used as inter-thread communication.
* The is the least efficient method of communication.
*/
MHD_LIB_INFO_FIXED_ITC_TYPE_SOCKETPAIR = 0
,
/**
* The pipe is used as inter-thread communication.
*/
MHD_LIB_INFO_FIXED_ITC_TYPE_PIPE = 1
,
/**
* The EventFD is used as inter-thread communication.
* This is the most efficient method of communication.
*/
MHD_LIB_INFO_FIXED_ITC_TYPE_EVENTFD = 2
};
/**
* Information about a connection.
* The types of the TLS backend supported
* @note the enum can be extended in future versions with new members
*/
union MHD_ConnectionInformation
struct MHD_LibInfoFixedTLSType
{
/**
* The TLS is supported.
* Set to #MHD_YES if any other member is #MHD_YES.
*/
enum MHD_Bool tls_supported;
/**
* The TLS is supported by GnuTLS backend.
*/
enum MHD_Bool tls_gnutls;
};
/**
* The data provided by #MHD_lib_get_info_fixed_sz()
*/
union MHD_LibInfoFixedData
{
/**
* The 32-bit unsigned integer value
*/
uint_fast32_t v_uint32;
/**
* The MHD string value
*/
struct MHD_String v_string;
/**
* The boolean value
*/
enum MHD_Bool v_bool;
/**
* The type of digest algorithm implemtation
*/
enum MHD_LibInfoFixedDigestAlgoType v_d_algo;
/**
* The types of the sockets polling functions/techniques supported
*/
struct MHD_LibInfoFixedPollingFunc v_polling;
/**
* The type of IPv6 supported
*/
enum MHD_LibInfoFixedIPv6Type v_ipv6;
/**
* The type of inter-thread communication
*/
enum MHD_LibInfoFixedITCType v_itc;
/**
* The types of the TLS backend supported
*/
struct MHD_LibInfoFixedTLSType v_tls;
};
/**
* Get fixed information about MHD that is not changed at run-time.
* The returned information can be cached by application as it will be not
* changed at run-time.
* The wrapper macro #MHD_lib_get_info_fixed() could be more convenient.
*
* @param info_type the type of requested information
* @param[out] return_data the pointer to union to be set to the required
* information
* @param return_data_size the size of the memory area pointed
* by @a return_data, in bytes
* @return #MHD_SC_OK if succeed,
* error code otherwise
* @ingroup specialized
*/
MHD_EXTERN_ enum MHD_StatusCode
MHD_lib_get_info_fixed_sz (enum MHD_LibInfoFixed info_type,
union MHD_LibInfoFixedData *return_data,
size_t return_data_size)
MHD_FN_PAR_NONNULL_(2) MHD_FN_PAR_OUT_SIZE_(2,3)
MHD_FN_PURE_;
/**
* Get fixed information about MHD that is not changed at run-time.
* The returned information can be cached by application as it will be not
* changed at run-time.
*
* @param info the type of requested information
* @param[out] data the pointer to union to set to the required information
* @return #MHD_SC_OK if succeed,
* error code otherwise
* @ingroup specialized
*/
#define MHD_lib_get_info_fixed(info,data) \
MHD_lib_get_info_fixed_sz((info),(data),sizeof(*(data)))
/**
* Types of information about MHD,
* used by #MHD_lib_get_dymanic_info_sz().
* This information may vary over time.
*/
enum MHD_FIXED_ENUM_APP_SET_ MHD_LibInfoDynamic
{
/* * Basic MHD information * */
/**
* Cipher algorithm used, of type "enum gnutls_cipher_algorithm".
* Get whether MHD was successfully initialised.
* The result is #MHD_NO when the library has not been yet initialised or
* when library has been de-initialised.
* Under normal conditions the result must be always #MHD_YES when requested
* by application.
* The result is placed in @a v_bool member.
*/
int /* enum gnutls_cipher_algorithm */ cipher_algorithm;
MHD_LIB_INFO_DYNAMIC_INITED = 0
,
/* * Sentinel * */
/**
* Protocol used, of type "enum gnutls_protocol".
* The sentinel value.
* This value enforces specific underlying integer type for the enum.
* Do not use.
*/
int /* enum gnutls_protocol */ protocol;
/**
* Amount of second that connection could spend in idle state
* before automatically disconnected.
* Zero for no timeout (unlimited idle time).
*/
unsigned int connection_timeout;
/**
* Connect socket
*/
MHD_socket connect_fd;
/**
* GNUtls session handle, of type "gnutls_session_t".
*/
void * /* gnutls_session_t */ tls_session;
/**
* GNUtls client certificate handle, of type "gnutls_x509_crt_t".
*/
void * /* gnutls_x509_crt_t */ client_cert;
/**
* Address information for the client.
*/
const struct sockaddr *client_addr;
/**
* Which daemon manages this connection (useful in case there are many
* daemons running).
*/
struct MHD_Daemon *daemon;
/**
* Pointer to connection-specific client context. Points to the
* same address as the "socket_context" of the
* #MHD_NotifyConnectionCallback.
*/
void **socket_context;
/**
* Is this connection right now suspended?
*/
enum MHD_Bool suspended;
MHD_LIB_INFO_DYNAMIC_SENTINEL = 65535
};
/**
* Obtain information about the given connection.
* Use wrapper macro #MHD_connection_get_information() instead of direct use
* of this function.
*
* @param connection what connection to get information about
* @param info_type what information is desired?
* @param[out] return_value pointer to union where requested information will
* be stored
* @param return_value_size size of union MHD_ConnectionInformation at compile
* time
* @return #MHD_YES on success, #MHD_NO on error
* (@a info_type is unknown, NULL pointer etc.)
* @ingroup specialized
* The data provided by #MHD_lib_get_dynamic_info_sz().
* The resulting value may vary over time.
*/
MHD_EXTERN_ enum MHD_Bool
MHD_connection_get_information_sz (struct MHD_Connection *connection,
enum MHD_ConnectionInformationType info_type,
union MHD_ConnectionInformation *return_value
,
size_t return_value_size)
MHD_FN_PAR_NONNULL_ (1,3);
/**
* Obtain information about the given connection.
*
* @param connection what connection to get information about
* @param info_type what information is desired?
* @param[out] return_value pointer to union where requested information will
* be stored
* @return #MHD_YES on success, #MHD_NO on error
* (@a info_type is unknown, NULL pointer etc.)
* @ingroup specialized
*/
#define MHD_connection_get_information(connection, \
info_type, \
return_value) \
MHD_connection_get_information_sz ((connection),(info_type),(return_value), \
sizeof(union MHD_ConnectionInformation))
/**
* Information we return about a request.
*/
union MHD_RequestInformation
{
/**
* Connection via which we received the request.
*/
struct MHD_Connection *connection;
/**
* Pointer to client context. Will also be given to
* the application in a #MHD_RequestTerminationCallback.
*/
void **request_context;
/**
* HTTP version requested by the client.
*/
const char *http_version;
/**
* HTTP method of the request, as a string. Particularly useful if
* #MHD_HTTP_METHOD_UNKNOWN was given.
*/
const char *http_method;
/**
* Size of the client's HTTP header.
*/
size_t header_size;
};
/**
* Select which member of the `struct RequestInformation`
* union is desired to be returned by #MHD_request_get_info().
*/
enum MHD_RequestInformationType
union MHD_LibInfoDynamicData
{
/**
* Return which connection the request is associated with.
* The boolean value
*/
MHD_REQUEST_INFORMATION_CONNECTION,
enum MHD_Bool v_bool;
/**
* Returns the client-specific pointer to a `void *` that
* is specific to this request.
* Unused member.
* Help enforcing future-proof alignment of the union.
* Do not use.
*/
MHD_REQUEST_INFORMATION_CLIENT_CONTEXT,
/**
* Return the HTTP version string given by the client.
* @ingroup request
*/
MHD_REQUEST_INFORMATION_HTTP_VERSION,
/**
* Return the HTTP method used by the request.
* @ingroup request
*/
MHD_REQUEST_INFORMATION_HTTP_METHOD,
/**
* Return length of the client's HTTP request header.
* @ingroup request
*/
MHD_REQUEST_INFORMATION_HEADER_SIZE
void *reserved;
};
/**
* Obtain information about the given request.
* Use wrapper macro #MHD_request_get_information() instead of direct use
* of this function.
* Get dynamic information about MHD that may be changed at run-time.
* The wrapper macro #MHD_lib_get_info_dynamic() could be more convenient.
*
* @param request what request to get information about
* @param info_type what information is desired?
* @param[out] return_value pointer to union where requested information will
* be stored
* @param return_value_size size of union MHD_RequestInformation at compile
* time
* @return #MHD_YES on success, #MHD_NO on error
* (@a info_type is unknown, NULL pointer etc.)
* @param info_type the type of requested information
* @param[out] return_data the pointer to union to be set to the required
* information
* @param return_data_size the size of the memory area pointed
* by @a return_data, in bytes
* @return #MHD_SC_OK if succeed,
* error code otherwise
* @ingroup specialized
*/
MHD_EXTERN_ enum MHD_Bool
MHD_request_get_information_sz (struct MHD_Request *request,
enum MHD_RequestInformationType info_type,
union MHD_RequestInformation *return_value,
size_t return_value_size)
MHD_FN_PAR_NONNULL_ (1) MHD_FN_PAR_NONNULL_ (3);
MHD_EXTERN_ enum MHD_StatusCode
MHD_lib_get_info_dynamic_sz (enum MHD_LibDynamicInfo info_type,
union MHD_LibDynamicInfoData *return_data,
size_t return_data_size)
MHD_FN_PAR_NONNULL_(2) MHD_FN_PAR_OUT_SIZE_(2,3);
/**
* Obtain information about the given request.
* Get dynamic information about MHD that may be changed at run-time.
*
* @param request what request to get information about
* @param info_type what information is desired?
* @param[out] return_value pointer to union where requested information will
* be stored
* @return #MHD_YES on success, #MHD_NO on error
* (@a info_type is unknown, NULL pointer etc.)
* @param info the type of requested information
* @param[out] data the pointer to union to set to the required information
* @return #MHD_SC_OK if succeed,
* error code otherwise
* @ingroup specialized
*/
#define MHD_request_get_information (request, \
info_type, \
return_value) \
MHD_request_get_information_sz ((request), (info_type), (return_value), \
sizeof(union MHD_RequestInformation))
#define MHD_lib_get_info_dynamic(info,data) \
MHD_lib_get_info_fixed_sz((info),(data),sizeof(*(data)))
/**
* Values of this enum are used to specify what
* information about a daemon is desired.
* This types of information are not changed at after start of the daemon until
* the daemon is destroyed.
*/
enum MHD_DaemonInformationType
enum MHD_DaemonInfoFixedType
{
/**
* Request the file descriptor for the listening socket.
* No extra arguments should be passed.
* The result is placed in @a v_socket member.
*/
MHD_DAEMON_INFORMATION_LISTEN_SOCKET,
MHD_DAEMON_INFO_FIXED_LISTEN_SOCKET = 1
,
/**
* Request the file descriptor for the external epoll.
* No extra arguments should be passed.
* Request the file descriptor for the single FD that triggered when
* any MHD event happens.
* This FD can be watched as aggregate indicator for all MHD events.
* The result is placed in @a v_fd member.
*/
MHD_DAEMON_INFORMATION_EPOLL_FD,
/**
* Request the number of current connections handled by the daemon.
* No extra arguments should be passed.
* Note: when using MHD in external polling mode, this type of request
* could be used only when #MHD_run()/#MHD_run_from_select is not
* working in other thread at the same time.
*/
MHD_DAEMON_INFORMATION_CURRENT_CONNECTIONS,
MHD_DAEMON_INFO_FIXED_AGGREAGATE_FD
,
/**
* Request the port number of daemon's listen socket.
* No extra arguments should be passed.
* Note: if port '0' was specified for #MHD_option_port(), returned
* value will be real port number.
* The result is placed in @a v_port member.
*/
MHD_DAEMON_INFORMATION_BIND_PORT
MHD_DAEMON_INFO_FIXED_BIND_PORT
,
/* * Sentinel * */
/**
* The sentinel value.
* This value enforces specific underlying integer type for the enum.
* Do not use.
*/
MHD_DAEMON_INFO_FIXED_SENTINEL = 65535
};
/**
* Information about an MHD daemon.
*/
union MHD_DaemonInformation
union MHD_DaemonInfoFixedData
{
/**
* Socket, returned for #MHD_DAEMON_INFORMATION_LISTEN_SOCKET.
* The socket type of data.
*/
MHD_socket listen_socket;
MHD_socket v_socket;
/**
* Bind port number, returned for #MHD_DAEMON_INFORMATION_BIND_PORT.
* File descriptor, except sockets
*/
uint16_t port;
int v_fd;
/**
* epoll FD, returned for #MHD_DAEMON_INFORMATION_EPOLL_FD.
* Port number
*/
int epoll_fd;
uint_fast16_t v_port;
/**
* Number of active connections, for #MHD_DAEMON_INFORMATION_CURRENT_CONNECTIONS.
* Unused member.
* Help enforcing future-proof alignment of the union.
* Do not use.
*/
unsigned int num_connections;
void *reserved;
};
/**
* Obtain information about the given daemon.
* Use wrapper macro #MHD_daemon_get_information() instead of direct use
* of this function.
* Obtain fixed information about the given daemon.
* This information is not changed at after start of the daemon until
* the daemon is destroyed.
* The wrapper macro #MHD_daemon_get_info_fixed() could be more convenient.
*
* @param daemon what daemon to get information about
* @param info_type what information is desired?
* @param daemon the daemon to get information about
* @param info_type the type of information requested
* @param[out] return_value pointer to union where requested information will
* be stored
* @param return_value_size size of union MHD_DaemonInformation at compile
* time
* @return #MHD_YES on success, #MHD_NO on error
* (@a info_type is unknown, NULL pointer etc.)
* @param return_value_size the size of the memory area pointed
* by @a return_data, in bytes
* @return #MHD_SC_OK if succeed,
* error code otherwise
* @ingroup specialized
*/
MHD_EXTERN_ enum MHD_Bool
MHD_daemon_get_information_sz (struct MHD_Daemon *daemon,
enum MHD_DaemonInformationType info_type,
union MHD_DaemonInformation *return_value,
MHD_EXTERN_ enum MHD_StatusCode
MHD_daemon_get_info_fixed_sz (struct MHD_Daemon *daemon,
enum MHD_DaemonInfoFixedType info_type,
union MHD_DaemonInfoFixedData *return_value,
size_t return_value_size)
MHD_FN_PAR_NONNULL_ (1,3);
MHD_FN_PAR_NONNULL_ (1)
MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_INOUT_SIZE_(3,4)
MHD_FN_PURE_;
/**
* Obtain information about the given daemon.
* Obtain fixed information about the given daemon.
* This types of information are not changed at after start of the daemon until
* the daemon is destroyed.
*
* @param daemon what daemon to get information about
* @param info_type what information is desired?
* @param daemon the daemon to get information about
* @param info_type the type of information requested
* @param[out] return_value pointer to union where requested information will
* be stored
* @return #MHD_YES on success, #MHD_NO on error
* (@a info_type is unknown, NULL pointer etc.)
* @return #MHD_SC_OK if succeed,
* error code otherwise
* @ingroup specialized
*/
#define MHD_daemon_get_information(daemon, \
info_type, \
return_value) \
MHD_daemon_get_information_sz ((daemon), (info_type), (return_value), \
sizeof(union MHD_DaemonInformation));
#define MHD_daemon_get_info_fixed(daemon,info_type,return_value) \
MHD_daemon_get_info_fixed_sz ((daemon), (info_type), (return_value), \
sizeof(*(return_value)))
/**
* Values of this enum are used to specify what
* information about a daemon is desired.
* This types of information may be changed after the start of the daemon.
*/
enum MHD_DaemonInfoDynamicType
{
/**
* The the maximum number of microseconds from the current moment until
* the mandatory call of the daemon data processing function (like
* #MHD_deamon_process_reg_events(), #MHD_daemon_process_blocking()).
* If resulting value is zero then daemon data processing function should be
* called as soon as possible as some data processing is already pending.
* The data processing function can also be called earlier as well.
* Available only for daemons stated in #MHD_TM_EXTERNAL_PERIODIC,
* #MHD_TM_EXTERNAL_EVENT_LOOP_CB_LEVEL, #MHD_TM_EXTERNAL_EVENT_LOOP_CB_EDGE
* or #MHD_TM_EXTERNAL_SINGLE_FD_WATCH modes.
* The result is placed in @a v_uint64 member.
*/
MHD_DAEMON_INFO_DYNAMIC_MAX_TIME_TO_WAIT = 1
,
/**
* Request the number of current connections handled by the daemon.
* No extra arguments should be passed.
* Note: when using MHD in external polling mode, this type of request
* could be used only when #MHD_run()/#MHD_run_from_select is not
* working in other thread at the same time.
* The result is placed in @a v_uint member.
*/
MHD_DAEMON_INFO_DYNAMIC_CURRENT_CONNECTIONS = 20
,
/* * Sentinel * */
/**
* The sentinel value.
* This value enforces specific underlying integer type for the enum.
* Do not use.
*/
MHD_DAEMON_INFO_FIXED_SENTINEL = 65535
};
/**
* Information about an MHD daemon.
*/
union MHD_DaemonInfoDynamicData
{
/**
* Unsigned 64 bits integer value.
*/
uint_fast64_t v_uint64;
/**
* Unsigned integer value.
*/
unsigned int v_uint;
/**
* Unused member.
* Help enforcing future-proof alignment of the union.
* Do not use.
*/
void *reserved;
};
/**
* Obtain dynamic information about the given daemon.
* This information may be changed after the start of the daemon.
* The wrapper macro #MHD_daemon_get_info_dynamic() could be more convenient.
*
* @param daemon the daemon to get information about
* @param info_type the type of information requested
* @param[out] return_value pointer to union where requested information will
* be stored
* @param return_value_size the size of the memory area pointed
* by @a return_data, in bytes
* @return #MHD_SC_OK if succeed,
* error code otherwise
* @ingroup specialized
*/
MHD_EXTERN_ enum MHD_StatusCode
MHD_daemon_get_info_dynamic_sz (struct MHD_Daemon *daemon,
enum MHD_DaemonInfoDynamicType info_type,
union MHD_DaemonInfoDynamicData *return_value,
size_t return_value_size)
MHD_FN_PAR_NONNULL_ (1)
MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_INOUT_SIZE_(3,4);
/**
* Obtain dynamic information about the given daemon.
* This types of information may be changed after the start of the daemon.
*
* @param daemon the daemon to get information about
* @param info_type the type of information requested
* @param[out] return_value pointer to union where requested information will
* be stored
* @return #MHD_SC_OK if succeed,
* error code otherwise
* @ingroup specialized
*/
#define MHD_daemon_get_info_dynamic(daemon,info_type,return_value) \
MHD_daemon_get_info_dynamic_sz ((daemon), (info_type), (return_value), \
sizeof(*(return_value)))
/**
* Select which fixed information about connection is desired.
* This information is not changed during the lifetime of the connection.
*/
enum MHD_ConnectionInfoFixedType
{
/**
* Obtain IP address of the client.
* The result is placed in @a vs_sa member.
* @ingroup request
*/
MHD_CONNECTION_INFO_FIXED_CLIENT_ADDRESS = 1
,
/**
* Request the file descriptor for the connection socket.
* The result is placed in @a v_fd member.
* @ingroup request
*/
MHD_CONNECTION_INFO_FIXED_CONNECTION_FD = 2
,
/**
* Get the `struct MHD_Daemon *` responsible for managing this connection.
* The result is placed in @a v_daemon member.
* @ingroup request
*/
MHD_CONNECTION_INFO_FIXED_DAEMON = 20
,
/* * Sentinel * */
/**
* The sentinel value.
* This value enforces specific underlying integer type for the enum.
* Do not use.
*/
MHD_CONNECTION_INFO_FIXED_SENTINEL = 65535
};
/**
* Information about a connection.
*/
union MHD_ConnectionInfoFixedData
{
/**
* Socket Address type
*/
const struct sockaddr *vs_sa;
/**
* Socket type
*/
MHD_socket v_fd;
/**
* Daemon handler type
*/
struct MHD_Daemon *v_daemon;
};
/**
* Obtain fixed information about the given connection.
* This information is not changed for the lifetime of the connection.
* The wrapper macro #MHD_connection_get_info_fixed() could be more convenient.
*
* @param connection the connection to get information about
* @param info_type the type of information requested
* @param[out] return_value pointer to union where requested information will
* be stored
* @param return_value_size the size of the memory area pointed
by @a return_data, in bytes
* @return #MHD_SC_OK if succeed,
* error code otherwise
* @ingroup specialized
*/
MHD_EXTERN_ enum MHD_StatusCode
MHD_connection_get_info_fixed_sz (
struct MHD_Connection *connection,
enum MHD_ConnectionInfoFixedType info_type,
union MHD_ConnectionInfoFixedData *return_value,
size_t return_value_size)
MHD_FN_PAR_NONNULL_ (1)
MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_INOUT_SIZE_(3,4)
MHD_FN_PURE_;
/**
* Obtain fixed information about the given connection.
* This information is not changed for the lifetime of the connection.
*
* @param connection the connection to get information about
* @param info_type the type of information requested
* @param[out] return_value pointer to union where requested information will
* be stored
* @return #MHD_SC_OK if succeed,
* error code otherwise
* @ingroup specialized
*/
#define MHD_connection_get_info_fixed(connection,info_type,return_value) \
MHD_connection_get_info_fixed_sz ((connection),(info_type),(return_value), \
sizeof(*(return_value)))
/**
* Select which dynamic information about connection is desired.
* This information may be changed during the lifetime of the connection.
*/
enum MHD_ConnectionInfoDynamicType
{
/**
* Get current version of HTTP protocol used for connection.
* The result is placed in @a v_http_ver member.
* @ingroup request
*/
MHD_CONNECTION_INFO_DYNAMIC_HTTP_VER = 1
,
/**
* Get connection timeout.
* The result is placed in @a v_uint member.
* @ingroup request
*/
MHD_CONNECTION_INFO_DYNAMIC_CONNECTION_TIMEOUT = 10
,
/**
* Check whether the connection is suspended.
* The result is placed in @a v_bool member.
* @ingroup request
*/
MHD_CONNECTION_INFO_DYNAMIC_CONNECTION_SUSPENDED = 11
,
/**
* Returns the connection-specific application context data that was
* (possibly) set during a #MHD_NotifyConnectionCallback or provided vai
* @a connection_cntx parameter of #MHD_daemon_add_connection().
* The result is placed in @a v_pvoid member.
*/
MHD_CONNECTION_INFO_DYNAMIC_SOCKET_CONTEXT = 20
,
/**
* Get current version of TLS transport protocol used for connection
* The result is placed in @a v_tls_ver member.
* @ingroup request
*/
MHD_CONNECTION_INFO_DYNAMIC_TLS_VER = 1
,
/**
* Get the GnuTLS session handle.
* The result is placed in @a v_gnutls_session member.
* @ingroup request
*/
MHD_CONNECTION_INFO_DYNAMIC_GNUTLS_SESSION = 40
,
/* * Sentinel * */
/**
* The sentinel value.
* This value enforces specific underlying integer type for the enum.
* Do not use.
*/
MHD_CONNECTION_INFO_DYNAMIC_SENTINEL = 65535
};
/**
* The versions of TLS protocol
*/
enum MHD_FIXED_ENUM_MHD_SET_ MHD_TlsVersion
{
/**
* No TLS / plain socket connection
*/
MHD_TLS_VERSION_NO_TLS = 0
,
/**
* Not supported/failed to negotiate/failed to handshake TLS
*/
MHD_TLS_VERSION_BROKEN = 1
,
/**
* TLS version 1.0
*/
MHD_TLS_VERSION_1_0 = 2
,
/**
* TLS version 1.1
*/
MHD_TLS_VERSION_1_1 = 3
,
/**
* TLS version 1.2
*/
MHD_TLS_VERSION_1_2 = 4
,
/**
* TLS version 1.3
*/
MHD_TLS_VERSION_1_3 = 5
,
/**
* Some unknown TLS version.
* The TLS version is supported by TLS backend, but unknown to MHD.
*/
MHD_TLS_VERSION_UNKNOWN = 1999
};
/**
* Information about a connection.
*/
union MHD_ConnectionInfoDynamicData
{
/**
* The type for HTTP version
*/
enum MHD_HTTP_ProtocolVersion v_http_ver;
/**
* The unsigned integer type
*/
unsigned int v_uint;
/**
* The boolean type
*/
enum MHD_Bool v_bool;
/**
* The pointer to void type
*/
void *v_pvoid;
/**
* The TLS version
*/
enum MHD_TlsVersion v_tls_ver;
/* Include <gnutls/gnutls.h> before this header to get a better type safety */
/**
* GnuTLS session handle, of type "gnutls_session_t".
*/
#if defined(GNUTLS_VERSION_MAJOR) && GNUTLS_VERSION_MAJOR >= 3
gnutls_session_t
#else
void * /* gnutls_session_t */
#endif
v_gnutls_session;
};
/**
* Obtain dynamic information about the given connection.
* This information may be changed during the lifetime of the connection.
* The wrapper macro #MHD_connection_get_info_dynamic() could be more
* convenient.
*
* @param connection the connection to get information about
* @param info_type the type of information requested
* @param[out] return_value pointer to union where requested information will
* be stored
* @param return_value_size the size of the memory area pointed
by @a return_data, in bytes
* @return #MHD_SC_OK if succeed,
* error code otherwise
* @ingroup specialized
*/
MHD_EXTERN_ enum MHD_StatusCode
MHD_connection_get_info_dynamic_sz (
struct MHD_Connection *connection,
enum MHD_ConnectionInfoDynamicType info_type,
union MHD_ConnectionInfoDynamicData *return_value,
size_t return_value_size)
MHD_FN_PAR_NONNULL_ (1)
MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_INOUT_SIZE_(3,4);
/**
* Obtain dynamic information about the given connection.
* This information may be changed during the lifetime of the connection.
*
* @param connection the connection to get information about
* @param info_type the type of information requested
* @param[out] return_value pointer to union where requested information will
* be stored
* @return #MHD_SC_OK if succeed,
* error code otherwise
* @ingroup specialized
*/
#define MHD_connection_get_info_dynamic(connection,info_type,return_value) \
MHD_connection_get_info_dynamic_sz ((connection),(info_type),(return_value), \
sizeof(*(return_value)))
/**
* Select which fixed information about stream is desired.
* This information is not changed during the lifetime of the connection.
*/
enum MHD_FIXED_ENUM_APP_SET_ MHD_StreamInfoFixedType
{
/**
* Get the `struct MHD_Connection *` responsible for managing this stream.
* The result is placed in @a v_connection member.
* @ingroup request
*/
MHD_STREAM_INFO_FIXED_CONNECTION = 1
,
/**
* Get the `struct MHD_Daemon *` responsible for managing connection which
* is responsible for this stream.
* The result is placed in @a v_daemon member.
* @ingroup request
*/
MHD_STREAM_INFO_FIXED_DAEMON = 2
,
/* * Sentinel * */
/**
* The sentinel value.
* This value enforces specific underlying integer type for the enum.
* Do not use.
*/
MHD_STREAM_INFO_FIXED_SENTINEL = 65535
};
/**
* Fixed information about a stream.
*/
union MHD_StreamInfoFixedData
{
/**
* Connection handler type
*/
struct MHD_Connection *v_connection;
/**
* Daemon handler type
*/
struct MHD_Daemon *v_daemon;
};
/**
* Obtain fixed information about the given stream.
* This information is not changed for the lifetime of the stream.
* The wrapper macro #MHD_stream_get_info_fixed() could be more convenient.
*
* @param stream the stream to get information about
* @param info_type the type of information requested
* @param[out] return_value pointer to union where requested information will
* be stored
* @param return_value_size the size of the memory area pointed
* by @a return_data, in bytes
* @return #MHD_SC_OK if succeed,
* error code otherwise
* @ingroup specialized
*/
MHD_EXTERN_ enum MHD_StatusCode
MHD_stream_get_info_fixed_sz (
struct MHD_Stream *stream,
enum MHD_StreamInfoFixedType info_type,
union MHD_StreamInfoFixedData *return_value,
size_t return_value_size)
MHD_FN_PAR_NONNULL_ (1)
MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_INOUT_SIZE_(3,4)
MHD_FN_PURE_;
/**
* Obtain fixed information about the given stream.
* This information is not changed for the lifetime of the tream.
*
* @param stream the stream to get information about
* @param info_type the type of information requested
* @param[out] return_value pointer to union where requested information will
* be stored
* @return #MHD_SC_OK if succeed,
* error code otherwise
* @ingroup specialized
*/
#define MHD_stream_get_info_fixed(stream,info_type,return_value) \
MHD_stream_get_info_fixed_sz ((stream),(info_type),(return_value), \
sizeof(*(return_value)))
/**
* Select which fixed information about stream is desired.
* This information may be changed during the lifetime of the stream.
*/
enum MHD_FIXED_ENUM_APP_SET_ MHD_StreamInfoDynamicType
{
/**
* Get the `struct MHD_Request *` for current request processed by the stream.
* If no request is being processed, the resulting pointer is NULL.
* The result is placed in @a v_request member.
* @ingroup request
*/
MHD_STREAM_INFO_DYNAMIC_REQUEST = 1
,
/* * Sentinel * */
/**
* The sentinel value.
* This value enforces specific underlying integer type for the enum.
* Do not use.
*/
MHD_STREAM_INFO_DYNAMIC_SENTINEL = 65535
};
/**
* Dynamic information about stream.
* This information may be changed during the lifetime of the connection.
*/
union MHD_StreamInfoDynamicData
{
/**
* The MHD_Request handler type
*/
struct MHD_Request *v_request;
};
/**
* Obtain dynamic information about the given stream.
* This information may be changed during the lifetime of the stream.
* The wrapper macro #MHD_stream_get_info_dynamic() could be more convenient.
*
* @param stream the stream to get information about
* @param info_type the type of information requested
* @param[out] return_value pointer to union where requested information will
* be stored
* @param return_value_size the size of the memory area pointed
by @a return_data, in bytes
* @return #MHD_SC_OK if succeed,
* error code otherwise
* @ingroup specialized
*/
MHD_EXTERN_ enum MHD_StatusCode
MHD_stream_get_info_dynamic_sz (
struct MHD_Stream *stream,
enum MHD_StreamInfoDynamicType info_type,
union MHD_StreamInfoDynamicData *return_value,
size_t return_value_size)
MHD_FN_PAR_NONNULL_ (1)
MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_INOUT_SIZE_(3,4);
/**
* Obtain dynamic information about the given stream.
* This information may be changed during the lifetime of the stream.
*
* @param stream the stream to get information about
* @param info_type the type of information requested
* @param[out] return_value pointer to union where requested information will
* be stored
* @return #MHD_SC_OK if succeed,
* error code otherwise
* @ingroup specialized
*/
#define MHD_stream_get_info_dynamic(stream,info_type,return_value) \
MHD_stream_get_info_dynamic_sz ((stream),(info_type),(return_value), \
sizeof(*(return_value)))
/**
* Select which fixed information about request is desired.
* This information is not changed during the lifetime of the request.
*/
enum MHD_FIXED_ENUM_APP_SET_ MHD_RequestInfoFixedType
{
/**
* Return which stream the request is associated with.
* The result is placed in @a v_stream member.
*/
MHD_REQUEST_INFO_FIXED_STREAM = 1
,
/**
* Return which connection is associated with the stream which is associated
* with the request.
* The result is placed in @a v_connection member.
*/
MHD_REQUEST_INFO_FIXED_CONNECTION = 2
,
/**
* Return MHD daemon to which the request belongs to.
* The result is placed in @a v_daemon member.
*/
MHD_REQUEST_INFO_FIXED_DAEMON = 3
,
/**
* Get the version of HTTP protocol used for the request.
* The result is placed in @a v_http_ver member.
* @ingroup request
*/
MHD_REQUEST_INFO_FIXED_HTTP_VER = 4
,
/**
* Get the HTTP method used for the request (as a enum).
* The result is placed in @a v_http_method member.
* @sa #MHD_REQUEST_INFO_DYNAMIC_HTTP_METHOD_STR
* @ingroup request
*/
MHD_REQUEST_INFO_FIXED_HTTP_METHOD = 4
,
/* * Sentinel * */
/**
* The sentinel value.
* This value enforces specific underlying integer type for the enum.
* Do not use.
*/
MHD_REQUEST_INFO_FIXED_SENTINEL = 65535
};
/**
* Fixed information about a request.
*/
union MHD_RequestInfoFixedData
{
/**
* The MHD stream handler type.
*/
struct MHD_Stream *v_stream;
/**
* The MHD connection handler type.
*/
struct MHD_Connection *v_connection;
/**
* The MHD daemon handler type.
*/
struct MHD_Daemon *v_daemon;
/**
* The HTTP version type.
*/
enum MHD_HTTP_Version v_http_ver;
/**
* The HTTP method type.
*/
enum MHD_HTTP_Method v_http_method;
};
/**
* Obtain fixed information about the given request.
* This information is not changed for the lifetime of the request.
* The wrapper macro #MHD_request_get_info_fixed() could be more convenient.
*
* @param request the request to get information about
* @param info_type the type of information requested
* @param[out] return_value pointer to union where requested information will
* be stored
* @param return_value_size the size of the memory area pointed
* by @a return_data, in bytes
* @return #MHD_SC_OK if succeed,
* error code otherwise
* @ingroup specialized
*/
MHD_EXTERN_ enum MHD_StatusCode
MHD_request_get_info_fixed_sz (struct MHD_Request *request,
enum MHD_RequestInfoFixedType info_type,
union MHD_RequestInfoFixedData *return_value,
size_t return_value_size)
MHD_FN_PAR_NONNULL_ (1)
MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_INOUT_SIZE_(3,4)
MHD_FN_PURE_;
/**
* Obtain fixed information about the given request.
* This information is not changed for the lifetime of the request.
*
* @param request the request to get information about
* @param info_type the type of information requested
* @param[out] return_value pointer to union where requested information will
* be stored
* @return #MHD_SC_OK if succeed,
* error code otherwise
* @ingroup specialized
*/
#define MHD_request_get_info_fixed(request,info_type,return_value) \
MHD_request_get_info_fixed_sz ((request), (info_type), (return_value), \
sizeof(*(return_value)))
/**
* Select which dynamic information about request is desired.
* This information may be changed during the lifetime of the request.
* Any returned string pointers are valid only until a response is provided.
*/
enum MHD_FIXED_ENUM_APP_SET_ MHD_RequestInfoDynamicType
{
/**
* Get the HTTP method used for the request (as a MHD_String).
* The result is placed in @a v_str member.
* The resulting string pointer in valid only until a response is provided.
* @sa #MHD_REQUEST_INFO_FIXED_HTTP_METHOD
* @ingroup request
*/
MHD_REQUEST_INFO_DYNAMIC_HTTP_METHOD_STR = 1
,
/**
* Get the URI used for the request (as a MHD_String), excluding
* the parameter part (anything after '?').
* The result is placed in @a v_str member.
* The resulting string pointer in valid only until a response is provided.
* @ingroup request
*/
MHD_REQUEST_INFO_DYNAMIC_URI = 2
,
/**
* Get the number of GET parameters (the decoded part of the origianl
* URI string after '?')
* The result is placed in @a v_sizet member.
* @ingroup request
*/
MHD_REQUEST_INFO_DYNAMIC_NUMBER_GET_PARAMS = 3
,
/**
* Get the number of cookies in the request.
* The result is placed in @a v_sizet member.
* @ingroup request
*/
MHD_REQUEST_INFO_DYNAMIC_NUMBER_COOKIES = 4
,
/**
* Get the number of decoded POST entries in the request.
* The result is placed in @a v_sizet member.
* @ingroup request
*/
MHD_REQUEST_INFO_DYNAMIC_NUMBER_POST_PARAMS = 5
,
/**
* Get whether the upload content is present in the request.
* The result is #MHD_YES if any upload content is present, even
* if the upload content size is zero.
* The result is placed in @a v_bool member.
* @ingroup request
*/
MHD_REQUEST_INFO_DYNAMIC_UPLOAD_PRESENT = 10
,
/**
* Get the total content upload size.
* Resulted in zero if no content upload or upload content size is zero,
* #MHD_SIZE_UNKNOWN if size is not known (chunked upload).
* The result is placed in @a v_uint64 member.
* @ingroup request
*/
MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_TOTAL = 11
,
/**
* Get the total size of the content upload already received from the client.
* This is the total size received, could be not yet fully processed by the
* application.
* The result is placed in @a v_uint64 member.
* @ingroup request
*/
MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_RECIEVED = 12
,
/**
* Get the total size of the content upload left to be received from
* the client.
* Resulted in #MHD_SIZE_UNKNOWN if total size is not known (chunked upload).
* The result is placed in @a v_uint64 member.
* @ingroup request
*/
MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_TO_RECIEVE = 13
,
/**
* Get the total size of the content upload already processed (upload callback
* called and completed (if any)).
* If the value is requested from #MHD_UploadCallback, then result does NOT
* include the current data being processed by the callback.
* The result is placed in @a v_uint64 member.
* @ingroup request
*/
MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_PROCESSED = 12
,
/**
* Get the total size of the content upload left to be processed.
* The resulting value includes the size of the data not yet received from
* the client.
* If the value is requested from #MHD_UploadCallback, then result includes
* the current data being processed by the callback.
* Resulted in #MHD_SIZE_UNKNOWN if total size is not known (chunked upload).
* The result is placed in @a v_uint64 member.
* @ingroup request
*/
MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_TO_PROCESS = 13
,
/**
* Return length of the client's HTTP request header.
* This is a total raw size of the header (after TLS decipher if any)
* The result is placed in @a v_sizet member.
* @ingroup request
*/
MHD_REQUEST_INFO_DYNAMIC_HEADER_SIZE = 21
,
/**
* Returns the client-specific pointer to a `void *` that
* is specific to this request. // TODO: check reference
* The result is placed in @a v_pvoid member.
*/
MHD_REQUEST_INFO_DYNAMIC_CLIENT_CONTEXT = 31
,
/**
* Returns pointer to information about username in client's digest auth
* request.
* The resulting pointer is NULL if no digest auth header is set by
* the client, the format of the digest auth header is broken, no
* username is provided or the format of the username parameter is broken.
* Pointers in the returned structure (if any) are valid until response
* is provided for the request.
* The result is placed in @a v_dauth_username member.
*/
MHD_REQUEST_INFO_DYNAMIC_DAUTH_USERNAME_INFO = 41
,
/**
* Returns pointer to information about digest auth in client request.
* The resulting pointer is NULL if no digest auth header is set by
* the client or the format of the digest auth header is broken.
* Pointers in the returned structure (if any) are valid until response
* is provided for the request.
* The result is placed in @a v_dauth_info member.
*/
MHD_REQUEST_INFO_DYNAMIC_DAUTH_REQ_INFO = 42
,
/**
* Returns pointer to information about basic auth in client request.
* The resulting pointer is NULL if no basic auth header is set by
* the client or the format of the basic auth header is broken.
* Pointers in the returned structure (if any) are valid until response
* is provided for the request.
* The result is placed in @a v_bauth_info member.
*/
MHD_REQUEST_INFO_DYNAMIC_BAUTH_REQ_INFO = 51
,
/* * Sentinel * */
/**
* The sentinel value.
* This value enforces specific underlying integer type for the enum.
* Do not use.
*/
MHD_REQUEST_INFO_DYNAMIC_SENTINEL = 65535
};
/**
* Dynamic information about a request.
*/
union MHD_RequestInfoDynamicData
{
/**
* The MHD String type
*/
struct MHD_String v_str;
/**
* The size_t type
*/
size_t v_sizet;
/**
* The boolean type
*/
enum MHD_Bool v_bool;
/**
* The unsigned 64 bits integer
*/
uint_fast64_t v_uint64;
/**
* The pointer to void
*/
void *v_pvoid;
/**
* The information about client provided username for digest auth
*/
struct MHD_DigestAuthUsernameInfo *v_dauth_username;
/**
* The information about client's digest auth
*/
struct MHD_DigestAuthInfo *v_dauth_info;
/**
* The information about client's basic auth
*/
struct MHD_BasicAuthInfo *v_bauth_info;
};
/**
* Obtain dynamic information about the given request.
* This information may be changed during the lifetime of the request.
* The wrapper macro #MHD_request_get_info_dynamic() could be more convenient.
*
* @param request the request to get information about
* @param info_type the type of information requested
* @param[out] return_value pointer to union where requested information will
* be stored
* @param return_value_size the size of the memory area pointed
* by @a return_data, in bytes
* @return #MHD_SC_OK if succeed,
* error code otherwise
* @ingroup specialized
*/
MHD_EXTERN_ enum MHD_StatusCode
MHD_request_get_info_dynamic_sz (struct MHD_Request *request,
enum MHD_RequestInfoDynamicType info_type,
union MHD_RequestInfoDynamicData *return_value,
size_t return_value_size)
MHD_FN_PAR_NONNULL_ (1)
MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_INOUT_SIZE_(3,4)
MHD_FN_PURE_;
/**
* Obtain dynamic information about the given request.
* This information may be changed during the lifetime of the request.
*
* @param request the request to get information about
* @param info_type the type of information requested
* @param[out] return_value pointer to union where requested information will
* be stored
* @return #MHD_SC_OK if succeed,
* error code otherwise
* @ingroup specialized
*/
#define MHD_request_get_info_dynamic(request,info_type,return_value) \
MHD_request_get_info_dynamic_sz ((request), (info_type), (return_value), \
sizeof(*(return_value)))
/**
* Callback for serious error condition. The default action is to print
* an error message and `abort()`.
* The callback should not return.
*
* @param cls user specified value
* @param file where the error occurred
* @param file where the error occurred, could be NULL if MHD built without
* messages (only for embedded project)
* @param line where the error occurred
* @param reason error detail, may be NULL
* @ingroup logging
@@ -7974,214 +8794,27 @@ typedef void
/**
* 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.
* Sets the global error handler to a different implementation.
* The @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.
* The @a cb should not return.
*
* 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 cb new error handler, NULL to reset to default handler
* @param cls passed to @a cb
* @ingroup logging
*/
MHD_EXTERN_ void
MHD_set_panic_func (MHD_PanicCallback cb,
void *cls);
/**
* Process escape sequences ('%HH') Updates val in place; the
* result should be UTF-8 encoded and cannot be larger than the input.
* The result must also still be 0-terminated.
*
* @param val value to unescape (modified in the process)
* @return length of the resulting val (`strlen(val)` may be
* shorter afterwards due to elimination of escape sequences)
*/
MHD_EXTERN_ size_t
MHD_http_unescape (char *val)
MHD_FN_PAR_NONNULL_ (1);
/**
* 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.
*/
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);
MHD_lib_set_panic_func (MHD_PanicCallback cb,
void *cls);
#define MHD_lib_set_panic_func_default() \
MHD_lib_set_panic_func (MHD_STATIC_CAST_(MHD_PanicCallback,NULL),NULL)
#endif