libmicrohttpd2

HTTP server C library (MHD 2.x, alpha)
Log | Files | Refs | README | LICENSE

commit 2ea2fe1662afecbfd1d20ad5a28fe04fdd5a8cfe
parent d43ac5cebad80cc48c7297f6b37259838deb71ed
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
Date:   Sun,  3 Mar 2024 14:58:25 +0100

microhttpd2.h edits

Diffstat:
Msrc/include/microhttpd2.h | 3532++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------
1 file changed, 2351 insertions(+), 1181 deletions(-)

diff --git a/src/include/microhttpd2.h b/src/include/microhttpd2.h @@ -172,6 +172,9 @@ * 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 @@ -226,10 +229,13 @@ typedef intptr_t ssize_t; */ #define MHD_VERSION 0x02000000 - /** * Representation of 'bool' in the public API as stdbool.h may not - * always be available. + * always be available and presence of 'bool' keyword may depend on + * used C version. + * It is always safe to cast 'MHD_Bool' variable to 'bool' and vice versa. + * Note: it may be NOT safe to cast pointers 'MHD_Bool*' to 'bool*' and + * vice versa. */ enum MHD_Bool { @@ -249,29 +255,43 @@ enum MHD_Bool /** + * String with length data. + */ +struct MHD_String +{ + /** + * Number of characters in @e str, not counting 0-termination. + */ + size_t len; + + /** + * 0-terminated C-string. + */ + const char *cstr; +}; + + +/** * Constant used to indicate unknown size (use when * creating a response). */ -#ifdef UINT64_MAX -#define MHD_SIZE_UNKNOWN UINT64_MAX +#ifdef UINT_FAST64_MAX +# define MHD_SIZE_UNKNOWN UINT_FAST64_MAX #else -#define MHD_SIZE_UNKNOWN ((uint64_t) -1LL) +# define MHD_SIZE_UNKNOWN ((uint_fast64_t) -1LL) #endif -#ifdef SIZE_MAX -#define MHD_CONTENT_READER_END_OF_STREAM SIZE_MAX -#define MHD_CONTENT_READER_END_WITH_ERROR (SIZE_MAX - 1) -#else -#define MHD_CONTENT_READER_END_OF_STREAM ((size_t) -1LL) -#define MHD_CONTENT_READER_END_WITH_ERROR (((size_t) -1LL) - 1) -#endif +// FIXME: Updated +#define MHD_DYNAMIC_CONTENT_END_OF_STREAM ((ssize_t) -1) +#define MHD_DYNAMIC_CONTENT_STOP_WITH_ERROR ((ssize_t) -2) +#define MHD_DYNAMIC_CONTENT_SUSPEND_REQUEST ((ssize_t) -3) #ifndef _MHD_EXTERN #if defined(_WIN32) && defined(MHD_W32LIB) #define _MHD_EXTERN extern #elif defined(_WIN32) && defined(MHD_W32DLL) /* Define MHD_W32DLL when using MHD as W32 .DLL to speed up linker a little */ -#define _MHD_EXTERN __declspec(dllimport) +#define _MHD_EXTERN extern __declspec(dllimport) #else #define _MHD_EXTERN extern #endif @@ -294,6 +314,8 @@ typedef SOCKET MHD_socket; #define MHD_SOCKET_DEFINED 1 #endif /* MHD_SOCKET_DEFINED */ +// TODO: move compiler macros to separate header + /** * Define MHD_NO_DEPRECATION before including "microhttpd.h" to disable deprecation messages */ @@ -377,7 +399,7 @@ typedef SOCKET MHD_socket; #endif /* !_MHD_DEPR_FUNC */ -/* Define MHD_NONNULL attribute */ +/* Define MHD_FUNC_PARAM_NONNULL_ attribute */ /** * Macro to indicate that certain parameters must be @@ -385,27 +407,208 @@ typedef SOCKET MHD_socket; */ #if defined(__CYGWIN__) || defined(_WIN32) || defined(MHD_W32LIB) || \ defined(__clang__) || ! defined(__GNUC__) -#define MHD_NONNULL(...) /* empty */ +// FIXME: vararg macros still not universally supported +// FIXME: discuss long list of attributes +#define MHD_FUNC_PARAM_NONNULL_(...) /* empty */ #else -#define MHD_NONNULL(...) __THROW __nonnull ((__VA_ARGS__)) +#define MHD_FUNC_PARAM_NONNULL_(...) __THROW __nonnull ((__VA_ARGS__)) #endif +// TODO: document +#if ! defined(MHD_NO_FUNC_ATTRIBUTES) +# if defined(__has_attribute) + +// TODO: document +# if __has_attribute (const) && ! defined(MHD_FUNC_CONST_) /** - * Not all architectures and `printf()`'s support the `long long` type. - * This gives the ability to replace `long long` with just a `long`, - * standard `int` or a `short`. + * MHD_FUNC_CONST_ functions always return the same value for this same + * input value, even if any memory pointed by parameter is changed or + * any global value changed. The functions do not change any global values. + * In general, such functions must not dereference any pointers provided + * as a parameter and must not access any global variables that can be + * changed over the time. + * Typical examples: + * int square(int x); + * int sum(int a, int b); */ -#ifndef MHD_UNSIGNED_LONG_LONG -#define MHD_UNSIGNED_LONG_LONG unsigned long long -#endif +# define MHD_FUNC_CONST_ __attribute__ ((const)) +# endif /* const && !MHD_FUNC_CONST_ */ + +// TODO: document +# if __has_attribute (pure) && ! defined(MHD_FUNC_PURE_) /** - * Format string for printing a variable of type #MHD_LONG_LONG. - * You should only redefine this if you also define #MHD_LONG_LONG. + * MHD_FUNC_PURE_ functions always return the same value for this same input + * if volatile memory content is not changed. + * In general, such functions must must not access any global variables that + * can be changed over the time. + * Typical examples: + * size_t strlen(const char *str); + * int memcmpconst void *ptr1, const void *ptr2, size_t _Size); */ -#ifndef MHD_UNSIGNED_LONG_LONG_PRINTF -#define MHD_UNSIGNED_LONG_LONG_PRINTF "%llu" -#endif +# define MHD_FUNC_PURE_ __attribute__ ((pure)) +# endif /* pure && !MHD_FUNC_PURE_ */ + +// TODO: document +# if __has_attribute (warn_unused_result) && \ + ! defined(MHD_FUNC_MUST_CHECK_RESULT_) +/** + * MHD_FUNC_MUST_CHECK_RESULT_ indicates that caller must check the value + * returned by the function. + */ +# define MHD_FUNC_MUST_CHECK_RESULT_ __attribute__ ((warn_unused_result)) +# endif /* warn_unused_result && !MHD_FUNC_MUST_CHECK_RESULT_ */ + +# if __has_attribute (nonnull) && \ + ! defined(MHD_FUNC_PARAM_NONNULL_) +/** + * MHD_FUNC_PARAM_NONNULL_ indicates function parameter number @a param_num + * must never be NULL. + */ +# define MHD_FUNC_PARAM_NONNULL_(param_num) \ + __attribute__ ((nonnull (param_num))) +# endif /* nonnull && !MHD_FUNC_PARAM_NONNULL_ */ + +# if __has_attribute (nonnull) && \ + ! defined(MHD_FUNC_PARAM_NONNULL_ALL_) +/** + * MHD_FUNC_PARAM_NONNULL_ALL_ indicates all function parameters must + * never be NULL. + */ +# define MHD_FUNC_PARAM_NONNULL_ALL_ __attribute__ ((nonnull)) +# endif /* nonnull && !MHD_FUNC_PARAM_NONNULL_ALL_ */ + +# if __has_attribute (access) + +# if ! defined(MHD_FUNC_PARAM_IN_) +/** + * MHD_FUNC_PARAM_IN_ indicates function parameter points to data + * that must not be modified by the function + */ +# define MHD_FUNC_PARAM_IN_(param_num) \ + __attribute__ ((access(read_only,pram_num))) +# endif /* !MHD_FUNC_PARAM_IN_ */ + +# if ! defined(MHD_FUNC_PARAM_IN_SIZE_) +/** + * MHD_FUNC_PARAM_IN_SIZE_ indicates function parameter points to data + * which size is specified by @a size_num parameter and that must not be + * modified by the function + */ +# define MHD_FUNC_PARAM_IN_SIZE_(param_num,size_num) \ + __attribute__ ((access(read_only,pram_num,size_num))) +# endif /* !MHD_FUNC_PARAM_IN_SIZE_ */ + +# if ! defined(MHD_FUNC_PARAM_OUT_) +/** + * MHD_FUNC_PARAM_OUT_ indicates function parameter points to data + * that could be written by the function, but not read. + */ +# define MHD_FUNC_PARAM_OUT_(param_num) \ + __attribute__ ((access(write_only,pram_num))) +# endif /* !MHD_FUNC_PARAM_OUT_ */ + +# if ! defined(MHD_FUNC_PARAM_OUT_SIZE_) +/** + * MHD_FUNC_PARAM_OUT_SIZE_ indicates function parameter points to data + * which size is specified by @a size_num parameter and that could be + * written by the function, but not read. + */ +# define MHD_FUNC_PARAM_OUT_SIZE_(param_num,size_num) \ + __attribute__ ((access(write_only,pram_num,size_num))) +# endif /* !MHD_FUNC_PARAM_OUT_SIZE_ */ + +# if ! defined(MHD_FUNC_PARAM_INOUT_) +/** + * MHD_FUNC_PARAM_INOUT_ indicates function parameter points to data + * that could be both read and written by the function. + */ +# define MHD_FUNC_PARAM_INOUT_(param_num) \ + __attribute__ ((access(read_write,pram_num))) +# endif /* !MHD_FUNC_PARAM_INOUT_ */ + +# if ! defined(MHD_FUNC_PARAM_INOUT_SIZE_) +/** + * MHD_FUNC_PARAM_INOUT_SIZE_ indicates function parameter points to data + * which size is specified by @a size_num parameter and that could be + * both read and written by the function. + */ +# define MHD_FUNC_PARAM_INOUT_SIZE_(param_num,size_num) \ + __attribute__ ((access(read_write,pram_num,size_num))) +# endif /* !MHD_FUNC_PARAM_INOUT_SIZE_ */ + +# endif /* access */ + +# if __has_attribute (returns_nonnull) && \ + ! defined(MHD_FUNC_RETURNS_NONNULL_) +/** + * MHD_FUNC_RETURNS_NONNULL_ indicates that function never returns NULL. + */ +# define MHD_FUNC_RETURNS_NONNULL_ __attribute__ ((returns_nonnull)) +# endif /* returns_nonnull && !MHD_FUNC_RETURNS_NONNULL_ */ + +# if __has_attribute (access) && \ + ! defined(MHD_FUNC_PARAM_IN_) +/** + * MHD_FUNC_PARAM_IN_ indicates function parameter points to data + * that must not be modified by the function + */ +# define MHD_FUNC_PARAM_IN_(param_num) \ + __attribute__ ((access(read_only,pram_num))) +# endif /* returns_nonnull && !MHD_FUNC_RETURNS_NONNULL_ */ +# endif /* __has_attribute */ +#endif /* ! MHD_NO_FUNC_ATTRIBUTES */ + +#ifndef MHD_C99_ +# if __STDC_VERSION__ >= 199901L +// FIXME: does not work with VLA on C11 on some compilers at least +// FIXME: whitelist supported compilers +// Probably problematic for typedefs for callbacks +# define MHD_C99_(x) x +# endif /* __STDC_VERSION__ >= 199901L */ +#endif /* MHD_C99_ */ + + +#ifndef MHD_FUNC_CONST_ +# define MHD_FUNC_CONST_ /* empty */ +#endif /* ! MHD_FUNC_CONST_ */ +#ifndef MHD_FUNC_PURE_ +# define MHD_FUNC_PURE_ /* empty */ +#endif /* ! MHD_FUNC_PURE_ */ +#ifndef MHD_FUNC_MUST_CHECK_RESULT_ +# define MHD_FUNC_MUST_CHECK_RESULT_ /* empty */ +#endif /* ! MHD_FUNC_MUST_CHECK_RESULT_ */ +#ifndef MHD_FUNC_PARAM_NONNULL_ +# define MHD_FUNC_PARAM_NONNULL_(ignored) /* empty */ +#endif /* ! MHD_FUNC_PARAM_NONNULL_ */ +#ifndef MHD_FUNC_PARAM_NONNULL_ALL_ +# define MHD_FUNC_PARAM_NONNULL_ALL_ /* empty */ +#endif /* ! MHD_FUNC_PARAM_NONNULL_ALL_ */ +#if ! defined(MHD_FUNC_PARAM_IN_) +# define MHD_FUNC_PARAM_IN_(param_num) /* empty */ +#endif /* !MHD_FUNC_PARAM_IN_ */ +#if ! defined(MHD_FUNC_PARAM_IN_SIZE_) +# define MHD_FUNC_PARAM_IN_SIZE_(param_num,size_num) /* empty */ +#endif /* !MHD_FUNC_PARAM_IN_SIZE_ */ +#if ! defined(MHD_FUNC_PARAM_OUT_) +# define MHD_FUNC_PARAM_OUT_(param_num) /* empty */ +#endif /* !MHD_FUNC_PARAM_OUT_ */ +#if ! defined(MHD_FUNC_PARAM_OUT_SIZE_) +# define MHD_FUNC_PARAM_OUT_SIZE_(param_num,size_num) /* empty */ +#endif /* !MHD_FUNC_PARAM_OUT_SIZE_ */ +#if ! defined(MHD_FUNC_PARAM_INOUT_) +# define MHD_FUNC_PARAM_INOUT_(param_num) /* empty */ +#endif /* !MHD_FUNC_PARAM_INOUT_ */ +#if ! defined(MHD_FUNC_PARAM_INOUT_SIZE_) +# define MHD_FUNC_PARAM_INOUT_SIZE_(param_num,size_num) /* empty */ +#endif /* !MHD_FUNC_PARAM_INOUT_SIZE_ */ +#ifndef MHD_FUNC_RETURNS_NONNULL_ +# define MHD_FUNC_RETURNS_NONNULL_ /* empty */ +#endif /* ! MHD_FUNC_RETURNS_NONNULL_ */ + +#ifndef MHD_C99_ +# define MHD_C99_(ignored) /* empty */ +#endif /* MHD_C99_ */ /* ********** (a) Core HTTP Processing ************ */ @@ -413,17 +616,17 @@ typedef SOCKET MHD_socket; /** * @brief Handle for a daemon that listens for requests. * - * Manages the listen socket, event loop (and/or thread pool) and server + * Manages the listen socket, event loop, optional threads and server * settings. */ struct MHD_Daemon; /** - * @brief A connection corresponds to the network/stream abstraction. + * @brief Handle/identifier of a network connection abstraction. * - * A single network (i.e. TCP) stream may be used for multiple - * requests, which in HTTP/1.1 must be processed sequentially. + * A single network (i.e. TCP) connection can be used for + * a single (in HTTP/1.1) data stream. * * @ingroup connection */ @@ -431,11 +634,22 @@ struct MHD_Connection; /** + * @brief Handle/identifier of a data stream over network + * connection. + * + * A data stream may be used for multiple requests, which + * in HTTP/1.1 must be processed sequentially. + * + * @ingroup connection + */ +struct MHD_Stream; + +/** * @brief Handle representing an HTTP request. * * With HTTP/1.1, multiple requests can be run over the same - * connection. However, MHD will only show one request per TCP - * connection to the client at any given time. + * stream. However, MHD will only show one request per data + * stream to the client at any given time. * * Replaces `struct MHD_Connection`, renamed to better reflect * what this object truly represents to the application using @@ -497,7 +711,7 @@ enum MHD_StatusCode MHD_SC_CONNECTION_ACCEPTED = 10001, /** - * Informational event, thread processing connection termiantes. + * Informational event, thread processing connection terminates. */ MHD_SC_THREAD_TERMINATING = 10002, @@ -705,6 +919,7 @@ enum MHD_StatusCode */ MHD_SC_IPV6_NOT_SUPPORTED_BY_BUILD = 50010, + /// FIXME: Similar to 60xxx??? /** * We failed to open the listen socket. Maybe the build * supports IPv6, but your kernel does not? @@ -949,6 +1164,26 @@ enum MHD_StatusCode */ MHD_SC_FAILED_RESPONSE_HEADER_GENERATION = 50056, + /** + * The feature is not supported by this MHD build (either + * disabled by configure parameters or build platform + * did not support it, because headers are missing or + * so kernel does not have such feature). + * The feature will not be enabled if the same MHD binary + * will be run on another kernel, computer or system + * configuration. + */ + MHD_SC_FEATURE_DISABLED = 500057, + + /** + * The feature is not supported by this platform, while + * supported by MHD build. + * The feature can be enabled by changing the kernel or + * running on another computer or with other system + * configuration. + */ + MHD_SC_FEATURE_NOT_AVAILABLE = 500058, + /* 60000-level errors are because the application logic did something wrong or generated an error. */ @@ -965,6 +1200,7 @@ enum MHD_StatusCode */ MHD_SC_SYSCALL_QUIESCE_REQUIRES_ITC = 60001, + // FIXME: similar to 50xxx??? /** * We failed to bind the listen socket. */ @@ -1007,10 +1243,32 @@ enum MHD_StatusCode */ MHD_SC_APPLICATION_HUNG_CONNECTION_CLOSED = 60008, + /** + * Application called function too late, for example because + * MHD already changed state. + */ + MHD_SC_TOO_LATE = 60009, + + /** + * Attempted to set an option that conflicts with another option + * already set. + */ + MHD_SC_OPTIONS_CONFLICT = 60010 + }; +// FIXME: maybe not needed? Too large possibly? +enum MHD_Bool +MHD_status_code_is_fatal(enum MHD_StatusCode code) +MHD_FUNC_CONST_; + + +const struct MHD_String * +MHD_status_code_to_string (enum MHD_StatusCode code) +MHD_FUNC_CONST_ MHD_FUNC_RETURNS_NONNULL_; + /** * HTTP methods explicitly supported by MHD. Note that for * non-canonical methods, MHD will return #MHD_METHOD_UNKNOWN @@ -1029,592 +1287,774 @@ enum MHD_StatusCode * Registry Version 2015-05-19 * @{ */ -enum MHD_Method +enum MHD_HTTP_Method { /** * Method did not match any of the methods given below. */ - MHD_METHOD_UNKNOWN = 0, - - /** - * "OPTIONS" method. - * Safe. Idempotent. RFC7231, Section 4.3.7. - */ - MHD_METHOD_OPTIONS = 1, - - /** - * "GET" method. - * Safe. Idempotent. RFC7231, Section 4.3.1. - */ - MHD_METHOD_GET = 2, - - /** - * "HEAD" method. - * Safe. Idempotent. RFC7231, Section 4.3.2. - */ - MHD_METHOD_HEAD = 3, - - /** - * "POST" method. - * Not safe. Not idempotent. RFC7231, Section 4.3.3. - */ - MHD_METHOD_POST = 4, - - /** - * "PUT" method. - * Not safe. Idempotent. RFC7231, Section 4.3.4. - */ - MHD_METHOD_PUT = 5, - - /** - * "DELETE" method. - * Not safe. Idempotent. RFC7231, Section 4.3.5. - */ - MHD_METHOD_DELETE = 6, - - /** - * "TRACE" method. - */ - MHD_METHOD_TRACE = 7, - - /** - * "CONNECT" method. - */ - MHD_METHOD_CONNECT = 8, - - /** - * "ACL" method. - */ - MHD_METHOD_ACL = 9, - - /** - * "BASELINE-CONTROL" method. - */ - MHD_METHOD_BASELINE_CONTROL = 10, - - /** - * "BIND" method. - */ - MHD_METHOD_BIND = 11, - - /** - * "CHECKIN" method. - */ - MHD_METHOD_CHECKIN = 12, - - /** - * "CHECKOUT" method. - */ - MHD_METHOD_CHECKOUT = 13, + MHD_HTTP_METHOD_OTHER = 0, - /** - * "COPY" method. - */ - MHD_METHOD_COPY = 14, - - /** - * "LABEL" method. - */ - MHD_METHOD_LABEL = 15, - - /** - * "LINK" method. - */ - MHD_METHOD_LINK = 16, - - /** - * "LOCK" method. - */ - MHD_METHOD_LOCK = 17, - - /** - * "MERGE" method. - */ - MHD_METHOD_MERGE = 18, - - /** - * "MKACTIVITY" method. - */ - MHD_METHOD_MKACTIVITY = 19, + /* Main HTTP methods. */ /** - * "MKCOL" method. + * "GET" + * Safe. Idempotent. RFC9110, Section 9.3.1. */ - MHD_METHOD_MKCOL = 20, + MHD_HTTP_METHOD_GET = 1, /** - * "MKREDIRECTREF" method. + * "HEAD" + * Safe. Idempotent. RFC9110, Section 9.3.2. */ - MHD_METHOD_MKREDIRECTREF = 21, + MHD_HTTP_METHOD_HEAD = 2, /** - * "MKWORKSPACE" method. + * "POST" + * Not safe. Not idempotent. RFC9110, Section 9.3.3. */ - MHD_METHOD_MKWORKSPACE = 22, + MHD_HTTP_METHOD_POST = 3, /** - * "MOVE" method. + * "PUT" + * Not safe. Idempotent. RFC9110, Section 9.3.4. */ - MHD_METHOD_MOVE = 23, + MHD_HTTP_METHOD_PUT = 4, /** - * "ORDERPATCH" method. + * "DELETE" + * Not safe. Idempotent. RFC9110, Section 9.3.5. */ - MHD_METHOD_ORDERPATCH = 24, + MHD_HTTP_METHOD_DELETE = 5, /** - * "PATCH" method. + * "CONNECT" + * Not safe. Not idempotent. RFC9110, Section 9.3.6. */ - MHD_METHOD_PATH = 25, + MHD_HTTP_METHOD_CONNECT = 6, /** - * "PRI" method. + * "OPTIONS" + * Safe. Idempotent. RFC9110, Section 9.3.7. */ - MHD_METHOD_PRI = 26, + MHD_HTTP_METHOD_OPTIONS = 7, /** - * "PROPFIND" method. + * "TRACE" + * Safe. Idempotent. RFC9110, Section 9.3.8. */ - MHD_METHOD_PROPFIND = 27, + MHD_HTTP_METHOD_TRACE = 8, /** - * "PROPPATCH" method. + * "*" + * Not safe. Not idempotent. RFC9110, Section 18.2. */ - MHD_METHOD_PROPPATCH = 28, + MHD_HTTP_METHOD_ASTERISK = 9 +}; - /** - * "REBIND" method. - */ - MHD_METHOD_REBIND = 29, +// FIXME: added +// FIXME: return 'const char *'? +_MHD_EXTERN const struct MHD_String * +MHD_get_http_method_string(enum MHD_HTTP_Method method) +MHD_FUNC_CONST_; - /** - * "REPORT" method. - */ - MHD_METHOD_REPORT = 30, +/** + * @defgroup methods HTTP methods + * HTTP methods (as strings). + * See: https://www.iana.org/assignments/http-methods/http-methods.xml + * Registry export date: 2023-10-02 + * @{ + */ - /** - * "SEARCH" method. - */ - MHD_METHOD_SEARCH = 31, +/* Main HTTP methods. */ +/* Safe. Idempotent. RFC9110, Section 9.3.1. */ +#define MHD_HTTP_METHOD_STR_GET "GET" +/* Safe. Idempotent. RFC9110, Section 9.3.2. */ +#define MHD_HTTP_METHOD_STR_HEAD "HEAD" +/* Not safe. Not idempotent. RFC9110, Section 9.3.3. */ +#define MHD_HTTP_METHOD_STR_POST "POST" +/* Not safe. Idempotent. RFC9110, Section 9.3.4. */ +#define MHD_HTTP_METHOD_STR_PUT "PUT" +/* Not safe. Idempotent. RFC9110, Section 9.3.5. */ +#define MHD_HTTP_METHOD_STR_DELETE "DELETE" +/* Not safe. Not idempotent. RFC9110, Section 9.3.6. */ +#define MHD_HTTP_METHOD_STR_CONNECT "CONNECT" +/* Safe. Idempotent. RFC9110, Section 9.3.7. */ +#define MHD_HTTP_METHOD_STR_OPTIONS "OPTIONS" +/* Safe. Idempotent. RFC9110, Section 9.3.8. */ +#define MHD_HTTP_METHOD_STR_TRACE "TRACE" + +/* Additional HTTP methods. */ +/* Not safe. Idempotent. RFC3744, Section 8.1. */ +#define MHD_HTTP_METHOD_STR_ACL "ACL" +/* Not safe. Idempotent. RFC3253, Section 12.6. */ +#define MHD_HTTP_METHOD_STR_BASELINE_CONTROL "BASELINE-CONTROL" +/* Not safe. Idempotent. RFC5842, Section 4. */ +#define MHD_HTTP_METHOD_STR_BIND "BIND" +/* Not safe. Idempotent. RFC3253, Section 4.4, Section 9.4. */ +#define MHD_HTTP_METHOD_STR_CHECKIN "CHECKIN" +/* Not safe. Idempotent. RFC3253, Section 4.3, Section 8.8. */ +#define MHD_HTTP_METHOD_STR_CHECKOUT "CHECKOUT" +/* Not safe. Idempotent. RFC4918, Section 9.8. */ +#define MHD_HTTP_METHOD_STR_COPY "COPY" +/* Not safe. Idempotent. RFC3253, Section 8.2. */ +#define MHD_HTTP_METHOD_STR_LABEL "LABEL" +/* Not safe. Idempotent. RFC2068, Section 19.6.1.2. */ +#define MHD_HTTP_METHOD_STR_LINK "LINK" +/* Not safe. Not idempotent. RFC4918, Section 9.10. */ +#define MHD_HTTP_METHOD_STR_LOCK "LOCK" +/* Not safe. Idempotent. RFC3253, Section 11.2. */ +#define MHD_HTTP_METHOD_STR_MERGE "MERGE" +/* Not safe. Idempotent. RFC3253, Section 13.5. */ +#define MHD_HTTP_METHOD_STR_MKACTIVITY "MKACTIVITY" +/* Not safe. Idempotent. RFC4791, Section 5.3.1; RFC8144, Section 2.3. */ +#define MHD_HTTP_METHOD_STR_MKCALENDAR "MKCALENDAR" +/* Not safe. Idempotent. RFC4918, Section 9.3; RFC5689, Section 3; RFC8144, Section 2.3. */ +#define MHD_HTTP_METHOD_STR_MKCOL "MKCOL" +/* Not safe. Idempotent. RFC4437, Section 6. */ +#define MHD_HTTP_METHOD_STR_MKREDIRECTREF "MKREDIRECTREF" +/* Not safe. Idempotent. RFC3253, Section 6.3. */ +#define MHD_HTTP_METHOD_STR_MKWORKSPACE "MKWORKSPACE" +/* Not safe. Idempotent. RFC4918, Section 9.9. */ +#define MHD_HTTP_METHOD_STR_MOVE "MOVE" +/* Not safe. Idempotent. RFC3648, Section 7. */ +#define MHD_HTTP_METHOD_STR_ORDERPATCH "ORDERPATCH" +/* Not safe. Not idempotent. RFC5789, Section 2. */ +#define MHD_HTTP_METHOD_STR_PATCH "PATCH" +/* Safe. Idempotent. RFC9113, Section 3.4. */ +#define MHD_HTTP_METHOD_STR_PRI "PRI" +/* Safe. Idempotent. RFC4918, Section 9.1; RFC8144, Section 2.1. */ +#define MHD_HTTP_METHOD_STR_PROPFIND "PROPFIND" +/* Not safe. Idempotent. RFC4918, Section 9.2; RFC8144, Section 2.2. */ +#define MHD_HTTP_METHOD_STR_PROPPATCH "PROPPATCH" +/* Not safe. Idempotent. RFC5842, Section 6. */ +#define MHD_HTTP_METHOD_STR_REBIND "REBIND" +/* Safe. Idempotent. RFC3253, Section 3.6; RFC8144, Section 2.1. */ +#define MHD_HTTP_METHOD_STR_REPORT "REPORT" +/* Safe. Idempotent. RFC5323, Section 2. */ +#define MHD_HTTP_METHOD_STR_SEARCH "SEARCH" +/* Not safe. Idempotent. RFC5842, Section 5. */ +#define MHD_HTTP_METHOD_STR_UNBIND "UNBIND" +/* Not safe. Idempotent. RFC3253, Section 4.5. */ +#define MHD_HTTP_METHOD_STR_UNCHECKOUT "UNCHECKOUT" +/* Not safe. Idempotent. RFC2068, Section 19.6.1.3. */ +#define MHD_HTTP_METHOD_STR_UNLINK "UNLINK" +/* Not safe. Idempotent. RFC4918, Section 9.11. */ +#define MHD_HTTP_METHOD_STR_UNLOCK "UNLOCK" +/* Not safe. Idempotent. RFC3253, Section 7.1. */ +#define MHD_HTTP_METHOD_STR_UPDATE "UPDATE" +/* Not safe. Idempotent. RFC4437, Section 7. */ +#define MHD_HTTP_METHOD_STR_UPDATEREDIRECTREF "UPDATEREDIRECTREF" +/* Not safe. Idempotent. RFC3253, Section 3.5. */ +#define MHD_HTTP_METHOD_STR_VERSION_CONTROL "VERSION-CONTROL" +/* Not safe. Not idempotent. RFC9110, Section 18.2. */ +#define MHD_HTTP_METHOD_STR_ASTERISK "*" - /** - * "UNBIND" method. - */ - MHD_METHOD_UNBIND = 32, +/** @} */ /* end of group methods */ - /** - * "UNCHECKOUT" method. - */ - MHD_METHOD_UNCHECKOUT = 33, - /** - * "UNLINK" method. - */ - MHD_METHOD_UNLINK = 34, +/** + * @defgroup postenc HTTP POST encodings + * See also: http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4 + * @{ + */ +enum MHD_HTTP_PostEncoding +{ /** - * "UNLOCK" method. + * No post encoding / broken data / unknown encoding */ - MHD_METHOD_UNLOCK = 35, + MHD_HTTP_POST_ENCODING_OTHER = 0, /** - * "UPDATE" method. + * "application/x-www-form-urlencoded" + * See https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#url-encoded-form-data + * See https://url.spec.whatwg.org/#application/x-www-form-urlencoded + * See https://datatracker.ietf.org/doc/html/rfc3986#section-2 */ - MHD_METHOD_UPDATE = 36, + MHD_HTTP_POST_ENCODING_FORM_URLENCODED = 1, /** - * "UPDATEDIRECTREF" method. + * "multipart/form-data" + * See https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#url-encoded-form-data + * See https://www.rfc-editor.org/rfc/rfc7578.html */ - MHD_METHOD_UPDATEDIRECTREF = 37, + MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA = 2, /** - * "VERSION-CONTROL" method. + * "text/plain" + * Introduced by HTML5 + * See https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#plain-text-form-data + * @warning Format is ambiguous. Do not use unless there is a very strong reason. */ - MHD_METHOD_VERSION_CONTROL = 38 - - /* For more, check: - https://www.iana.org/assignments/http-methods/http-methods.xhtml */ - + MHD_HTTP_POST_ENCODING_TEXT_PLAIN = 3 }; -/** @} */ /* end of group methods */ - - -/** - * @defgroup postenc HTTP POST encodings - * See also: http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4 - * @{ - */ -#define MHD_HTTP_POST_ENCODING_FORM_URLENCODED \ - "application/x-www-form-urlencoded" - -#define MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA "multipart/form-data" /** @} */ /* end of group postenc */ /** * @defgroup headers HTTP headers - * These are the standard headers found in HTTP requests and responses. - * See: http://www.iana.org/assignments/message-headers/message-headers.xml - * Registry Version 2017-01-27 + * The standard headers found in HTTP requests and responses. + * See: https://www.iana.org/assignments/http-fields/http-fields.xhtml + * Registry export date: 2023-10-02 * @{ */ /* Main HTTP headers. */ -/* Standard. RFC7231, Section 5.3.2 */ -#define MHD_HTTP_HEADER_ACCEPT "Accept" -/* Standard. RFC7231, Section 5.3.3 */ +/* Permanent. RFC9110, Section 12.5.1: HTTP Semantics */ +#define MHD_HTTP_HEADER_ACCEPT "Accept" +/* Deprecated. RFC9110, Section 12.5.2: HTTP Semantics */ #define MHD_HTTP_HEADER_ACCEPT_CHARSET "Accept-Charset" -/* Standard. RFC7231, Section 5.3.4; RFC7694, Section 3 */ +/* Permanent. RFC9110, Section 12.5.3: HTTP Semantics */ #define MHD_HTTP_HEADER_ACCEPT_ENCODING "Accept-Encoding" -/* Standard. RFC7231, Section 5.3.5 */ +/* Permanent. RFC9110, Section 12.5.4: HTTP Semantics */ #define MHD_HTTP_HEADER_ACCEPT_LANGUAGE "Accept-Language" -/* Standard. RFC7233, Section 2.3 */ +/* Permanent. RFC9110, Section 14.3: HTTP Semantics */ #define MHD_HTTP_HEADER_ACCEPT_RANGES "Accept-Ranges" -/* Standard. RFC7234, Section 5.1 */ -#define MHD_HTTP_HEADER_AGE "Age" -/* Standard. RFC7231, Section 7.4.1 */ -#define MHD_HTTP_HEADER_ALLOW "Allow" -/* Standard. RFC7235, Section 4.2 */ +/* Permanent. RFC9111, Section 5.1: HTTP Caching */ +#define MHD_HTTP_HEADER_AGE "Age" +/* Permanent. RFC9110, Section 10.2.1: HTTP Semantics */ +#define MHD_HTTP_HEADER_ALLOW "Allow" +/* Permanent. RFC9110, Section 11.6.3: HTTP Semantics */ +#define MHD_HTTP_HEADER_AUTHENTICATION_INFO "Authentication-Info" +/* Permanent. RFC9110, Section 11.6.2: HTTP Semantics */ #define MHD_HTTP_HEADER_AUTHORIZATION "Authorization" -/* Standard. RFC7234, Section 5.2 */ +/* Permanent. RFC9111, Section 5.2 */ #define MHD_HTTP_HEADER_CACHE_CONTROL "Cache-Control" -/* Reserved. RFC7230, Section 8.1 */ -#define MHD_HTTP_HEADER_CLOSE "Close" -/* Standard. RFC7230, Section 6.1 */ -#define MHD_HTTP_HEADER_CONNECTION "Connection" -/* Standard. RFC7231, Section 3.1.2.2 */ +/* Permanent. RFC9112, Section 9.6: HTTP/1.1 */ +#define MHD_HTTP_HEADER_CLOSE "Close" +/* Permanent. RFC9110, Section 7.6.1: HTTP Semantics */ +#define MHD_HTTP_HEADER_CONNECTION "Connection" +/* Permanent. RFC9110, Section 8.4: HTTP Semantics */ #define MHD_HTTP_HEADER_CONTENT_ENCODING "Content-Encoding" -/* Standard. RFC7231, Section 3.1.3.2 */ +/* Permanent. RFC9110, Section 8.5: HTTP Semantics */ #define MHD_HTTP_HEADER_CONTENT_LANGUAGE "Content-Language" -/* Standard. RFC7230, Section 3.3.2 */ +/* Permanent. RFC9110, Section 8.6: HTTP Semantics */ #define MHD_HTTP_HEADER_CONTENT_LENGTH "Content-Length" -/* Standard. RFC7231, Section 3.1.4.2 */ +/* Permanent. RFC9110, Section 8.7: HTTP Semantics */ #define MHD_HTTP_HEADER_CONTENT_LOCATION "Content-Location" -/* Standard. RFC7233, Section 4.2 */ +/* Permanent. RFC9110, Section 14.4: HTTP Semantics */ #define MHD_HTTP_HEADER_CONTENT_RANGE "Content-Range" -/* Standard. RFC7231, Section 3.1.1.5 */ +/* Permanent. RFC9110, Section 8.3: HTTP Semantics */ #define MHD_HTTP_HEADER_CONTENT_TYPE "Content-Type" -/* Standard. RFC7231, Section 7.1.1.2 */ -#define MHD_HTTP_HEADER_DATE "Date" -/* Standard. RFC7232, Section 2.3 */ -#define MHD_HTTP_HEADER_ETAG "ETag" -/* Standard. RFC7231, Section 5.1.1 */ -#define MHD_HTTP_HEADER_EXPECT "Expect" -/* Standard. RFC7234, Section 5.3 */ -#define MHD_HTTP_HEADER_EXPIRES "Expires" -/* Standard. RFC7231, Section 5.5.1 */ -#define MHD_HTTP_HEADER_FROM "From" -/* Standard. RFC7230, Section 5.4 */ -#define MHD_HTTP_HEADER_HOST "Host" -/* Standard. RFC7232, Section 3.1 */ -#define MHD_HTTP_HEADER_IF_MATCH "If-Match" -/* Standard. RFC7232, Section 3.3 */ +/* Permanent. RFC9110, Section 6.6.1: HTTP Semantics */ +#define MHD_HTTP_HEADER_DATE "Date" +/* Permanent. RFC9110, Section 8.8.3: HTTP Semantics */ +#define MHD_HTTP_HEADER_ETAG "ETag" +/* Permanent. RFC9110, Section 10.1.1: HTTP Semantics */ +#define MHD_HTTP_HEADER_EXPECT "Expect" +/* Permanent. RFC9111, Section 5.3: HTTP Caching */ +#define MHD_HTTP_HEADER_EXPIRES "Expires" +/* Permanent. RFC9110, Section 10.1.2: HTTP Semantics */ +#define MHD_HTTP_HEADER_FROM "From" +/* Permanent. RFC9110, Section 7.2: HTTP Semantics */ +#define MHD_HTTP_HEADER_HOST "Host" +/* Permanent. RFC9110, Section 13.1.1: HTTP Semantics */ +#define MHD_HTTP_HEADER_IF_MATCH "If-Match" +/* Permanent. RFC9110, Section 13.1.3: HTTP Semantics */ #define MHD_HTTP_HEADER_IF_MODIFIED_SINCE "If-Modified-Since" -/* Standard. RFC7232, Section 3.2 */ +/* Permanent. RFC9110, Section 13.1.2: HTTP Semantics */ #define MHD_HTTP_HEADER_IF_NONE_MATCH "If-None-Match" -/* Standard. RFC7233, Section 3.2 */ -#define MHD_HTTP_HEADER_IF_RANGE "If-Range" -/* Standard. RFC7232, Section 3.4 */ +/* Permanent. RFC9110, Section 13.1.5: HTTP Semantics */ +#define MHD_HTTP_HEADER_IF_RANGE "If-Range" +/* Permanent. RFC9110, Section 13.1.4: HTTP Semantics */ #define MHD_HTTP_HEADER_IF_UNMODIFIED_SINCE "If-Unmodified-Since" -/* Standard. RFC7232, Section 2.2 */ +/* Permanent. RFC9110, Section 8.8.2: HTTP Semantics */ #define MHD_HTTP_HEADER_LAST_MODIFIED "Last-Modified" -/* Standard. RFC7231, Section 7.1.2 */ -#define MHD_HTTP_HEADER_LOCATION "Location" -/* Standard. RFC7231, Section 5.1.2 */ +/* Permanent. RFC9110, Section 10.2.2: HTTP Semantics */ +#define MHD_HTTP_HEADER_LOCATION "Location" +/* Permanent. RFC9110, Section 7.6.2: HTTP Semantics */ #define MHD_HTTP_HEADER_MAX_FORWARDS "Max-Forwards" -/* Standard. RFC7231, Appendix A.1 */ +/* Permanent. RFC9112, Appendix B.1: HTTP/1.1 */ #define MHD_HTTP_HEADER_MIME_VERSION "MIME-Version" -/* Standard. RFC7234, Section 5.4 */ -#define MHD_HTTP_HEADER_PRAGMA "Pragma" -/* Standard. RFC7235, Section 4.3 */ +/* Deprecated. RFC9111, Section 5.4: HTTP Caching */ +#define MHD_HTTP_HEADER_PRAGMA "Pragma" +/* Permanent. RFC9110, Section 11.7.1: HTTP Semantics */ #define MHD_HTTP_HEADER_PROXY_AUTHENTICATE "Proxy-Authenticate" -/* Standard. RFC7235, Section 4.4 */ +/* Permanent. RFC9110, Section 11.7.3: HTTP Semantics */ +#define MHD_HTTP_HEADER_PROXY_AUTHENTICATION_INFO "Proxy-Authentication-Info" +/* Permanent. RFC9110, Section 11.7.2: HTTP Semantics */ #define MHD_HTTP_HEADER_PROXY_AUTHORIZATION "Proxy-Authorization" -/* Standard. RFC7233, Section 3.1 */ -#define MHD_HTTP_HEADER_RANGE "Range" -/* Standard. RFC7231, Section 5.5.2 */ -#define MHD_HTTP_HEADER_REFERER "Referer" -/* Standard. RFC7231, Section 7.1.3 */ -#define MHD_HTTP_HEADER_RETRY_AFTER "Retry-After" -/* Standard. RFC7231, Section 7.4.2 */ -#define MHD_HTTP_HEADER_SERVER "Server" -/* Standard. RFC7230, Section 4.3 */ -#define MHD_HTTP_HEADER_TE "TE" -/* Standard. RFC7230, Section 4.4 */ -#define MHD_HTTP_HEADER_TRAILER "Trailer" -/* Standard. RFC7230, Section 3.3.1 */ +/* Permanent. RFC9110, Section 14.2: HTTP Semantics */ +#define MHD_HTTP_HEADER_RANGE "Range" +/* Permanent. RFC9110, Section 10.1.3: HTTP Semantics */ +#define MHD_HTTP_HEADER_REFERER "Referer" +/* Permanent. RFC9110, Section 10.2.3: HTTP Semantics */ +#define MHD_HTTP_HEADER_RETRY_AFTER "Retry-After" +/* Permanent. RFC9110, Section 10.2.4: HTTP Semantics */ +#define MHD_HTTP_HEADER_SERVER "Server" +/* Permanent. RFC9110, Section 10.1.4: HTTP Semantics */ +#define MHD_HTTP_HEADER_TE "TE" +/* Permanent. RFC9110, Section 6.6.2: HTTP Semantics */ +#define MHD_HTTP_HEADER_TRAILER "Trailer" +/* Permanent. RFC9112, Section 6.1: HTTP Semantics */ #define MHD_HTTP_HEADER_TRANSFER_ENCODING "Transfer-Encoding" -/* Standard. RFC7230, Section 6.7 */ -#define MHD_HTTP_HEADER_UPGRADE "Upgrade" -/* Standard. RFC7231, Section 5.5.3 */ -#define MHD_HTTP_HEADER_USER_AGENT "User-Agent" -/* Standard. RFC7231, Section 7.1.4 */ -#define MHD_HTTP_HEADER_VARY "Vary" -/* Standard. RFC7230, Section 5.7.1 */ -#define MHD_HTTP_HEADER_VIA "Via" -/* Standard. RFC7235, Section 4.1 */ +/* Permanent. RFC9110, Section 7.8: HTTP Semantics */ +#define MHD_HTTP_HEADER_UPGRADE "Upgrade" +/* Permanent. RFC9110, Section 10.1.5: HTTP Semantics */ +#define MHD_HTTP_HEADER_USER_AGENT "User-Agent" +/* Permanent. RFC9110, Section 12.5.5: HTTP Semantics */ +#define MHD_HTTP_HEADER_VARY "Vary" +/* Permanent. RFC9110, Section 7.6.3: HTTP Semantics */ +#define MHD_HTTP_HEADER_VIA "Via" +/* Permanent. RFC9110, Section 11.6.1: HTTP Semantics */ #define MHD_HTTP_HEADER_WWW_AUTHENTICATE "WWW-Authenticate" -/* Standard. RFC7234, Section 5.5 */ -#define MHD_HTTP_HEADER_WARNING "Warning" +/* Permanent. RFC9110, Section 12.5.5: HTTP Semantics */ +#define MHD_HTTP_HEADER_ASTERISK "*" /* Additional HTTP headers. */ -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_A_IM "A-IM" -/* No category. RFC4229 */ +/* Permanent. RFC 3229: Delta encoding in HTTP */ +#define MHD_HTTP_HEADER_A_IM "A-IM" +/* Permanent. RFC 2324: Hyper Text Coffee Pot Control Protocol (HTCPCP/1.0) */ #define MHD_HTTP_HEADER_ACCEPT_ADDITIONS "Accept-Additions" -/* Informational. RFC7089 */ +/* Permanent. RFC 8942, Section 3.1: HTTP Client Hints */ +#define MHD_HTTP_HEADER_ACCEPT_CH "Accept-CH" +/* Permanent. RFC 7089: HTTP Framework for Time-Based Access to Resource States -- Memento */ #define MHD_HTTP_HEADER_ACCEPT_DATETIME "Accept-Datetime" -/* No category. RFC4229 */ +/* Permanent. RFC 2295: Transparent Content Negotiation in HTTP */ #define MHD_HTTP_HEADER_ACCEPT_FEATURES "Accept-Features" -/* No category. RFC5789 */ +/* Permanent. RFC 5789: PATCH Method for HTTP */ #define MHD_HTTP_HEADER_ACCEPT_PATCH "Accept-Patch" -/* Standard. RFC7639, Section 2 */ -#define MHD_HTTP_HEADER_ALPN "ALPN" -/* Standard. RFC7838 */ -#define MHD_HTTP_HEADER_ALT_SVC "Alt-Svc" -/* Standard. RFC7838 */ -#define MHD_HTTP_HEADER_ALT_USED "Alt-Used" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_ALTERNATES "Alternates" -/* No category. RFC4437 */ +/* Permanent. Linked Data Platform 1.0 */ +#define MHD_HTTP_HEADER_ACCEPT_POST "Accept-Post" +/* Permanent. RFC-ietf-httpbis-message-signatures-19, Section 5.1: HTTP Message Signatures */ +#define MHD_HTTP_HEADER_ACCEPT_SIGNATURE "Accept-Signature" +/* Permanent. Fetch */ +#define MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS \ + "Access-Control-Allow-Credentials" +/* Permanent. Fetch */ +#define MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_HEADERS \ + "Access-Control-Allow-Headers" +/* Permanent. Fetch */ +#define MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_METHODS \ + "Access-Control-Allow-Methods" +/* Permanent. Fetch */ +#define MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN \ + "Access-Control-Allow-Origin" +/* Permanent. Fetch */ +#define MHD_HTTP_HEADER_ACCESS_CONTROL_EXPOSE_HEADERS \ + "Access-Control-Expose-Headers" +/* Permanent. Fetch */ +#define MHD_HTTP_HEADER_ACCESS_CONTROL_MAX_AGE "Access-Control-Max-Age" +/* Permanent. Fetch */ +#define MHD_HTTP_HEADER_ACCESS_CONTROL_REQUEST_HEADERS \ + "Access-Control-Request-Headers" +/* Permanent. Fetch */ +#define MHD_HTTP_HEADER_ACCESS_CONTROL_REQUEST_METHOD \ + "Access-Control-Request-Method" +/* Permanent. RFC 7639, Section 2: The ALPN HTTP Header Field */ +#define MHD_HTTP_HEADER_ALPN "ALPN" +/* Permanent. RFC 7838: HTTP Alternative Services */ +#define MHD_HTTP_HEADER_ALT_SVC "Alt-Svc" +/* Permanent. RFC 7838: HTTP Alternative Services */ +#define MHD_HTTP_HEADER_ALT_USED "Alt-Used" +/* Permanent. RFC 2295: Transparent Content Negotiation in HTTP */ +#define MHD_HTTP_HEADER_ALTERNATES "Alternates" +/* Permanent. RFC 4437: Web Distributed Authoring and Versioning (WebDAV) Redirect Reference Resources */ #define MHD_HTTP_HEADER_APPLY_TO_REDIRECT_REF "Apply-To-Redirect-Ref" -/* Experimental. RFC8053, Section 4 */ +/* Permanent. RFC 8053, Section 4: HTTP Authentication Extensions for Interactive Clients */ #define MHD_HTTP_HEADER_AUTHENTICATION_CONTROL "Authentication-Control" -/* Standard. RFC7615, Section 3 */ -#define MHD_HTTP_HEADER_AUTHENTICATION_INFO "Authentication-Info" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_C_EXT "C-Ext" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_C_MAN "C-Man" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_C_OPT "C-Opt" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_C_PEP "C-PEP" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_C_PEP_INFO "C-PEP-Info" -/* Standard. RFC7809, Section 7.1 */ +/* Permanent. RFC9211: The Cache-Status HTTP Response Header Field */ +#define MHD_HTTP_HEADER_CACHE_STATUS "Cache-Status" +/* Permanent. RFC 8607, Section 5.1: Calendaring Extensions to WebDAV (CalDAV): Managed Attachments */ +#define MHD_HTTP_HEADER_CAL_MANAGED_ID "Cal-Managed-ID" +/* Permanent. RFC 7809, Section 7.1: Calendaring Extensions to WebDAV (CalDAV): Time Zones by Reference */ #define MHD_HTTP_HEADER_CALDAV_TIMEZONES "CalDAV-Timezones" -/* Obsoleted. RFC2068; RFC2616 */ -#define MHD_HTTP_HEADER_CONTENT_BASE "Content-Base" -/* Standard. RFC6266 */ +/* Permanent. RFC9297 */ +#define MHD_HTTP_HEADER_CAPSULE_PROTOCOL "Capsule-Protocol" +/* Permanent. RFC9213: Targeted HTTP Cache Control */ +#define MHD_HTTP_HEADER_CDN_CACHE_CONTROL "CDN-Cache-Control" +/* Permanent. RFC 8586: Loop Detection in Content Delivery Networks (CDNs) */ +#define MHD_HTTP_HEADER_CDN_LOOP "CDN-Loop" +/* Permanent. RFC 8739, Section 3.3: Support for Short-Term, Automatically Renewed (STAR) Certificates in the Automated Certificate Management Environment (ACME) */ +#define MHD_HTTP_HEADER_CERT_NOT_AFTER "Cert-Not-After" +/* Permanent. RFC 8739, Section 3.3: Support for Short-Term, Automatically Renewed (STAR) Certificates in the Automated Certificate Management Environment (ACME) */ +#define MHD_HTTP_HEADER_CERT_NOT_BEFORE "Cert-Not-Before" +/* Permanent. Clear Site Data */ +#define MHD_HTTP_HEADER_CLEAR_SITE_DATA "Clear-Site-Data" +/* Permanent. RFC9440, Section 2: Client-Cert HTTP Header Field */ +#define MHD_HTTP_HEADER_CLIENT_CERT "Client-Cert" +/* Permanent. RFC9440, Section 2: Client-Cert HTTP Header Field */ +#define MHD_HTTP_HEADER_CLIENT_CERT_CHAIN "Client-Cert-Chain" +/* Permanent. RFC-ietf-httpbis-digest-headers-13, Section 2: Digest Fields */ +#define MHD_HTTP_HEADER_CONTENT_DIGEST "Content-Digest" +/* Permanent. RFC 6266: Use of the Content-Disposition Header Field in the Hypertext Transfer Protocol (HTTP) */ #define MHD_HTTP_HEADER_CONTENT_DISPOSITION "Content-Disposition" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_CONTENT_ID "Content-ID" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_CONTENT_MD5 "Content-MD5" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_CONTENT_SCRIPT_TYPE "Content-Script-Type" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_CONTENT_STYLE_TYPE "Content-Style-Type" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_CONTENT_VERSION "Content-Version" -/* Standard. RFC6265 */ -#define MHD_HTTP_HEADER_COOKIE "Cookie" -/* Obsoleted. RFC2965; RFC6265 */ -#define MHD_HTTP_HEADER_COOKIE2 "Cookie2" -/* Standard. RFC5323 */ -#define MHD_HTTP_HEADER_DASL "DASL" -/* Standard. RFC4918 */ -#define MHD_HTTP_HEADER_DAV "DAV" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_DEFAULT_STYLE "Default-Style" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_DELTA_BASE "Delta-Base" -/* Standard. RFC4918 */ -#define MHD_HTTP_HEADER_DEPTH "Depth" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_DERIVED_FROM "Derived-From" -/* Standard. RFC4918 */ -#define MHD_HTTP_HEADER_DESTINATION "Destination" -/* No category. RFC4229 */ +/* Permanent. The HTTP Distribution and Replication Protocol */ +#define MHD_HTTP_HEADER_CONTENT_ID "Content-ID" +/* Permanent. Content Security Policy Level 3 */ +#define MHD_HTTP_HEADER_CONTENT_SECURITY_POLICY "Content-Security-Policy" +/* Permanent. Content Security Policy Level 3 */ +#define MHD_HTTP_HEADER_CONTENT_SECURITY_POLICY_REPORT_ONLY \ + "Content-Security-Policy-Report-Only" +/* Permanent. RFC 6265: HTTP State Management Mechanism */ +#define MHD_HTTP_HEADER_COOKIE "Cookie" +/* Permanent. HTML */ +#define MHD_HTTP_HEADER_CROSS_ORIGIN_EMBEDDER_POLICY \ + "Cross-Origin-Embedder-Policy" +/* Permanent. HTML */ +#define MHD_HTTP_HEADER_CROSS_ORIGIN_EMBEDDER_POLICY_REPORT_ONLY \ + "Cross-Origin-Embedder-Policy-Report-Only" +/* Permanent. HTML */ +#define MHD_HTTP_HEADER_CROSS_ORIGIN_OPENER_POLICY "Cross-Origin-Opener-Policy" +/* Permanent. HTML */ +#define MHD_HTTP_HEADER_CROSS_ORIGIN_OPENER_POLICY_REPORT_ONLY \ + "Cross-Origin-Opener-Policy-Report-Only" +/* Permanent. Fetch */ +#define MHD_HTTP_HEADER_CROSS_ORIGIN_RESOURCE_POLICY \ + "Cross-Origin-Resource-Policy" +/* Permanent. RFC 5323: Web Distributed Authoring and Versioning (WebDAV) SEARCH */ +#define MHD_HTTP_HEADER_DASL "DASL" +/* Permanent. RFC 4918: HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV) */ +#define MHD_HTTP_HEADER_DAV "DAV" +/* Permanent. RFC 3229: Delta encoding in HTTP */ +#define MHD_HTTP_HEADER_DELTA_BASE "Delta-Base" +/* Permanent. RFC 4918: HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV) */ +#define MHD_HTTP_HEADER_DEPTH "Depth" +/* Permanent. RFC 4918: HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV) */ +#define MHD_HTTP_HEADER_DESTINATION "Destination" +/* Permanent. The HTTP Distribution and Replication Protocol */ #define MHD_HTTP_HEADER_DIFFERENTIAL_ID "Differential-ID" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_DIGEST "Digest" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_EXT "Ext" -/* Standard. RFC7239 */ -#define MHD_HTTP_HEADER_FORWARDED "Forwarded" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_GETPROFILE "GetProfile" -/* Experimental. RFC7486, Section 6.1.1 */ -#define MHD_HTTP_HEADER_HOBAREG "Hobareg" -/* Standard. RFC7540, Section 3.2.1 */ -#define MHD_HTTP_HEADER_HTTP2_SETTINGS "HTTP2-Settings" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_IM "IM" -/* Standard. RFC4918 */ -#define MHD_HTTP_HEADER_IF "If" -/* Standard. RFC6638 */ +/* Permanent. RFC9449: OAuth 2.0 Demonstrating Proof of Possession (DPoP) */ +#define MHD_HTTP_HEADER_DPOP "DPoP" +/* Permanent. RFC9449: OAuth 2.0 Demonstrating Proof of Possession (DPoP) */ +#define MHD_HTTP_HEADER_DPOP_NONCE "DPoP-Nonce" +/* Permanent. RFC 8470: Using Early Data in HTTP */ +#define MHD_HTTP_HEADER_EARLY_DATA "Early-Data" +/* Permanent. RFC9163: Expect-CT Extension for HTTP */ +#define MHD_HTTP_HEADER_EXPECT_CT "Expect-CT" +/* Permanent. RFC 7239: Forwarded HTTP Extension */ +#define MHD_HTTP_HEADER_FORWARDED "Forwarded" +/* Permanent. RFC 7486, Section 6.1.1: HTTP Origin-Bound Authentication (HOBA) */ +#define MHD_HTTP_HEADER_HOBAREG "Hobareg" +/* Permanent. RFC 4918: HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV) */ +#define MHD_HTTP_HEADER_IF "If" +/* Permanent. RFC 6338: Scheduling Extensions to CalDAV */ #define MHD_HTTP_HEADER_IF_SCHEDULE_TAG_MATCH "If-Schedule-Tag-Match" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_KEEP_ALIVE "Keep-Alive" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_LABEL "Label" -/* No category. RFC5988 */ -#define MHD_HTTP_HEADER_LINK "Link" -/* Standard. RFC4918 */ -#define MHD_HTTP_HEADER_LOCK_TOKEN "Lock-Token" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_MAN "Man" -/* Informational. RFC7089 */ +/* Permanent. RFC 3229: Delta encoding in HTTP */ +#define MHD_HTTP_HEADER_IM "IM" +/* Permanent. RFC 8473: Token Binding over HTTP */ +#define MHD_HTTP_HEADER_INCLUDE_REFERRED_TOKEN_BINDING_ID \ + "Include-Referred-Token-Binding-ID" +/* Permanent. RFC 2068: Hypertext Transfer Protocol -- HTTP/1.1 */ +#define MHD_HTTP_HEADER_KEEP_ALIVE "Keep-Alive" +/* Permanent. RFC 3253: Versioning Extensions to WebDAV: (Web Distributed Authoring and Versioning) */ +#define MHD_HTTP_HEADER_LABEL "Label" +/* Permanent. HTML */ +#define MHD_HTTP_HEADER_LAST_EVENT_ID "Last-Event-ID" +/* Permanent. RFC 8288: Web Linking */ +#define MHD_HTTP_HEADER_LINK "Link" +/* Permanent. RFC 4918: HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV) */ +#define MHD_HTTP_HEADER_LOCK_TOKEN "Lock-Token" +/* Permanent. RFC 7089: HTTP Framework for Time-Based Access to Resource States -- Memento */ #define MHD_HTTP_HEADER_MEMENTO_DATETIME "Memento-Datetime" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_METER "Meter" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_NEGOTIATE "Negotiate" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_OPT "Opt" -/* Experimental. RFC8053, Section 3 */ +/* Permanent. RFC 2227: Simple Hit-Metering and Usage-Limiting for HTTP */ +#define MHD_HTTP_HEADER_METER "Meter" +/* Permanent. RFC 2295: Transparent Content Negotiation in HTTP */ +#define MHD_HTTP_HEADER_NEGOTIATE "Negotiate" +/* Permanent. Network Error Logging */ +#define MHD_HTTP_HEADER_NEL "NEL" +/* Permanent. OData Version 4.01 Part 1: Protocol; OASIS; Chet_Ensign */ +#define MHD_HTTP_HEADER_ODATA_ENTITYID "OData-EntityId" +/* Permanent. OData Version 4.01 Part 1: Protocol; OASIS; Chet_Ensign */ +#define MHD_HTTP_HEADER_ODATA_ISOLATION "OData-Isolation" +/* Permanent. OData Version 4.01 Part 1: Protocol; OASIS; Chet_Ensign */ +#define MHD_HTTP_HEADER_ODATA_MAXVERSION "OData-MaxVersion" +/* Permanent. OData Version 4.01 Part 1: Protocol; OASIS; Chet_Ensign */ +#define MHD_HTTP_HEADER_ODATA_VERSION "OData-Version" +/* Permanent. RFC 8053, Section 3: HTTP Authentication Extensions for Interactive Clients */ #define MHD_HTTP_HEADER_OPTIONAL_WWW_AUTHENTICATE "Optional-WWW-Authenticate" -/* Standard. RFC4229 */ +/* Permanent. RFC 3648: Web Distributed Authoring and Versioning (WebDAV) Ordered Collections Protocol */ #define MHD_HTTP_HEADER_ORDERING_TYPE "Ordering-Type" -/* Standard. RFC6454 */ -#define MHD_HTTP_HEADER_ORIGIN "Origin" -/* Standard. RFC4918 */ -#define MHD_HTTP_HEADER_OVERWRITE "Overwrite" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_P3P "P3P" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_PEP "PEP" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_PICS_LABEL "PICS-Label" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_PEP_INFO "Pep-Info" -/* Standard. RFC4229 */ -#define MHD_HTTP_HEADER_POSITION "Position" -/* Standard. RFC7240 */ -#define MHD_HTTP_HEADER_PREFER "Prefer" -/* Standard. RFC7240 */ +/* Permanent. RFC 6454: The Web Origin Concept */ +#define MHD_HTTP_HEADER_ORIGIN "Origin" +/* Permanent. HTML */ +#define MHD_HTTP_HEADER_ORIGIN_AGENT_CLUSTER "Origin-Agent-Cluster" +/* Permanent. RFC 8613, Section 11.1: Object Security for Constrained RESTful Environments (OSCORE) */ +#define MHD_HTTP_HEADER_OSCORE "OSCORE" +/* Permanent. OASIS Project Specification 01; OASIS; Chet_Ensign */ +#define MHD_HTTP_HEADER_OSLC_CORE_VERSION "OSLC-Core-Version" +/* Permanent. RFC 4918: HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV) */ +#define MHD_HTTP_HEADER_OVERWRITE "Overwrite" +/* Permanent. HTML */ +#define MHD_HTTP_HEADER_PING_FROM "Ping-From" +/* Permanent. HTML */ +#define MHD_HTTP_HEADER_PING_TO "Ping-To" +/* Permanent. RFC 3648: Web Distributed Authoring and Versioning (WebDAV) Ordered Collections Protocol */ +#define MHD_HTTP_HEADER_POSITION "Position" +/* Permanent. RFC 7240: Prefer Header for HTTP */ +#define MHD_HTTP_HEADER_PREFER "Prefer" +/* Permanent. RFC 7240: Prefer Header for HTTP */ #define MHD_HTTP_HEADER_PREFERENCE_APPLIED "Preference-Applied" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_PROFILEOBJECT "ProfileObject" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_PROTOCOL "Protocol" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_PROTOCOL_INFO "Protocol-Info" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_PROTOCOL_QUERY "Protocol-Query" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_PROTOCOL_REQUEST "Protocol-Request" -/* Standard. RFC7615, Section 4 */ -#define MHD_HTTP_HEADER_PROXY_AUTHENTICATION_INFO "Proxy-Authentication-Info" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_PROXY_FEATURES "Proxy-Features" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_PROXY_INSTRUCTION "Proxy-Instruction" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_PUBLIC "Public" -/* Standard. RFC7469 */ +/* Permanent. RFC9218: Extensible Prioritization Scheme for HTTP */ +#define MHD_HTTP_HEADER_PRIORITY "Priority" +/* Permanent. RFC9209: The Proxy-Status HTTP Response Header Field */ +#define MHD_HTTP_HEADER_PROXY_STATUS "Proxy-Status" +/* Permanent. RFC 7469: Public Key Pinning Extension for HTTP */ #define MHD_HTTP_HEADER_PUBLIC_KEY_PINS "Public-Key-Pins" -/* Standard. RFC7469 */ +/* Permanent. RFC 7469: Public Key Pinning Extension for HTTP */ #define MHD_HTTP_HEADER_PUBLIC_KEY_PINS_REPORT_ONLY \ "Public-Key-Pins-Report-Only" -/* No category. RFC4437 */ +/* Permanent. RFC 4437: Web Distributed Authoring and Versioning (WebDAV) Redirect Reference Resources */ #define MHD_HTTP_HEADER_REDIRECT_REF "Redirect-Ref" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_SAFE "Safe" -/* Standard. RFC6638 */ +/* Permanent. HTML */ +#define MHD_HTTP_HEADER_REFRESH "Refresh" +/* Permanent. RFC 8555, Section 6.5.1: Automatic Certificate Management Environment (ACME) */ +#define MHD_HTTP_HEADER_REPLAY_NONCE "Replay-Nonce" +/* Permanent. RFC-ietf-httpbis-digest-headers-13, Section 3: Digest Fields */ +#define MHD_HTTP_HEADER_REPR_DIGEST "Repr-Digest" +/* Permanent. RFC 6638: Scheduling Extensions to CalDAV */ #define MHD_HTTP_HEADER_SCHEDULE_REPLY "Schedule-Reply" -/* Standard. RFC6638 */ +/* Permanent. RFC 6338: Scheduling Extensions to CalDAV */ #define MHD_HTTP_HEADER_SCHEDULE_TAG "Schedule-Tag" -/* Standard. RFC6455 */ +/* Permanent. Fetch */ +#define MHD_HTTP_HEADER_SEC_PURPOSE "Sec-Purpose" +/* Permanent. RFC 8473: Token Binding over HTTP */ +#define MHD_HTTP_HEADER_SEC_TOKEN_BINDING "Sec-Token-Binding" +/* Permanent. RFC 6455: The WebSocket Protocol */ #define MHD_HTTP_HEADER_SEC_WEBSOCKET_ACCEPT "Sec-WebSocket-Accept" -/* Standard. RFC6455 */ +/* Permanent. RFC 6455: The WebSocket Protocol */ #define MHD_HTTP_HEADER_SEC_WEBSOCKET_EXTENSIONS "Sec-WebSocket-Extensions" -/* Standard. RFC6455 */ +/* Permanent. RFC 6455: The WebSocket Protocol */ #define MHD_HTTP_HEADER_SEC_WEBSOCKET_KEY "Sec-WebSocket-Key" -/* Standard. RFC6455 */ +/* Permanent. RFC 6455: The WebSocket Protocol */ #define MHD_HTTP_HEADER_SEC_WEBSOCKET_PROTOCOL "Sec-WebSocket-Protocol" -/* Standard. RFC6455 */ +/* Permanent. RFC 6455: The WebSocket Protocol */ #define MHD_HTTP_HEADER_SEC_WEBSOCKET_VERSION "Sec-WebSocket-Version" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_SECURITY_SCHEME "Security-Scheme" -/* Standard. RFC6265 */ -#define MHD_HTTP_HEADER_SET_COOKIE "Set-Cookie" -/* Obsoleted. RFC2965; RFC6265 */ -#define MHD_HTTP_HEADER_SET_COOKIE2 "Set-Cookie2" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_SETPROFILE "SetProfile" -/* Standard. RFC5023 */ -#define MHD_HTTP_HEADER_SLUG "SLUG" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_SOAPACTION "SoapAction" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_STATUS_URI "Status-URI" -/* Standard. RFC6797 */ +/* Permanent. Server Timing */ +#define MHD_HTTP_HEADER_SERVER_TIMING "Server-Timing" +/* Permanent. RFC 6265: HTTP State Management Mechanism */ +#define MHD_HTTP_HEADER_SET_COOKIE "Set-Cookie" +/* Permanent. RFC-ietf-httpbis-message-signatures-19, Section 4.2: HTTP Message Signatures */ +#define MHD_HTTP_HEADER_SIGNATURE "Signature" +/* Permanent. RFC-ietf-httpbis-message-signatures-19, Section 4.1: HTTP Message Signatures */ +#define MHD_HTTP_HEADER_SIGNATURE_INPUT "Signature-Input" +/* Permanent. RFC 5023: The Atom Publishing Protocol */ +#define MHD_HTTP_HEADER_SLUG "SLUG" +/* Permanent. Simple Object Access Protocol (SOAP) 1.1 */ +#define MHD_HTTP_HEADER_SOAPACTION "SoapAction" +/* Permanent. RFC 2518: HTTP Extensions for Distributed Authoring -- WEBDAV */ +#define MHD_HTTP_HEADER_STATUS_URI "Status-URI" +/* Permanent. RFC 6797: HTTP Strict Transport Security (HSTS) */ #define MHD_HTTP_HEADER_STRICT_TRANSPORT_SECURITY "Strict-Transport-Security" -/* No category. RFC4229 */ +/* Permanent. RFC 8594: The Sunset HTTP Header Field */ +#define MHD_HTTP_HEADER_SUNSET "Sunset" +/* Permanent. Edge Architecture Specification */ #define MHD_HTTP_HEADER_SURROGATE_CAPABILITY "Surrogate-Capability" -/* No category. RFC4229 */ +/* Permanent. Edge Architecture Specification */ #define MHD_HTTP_HEADER_SURROGATE_CONTROL "Surrogate-Control" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_TCN "TCN" -/* Standard. RFC4918 */ -#define MHD_HTTP_HEADER_TIMEOUT "Timeout" -/* Standard. RFC8030, Section 5.4 */ -#define MHD_HTTP_HEADER_TOPIC "Topic" -/* Standard. RFC8030, Section 5.2 */ -#define MHD_HTTP_HEADER_TTL "TTL" -/* Standard. RFC8030, Section 5.3 */ -#define MHD_HTTP_HEADER_URGENCY "Urgency" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_URI "URI" -/* No category. RFC4229 */ +/* Permanent. RFC 2295: Transparent Content Negotiation in HTTP */ +#define MHD_HTTP_HEADER_TCN "TCN" +/* Permanent. RFC 4918: HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV) */ +#define MHD_HTTP_HEADER_TIMEOUT "Timeout" +/* Permanent. RFC 8030, Section 5.4: Generic Event Delivery Using HTTP Push */ +#define MHD_HTTP_HEADER_TOPIC "Topic" +/* Permanent. Trace Context */ +#define MHD_HTTP_HEADER_TRACEPARENT "Traceparent" +/* Permanent. Trace Context */ +#define MHD_HTTP_HEADER_TRACESTATE "Tracestate" +/* Permanent. RFC 8030, Section 5.2: Generic Event Delivery Using HTTP Push */ +#define MHD_HTTP_HEADER_TTL "TTL" +/* Permanent. RFC 8030, Section 5.3: Generic Event Delivery Using HTTP Push */ +#define MHD_HTTP_HEADER_URGENCY "Urgency" +/* Permanent. RFC 2295: Transparent Content Negotiation in HTTP */ #define MHD_HTTP_HEADER_VARIANT_VARY "Variant-Vary" -/* No category. RFC4229 */ -#define MHD_HTTP_HEADER_WANT_DIGEST "Want-Digest" -/* Informational. RFC7034 */ +/* Permanent. RFC-ietf-httpbis-digest-headers-13, Section 4: Digest Fields */ +#define MHD_HTTP_HEADER_WANT_CONTENT_DIGEST "Want-Content-Digest" +/* Permanent. RFC-ietf-httpbis-digest-headers-13, Section 4: Digest Fields */ +#define MHD_HTTP_HEADER_WANT_REPR_DIGEST "Want-Repr-Digest" +/* Permanent. Fetch */ +#define MHD_HTTP_HEADER_X_CONTENT_TYPE_OPTIONS "X-Content-Type-Options" +/* Permanent. HTML */ #define MHD_HTTP_HEADER_X_FRAME_OPTIONS "X-Frame-Options" +/* Provisional. AMP-Cache-Transform HTTP request header */ +#define MHD_HTTP_HEADER_AMP_CACHE_TRANSFORM "AMP-Cache-Transform" +/* Provisional. OSLC Configuration Management Version 1.0. Part 3: Configuration Specification */ +#define MHD_HTTP_HEADER_CONFIGURATION_CONTEXT "Configuration-Context" +/* Provisional. RFC 6017: Electronic Data Interchange - Internet Integration (EDIINT) Features Header Field */ +#define MHD_HTTP_HEADER_EDIINT_FEATURES "EDIINT-Features" +/* Provisional. OData Version 4.01 Part 1: Protocol; OASIS; Chet_Ensign */ +#define MHD_HTTP_HEADER_ISOLATION "Isolation" +/* Provisional. Permissions Policy */ +#define MHD_HTTP_HEADER_PERMISSIONS_POLICY "Permissions-Policy" +/* Provisional. Repeatable Requests Version 1.0; OASIS; Chet_Ensign */ +#define MHD_HTTP_HEADER_REPEATABILITY_CLIENT_ID "Repeatability-Client-ID" +/* Provisional. Repeatable Requests Version 1.0; OASIS; Chet_Ensign */ +#define MHD_HTTP_HEADER_REPEATABILITY_FIRST_SENT "Repeatability-First-Sent" +/* Provisional. Repeatable Requests Version 1.0; OASIS; Chet_Ensign */ +#define MHD_HTTP_HEADER_REPEATABILITY_REQUEST_ID "Repeatability-Request-ID" +/* Provisional. Repeatable Requests Version 1.0; OASIS; Chet_Ensign */ +#define MHD_HTTP_HEADER_REPEATABILITY_RESULT "Repeatability-Result" +/* Provisional. Reporting API */ +#define MHD_HTTP_HEADER_REPORTING_ENDPOINTS "Reporting-Endpoints" +/* Provisional. Global Privacy Control (GPC) */ +#define MHD_HTTP_HEADER_SEC_GPC "Sec-GPC" +/* Provisional. Resource Timing Level 1 */ +#define MHD_HTTP_HEADER_TIMING_ALLOW_ORIGIN "Timing-Allow-Origin" +/* Deprecated. PEP - an Extension Mechanism for HTTP; status-change-http-experiments-to-historic */ +#define MHD_HTTP_HEADER_C_PEP_INFO "C-PEP-Info" +/* Deprecated. White Paper: Joint Electronic Payment Initiative */ +#define MHD_HTTP_HEADER_PROTOCOL_INFO "Protocol-Info" +/* Deprecated. White Paper: Joint Electronic Payment Initiative */ +#define MHD_HTTP_HEADER_PROTOCOL_QUERY "Protocol-Query" +/* Obsoleted. Access Control for Cross-site Requests */ +#define MHD_HTTP_HEADER_ACCESS_CONTROL "Access-Control" +/* Obsoleted. RFC 2774: An HTTP Extension Framework; status-change-http-experiments-to-historic */ +#define MHD_HTTP_HEADER_C_EXT "C-Ext" +/* Obsoleted. RFC 2774: An HTTP Extension Framework; status-change-http-experiments-to-historic */ +#define MHD_HTTP_HEADER_C_MAN "C-Man" +/* Obsoleted. RFC 2774: An HTTP Extension Framework; status-change-http-experiments-to-historic */ +#define MHD_HTTP_HEADER_C_OPT "C-Opt" +/* Obsoleted. PEP - an Extension Mechanism for HTTP; status-change-http-experiments-to-historic */ +#define MHD_HTTP_HEADER_C_PEP "C-PEP" +/* Obsoleted. RFC 2068: Hypertext Transfer Protocol -- HTTP/1.1; RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1 */ +#define MHD_HTTP_HEADER_CONTENT_BASE "Content-Base" +/* Obsoleted. RFC 2616, Section 14.15: Hypertext Transfer Protocol -- HTTP/1.1; RFC 7231, Appendix B: Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content */ +#define MHD_HTTP_HEADER_CONTENT_MD5 "Content-MD5" +/* Obsoleted. HTML 4.01 Specification */ +#define MHD_HTTP_HEADER_CONTENT_SCRIPT_TYPE "Content-Script-Type" +/* Obsoleted. HTML 4.01 Specification */ +#define MHD_HTTP_HEADER_CONTENT_STYLE_TYPE "Content-Style-Type" +/* Obsoleted. RFC 2068: Hypertext Transfer Protocol -- HTTP/1.1 */ +#define MHD_HTTP_HEADER_CONTENT_VERSION "Content-Version" +/* Obsoleted. RFC 2965: HTTP State Management Mechanism; RFC 6265: HTTP State Management Mechanism */ +#define MHD_HTTP_HEADER_COOKIE2 "Cookie2" +/* Obsoleted. HTML 4.01 Specification */ +#define MHD_HTTP_HEADER_DEFAULT_STYLE "Default-Style" +/* Obsoleted. RFC 2068: Hypertext Transfer Protocol -- HTTP/1.1 */ +#define MHD_HTTP_HEADER_DERIVED_FROM "Derived-From" +/* Obsoleted. RFC 3230: Instance Digests in HTTP; RFC-ietf-httpbis-digest-headers-13, Section 1.3: Digest Fields */ +#define MHD_HTTP_HEADER_DIGEST "Digest" +/* Obsoleted. RFC 2774: An HTTP Extension Framework; status-change-http-experiments-to-historic */ +#define MHD_HTTP_HEADER_EXT "Ext" +/* Obsoleted. Implementation of OPS Over HTTP */ +#define MHD_HTTP_HEADER_GETPROFILE "GetProfile" +/* Obsoleted. RFC 7540, Section 3.2.1: Hypertext Transfer Protocol Version 2 (HTTP/2) */ +#define MHD_HTTP_HEADER_HTTP2_SETTINGS "HTTP2-Settings" +/* Obsoleted. RFC 2774: An HTTP Extension Framework; status-change-http-experiments-to-historic */ +#define MHD_HTTP_HEADER_MAN "Man" +/* Obsoleted. Access Control for Cross-site Requests */ +#define MHD_HTTP_HEADER_METHOD_CHECK "Method-Check" +/* Obsoleted. Access Control for Cross-site Requests */ +#define MHD_HTTP_HEADER_METHOD_CHECK_EXPIRES "Method-Check-Expires" +/* Obsoleted. RFC 2774: An HTTP Extension Framework; status-change-http-experiments-to-historic */ +#define MHD_HTTP_HEADER_OPT "Opt" +/* Obsoleted. The Platform for Privacy Preferences 1.0 (P3P1.0) Specification */ +#define MHD_HTTP_HEADER_P3P "P3P" +/* Obsoleted. PEP - an Extension Mechanism for HTTP */ +#define MHD_HTTP_HEADER_PEP "PEP" +/* Obsoleted. PEP - an Extension Mechanism for HTTP */ +#define MHD_HTTP_HEADER_PEP_INFO "Pep-Info" +/* Obsoleted. PICS Label Distribution Label Syntax and Communication Protocols */ +#define MHD_HTTP_HEADER_PICS_LABEL "PICS-Label" +/* Obsoleted. Implementation of OPS Over HTTP */ +#define MHD_HTTP_HEADER_PROFILEOBJECT "ProfileObject" +/* Obsoleted. PICS Label Distribution Label Syntax and Communication Protocols */ +#define MHD_HTTP_HEADER_PROTOCOL "Protocol" +/* Obsoleted. PICS Label Distribution Label Syntax and Communication Protocols */ +#define MHD_HTTP_HEADER_PROTOCOL_REQUEST "Protocol-Request" +/* Obsoleted. Notification for Proxy Caches */ +#define MHD_HTTP_HEADER_PROXY_FEATURES "Proxy-Features" +/* Obsoleted. Notification for Proxy Caches */ +#define MHD_HTTP_HEADER_PROXY_INSTRUCTION "Proxy-Instruction" +/* Obsoleted. RFC 2068: Hypertext Transfer Protocol -- HTTP/1.1 */ +#define MHD_HTTP_HEADER_PUBLIC "Public" +/* Obsoleted. Access Control for Cross-site Requests */ +#define MHD_HTTP_HEADER_REFERER_ROOT "Referer-Root" +/* Obsoleted. RFC 2310: The Safe Response Header Field; status-change-http-experiments-to-historic */ +#define MHD_HTTP_HEADER_SAFE "Safe" +/* Obsoleted. RFC 2660: The Secure HyperText Transfer Protocol; status-change-http-experiments-to-historic */ +#define MHD_HTTP_HEADER_SECURITY_SCHEME "Security-Scheme" +/* Obsoleted. RFC 2965: HTTP State Management Mechanism; RFC 6265: HTTP State Management Mechanism */ +#define MHD_HTTP_HEADER_SET_COOKIE2 "Set-Cookie2" +/* Obsoleted. Implementation of OPS Over HTTP */ +#define MHD_HTTP_HEADER_SETPROFILE "SetProfile" +/* Obsoleted. RFC 2068: Hypertext Transfer Protocol -- HTTP/1.1 */ +#define MHD_HTTP_HEADER_URI "URI" +/* Obsoleted. RFC 3230: Instance Digests in HTTP; RFC-ietf-httpbis-digest-headers-13, Section 1.3: Digest Fields */ +#define MHD_HTTP_HEADER_WANT_DIGEST "Want-Digest" +/* Obsoleted. RFC9111, Section 5.5: HTTP Caching */ +#define MHD_HTTP_HEADER_WARNING "Warning" + +/* Headers removed from the registry. Do not use! */ +/* Obsoleted. RFC4229 */ +#define MHD_HTTP_HEADER_COMPLIANCE "Compliance" +/* Obsoleted. RFC4229 */ +#define MHD_HTTP_HEADER_CONTENT_TRANSFER_ENCODING "Content-Transfer-Encoding" +/* Obsoleted. RFC4229 */ +#define MHD_HTTP_HEADER_COST "Cost" +/* Obsoleted. RFC4229 */ +#define MHD_HTTP_HEADER_MESSAGE_ID "Message-ID" +/* Obsoleted. RFC4229 */ +#define MHD_HTTP_HEADER_NON_COMPLIANCE "Non-Compliance" +/* Obsoleted. RFC4229 */ +#define MHD_HTTP_HEADER_OPTIONAL "Optional" +/* Obsoleted. RFC4229 */ +#define MHD_HTTP_HEADER_RESOLUTION_HINT "Resolution-Hint" +/* Obsoleted. RFC4229 */ +#define MHD_HTTP_HEADER_RESOLVER_LOCATION "Resolver-Location" +/* Obsoleted. RFC4229 */ +#define MHD_HTTP_HEADER_SUBOK "SubOK" +/* Obsoleted. RFC4229 */ +#define MHD_HTTP_HEADER_SUBST "Subst" +/* Obsoleted. RFC4229 */ +#define MHD_HTTP_HEADER_TITLE "Title" +/* Obsoleted. RFC4229 */ +#define MHD_HTTP_HEADER_UA_COLOR "UA-Color" +/* Obsoleted. RFC4229 */ +#define MHD_HTTP_HEADER_UA_MEDIA "UA-Media" +/* Obsoleted. RFC4229 */ +#define MHD_HTTP_HEADER_UA_PIXELS "UA-Pixels" +/* Obsoleted. RFC4229 */ +#define MHD_HTTP_HEADER_UA_RESOLUTION "UA-Resolution" +/* Obsoleted. RFC4229 */ +#define MHD_HTTP_HEADER_UA_WINDOWPIXELS "UA-Windowpixels" +/* Obsoleted. RFC4229 */ +#define MHD_HTTP_HEADER_VERSION "Version" +/* Obsoleted. W3C Mobile Web Best Practices Working Group */ +#define MHD_HTTP_HEADER_X_DEVICE_ACCEPT "X-Device-Accept" +/* Obsoleted. W3C Mobile Web Best Practices Working Group */ +#define MHD_HTTP_HEADER_X_DEVICE_ACCEPT_CHARSET "X-Device-Accept-Charset" +/* Obsoleted. W3C Mobile Web Best Practices Working Group */ +#define MHD_HTTP_HEADER_X_DEVICE_ACCEPT_ENCODING "X-Device-Accept-Encoding" +/* Obsoleted. W3C Mobile Web Best Practices Working Group */ +#define MHD_HTTP_HEADER_X_DEVICE_ACCEPT_LANGUAGE "X-Device-Accept-Language" +/* Obsoleted. W3C Mobile Web Best Practices Working Group */ +#define MHD_HTTP_HEADER_X_DEVICE_USER_AGENT "X-Device-User-Agent" -/* Some provisional headers. */ -#define MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN \ - "Access-Control-Allow-Origin" /** @} */ /* end of group headers */ - -/** - * String with length data. - */ -struct MHD_String -{ - /** - * Number of characters in @e buf, without 0-termination. - */ - size_t len; - - /** - * 0-terminated C-string. - */ - const char *buf; -}; - +/* Forward declaration */ +struct MHD_Action; /** * A client has requested the given url using the given method * (#MHD_HTTP_METHOD_GET, #MHD_HTTP_METHOD_PUT, - * #MHD_HTTP_METHOD_DELETE, #MHD_HTTP_METHOD_POST, etc). The callback - * must initialize @a rhp to provide further callbacks which will - * process the request further and ultimately to provide the response - * to give back to the client, or return #MHD_NO. + * #MHD_HTTP_METHOD_DELETE, #MHD_HTTP_METHOD_POST, etc). * * @param cls argument given together with the function * pointer when the handler was registered with MHD - * @param url the requested url (without arguments after "?") + * @param path the requested uri (without arguments after "?") * @param method the HTTP method used (#MHD_HTTP_METHOD_GET, * #MHD_HTTP_METHOD_PUT, etc.) + * @param upload_size the size of the message upload content payload, + * #MHD_SIZE_UNKNOWN for chunked uploads (if the + * final chunk has not been processed yet) * @return action how to proceed, NULL - * if the socket must be closed due to a serious - * error while handling the request + * if the request must be closed due to a serious + * error while handling the request (implies closure + * of underling data stream, for HTTP/1.1 it means + * socket closure). */ -// FIXME: const or no const? typedef const struct MHD_Action * -(*MHD_RequestCallback) (void *cls, +(MHD_FUNC_PARAM_NONNULL_ (2) MHD_FUNC_PARAM_NONNULL_ (3) + *MHD_RequestCallback) (void *cls, struct MHD_Request *request, - const struct MHD_String *url, - enum MHD_Method method); + const struct MHD_String *path, + enum MHD_Method method, + uint_fast64_t upload_size); /** @@ -1629,7 +2069,7 @@ typedef const struct MHD_Action * _MHD_EXTERN struct MHD_Daemon * MHD_daemon_create (MHD_RequestCallback cb, void *cb_cls) -MHD_NONNULL (1); +MHD_FUNC_PARAM_NONNULL_(1); /** @@ -1642,7 +2082,7 @@ MHD_NONNULL (1); */ _MHD_EXTERN enum MHD_StatusCode MHD_daemon_start (struct MHD_Daemon *daemon) -MHD_NONNULL (1); +MHD_FUNC_PARAM_NONNULL_ (1); /** @@ -1662,12 +2102,12 @@ MHD_NONNULL (1); * @param[in,out] daemon daemon to stop accepting new connections for * @return old listen socket on success, #MHD_INVALID_SOCKET if * the daemon was already not listening anymore, or - * was never started + * was never started, or has not listen socket. * @ingroup specialized */ _MHD_EXTERN MHD_socket MHD_daemon_quiesce (struct MHD_Daemon *daemon) -MHD_NONNULL (1); +MHD_FUNC_PARAM_NONNULL_ALL_; /** @@ -1678,7 +2118,7 @@ MHD_NONNULL (1); */ _MHD_EXTERN void MHD_daemon_destroy (struct MHD_Daemon *daemon) -MHD_NONNULL (1); +MHD_FUNC_PARAM_NONNULL_ALL_; /* ********************* daemon options ************** */ @@ -1712,13 +2152,13 @@ typedef void * @param[in,out] daemon which instance to setup logging for * @param logger function to invoke * @param logger_cls closure for @a logger - * @return #MHD_SC_LOGGING_NOT_SUPPORTED + * @return #MHD_SC_FEATURE_DISABLED */ _MHD_EXTERN enum MHD_StatusCode MHD_daemon_set_logger (struct MHD_Daemon *daemon, MHD_LoggingCallback logger, void *logger_cls) -MHD_NONNULL (1); +MHD_FUNC_PARAM_NONNULL_ (1); /** @@ -1727,24 +2167,25 @@ MHD_NONNULL (1); * @param daemon which instance to disable logging for */ #define MHD_daemon_disable_logging(daemon) \ - MHD_daemon_set_logger (daemon, \ + MHD_daemon_set_logger ((daemon), \ NULL, \ NULL) - +// TODO: Sort values and assign numbers enum MHD_DeamonOptionBool { + // FIXME: edited names, shortened /** - * Suppresses use of "Date:" header as this system has no RTC - * if the value is set to true. + * Suppresses use of "Date:" header. + * According to RFC should be used only if the system has no RTC. */ - MHD_DAEMON_OPTION_BOOL_SUPPRESS_DATE_HEADER, + MHD_DAEMON_OB_SUPPRESS_DATE_HEADER = 1, /** * Disable use of inter-thread communication channel. * #MHD_daemon_disable_itc() can be used with * #MHD_daemon_thread_internal() to perform some additional * optimizations (in particular, not creating a pipe for IPC - * signalling). If it is used, certain functions like + * signaling). If it is used, certain functions like * #MHD_daemon_quiesce() or #MHD_daemon_add_connection() or * #MHD_action_suspend() cannot be used anymore. * #MHD_daemon_disable_itc() is not beneficial on platforms where @@ -1754,7 +2195,59 @@ enum MHD_DeamonOptionBool * satisfy all of its requirements and need a generally minor * boost in performance. */ - MHD_DAEMON_OPTION_BOOL_SUPPRESS_ITC, + MHD_DAEMON_OB_SUPPRESS_ITC = 2, + + /** + * Enable `turbo`. Disables certain calls to `shutdown()`, + * enables aggressive non-blocking optimistic reads and + * other potentially unsafe optimizations. + * Most effects only happen with #MHD_USE_EPOLL. + */ + MHD_DAEMON_OB_TURBO = 3, + + /** + * You need to set this option if you want to disable use of HTTP "Upgrade". + * "Upgrade" may require usage of additional internal resources, + * which we can avoid providing if they will not be used. + * + * You should only use this function if you are sure you do + * satisfy all of its requirements and need a generally minor + * boost in performance. + */ + MHD_DAEMON_OB_DISALLOW_UPGRADE, + + /** + * Disable #MHD_action_suspend() functionality. + * + * You should only use this function if you are sure you do + * satisfy all of its requirements and need a generally minor + * boost in performance. + */ + MHD_DAEMON_OB_DISALLOW_SUSPEND_RESUME, + + /** + * If present true, allow reusing address:port socket (by using + * SO_REUSEPORT on most platform, or platform-specific ways). If + * present and set to false, disallow reusing address:port socket + * (does nothing on most platform, but uses SO_EXCLUSIVEADDRUSE on + * Windows). + * Ineffective in conjunction with #MHD_daemon_listen_socket(). + */ + MHD_DAEMON_OB_LISTEN_ALLOW_ADDRESS_REUSE, + + /** + * Use SHOUTcast. This will cause *all* responses to begin + * with the SHOUTcast "ICY" line instead of "HTTP". + */ + MHD_DAEMON_OB_ENABLE_SHOUTCAST, + + // FIXME: Added + /** + * Disable converting plus ('+') character to space in GET + * parameters (URI part after '?'). + * TODO: Add explanation, RFCs, HTML + */ + MHD_DAEMON_OB_DISABLE_PLUS_SPACE }; @@ -1766,96 +2259,29 @@ enum MHD_DeamonOptionBool * @param value new value for the option * @return #MHD_SC_OK on on success, * #MHD_SC_TOO_LATE if this option was set after the daemon was started and it cannot be set anymore - * #MHD_SC_NOT_IMPLEMENTED if this option is not implemented in this version of the library + * #MHD_SC_FEATURE_DISABLED if this option is not implemented in this version of the library, + * #MHD_SC_FEATURE_NOT_AVAILABLE if this options is not supported on this system + * #MHD_SC_OPTIONS_CONFLICT */ _MHD_EXTERN enum MHD_StatusCode MHD_daemon_set_option_bool (struct MHD_Daemon *daemon, enum MHD_DaemonOptionBool option, - bool value) -MHD_NONNULL (1); - + enum MHD_Bool value) +MHD_FUNC_PARAM_NONNULL_ALL_ MHD_FUNC_MUST_CHECK_RESULT_; /** - * Enable `turbo`. Disables certain calls to `shutdown()`, - * enables aggressive non-blocking optimistic reads and - * other potentially unsafe optimizations. - * Most effects only happen with #MHD_ELS_EPOLL. - * - * @param daemon which instance to enable turbo for + * Possible levels of enforcement for TCP_FASTOPEN. */ -_MHD_EXTERN void -MHD_daemon_enable_turbo (struct MHD_Daemon *daemon) -MHD_NONNULL (1); - - -/** - * Disable #MHD_action_suspend() functionality. - * - * You should only use this function if you are sure you do - * satisfy all of its requirements and need a generally minor - * boost in performance. - * - * @param daemon which instance to disable suspend for - */ -_MHD_EXTERN void -MHD_daemon_disallow_suspend_resume (struct MHD_Daemon *daemon) -MHD_NONNULL (1); - - -/** - * You need to set this option if you want to disable use of HTTP "Upgrade". - * "Upgrade" may require usage of additional internal resources, - * which we can avoid providing if they will not be used. - * - * You should only use this function if you are sure you do - * satisfy all of its requirements and need a generally minor - * boost in performance. - * - * @param daemon which instance to enable suspend/resume for - */ -_MHD_EXTERN void -MHD_daemon_disallow_upgrade (struct MHD_Daemon *daemon) -MHD_NONNULL (1); - - -/** - * If present true, allow reusing address:port socket (by using - * SO_REUSEPORT on most platform, or platform-specific ways). If - * present and set to false, disallow reusing address:port socket - * (does nothing on most platform, but uses SO_EXCLUSIVEADDRUSE on - * Windows). - * Ineffective in conjunction with #MHD_daemon_listen_socket(). - * - * @param daemon daemon to configure address reuse for - */ -_MHD_EXTERN void -MHD_daemon_listen_allow_address_reuse (struct MHD_Daemon *daemon) -MHD_NONNULL (1); - - -/** - * Use SHOUTcast. This will cause the response to begin - * with the SHOUTcast "ICY" line instead of "HTTP". - * - * @param daemon daemon to set SHOUTcast option for - */ -_MHD_EXTERN void -MHD_daemon_enable_shoutcast (struct MHD_Daemon *daemon) -MHD_NONNULL (1); - - -/** - * Possible levels of enforcement for TCP_FASTOPEN. - */ -enum MHD_FastOpenMethod -{ - /** - * Disable use of TCP_FASTOPEN. - */ - MHD_FOM_DISABLE = -1, +enum MHD_FastOpenOption +{ + /** + * Disable use of TCP_FASTOPEN. + */ + MHD_FOM_DISABLE = -1, /** - * Enable TCP_FASTOPEN where supported (Linux with a kernel >= 3.6). + * Enable TCP_FASTOPEN where supported. + * On GNU/Linux it works with a kernel >= 3.6. * This is the default. */ MHD_FOM_AUTO = 0, @@ -1881,14 +2307,17 @@ enum MHD_FastOpenMethod * @param fom under which conditions should we use TCP_FASTOPEN? * @param queue_length queue length to use, default is 50 if this * option is never given. - * @return FIXME: add proper SCs. #MHD_YES upon success, #MHD_NO if #MHD_FOM_REQUIRE was - * given, but TCP_FASTOPEN is not available on the platform + * @return #MHD_SC_OK on on success, + * #MHD_SC_TOO_LATE if this option was set after the daemon was started and it cannot be set anymore + * #MHD_SC_FEATURE_DISABLED, + * #MHD_SC_FEATURE_NOT_AVAILABLE, + * #MHD_SC_OPTIONS_CONFLICT */ _MHD_EXTERN enum MHD_StatusCode MHD_daemon_set_option_tcp_fastopen (struct MHD_Daemon *daemon, - enum MHD_FastOpenMethod fom, + enum MHD_FastOpenOption option, unsigned int queue_length) -MHD_NONNULL (1); +MHD_FUNC_PARAM_NONNULL_ALL_ MHD_FUNC_MUST_CHECK_RESULT_; /** @@ -1906,22 +2335,22 @@ enum MHD_AddressFamily /** * Pick "best" available method automatically. */ - MHD_AF_AUTO, + MHD_AF_AUTO = 1, /** * Use IPv4. */ - MHD_AF_INET4, + MHD_AF_INET4 = 2, /** * Use IPv6. */ - MHD_AF_INET6, + MHD_AF_INET6 = 3, /** * Use dual stack. */ - MHD_AF_DUAL + MHD_AF_DUAL = 4 }; @@ -1937,12 +2366,17 @@ enum MHD_AddressFamily * @param[in,out] daemon which instance to configure the TCP port for * @param af address family to use * @param port port to use, 0 to bind to a random (free) port + * @return #MHD_SC_OK on on success, + * #MHD_SC_TOO_LATE if this option was set after the daemon was started and it cannot be set anymore + * #MHD_SC_FEATURE_DISABLED, + * #MHD_SC_FEATURE_NOT_AVAILABLE, + * #MHD_SC_OPTIONS_CONFLICT */ -_MHD_EXTERN void +_MHD_EXTERN enum MHD_StatusCode MHD_daemon_bind_port (struct MHD_Daemon *daemon, enum MHD_AddressFamily af, uint16_t port) -MHD_NONNULL (1); +MHD_FUNC_PARAM_NONNULL_ALL_ MHD_FUNC_MUST_CHECK_RESULT_; /** @@ -1953,91 +2387,138 @@ MHD_NONNULL (1); * @param sa address to bind to; can be IPv4 (AF_INET), IPv6 (AF_INET6) * or even a UNIX domain socket (AF_UNIX) * @param sa_len number of bytes in @a sa + * @return #MHD_SC_OK on on success, + * #MHD_SC_TOO_LATE if this option was set after the daemon was started and it cannot be set anymore + * #MHD_SC_FEATURE_DISABLED, + * #MHD_SC_FEATURE_NOT_AVAILABLE, + * #MHD_SC_OPTIONS_CONFLICT */ -_MHD_EXTERN void +_MHD_EXTERN enum MHD_StatusCode MHD_daemon_bind_socket_address (struct MHD_Daemon *daemon, const struct sockaddr *sa, size_t sa_len) -MHD_NONNULL (1); +MHD_FUNC_PARAM_NONNULL_ALL_ MHD_FUNC_MUST_CHECK_RESULT_; +// TODO: Sort values and assign numbers +enum MHD_DeamonOptionUInt +{ + /** + * Use the given backlog for the listen() call. + * Ineffective in conjunction with #MHD_daemon_listen_socket() + */ + MHD_DAEMON_OPTION_UINT_LISTEN_BACKLOG, + /** + * Maximum number of (concurrent) network connections served + * by daemon + */ + MHD_DAEMON_OPTION_UINT_GLOBAL_CONNECTION_LIMIT, + /** + * Limit on the number of (concurrent) network connections + * made to the server from the same IP address. + * Can be used to prevent one IP from taking over all of + * the allowed connections. If the same IP tries to establish + * more than the specified number of connections, they will + * be immediately rejected. + */ + MHD_DAEMON_OPTION_UINT_IP_CONNECTION_LIMIT, -// FIXME... -_MHD_EXTERN enum MHD_StatusCode -MHD_daemon_set_option_uint (struct MHD_Daemon *daemon, - unsigned int listen_backlog) -MHD_NONNULL (1); + /** + * After how many seconds of inactivity should a + * connection automatically be timed out? + * Use zero for no timeout, which is also the (unsafe!) default. + */ + MHD_DAEMON_OPTION_UINT_DEFAULT_TIMEOUT, -/** - * Use the given backlog for the listen() call. - * Ineffective in conjunction with #MHD_daemon_listen_socket(). - * - * @param[in,out] daemon which instance to configure the backlog for - * @param listen_backlog backlog to use - */ -_MHD_EXTERN void -MHD_daemon_listen_backlog (struct MHD_Daemon *daemon, - unsigned int listen_backlog) -MHD_NONNULL (1); + /** + * The number of worker threads. + * Only useful if the selected threading mode + * is #MHD_TM_WORKER_THREADS. + * Zero number is silently ignored. + */ + MHD_DAEMON_OPTION_UINT_NUM_WORKERS +}; +// ADD - Discussed /** - * Set maximum number of concurrent connections to accept. If not - * given, MHD will not enforce any limits (modulo running into - * OS limits). Values of 0 mean no limit. + * Set unsigned integer MHD option. * - * @param daemon daemon to configure - * @param global_connection_limit maximum number of (concurrent) - connections - * @param ip_connection_limit limit on the number of (concurrent) - * connections made to the server from the same IP address. - * Can be used to prevent one IP from taking over all of - * the allowed connections. If the same IP tries to - * establish more than the specified number of - * connections, they will be immediately rejected. + * @param[in,out] daemon which instance to set uint @a option for + * @param option option to modify + * @param value new value for the option + * @return #MHD_SC_OK on on success, + * #MHD_SC_TOO_LATE if this option was set after the daemon was started and it cannot be set anymore + * #MHD_SC_FEATURE_DISABLED if this option is not implemented in this version of the library, + * #MHD_SC_FEATURE_NOT_AVAILABLE if this options is not supported on this system + * #MHD_SC_OPTIONS_CONFLICT */ -_MHD_EXTERN void -MHD_daemon_connection_limits (struct MHD_Daemon *daemon, - unsigned int global_connection_limit, - unsigned int ip_connection_limit) -MHD_NONNULL (1); +_MHD_EXTERN enum MHD_StatusCode +MHD_daemon_set_option_uint (struct MHD_Daemon *daemon, + enum MHD_DeamonOptionUInt option, + unsigned int value) +MHD_FUNC_PARAM_NONNULL_ (1); +// FIXME: Alternative or additional implementation. + +struct MHD_DaemonOptioniUIntEntry +{ + /** + * The option to update the @a value + */ + enum MHD_DeamonOptionUInt option; + /** + * The value to update for the @a option + */ + unsigned int value; + // TODO: union +}; /** - * After how many seconds of inactivity should a - * connection automatically be timed out? - * Use zero for no timeout, which is also the (unsafe!) default. + * Set unsigned integer MHD options. * - * @param daemon daemon to configure - * @param timeout_s number of seconds of timeout to use + * @param[in,out] daemon which instance to set uint @a option for + * @param num_entries the number of entries in the @a opt_val array + * and in @a results (if not NULL) + * @param[in] opt_val the array with options and values to modify + * @param[out] results the results for the applying the options, + * can be NULL, + * if not NULL must have @a num_entries entries + * @return #MHD_YES if all options have applied successfully + * #MHD_NO if at least single option failed (for more + * details check @a results) */ -_MHD_EXTERN void -MHD_daemon_connection_default_timeout (struct MHD_Daemon *daemon, - unsigned int timeout_s) -MHD_NONNULL (1); - +_MHD_EXTERN enum MHD_StatusCode // First failed // TODO: Document that rest may be used +MHD_daemon_set_option_uint ( + struct MHD_Daemon *daemon, + size_t num_entries, + struct MHD_DaemonOptioniUIntEntry opt_val[MHD_C99_ (static num_entries)]) +MHD_FUNC_PARAM_NONNULL_ (1) MHD_FUNC_PARAM_NONNULL_ (3); +// TODO: combine all types of options into single list with union /** * Accept connections from the given socket. Socket * must be a TCP or UNIX domain (stream) socket. * - * Unless -1 is given, this disables other listen options, including - * #MHD_daemon_bind_sa(), #MHD_daemon_bind_port(), - * #MHD_daemon_listen_queue() and - * #MHD_daemon_listen_allow_address_reuse(). + * Unless MHD_INVALID_SOCKET is given, this disables + * other listen options. * * @param daemon daemon to set listen socket for * @param listen_socket listen socket to use, * MHD_INVALID_SOCKET value will cause this call to be * ignored (other binding options may still be effective) + * @return #MHD_SC_OK on on success, + * #MHD_SC_TOO_LATE if this option was set after the daemon was started and it cannot be set anymore + * #MHD_SC_FEATURE_DISABLED if this option is not implemented in this version of the library, + * #MHD_SC_FEATURE_NOT_AVAILABLE if this options is not supported on this system + * #MHD_SC_OPTIONS_CONFLICT */ -_MHD_EXTERN void +_MHD_EXTERN enum MHD_StatusCode MHD_daemon_listen_socket (struct MHD_Daemon *daemon, MHD_socket listen_socket) -MHD_NONNULL (1); - +MHD_FUNC_PARAM_NONNULL_ (1); /** - * Event loop syscalls supported by MHD. + * Event loop internal syscalls supported by MHD. */ enum MHD_EventLoopSyscall { @@ -2069,59 +2550,146 @@ enum MHD_EventLoopSyscall * * @param daemon daemon to set event loop style for * @param els event loop syscall to use - * @return #MHD_NO on failure, #MHD_YES on success + * @return #MHD_SC_OK on on success, + * #MHD_SC_TOO_LATE if this option was set after the daemon was started and it cannot be set anymore + * #MHD_SC_FEATURE_DISABLED if this option is not implemented in this version of the library, + * #MHD_SC_FEATURE_NOT_AVAILABLE if this options is not supported on this system + * #MHD_SC_OPTIONS_CONFLICT */ -_MHD_EXTERN enum MHD_Bool +_MHD_EXTERN enum MHD_StatusCode // FIXME - corrected MHD_daemon_event_loop (struct MHD_Daemon *daemon, enum MHD_EventLoopSyscall els) -MHD_NONNULL (1); +MHD_FUNC_PARAM_NONNULL_ (1); /** * Protocol strictness enforced by MHD on clients. + * All levels have different parsing settings for the headers. */ enum MHD_ProtocolStrictLevel { - /** - * Be particularly permissive about the protocol, allowing slight - * deviations that are technically not allowed by the - * RFC. Specifically, at the moment, this flag causes MHD to allow - * spaces in header field names. This is disallowed by the standard. - * It is not recommended to set this value on publicly available - * servers as it may potentially lower level of protection. - */ - MHD_PSL_PERMISSIVE = -1, + /* * Basic levels * */ /** * Sane level of protocol enforcement for production use. + * A balance between extra security and broader compatibility, + * as allowed by RFCs for HTTP servers. */ MHD_PSL_DEFAULT = 0, /** * Be strict about the protocol (as opposed to as tolerant as - * possible). Specifically, at the moment, this flag causes MHD to - * reject HTTP 1.1 connections without a "Host" header. This is - * required by the standard, but of course in violation of the "be - * as liberal as possible in what you accept" norm. It is - * recommended to set this if you are testing clients against - * MHD, and to use default in production. - */ - MHD_PSL_STRICT = 1 + * possible), within the limits set by RFCs for HTTP servers. + * This level (and more strict) forbids use of bare LF as + * CRLF. It also rejects requests with both "Transfer-Encoding:" + * and "Content-Length:". + * It is suitable for public servers. + */ + MHD_PSL_STRICT = 1, + + /** + * Be particularly permissive about the protocol, within + * the limits set by RFCs for HTTP servers. + */ + MHD_PSL_PERMISSIVE = -1, + + /* * Special levels * */ + /** + * Stricter protocol interpretation, even stricter then allowed + * by RFCs for HTTP servers. + * However it should be absolutely compatible with clients + * following at least RFCs' "MUST" type of requirements + * for HTTP clients. + * For chunked encoding parsing this level (and more strict) + * forbids whitespace in chunk extension. + * For cookies parsing this (and more strict) level rejects + * cookie in full even if a single value is encoded incorrectly + * in it. + * This level is recommended for testing clients against + * MHD. Also can be used for security-centric application, + * however it is slight violation of RFCs' requirements. + */ + MHD_PSL_VERY_STRICT = 2, + + /** + * The most strict interpretation of the HTTP protocol, + * much stricter that defined for HTTP servers by RFC. + * However it should be absolutely compatible with clients + * following RFCs' "SHOULD" and "MUST" types of requirements + * for HTTP clients. + * This level can be used for testing clients against MHD. + * It is not recommended for any public services as it may + * reject legitimate clients (clients not following "SHOULD" + * type of RFC requirements). + */ + MHD_PSL_EXTRA_STRICT = 3, + + /** + * More relaxed protocol interpretation, violating RFCs' + * "SHOULD" type of requirements for HTTP servers. + * For cookies parsing this (and more permissive) level + * allows whitespaces in cookie values. + * This level can be used in isolated environments. + */ + MHD_PSL_VERY_PERMISSIVE = -2, + + /** + * The most flexible protocol interpretation, beyond + * RFCs' "MUST" type of requirements for HTTP server. + * The level allow HTTP/1.1 requests without "Host:" header. + * For cookies parsing this level adds allowance of + * whitespaces before and after '=' character. + * This level is not recommended unless it is absolutely + * necessary to communicate with some client(s) with + * badly broken HTTP implementation. + */ + MHD_PSL_EXTRA_PERMISSIVE = -3, }; +/** + * The way Strict Level is enforced. + * MHD can be compiled with limited set of strictness levels. + * These values instructs MHD how to apply the request level. + */ +enum MHD_UseStictLevel +{ + /** + * Use requested level if available or the nearest stricter + * level. + * Fail if only more permissive levels available. + */ + MHD_USL_THIS_OR_STRICTER = 0, + /** + * Use requested level only. + * Fail if this level is not available. + */ + MHD_USL_PRECISE = 1, + /** + * Use requested level if available or the nearest level (stricter + * or more permissive). + */ + MHD_USL_NEAREST = 2 +}; /** * Set how strictly MHD will enforce the HTTP protocol. * * @param[in,out] daemon daemon to configure strictness for - * @param sl how strict should we be + * @param sl the level of strictness + * @param how the way how to use the requested level + * @return #MHD_SC_OK on on success, + * #MHD_SC_TOO_LATE if this option was set after the daemon was started and it cannot be set anymore + * #MHD_SC_FEATURE_DISABLED if this option is not implemented in this version of the library, */ -_MHD_EXTERN void +_MHD_EXTERN enum MHD_StatusCode MHD_daemon_protocol_strict_level (struct MHD_Daemon *daemon, - enum MHD_ProtocolStrictLevel sl) -MHD_NONNULL (1); - + enum MHD_ProtocolStrictLevel sl, + enum MHD_UseStictLevel how) +MHD_FUNC_PARAM_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. @@ -2131,8 +2699,9 @@ _MHD_EXTERN enum MHD_StatusCode MHD_daemon_set_option_string (struct MHD_Daemon *daemon, enum foo, const char *value) -MHD_NONNULL (1); +MHD_FUNC_PARAM_NONNULL_ (1); +// TODO: three options /** * Provide TLS key and certificate data in-memory. * @@ -2150,7 +2719,8 @@ MHD_daemon_tls_key_and_cert_from_memory (struct MHD_Daemon *daemon, const char *mem_key, const char *mem_cert, const char *pass) -MHD_NONNULL (1,2,3); +MHD_FUNC_PARAM_NONNULL_ (1) MHD_FUNC_PARAM_NONNULL_ (2) +MHD_FUNC_PARAM_NONNULL_ (3); /** @@ -2164,7 +2734,7 @@ MHD_NONNULL (1,2,3); _MHD_EXTERN enum MHD_StatusCode MHD_daemon_tls_mem_dhparams (struct MHD_Daemon *daemon, const char *dh) -MHD_NONNULL (1); +MHD_FUNC_PARAM_NONNULL_ (1); /** * Memory pointer for the certificate (ca.pem) to be used by the @@ -2177,11 +2747,31 @@ MHD_NONNULL (1); _MHD_EXTERN enum MHD_StatusCode MHD_daemon_tls_mem_trust (struct MHD_Daemon *daemon, const char *mem_trust) -MHD_NONNULL (1); +MHD_FUNC_PARAM_NONNULL_ (1); /* ********************** (d) TLS support ********************** */ +/** + * The TLS backend choice + */ +enum MHD_TlsBackend +{ + /** + * TODO add descr + */ + MHD_TLS_BACKEND_NONE = 0, + /** + * Use best available TLS backend. + * Currently this is equivalent to GnuTLS (if TLS is enabled + * for MHD build). + */ + MHD_TLS_BACKEND_ANY = 1, + /** + * Use GnuTLS as TLS backend. + */ + MHD_TLS_BACKEND_GNUTLS = 2 +}; /** * Enable and configure TLS. @@ -2198,8 +2788,8 @@ MHD_NONNULL (1); */ _MHD_EXTERN enum MHD_StatusCode MHD_daemon_set_tls_backend (struct MHD_Daemon *daemon, - enum MHD_TlsBackend backend); -MHD_NONNULL (1); + enum MHD_TlsBackend backend) +MHD_FUNC_PARAM_NONNULL_ (1); /** @@ -2216,7 +2806,7 @@ struct MHD_ServerCredentialsContext; enum MHD_StatusCode MHD_connection_set_psk (struct MHD_ServerCredentialsContext *mscc, size_t psk_size, - const /*void? */ char psk[MHD_C99 (psk_size)]); + const /*void? */ char psk[MHD_C99_ (psk_size)]); #define MHD_connection_set_psk_unavailable(mscc) \ MHD_connection_set_psk (mscc, 0, NULL) @@ -2254,7 +2844,7 @@ _MHD_EXTERN enum MHD_StatusCode MHD_daemon_set_tls_psk_callback (struct MHD_Daemon *daemon, MHD_PskServerCredentialsCallback psk_cb, void *psk_cb_cls) -MHD_NONNULL (1); +MHD_FUNC_PARAM_NONNULL_ (1); /** @@ -2271,7 +2861,7 @@ MHD_NONNULL (1); _MHD_EXTERN enum MHD_StatusCode MHD_daemon_gnutls_credentials (struct MHD_Daemon *daemon, int gnutls_credentials) -MHD_NONNULL (1); +MHD_FUNC_PARAM_NONNULL_ (1); /** @@ -2298,7 +2888,7 @@ MHD_NONNULL (1); _MHD_EXTERN enum MHD_StatusCode MHD_daemon_gnutls_key_and_cert_from_callback (struct MHD_Daemon *daemon, void *cb) -MHD_NONNULL (1); +MHD_FUNC_PARAM_NONNULL_ (1); // Callback invoked between full initialization of MHD // during MHD_daemon_start() and actual event loop @@ -2313,7 +2903,7 @@ _MHD_EXTERN enum MHD_StatusCode MHD_daemon_set_daemon_ready_callback (struct MHD_Daemon *daemon, MHD_DaemonReadyCallback cb, void *cb) -MHD_NONNULL (1); +MHD_FUNC_PARAM_NONNULL_ (1); /** @@ -2332,7 +2922,7 @@ typedef enum MHD_Bool /** - * Set a policy callback that accepts/rejects connections + * Set a policy callback that accepts/rejects connections * based on the client's IP address. This function will be called * before a connection object is created. * @@ -2344,12 +2934,15 @@ _MHD_EXTERN void MHD_daemon_accept_policy (struct MHD_Daemon *daemon, MHD_AcceptPolicyCallback apc, void *apc_cls) -MHD_NONNULL (1); +MHD_FUNC_PARAM_NONNULL_ (1); /** * Function called by MHD to allow the application to log * the @a full_uri of a @a request. + * This is the only moment when unmodified URI is provided. + * After this callback MHD parses the URI and modifies it + * by extracting GET parameters in-place. * * @param cls client-defined closure * @param[in,out] request the HTTP request handle (headers are @@ -2357,7 +2950,8 @@ MHD_NONNULL (1); * @param uri the full URI from the HTTP request including parameters (after '?') */ typedef void -(*MHD_EarlyUriLogCallback)(void *cls, +(MHD_FUNC_PARAM_NONNULL_ (2) MHD_FUNC_PARAM_NONNULL_ (3) + *MHD_EarlyUriLogCallback)(void *cls, struct MHD_Request *request, const struct MHD_String *full_uri); @@ -2375,7 +2969,7 @@ _MHD_EXTERN enum MHD_StatusCode MHD_daemon_set_early_uri_logger (struct MHD_Daemon *daemon, MHD_EarlyUriLogCallback cb, void *cb_cls) -MHD_NONNULL (1); +MHD_FUNC_PARAM_NONNULL_ (1); /** @@ -2403,25 +2997,17 @@ enum MHD_ConnectionNotificationCode /** * Signature of the callback used by MHD to notify the - * application about started/stopped connections + * application about started/stopped network connections * * @param cls client-defined closure * @param connection connection handle - * @param socket_context socket-specific pointer where the - * client can associate some state specific - * to the TCP connection; note that this is - * different from the "req_cls" which is per - * HTTP request. The client can initialize - * during #MHD_CONNECTION_NOTIFY_STARTED and - * cleanup during #MHD_CONNECTION_NOTIFY_CLOSED - * and access in the meantime using - * #MHD_CONNECTION_INFO_SOCKET_CONTEXT. * @param toe reason for connection notification - * @see #MHD_OPTION_NOTIFY_CONNECTION + * @see #MHD_daemon_set_notify_connection() * @ingroup request */ typedef void -(*MHD_NotifyConnectionCallback) (void *cls, +(MHD_FUNC_PARAM_NONNULL_ (2) + *MHD_NotifyConnectionCallback) (void *cls, struct MHD_Connection *connection, enum MHD_ConnectionNotificationCode toe); @@ -2438,85 +3024,178 @@ _MHD_EXTERN enum MHD_StatusCode MHD_daemon_set_notify_connection (struct MHD_Daemon *daemon, MHD_NotifyConnectionCallback ncc, void *ncc_cls) -MHD_NONNULL (1); +MHD_FUNC_PARAM_NONNULL_ (1); -// FIXME: -_MHD_EXTERN void -MHD_daemon_option_set_size (struct MHD_Daemon *daemon, - enum foo, - size_t limit) -MHD_NONNULL (1); +/** + * The `enum MHD_ConnectionNotificationCode` specifies types + * of connection notifications. + * TODO: document possible extensibility + * @ingroup request + */ +enum MHD_StreamNotificationCode +{ + /** + * A new connection has been started. + * @ingroup request + */ + MHD_STREAM_NOTIFY_STARTED = 0, + + /** + * A connection is closed. + * @ingroup request + */ + MHD_STREAM_NOTIFY_CLOSED = 1 + +}; + +// TODO: finish +struct MHD_something +{ + struct MHD_Stream *stream; // const? + enum MHD_StreamNotificationCode code; + union something; +}; /** - * Maximum memory size per connection. - * Default is 32 kb (#MHD_POOL_SIZE_DEFAULT). - * Values above 128k are unlikely to result in much benefit, as half - * of the memory will be typically used for IO, and TCP buffers are - * unlikely to support window sizes above 64k on most systems. + * Signature of the callback used by MHD to notify the + * application about started/stopped data stream + * For HTTP/1.1 it is the same like network connection + * with 1:1 match. * - * @param daemon daemon to configure - * @param memory_limit_b connection memory limit to use in bytes - * @param memory_increment_b increment to use when growing the read buffer, must be smaller than @a memory_limit_b + * @param cls client-defined closure + * @param stream the stream handle + * @param toe reason for connection notification + * @see #MHD_OPTION_NOTIFY_CONNECTION + * @ingroup request */ -_MHD_EXTERN void -MHD_daemon_connection_memory_limit (struct MHD_Daemon *daemon, - size_t memory_limit_b, - size_t memory_increment_b) -MHD_NONNULL (1); +typedef void +(MHD_FUNC_PARAM_NONNULL_ (2) + *MHD_NotifyStreamCallback) (void *cls, + const struct MHD_something *notification); /** - * Desired size of the stack for threads created by MHD. Use 0 for - * system default. Only useful if the selected threading mode - * is not #MHD_TM_EXTERNAL_EVENT_LOOP. + * Register a function that should be called whenever a stream is + * started or closed. * - * @param daemon daemon to configure - * @param stack_limit_b stack size to use in bytes + * @param daemon daemon to set callback for + * @param nsc function to call to check the policy + * @param nsc_cls closure for @a apc */ -_MHD_EXTERN void -MHD_daemon_thread_stack_size (struct MHD_Daemon *daemon, - size_t stack_limit_b) -MHD_NONNULL (1); +_MHD_EXTERN enum MHD_StatusCode +MHD_daemon_set_notify_stream (struct MHD_Daemon *daemon, + MHD_NotifyStreamCallback nsc, + void *nsc_cls) +MHD_FUNC_PARAM_NONNULL_ (1); + +// TODO: Sort and assign values +enum MHD_DaemonOptionSizet +{ + /** + * Maximum memory size per connection. + * Default is 32 kb (#MHD_POOL_SIZE_DEFAULT). + * Values above 128k are unlikely to result in much performance benefit, + * as half of the memory will be typically used for IO, and TCP buffers + * are unlikely to support window sizes above 64k on most systems. + * The size should be large enough to fit all request headers (together + * 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. + * Only useful if the selected threading mode + * is not #MHD_TM_EXTERNAL_EVENT_LOOP. + */ + MHD_DAEMON_OPTION_SIZET_STACK_SIZE, +}; +// FIXME: finish +_MHD_EXTERN void +MHD_daemon_option_set_sizet (struct MHD_Daemon *daemon, + enum MHD_DaemonOptionSizet option, + size_t value) +MHD_FUNC_PARAM_NONNULL_ (1); /* ******************* Event loop ************************ */ +// FIXME: updated, renamed /** - * Which threading mode should be used by MHD? + * Which threading and polling mode should be used by MHD? */ -enum MHD_ThreadingMode +enum MHD_ThreadingPollingMode { - + // FIXME: Updated - OK /** - * Use an external event loop. This is the default. + * The daemon has no internal threads. + * The application periodically calls #MHD_process_data(), MHD checks + * all sockets internally automatically. + * This is the default. // FIXME: keep as default? */ - MHD_TM_EXTERNAL_EVENT_LOOP = 0, - + MHD_TM_EXTERNAL_PERIODIC = 0, + // FIXME: updated /** - * Run with one or more worker threads. Any positive value - * means that MHD should start that number of worker threads - * (so > 1 is a thread pool) and distributed processing of - * requests among the workers. - * - * FIXME: A good way to express the use of a thread pool - * in your code would be to write "MHD_TM_THREAD_POOL(4)" - * to indicate four threads. + * Use an external event loop. + * Application use #MHD_set_external_event_loop() and level + * triggered sockets polling (like select() or poll()). + */ + MHD_TM_EXTERNAL_EVENT_LOOP_CB_LEVEL = 1, + /** + * Use an external event loop. + * Application use #MHD_set_external_event_loop() and edge + * triggered sockets polling. + */ + MHD_TM_EXTERNAL_EVENT_LOOP_CB_EDGE = 2, + /** + * Use an external event loop. + * Application use #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 = 3, + /** + * Use an external event loop. + * Application use #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 = 4, + /** + * Run with one or more worker threads. + * If #MHD_DAEMON_OPTION_UINT_NUM_WORKERS is not specified + * then daemon starts with single worker thread that process + * all connections. + * 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 a positive value is set, * #MHD_daemon_run() and + * If this mode is specified, #MHD_daemon_run() and * #MHD_daemon_run_from_select() cannot be used. */ - MHD_TM_WORKER_THREADS = 1, + MHD_TM_WORKER_THREADS = 5, + // 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 * another thread per request. Threads may be re-used on the same * connection. Use this if handling requests is CPU-intensive or blocking, * your application is thread-safe and you have plenty of memory (per - * request). + * connection). */ - MHD_TM_THREAD_PER_REQUEST = 2 + MHD_TM_THREAD_PER_CONNECTION = 6 }; @@ -2525,18 +3204,6 @@ enum MHD_ThreadingMode MHD_TM_WORKER_THREADS_WITH_MASTER_LISTENER = 3 */ -// FIXME: replace by set_uint option(s) -// + number of worker threads -// + number of 'listen' threads (stretch goal, later...) -/** - * Use a thread pool of size @a n. - * - * @return an `enum MHD_ThreadingMode` for a thread pool of size @a n - * @deprecated - */ -#define MHD_TM_THREAD_POOL(n) ((enum MHD_ThreadingMode) (n)) - - /** * Specify threading mode to use. * @@ -2546,7 +3213,7 @@ enum MHD_ThreadingMode _MHD_EXTERN enum MHD_StatusCode MHD_daemon_set_threading_mode (struct MHD_Daemon *daemon, enum MHD_ThreadingMode tm) -MHD_NONNULL (1); +MHD_FUNC_PARAM_NONNULL_ (1); // edge vs. level triggers? howto unify? => application returns type? @@ -2565,6 +3232,7 @@ enum MHD_EventType // bitmask MHD_ET_EXCEPT = 8 // care about remote close / interruption }; +// FIXME: remove it, pre-selected by Polling Mode enum MHD_TriggerLevel { MHD_TL_EDGE, // epoll in edge trigger mode @@ -2668,104 +3336,234 @@ MHD_set_external_event_loop (struct MHD_Daemon *daemon, void *cb_cls); +// FIXME: Updated +// FIXME: any better name? "send_ready"? /** - * Obtain the `select()` sets for this daemon. Daemon's FDs will be - * added to fd_sets. To get only daemon FDs in fd_sets, call FD_ZERO - * for each fd_set before calling this function. FD_SETSIZE is assumed - * to be platform's default. - * - * Passing custom FD_SETSIZE as @a fd_setsize allow usage of - * larger/smaller than platform's default fd_sets. + * The network status of the socket. + * When set by MHD (by #MHD_get_watched_fds() or #MHD_get_watched_fds_update()) + * it indicates a request to watch for specific socket state: + * readiness for receiving the data, readiness for sending the data and/or + * exception state of the socket. + * When set by application and provided for #MHD_process_watched_fds() it must + * indicate the actual status of the socket. * - * This function should only be called in when MHD is configured to - * use external select with 'select()' or with 'epoll'. In the latter - * case, it will only add the single 'epoll()' file descriptor used by - * MHD to the sets. It's necessary to use #MHD_get_timeout() in - * combination with this function. + * Any actual state is a bitwise OR combination of #MHD_FD_STATE_RECV, + * #MHD_FD_STATE_SEND, #MHD_FD_STATE_EXCEPT. + */ +enum MHD_FdState +{ + /** + * The socket is not ready for receiving or sending and + * does not have any exceptional state. + * The state never set by MHD. + */ + MHD_FD_STATE_NONE = 0, + + /* ** Three bit-flags ** */ + + /** + * Indicates that socket should be watched for incoming data + * (when set by #MHD_get_watched_fds()) + * / socket has incoming data ready to read (when used for + * #MHD_process_watched_fds()) + */ + MHD_FD_STATE_RECV = 1 << 0, + /** + * Indicates that socket should be watched for availability for sending + * (when set by #MHD_get_watched_fds()) + * / socket has ability to send data (when used for + * #MHD_process_watched_fds()) + */ + MHD_FD_STATE_SEND = 1 << 1, + /** + * Indicates that socket should be watched for disconnect, out-of-band + * data available or high priority data available (when set by + * #MHD_get_watched_fds()) + * / socket has been disconnected, has out-of-band data available or + * has high priority data available (when used for + * #MHD_process_watched_fds()). This status must not include "remote + * peer shut down writing" status. + * Note: #MHD_get_watched_fds() always set it as exceptions must be + * always watched. + */ + MHD_FD_STATE_EXCEPT = 1 << 2, + + /* The rest of the list is a bit-wise combination of three main + * state. Application may use three main states directly as + * a bit-mask instead of using of following values + */ + + /** + * Combination of #MHD_FD_STATE_RECV and #MHD_FD_STATE_SEND states. + */ + MHD_FD_STATE_RECV_SEND = MHD_FD_STATE_RECV | MHD_FD_STATE_SEND, + /** + * Combination of #MHD_FD_STATE_RECV and #MHD_FD_STATE_EXCEPT states. + */ + MHD_FD_STATE_RECV_EXCEPT = MHD_FD_STATE_RECV | MHD_FD_STATE_EXCEPT, + /** + * Combination of #MHD_FD_STATE_RECV and #MHD_FD_STATE_EXCEPT states. + */ + MHD_FD_STATE_SEND_EXCEPT = MHD_FD_STATE_RECV | MHD_FD_STATE_EXCEPT, + /** + * Combination of #MHD_FD_STATE_RECV, #MHD_FD_STATE_SEND and + * #MHD_FD_STATE_EXCEPT states. + */ + MHD_FD_STATE_RECV_SEND_EXCEPT = \ + MHD_FD_STATE_RECV | MHD_FD_STATE_SEND | MHD_FD_STATE_EXCEPT +}; + +// FIXME: added macros +// TODO: add doxy +#define MHD_FD_STATE_IS_SET(var,state) \ + (0 != (((unsigned int)(var)) & ((unsigned int)(state)))) + +#define MHD_FD_STATE_IS_SET_RECV(var) \ + MHD_FD_STATE_IS_SET((var),MHD_FD_STATE_RECV) +#define MHD_FD_STATE_IS_SET_SEND(var) \ + MHD_FD_STATE_IS_SET((var),MHD_FD_STATE_SEND) +#define MHD_FD_STATE_IS_SET_EXCEPT(var) \ + MHD_FD_STATE_IS_SET((var),MHD_FD_STATE_EXCEPT) + + +#define MHD_FD_STATE_SET(var,state) \ + (var) = (enum MHD_FdState)((var) | (state)) +#define MHD_FD_STATE_CLEAR(var,state) \ + (var) = (enum MHD_FdState)((var) & (((enum MHD_FdState))(~state))) + +#define MHD_FD_STATE_SET_RECV(var) MHD_FD_STATE_SET((var),MHD_FD_STATE_RECV) +#define MHD_FD_STATE_SET_SEND(var) MHD_FD_STATE_SET((var),MHD_FD_STATE_SEND) +#define MHD_FD_STATE_SET_EXCEPT(var) \ + MHD_FD_STATE_SET((var),MHD_FD_STATE_EXCEPT) + +#define MHD_FD_STATE_CLEAR_RECV(var) \ + MHD_FD_STATE_CLEAR((var),MHD_FD_STATE_RECV) +#define MHD_FD_STATE_CLEAR_SEND(var) \ + MHD_FD_STATE_CLEAR((var),MHD_FD_STATE_SEND) +#define MHD_FD_STATE_CLEAR_EXCEPT(var) \ + MHD_FD_STATE_CLEAR((var),MHD_FD_STATE_EXCEPT) + +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. * - * This function must be called only for daemon started without - * #MHD_USE_INTERNAL_POLLING_THREAD flag. + * 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. * - * @param[in,out] daemon daemon to get sets from - * @param[in,out] read_fd_set read set; our FDs are added, existing bits set are unchanged - * @param[in,out] write_fd_set write set; our FDs are added, existing bits set are unchanged - * @param[in,out] except_fd_set except set; our FDs are added, existing bits set are unchanged - * @param[in,out] max_fd increased to largest FD added (if larger - * than existing value); can be NULL - * @param[out] timeout set to the timeout (in milliseconds), -1LL indicates "forever" - * @param fd_setsize value of FD_SETSIZE (needed if application set custom values that do not match compile-time MHD) - * @return #MHD_SC_OK on success, otherwise error code (specify which ones...); #MHD_SC_NOT_IMPLEMENTED ... - * @ingroup event + * @param daemon the daemon to get the list + * @param num_elements the number of elements in @a fds list + * @param[out] fds the arrays of @a num_elements of sockets to be watched + * by application, + * could be NULL to get the required number of elements // TODO: replace with introspection + * @param[out] max_wait the pointer to value set to maximum wait time + * for the network events, set only if @fds is not NULL + * @return number of elements set in @a fds, never larger than + * @a num_elements (if @a fds in not NULL); + * the required number elements in @a fds (if @a fds is NULL) */ -// @deprecated, new CB approach! -_MHD_EXTERN enum MHD_StatusCode -MHD_daemon_get_fdset2 (struct MHD_Daemon *daemon, - fd_set *read_fd_set, - fd_set *write_fd_set, - fd_set *except_fd_set, - MHD_socket *max_fd, - int64_fast_t *timeout, - unsigned int fd_setsize) -MHD_NONNULL (1,2,3,4,6); - - -/** - * Obtain the `select()` sets for this daemon. Daemon's FDs will be - * added to fd_sets. To get only daemon FDs in fd_sets, call FD_ZERO - * for each fd_set before calling this function. Size of fd_set is - * determined by current value of FD_SETSIZE. It's necessary to use - * #MHD_get_timeout() in combination with this function. - * - * This function could be called only for daemon started - * without #MHD_USE_INTERNAL_POLLING_THREAD flag. - * - * @param daemon daemon to get sets from - * @param read_fd_set read set - * @param write_fd_set write set - * @param except_fd_set except set - * @param max_fd increased to largest FD added (if larger - * than existing value); can be NULL - * @return #MHD_YES on success, #MHD_NO if this - * daemon was not started with the right - * options for this call or any FD didn't - * fit fd_set. - * @ingroup event +_MHD_EXTERN unsigned int +MHD_get_watched_fds (struct MHD_Daemon *daemon, + unsigned int num_elements, + struct MHD_WatchedFD *fds, + uint_fast64_t *max_wait) // FIXME: never return "no timeout" +MHD_FUNC_PARAM_NONNULL_ (1) MHD_FUNC_PARAM_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 +}; + +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() with non-NULL @a fds. + * 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] fds the arrays of @a num_elements to update the list + * of watched sockets, + * could be NULL to get the required number of elements // TODO: convert to introspection + * @param[out] max_wait the pointer to value set to maximum wait time in millisec // TODO: check with microseconds + * for the network events, set only if @fds is not NULL + * @return number of elements set in @a fds, never larger than + * @a num_elements (if @a fds in not NULL); + * the required number elements in @a fds (if @a fds is NULL) */ -// @deprecated, new CB approach! -#define MHD_daemon_get_fdset(daemon,read_fd_set,write_fd_set,except_fd_set, \ - max_fd) \ - MHD_get_fdset2 ((daemon),(read_fd_set),(write_fd_set),(except_fd_set), \ - (max_fd),FD_SETSIZE) - -/** - * Run webserver operations. This method should be called by clients - * in combination with #MHD_get_fdset and #MHD_get_timeout() if the - * client-controlled select method is used. - * - * You can use this function instead of #MHD_run if you called - * `select()` on the result from #MHD_get_fdset. File descriptors in - * the sets that are not controlled by MHD will be ignored. Calling - * this function instead of #MHD_run is more efficient as MHD will not - * have to call `select()` again to determine which operations are - * ready. - * - * This function cannot be used with daemon started with - * #MHD_USE_INTERNAL_POLLING_THREAD flag. - * - * @param[in,out] daemon daemon to run select loop for - * @param read_fd_set read set - * @param write_fd_set write set - * @param except_fd_set except set - * @return #MHD_SC_OK on success, #MHD_SC_NOT_IMPLEMENTED ... - * @ingroup event +_MHD_EXTERN unsigned int +MHD_get_watched_fds_update (struct MHD_Daemon *daemon, + unsigned int num_elements, + struct MHD_WatchedFdUpdate *fds, + uint_fast64_t *max_wait) +MHD_FUNC_PARAM_NONNULL_ (1); + + +/** + * 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 if @a type is #MHD_TL_LEVEL or + * just partial list otherwise + * @param type the type of the trigger used to watch sockets + * @return #MHD_SC_OK on success, + * otherwise error code TODO: complete list of error codes */ -// @deprecated, new CB approach! -_MHD_EXTERN enum MHD_StatusCode -MHD_daemon_run_from_select (struct MHD_Daemon *daemon, - const fd_set *read_fd_set, - const fd_set *write_fd_set, - const fd_set *except_fd_set) -MHD_NONNULL (1,2,3,4); +_MHD_EXTERN enum MHD_StatusCode // FIXME: bool? void? +MHD_process_watched_fds ( + struct MHD_Daemon *daemon, + unsigned int num_elements, + struct MHD_WatchedFD fds[MHD_C99_ (static num_elements)], + enum MHD_TriggerLevel type) // TODO: maybe not need +MHD_FUNC_PARAM_NONNULL_ (1) MHD_FUNC_PARAM_NONNULL_ (2); /** @@ -2791,7 +3589,7 @@ MHD_NONNULL (1,2,3,4); _MHD_EXTERN enum MHD_StatusCode MHD_daemon_get_timeout (struct MHD_Daemon *daemon, uint64_fast_t *timeout) -MHD_NONNULL (1,2); +MHD_FUNC_PARAM_NONNULL_ (1) MHD_FUNC_PARAM_NONNULL_ (2); /** @@ -2835,9 +3633,11 @@ MHD_NONNULL (1,2); * @ingroup event */ // @deprecated, new CB approach! +// FIXME: NOT deprecated, useful, renamed +// FIXME: to be used only in ::MHD_TM_EXTERNAL_PERIODIC mode _MHD_EXTERN enum MHD_Result -MHD_daemon_run_wait (struct MHD_Daemon *daemon, - int32_t millisec); +MHD_process_data (struct MHD_Daemon *daemon, + int32_t millisec); /** @@ -2860,26 +3660,8 @@ MHD_daemon_run_wait (struct MHD_Daemon *daemon, * @return #MHD_SC_OK on success * @ingroup event */ -#define MHD_daemon_run(d) \ - MHD_daemon_run_wait (d, 0); - - -// FIXME: support external poll??? -struct pollfd; - -// num_fds: in,out: in: fds length, out: number desired (if larger than in), number initialized (if smaller or equal to in) -// @deprecated, new CB approach! -_MHD_EXTERN enum MHD_StatusCode -MHD_daemon_get_poll_set (struct MHD_Daemon *daemon, - unsigned int *num_fds, - struct pollfd *fds); - - -// @deprecated, new CB approach! -_MHD_EXTERN enum MHD_StatusCode -MHD_daemon_run_from_poll (struct MHD_Daemon *daemon, - unsigned int num_fds, - const struct pollfd fds[MHD_C99 (static num_fds)]); +#define MHD_process_data_simple(d) \ + MHD_process_data (d, 0); /** @@ -2905,8 +3687,7 @@ MHD_daemon_run_from_poll (struct MHD_Daemon *daemon, * @param connection_cls meta data the application wants to * associate with the new connection object * @return #MHD_SC_OK on success - * The socket will be closed in any case; `errno` is - * set to indicate further details about the error. + * FIXME: add detailed list of codes * @ingroup specialized */ _MHD_EXTERN enum MHD_StatusCode @@ -2915,7 +3696,7 @@ MHD_daemon_add_connection (struct MHD_Daemon *daemon, const struct sockaddr *addr, socklen_t addrlen, void *connection_cls) -MHD_NONNULL (1); +MHD_FUNC_PARAM_NONNULL_ (1); /* ********************* connection options ************** */ @@ -2932,12 +3713,13 @@ MHD_NONNULL (1); _MHD_EXTERN enum MHD_StatusCode MHD_connection_set_timeout (struct MHD_Connection *connection, unsigned int timeout_s) -MHD_NONNULL (1); +MHD_FUNC_PARAM_NONNULL_ (1); /* **************** Request handling functions ***************** */ +// FIXME: Updated /** * The `enum MHD_ValueKind` specifies the source of * the key-value pairs in the HTTP protocol. @@ -2946,61 +3728,82 @@ enum MHD_ValueKind { /** - * HTTP header (request/response). + * HTTP header. */ - MHD_HEADER_KIND = 1, + MHD_VK_HEADER = 1, /** * Cookies. Note that the original HTTP header containing * the cookie(s) will still be available and intact. */ - MHD_COOKIE_KIND = 2, + MHD_VK_COOKIE = 2, + // FIXME: swapped values /** - * POST data. This is available only if a content encoding - * supported by MHD is used (currently only URL encoding), - * and only if the posted content fits within the available - * memory pool. Note that in that case, the upload data - * given to the #MHD_AccessHandlerCallback will be - * empty (since it has already been processed). + * GET (URI) arguments. */ - MHD_POSTDATA_KIND = 4, + MHD_VK_GET_ARGUMENT = 4, /** - * GET (URI) arguments. + * POST data. + * FIXME: Correct description + * This is available only if a content encoding + * supported by MHD is used, and only if the posted content + * fits within the available memory pool. + * Note that in that case, the upload data given to + * the #MHD_AccessHandlerCallback will be empty (since it has + * already been processed). */ - MHD_GET_ARGUMENT_KIND = 8, + MHD_VK_POSTDATA = 8, /** * HTTP footer (only for HTTP 1.1 chunked encodings). */ - MHD_FOOTER_KIND = 16 -}; + MHD_VK_FOOTER = 16, + // FIXME: combined values + /** + * Header and footer values + */ + MHD_VK_HEADER_FOOTER = MHD_VK_HEADER | MHD_VK_FOOTER, + /** + * Values from get arguments or post data + */ + MHD_VK_GET_POST = MHD_VK_POSTDATA | MHD_VK_GET_ARGUMENT + // FIXME: Add chunk extension? Another API for extension? +}; + +// FIXME: use struct MHD_KeyValue? /** * Iterator over key-value pairs. This iterator can be used to * iterate over all of the cookies, headers, or POST-data fields of a * request, and also to iterate over the headers that have been added * to a response. * + * The pointers to the strings in @a key and @a value are valid + * until the response is queued. If the data is needed beyond this + * point, it should be copied. + * * @param cls closure * @param kind kind of the header we are looking at * @param key key for the value, can be an empty string - * @param value corresponding value, can be NULL + * @param value corresponding value, can be NULL (no value set) or + * empty (the value is empty) * @return #MHD_YES to continue iterating, * #MHD_NO to abort the iteration * @ingroup request */ typedef enum MHD_Bool -(*MHD_KeyValueIterator)(void *cls, +(MHD_FUNC_PARAM_NONNULL_ (3) + *MHD_KeyValueIterator)(void *cls, enum MHD_ValueKind kind, const struct MHD_String *key, const struct MHD_String *value); /** - * Get all of the headers from the request. + * Get all of the headers from the request via callback. * * @param[in,out] request request to get values from * @param kind types of values to iterate over, can be a bitmask @@ -3011,16 +3814,55 @@ typedef enum MHD_Bool * @ingroup request */ _MHD_EXTERN unsigned int -MHD_request_get_values (struct MHD_Request *request, - enum MHD_ValueKind kind, - MHD_KeyValueIterator iterator, - void *iterator_cls) -MHD_NONNULL (1); +MHD_request_get_values_cb (struct MHD_Request *request, + enum MHD_ValueKind kind, + MHD_KeyValueIterator iterator, + void *iterator_cls) +MHD_FUNC_PARAM_NONNULL_ (1); + +// FIXME: added - to discuss /** - * Get a particular header value. If multiple - * values match the kind, return any one of them. + * The Key-Value pair + */ +struct MHD_KeyValue +{ + struct MHD_String key; + struct MHD_String value; +}; + +/** + * Get all of the headers (or other kind of request data) from the request. + * + * The pointers to the strings in @a elements are valid until the response + * is queued. If the data is needed beyond this point, it should be copied. + * + * @param[in] request request to get values from + * @param kind the types of values to get, can be a bitmask + * @param num_elements the number of elements in @a elements array + * @param[out] elements the array of @a num_elements strings to be filled with + * the key-value pairs; if @a request has more elements + * than @a num_elements than any @a num_elements are + * stored + * @return the number of elements stored in @a key (and in @a values), the + * number cannot be larger then @a num_elements, + * zero if there is no such values or any error occurs + */ +_MHD_EXTERN unsigned int +MHD_request_get_values_list (struct MHD_Request *request, + enum MHD_ValueKind kind, + unsigned int num_elements, + struct MHD_KeyValue elements[MHD_C99_ (static)]) +MHD_FUNC_PARAM_NONNULL_ (1) MHD_FUNC_PARAM_NONNULL_ (4); + + +/** + * Get a particular header (or other kind of request data) value. + * If multiple values match the kind, return any one of them. + * + * The returned pointer is valid until the response is queued. + * If the data is needed beyond this point, it should be copied. * * @param request request to get values from * @param kind what kind of value are we looking for @@ -3029,30 +3871,65 @@ MHD_NONNULL (1); * @ingroup request */ _MHD_EXTERN const char * -MHD_request_lookup_value (struct MHD_Request *request, - enum MHD_ValueKind kind, - const char *key) -MHD_NONNULL (1); +MHD_request_get_value (struct MHD_Request *request, + enum MHD_ValueKind kind, + const char *key) +MHD_FUNC_PARAM_NONNULL_ (1); +// FIXME: Remove duplicate?? +/** + * Get a particular header (or other kind of request data) value. + * If multiple values match the kind, return any one of them. + * + * 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 request request to get values from + * @param kind what kind of value are we looking for + * @param[in] key the header to look for, zero-length to + * lookup 'trailing' value without a key + * @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_get_value_string (struct MHD_Request *request, + enum MHD_ValueKind kind, + struct MHD_String *key, + struct MHD_String *value) +MHD_FUNC_PARAM_NONNULL_ (1) MHD_FUNC_PARAM_NONNULL_ (3) +MHD_FUNC_PARAM_NONNULL_ (4); -// FIXME: gana table for RFC 7541... -enum MHD_StaticTableKey; +// 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 occurence 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. - * @return NULL if no such item was found + * @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 const char * +_MHD_EXTERN enum MHD_StatusCode MHD_request_lookup_value_by_static_header (struct MHD_Request *request, enum MHD_ValueKind kind, - enum MHD_StaticTableKey skt) -MHD_NONNULL (1); + enum MHD_PredefinedHeader skt, + struct MHD_String *value) +MHD_FUNC_PARAM_NONNULL_ (1) MHD_FUNC_PARAM_NONNULL_ (4); /** @@ -3062,8 +3939,10 @@ MHD_NONNULL (1); */ /* 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 { + MHD_HTTP_STATUS_CONTINUE = 100, MHD_HTTP_STATUS_SWITCHING_PROTOCOLS = 101, MHD_HTTP_STATUS_PROCESSING = 102, @@ -3097,11 +3976,6 @@ enum MHD_HTTP_StatusCode MHD_HTTP_STATUS_NOT_FOUND = 404, MHD_HTTP_STATUS_METHOD_NOT_ALLOWED = 405, MHD_HTTP_STATUS_NOT_ACCEPTABLE = 406, -/** @deprecated */ -#define MHD_HTTP_STATUS_METHOD_NOT_ACCEPTABLE \ - _MHD_DEPR_IN_MACRO ( \ - "Value MHD_HTTP_STATUS_METHOD_NOT_ACCEPTABLE is deprecated, use MHD_HTTP_STATUS_NOT_ACCEPTABLE") \ - MHD_HTTP_STATUS_NOT_ACCEPTABLE MHD_HTTP_STATUS_PROXY_AUTHENTICATION_REQUIRED = 407, MHD_HTTP_STATUS_REQUEST_TIMEOUT = 408, MHD_HTTP_STATUS_CONFLICT = 409, @@ -3109,24 +3983,9 @@ enum MHD_HTTP_StatusCode MHD_HTTP_STATUS_LENGTH_REQUIRED = 411, MHD_HTTP_STATUS_PRECONDITION_FAILED = 412, MHD_HTTP_STATUS_PAYLOAD_TOO_LARGE = 413, -/** @deprecated */ -#define MHD_HTTP_STATUS_REQUEST_ENTITY_TOO_LARGE \ - _MHD_DEPR_IN_MACRO ( \ - "Value MHD_HTTP_STATUS_REQUEST_ENTITY_TOO_LARGE is deprecated, use MHD_HTTP_STATUS_PAYLOAD_TOO_LARGE") \ - MHD_HTTP_STATUS_PAYLOAD_TOO_LARGE MHD_HTTP_STATUS_URI_TOO_LONG = 414, -/** @deprecated */ -#define MHD_HTTP_STATUS_REQUEST_URI_TOO_LONG \ - _MHD_DEPR_IN_MACRO ( \ - "Value MHD_HTTP_STATUS_REQUEST_URI_TOO_LONG is deprecated, use MHD_HTTP_STATUS_URI_TOO_LONG") \ - MHD_HTTP_STATUS_URI_TOO_LONG MHD_HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE = 415, MHD_HTTP_STATUS_RANGE_NOT_SATISFIABLE = 416, -/** @deprecated */ -#define MHD_HTTP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE \ - _MHD_DEPR_IN_MACRO ( \ - "Value MHD_HTTP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE is deprecated, use MHD_HTTP_STATUS_RANGE_NOT_SATISFIABLE") \ - MHD_HTTP_STATUS_RANGE_NOT_SATISFIABLE MHD_HTTP_STATUS_EXPECTATION_FAILED = 417, MHD_HTTP_STATUS_MISDIRECTED_REQUEST = 421, @@ -3163,12 +4022,12 @@ enum MHD_HTTP_StatusCode /** - * Returns the string reason phrase for a response code. + * Returns the string status for a response code. * * If we don't have a string for a status code, we give the first * message in that status code class. */ -_MHD_EXTERN const char * +_MHD_EXTERN const char* MHD_status_code_to_string (enum MHD_HTTP_StatusCode code); /** @} */ /* end of group httpcode */ @@ -3181,23 +4040,27 @@ MHD_status_code_to_string (enum MHD_HTTP_StatusCode code); * @{ */ // Again: GANA? +// FIXME: Discuss GANA. Just a few entries so far. enum MHD_HTTP_ProtocolVersion { MHD_HTTP_VERSION_INVALID = 0, MHD_HTTP_VERSION_1_0 = 1, MHD_HTTP_VERSION_1_1 = 2, MHD_HTTP_VERSION_2_0 = 3, - MHD_HTTP_VERSION_3_0 = 4 + MHD_HTTP_VERSION_3_0 = 4, + MHD_HTTP_VERSION_FUTURE = 99 }; +// FIXME: remove completely, usable only for HTTP/1.x, no practical use with the new API _MHD_EXTERN const char * MHD_protocol_version_to_string (enum MHD_HTTP_ProtocolVersion pv); +// FIXME: remove completely, usable only for HTTP/1.x, no practical use with the new API // Reminder: // #define MHD_HTTP_VERSION_1_0 "HTTP/1.0" // #define MHD_HTTP_VERSION_1_1 "HTTP/1.1" -// #define MHD_HTTP_VERSION_2 "HTTP/2" -// #define MHD_HTTP_VERSION_3 "HTTP/3" +// #define MHD_HTTP_VERSION_2 "HTTP/2" // FIXME: Used only for non-TLS handshake +// #define MHD_HTTP_VERSION_3 "HTTP/3" // FIXME: not defined anywhere /** @} */ /* end of group versions */ @@ -3206,31 +4069,30 @@ MHD_protocol_version_to_string (enum MHD_HTTP_ProtocolVersion pv); * Suspend handling of network data for a given request. This can * be used to dequeue a request from MHD's event loop for a while. * - * If you use this API in conjunction with a internal select or a - * thread pool, you must set the option #MHD_USE_ITC to - * ensure that a resumed request is immediately processed by MHD. - * * Suspended requests continue to count against the total number of * requests allowed (per daemon, as well as per IP, if such limits * are set). Suspended requests will NOT time out; timeouts will * restart when the request handling is resumed. While a - * request is suspended, MHD will not detect disconnects by the + * request is suspended, MHD may not detect disconnects by the * client. * - * The only safe time to suspend a request is from either a - * #MHD_RequestHeaderCallback, #MHD_UploadCallback, or a - * #MHD_RequestfetchResponseCallback. Suspending a request - * at any other time will cause an assertion failure. - * - * Finally, it is an API violation to call #MHD_daemon_stop() while - * having suspended requests (this will at least create memory and - * socket leaks or lead to undefined behavior). You must explicitly - * resume all requests before stopping the daemon. - * + * @param[in,out] requests the request for which the action is generated + * @param suspend_microsec the maximum duration of suspension after which + * the request is automatically resumed, if not + * resumed earlier by #MHD_request_resume(), + * the precise resume moment is not guaranteed, it + * may happen later (but not earlier) depending + * on timer granularity and the system load; + * if set to UINT64_MAX (or higher) the request + * is not resumed automatically, + * the suspension period can be shorter then requested + * if the number is higher than 86 400 000 000 (one day) // FIXME: discuss * @return action to cause a request to be suspended. */ _MHD_EXTERN const struct MHD_Action * -MHD_action_suspend (void); +MHD_action_suspend (struct MHD_Request *request, // FIXME: need check whether used Action matches Request + uint_fast64_t suspend_microsec) +MHD_FUNC_RETURNS_NONNULL_ MHD_FUNC_PARAM_NONNULL_ALL_; /** @@ -3249,7 +4111,7 @@ MHD_action_suspend (void); */ _MHD_EXTERN void MHD_request_resume (struct MHD_Request *request) -MHD_NONNULL (1); +MHD_FUNC_PARAM_NONNULL_ALL_; /* **************** Response manipulation functions ***************** */ @@ -3264,78 +4126,81 @@ struct MHD_Response; /** - * Converts a @a response to an action. If @a destroy_after_use - * is set, the reference to the @a response is consumed - * by the conversion. If @a consume is #MHD_NO, then - * the @a response can be converted to actions in the future. + * Converts a @a response to an action. If @a MHD_RESP_OPT_BOOL_REUSABLE + * is not set, the reference to the @a response is consumed + * by the conversion. If #MHD_RESP_OPT_BOOL_REUSABLE is #MHD_YES, + * then the @a response can be used again to create actions in + * the future. * However, the @a response is frozen by this step and * must no longer be modified (i.e. by setting headers). * - * @param[in] response response to convert, not NULL + * @param[in] response the response to convert, + * if NULL then this function is equivalent to + * #MHD_action_close_connection() call + * @return pointer to the action, the action must be consumed + * otherwise response object may leak; + * NULL if failed (no memory), when failed + * the response object is consumed and need not + * to be "destroyed". */ _MHD_EXTERN const struct MHD_Action * -MHD_action_from_response (struct MHD_Response *response) -MHD_NONNULL (1); - -#ifndef FIXME_FUN -struct MHD_Action -{ - enum type; - // depending on type: - union - { - struct - { - struct MHD_Response *response; - } from_response; - } details; -}; -struct MHD_Response -{ - struct MHD_Action my_action = { - .type = from_response; - .details.from_response = &self; - }; -}; -#endif +MHD_action_from_response (struct MHD_Response *response); /** * Flags for special handling of responses. */ -// FIXME: this should not be a bit map... -enum MHD_ResponseOption +// FIXME: extended, sorted +enum MHD_ResponseOptionBool { /** - * Default: no special flags. - * @note Available since #MHD_VERSION 0x00093701 + * Not a real option, terminate the list of options + */ + MHD_RESP_OPT_BOOL_END = 0, + + /** + * Make the response object re-usable. + * The response will not be consumed by MHD_action_from_response() and + * must be destroyed by MHD_response_destroy(). + * Useful if the response is often used to reply. + */ + MHD_RESP_OPT_BOOL_REUSABLE = 1, + + /** + * Force close connection after sending the response, prevents keep-alive + * connections and adds "Connection: close" header. + */ + MHD_RESP_OPT_BOOL_CONN_CLOSE = 21, + + /** + * Force use of chunked encoding even if the response content size is known. + * Ignored when the reply cannot have body/content. */ - MHD_RF_NONE = 0, + MHD_RESP_OPT_BOOL_CHUNKED_ENC = 22, + + /** + * Enable sending of "Connection: keep-alive" header even for + * HTTP/1.1 clients when "Keep-Alive" connection is used. + * Disabled by default for HTTP/1.1 clients as per RFC. + */ + MHD_RESP_OPT_BOOL_SEND_KEEP_ALIVE_HEADER = 41, /** * Only respond in conservative (dumb) HTTP/1.0-compatible mode. * Response still use HTTP/1.1 version in header, but always close * the connection after sending the response and do not use chunked * encoding for the response. - * You can also set the #MHD_RF_HTTP_1_0_SERVER flag to force + * You can also set the #MHD_RESP_OPT_BOOL_HTTP_1_0_SERVER flag to force * HTTP/1.0 version in the response. * Responses are still compatible with HTTP/1.1. * This option can be used to communicate with some broken client, which * does not implement HTTP/1.1 features, but advertises HTTP/1.1 support. - * @note Available since #MHD_VERSION 0x00097308 - */ - // FIXME: no more bit mask! - MHD_RF_HTTP_1_0_COMPATIBLE_STRICT = 1 << 0, - - /** - * The same as #MHD_RF_HTTP_1_0_COMPATIBLE_STRICT - * @note Available since #MHD_VERSION 0x00093701 */ - MHD_RF_HTTP_VERSION_1_0_ONLY = 1 << 0, + MHD_RESP_OPT_BOOL_HTTP_1_0_COMPATIBLE_STRICT = 42, /** - * Only respond in HTTP 1.0-mode. - * Contrary to the #MHD_RF_HTTP_1_0_COMPATIBLE_STRICT flag, the response's + * Only respond in HTTP/1.0-mode. + * Contrary to the #MHD_RESP_OPT_BOOL_HTTP_1_0_COMPATIBLE_STRICT flag, the response's * HTTP version will always be set to 1.0 and keep-alive connections * will be used if explicitly requested by the client. * The "Connection:" header will be added for both "close" and "keep-alive" @@ -3345,31 +4210,15 @@ enum MHD_ResponseOption * HTTP/1.1 clients. * This option can be used to emulate HTTP/1.0 server (for response part * only as chunked encoding in requests (if any) is processed by MHD). - * @note Available since #MHD_VERSION 0x00097308 */ - MHD_RF_HTTP_1_0_SERVER = 1 << 1, - /** - * The same as #MHD_RF_HTTP_1_0_SERVER - * @note Available since #MHD_VERSION 0x00096000 - */ - MHD_RF_HTTP_VERSION_1_0_RESPONSE = 1 << 1, - + MHD_RESP_OPT_BOOL_HTTP_1_0_SERVER = 43, /** * Disable sanity check preventing clients from manually * setting the HTTP content length option. * Allow to set several "Content-Length" headers. These headers will * be used even with replies without body. - * @note Available since #MHD_VERSION 0x00096702 */ - MHD_RF_INSANITY_HEADER_CONTENT_LENGTH = 1 << 2, - - /** - * Enable sending of "Connection: keep-alive" header even for - * HTTP/1.1 clients when "Keep-Alive" connection is used. - * Disabled by default for HTTP/1.1 clients as per RFC. - * @note Available since #MHD_VERSION 0x00097310 - */ - MHD_RF_SEND_KEEP_ALIVE_HEADER = 1 << 3, + MHD_RESP_OPT_BOOL_INSANITY_HEADER_CONTENT_LENGTH = 61, /** * Enable special processing of the response as body-less (with undefined @@ -3384,32 +4233,52 @@ enum MHD_ResponseOption * reply body must be sent to the client. * This flag is primarily intended to be used when automatic "Content-Length" * header is undesirable in response to HEAD requests. - * @note Available since #MHD_VERSION 0x00097701 */ - MHD_RF_HEAD_ONLY_RESPONSE = 1 << 4, - - // action_from_response does not decrement RC... - MHD_RF_REUSABLE = 1 << 5 + MHD_RESP_OPT_BOOL_HEAD_ONLY_RESPONSE = 81 // FIXME: replace with special "create" function? } _MHD_FIXED_FLAGS_ENUM; +// FIXME: use the same approach as for the daemon _MHD_EXTERN enum MHD_StatusCode MHD_response_set_option_bool (struct MHD_Response *response, enum MHD_ResponseOption ro, - bool value) -MHD_NONNULL (1); + enum MHD_Bool value) +MHD_FUNC_PARAM_NONNULL_ALL_; + +// FIXME: the suggested approach +struct MHD_ResponseOptionBoolSet +{ + enum MHD_ResponseOptionBool option; + enum MHD_Bool value; +}; + +// FIXME: fully type-safe, options array can be built incrementally +// See https://github.com/babelouest/ulfius/blob/1ed26069fd7e1decd38e8d403a5649b0337893ff/src/ulfius.c#L1073 +// for incrementally built options /** - * Only respond in conservative HTTP 1.0-mode. In - * particular, do not (automatically) sent "Connection" headers and - * always close the connection after generating the response. - * - * @param request the request for which we force HTTP 1.0 to be used + * Set several options for the response object + * @param response the response to set the options + * @param options_array the pointer to the array with the options; + * the array is read until first ::MHD_RESP_OPT_BOOL_END + * option, but not more than @a max_num_options elements + * @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 */ -_MHD_EXTERN void -MHD_response_option_v10_only (struct MHD_Response *response) -MHD_NONNULL (1); +_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 +MHD_FUNC_PARAM_NONNULL_ALL_; + + +#if 1 //def MHD_USE_VARARG_MACROS_ // FIXME +// FIXME: How? +#define MHD_response_set_options_bool_macro(response,...) +#endif /* MHD_USE_VARARG_MACROS_ */ /** @@ -3424,48 +4293,57 @@ enum MHD_RequestTerminationCode * We finished sending the response. * @ingroup request */ - MHD_REQUEST_TERMINATED_COMPLETED_OK = 0, - + MHD_REQUEST_TERMINATED_COMPLETED_OK = 0 + , + // FIXME: extended, sorted /** - * Error handling the connection (resources - * exhausted, other side closed connection, - * application error accepting request, etc.) + * The application terminated request without response. * @ingroup request */ - MHD_REQUEST_TERMINATED_WITH_ERROR = 1, - + MHD_REQUEST_TERMINATED_BY_APP = 1 + , /** - * No activity on the connection for the number - * of seconds specified using - * #MHD_OPTION_CONNECTION_TIMEOUT. + * The request is not valid according to + * HTTP specifications. * @ingroup request */ - MHD_REQUEST_TERMINATED_TIMEOUT_REACHED = 2, - + MHD_REQUEST_TERMINATED_HTTP_PROTOCOL_ERROR = 2 + , + /** + * The client terminated the connection by closing the socket + * for writing (TCP half-closed) before sending complete request; + * MHD aborted sending the response according to RFC 2616, section 8.1.4. + * @ingroup request + */ + MHD_REQUEST_TERMINATED_CLIENT_ABORT = 3 + , + /** + * Error handling the connection due to resources + * exhausted. + * @ingroup request + */ + MHD_REQUEST_TERMINATED_NO_RESOURCES = 4 + , /** * We had to close the session since MHD was being * shut down. * @ingroup request */ - MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN = 3, - + MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN = 5 + , /** - * We tried to read additional data, but the other side closed the - * connection. This error is similar to - * #MHD_REQUEST_TERMINATED_WITH_ERROR, but specific to the case where - * the connection died because the other side did not send expected - * data. + * No activity on the connection for the number + * of seconds specified using + * #MHD_OPTION_CONNECTION_TIMEOUT. * @ingroup request */ - MHD_REQUEST_TERMINATED_READ_ERROR = 4, - + MHD_REQUEST_TERMINATED_TIMEOUT_REACHED = 6 + , /** - * The client terminated the connection by closing the socket - * for writing (TCP half-closed); MHD aborted sending the - * response according to RFC 2616, section 8.1.4. + * The connection was broken or TLS protocol error. * @ingroup request */ - MHD_REQUEST_TERMINATED_CLIENT_ABORT = 5 + MHD_REQUEST_TERMINATED_CONNECTION_ERROR = 7 }; @@ -3475,7 +4353,7 @@ enum MHD_RequestTerminationCode * about completed requests. * * @param cls client-defined closure - * @param toe reason for request termination + * @param reqtc the reason for request termination * @param request_context request context value, as originally * returned by the #MHD_EarlyUriLogCallback * @see #MHD_option_request_completion() @@ -3483,7 +4361,7 @@ enum MHD_RequestTerminationCode */ typedef void (*MHD_RequestTerminationCallback) (void *cls, - enum MHD_RequestTerminationCode toe, + enum MHD_RequestTerminationCode reqtc, void *request_context); @@ -3492,7 +4370,7 @@ typedef void * request. * * @param[in,out] response which response to set the callback for - * @param termination_cb function to call + * @param termination_cb function to call, can be NULL to not use the callback * @param termination_cb_cls closure for @e termination_cb */ _MHD_EXTERN enum MHD_StatusCode @@ -3500,20 +4378,181 @@ MHD_response_set_option_termination_callback ( struct MHD_Response *response, MHD_RequestTerminationCallback termination_cb, void *termination_cb_cls) -MHD_NONNULL (1); +MHD_FUNC_PARAM_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 + * is being destroyed. It should be used to free resources associated + * with the dynamic content. + * + * @param[in] free_cls closure + * @ingroup response + */ +typedef void +(*MHD_FreeCallback) (void *free_cls); +// TODO: Doxy +struct MHD_DynContentZCIoVec +{ + /** + * The number of elements in @a iov + */ + unsigned int iov_count; + /** + * The pointer to the array with @a iov_count elements. + */ + const struct MHD_IoVec *iov; + /** + * The callback to free resources. + * It is called once the full array of iov elements is sent. + * No callback is called if NULL. + */ + MHD_FreeCallback iov_fcb; + /** + * The parameter for @a iov_fcb + */ + void *iov_fcb_cls; +}; + +struct MHD_DynamicContentCreatorAction; + +/** + * Set action to "continue processing", the data is provided in the + * buffer. + * If function failed for any reason, the action is automatically + * set to "stop with error". + * @param[in,out] action the pointer the action as provided to the callback + * @param data_size the amount of the data placed to the provided buffer, + * cannot be larger than provided buffer size + * @param chunk_ext the optional pointer to chunk extension string, + * can be NULL to not use chunk extension, + * ignored if chunked encoding is not used + * @return MHD_SC_OK if success, + * error code otherwise // TODO: add the list + */ +_MHD_EXTERN enum MHD_StatusCode +MHD_DCC_set_action_continue( + struct MHD_DynamicContentCreatorAction *action, + size_t data_size, + const char *chunk_ext) +MHD_FUNC_PARAM_NONNULL_ (1); + + +// FIXME: the @a buf parameter will be ignored +/** + * Set action to "continue processing", the zero-copy data is provided + * in the @a iov_data. + * If function failed for any reason, the action is automatically + * set to "stop with error". + * @param[in,out] action the pointer the action as provided to the callback + * @param data_size the amount of the data placed to the provided buffer, + * cannot be larger than provided buffer size + * @param chunk_ext the optional pointer to chunk extension string, + * can be NULL to not use chunk extension, + * ignored if chunked encoding is not used + * @return MHD_SC_OK if success, + * error code otherwise // TODO: add the list + */ +_MHD_EXTERN enum MHD_StatusCode +MHD_DCC_set_action_continue_zc( + struct MHD_DynamicContentCreatorAction *action, + struct MHD_DynContentZCIoVec *iov_data, + const char *chunk_ext) +MHD_FUNC_PARAM_NONNULL_ (1); + +/** + * Set action to "finished". + * If function failed for any reason, the action is automatically + * set to "stop with error". + * @param[in,out] action the pointer the action as provided to the callback + * @param num_footers number of elements in the @a footers array, + * must be zero if @a footers is NULL + * @param footers the optional pointer to the array of the footers, + * can be NULL + * @return MHD_SC_OK if success, + * error code otherwise // TODO: add the list + */ +_MHD_EXTERN enum MHD_StatusCode +MHD_DCC_set_action_finished( + struct MHD_DynamicContentCreatorAction *action, + size_t num_footers, + struct MHD_KeyValue *footers) +MHD_FUNC_PARAM_NONNULL_ (1); + +/** + * Set action to "finished". + * If function failed for any reason, the action is automatically + * set to "stop with error". + * @param[in,out] action the pointer the action as provided to the callback + * @param suspend_microsec the maximum duration of suspension after which + * the request is automatically resumed, if not + * resumed earlier by #MHD_request_resume(), + * the precise resume moment is not guaranteed, it + * may happen later (but not earlier) depending + * on timer granularity and the system load; + * if set to UINT64_MAX (or higher) the request + * is not resumed automatically, + * the suspension period can be shorter then requested + * if the number is higher than 86 400 000 000 (one day) // FIXME: discuss + * @return MHD_SC_OK if success, + * error code otherwise // TODO: add the list + */ +_MHD_EXTERN enum MHD_StatusCode +MHD_DCC_set_action_suspend( + struct MHD_DynamicContentCreatorAction *action, + uint_fast64_t suspend_microsec) +MHD_FUNC_PARAM_NONNULL_ (1); + +/** + * Set action to "stop with error". + * @param[in,out] action the pointer the action as provided to the callback + * @return always MHD_SC_OK + */ +_MHD_EXTERN enum MHD_StatusCode +MHD_DCC_set_action_error_stop( + struct MHD_DynamicContentCreatorAction *action) +MHD_FUNC_PARAM_NONNULL_ (1); + + +// 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. The * total number of bytes that has been placed into @a buf should be * returned. * - * Note that returning zero will cause libmicrohttpd to try again. - * Thus, returning zero should only be used in conjunction - * with MHD_suspend_connection() to avoid busy waiting. - * - * @param cls extra argument to the callback + * @param dyn_cont_cls closure argument to the callback * @param pos position in the datastream to access; * note that if a `struct MHD_Response` object is re-used, * it is possible for the same content reader to @@ -3523,52 +4562,130 @@ MHD_NONNULL (1); * the sum of all non-negative return values * obtained from the content reader so far. * @param[out] buf where to copy the data - * @param max maximum number of bytes to copy to @a buf (size of @a buf) + * @param max maximum number of bytes to copy to @a buf (size of @a buf), + * the value of @a max is always less or equal SSIZE_MAX + * @param[out] action the action to set, + * the pointer is only valid until + * the callback returns * @return number of bytes written to @a buf; - * 0 is legal unless we are running in internal select mode (since - * this would cause busy-waiting); 0 in external select mode - * will cause this function to be called again once the external - * select calls MHD again; - * #MHD_CONTENT_READER_END_OF_STREAM (-1) for the regular + * 0 is legal only for external polling modes; + * with internal polling thread(s) it is interpreted as + * #MHD_DYNAMIC_CONTENT_END_WITH_ERROR (see below); + * #MHD_DYNAMIC_CONTENT_END_OF_STREAM (-1) for the regular * end of transmission (with chunked encoding, MHD will then * terminate the chunk and send any HTTP footers that might be - * present; without chunked encoding and given an unknown - * response size, MHD will simply close the connection; note - * that while returning #MHD_CONTENT_READER_END_OF_STREAM is not technically + * present; with HTTP/1.0 and given an unknown response size, + * MHD will simply close the connection; note that while + * returning #MHD_DYNAMIC_CONTENT_END_OF_STREAM is not technically * legal if a response size was specified, MHD accepts this - * and treats it just as #MHD_CONTENT_READER_END_WITH_ERROR; - * #MHD_CONTENT_READER_END_WITH_ERROR (-2) to indicate a server + * and treats it just as #MHD_DYNAMIC_CONTENT_END_WITH_ERROR; + * #MHD_DYNAMIC_CONTENT_STOP_WITH_ERROR (-2) to indicate a server * error generating the response; this will cause MHD to simply * close the connection immediately. If a response size was * given or if chunked encoding is in use, this will indicate - * an error to the client. Note, however, that if the client - * does not know a response size and chunked encoding is not in - * use, then clients will not be able to tell the difference between - * #MHD_CONTENT_READER_END_WITH_ERROR and #MHD_CONTENT_READER_END_OF_STREAM. - * This is not a limitation of MHD but rather of the HTTP protocol. + * an error to the client. Note, however, that if HTTP/1.0 + * is used then the clients will not be able to differentiate between + * #MHD_DYNAMIC_CONTENT_STOP_WITH_ERROR and #MHD_DYNAMIC_CONTENT_END_OF_STREAM. + * This is not a limitation of MHD but rather of the HTTP/1.0 protocol. + * #MHD_DYNAMIC_CONTENT_SUSPEND_REQUEST (-3) to suspend the request + * processing until MHD_request_resume() is called. */ typedef ssize_t -(*MHD_ContentReaderCallback) (void *cls, +(MHD_FUNC_PARAM_NONNULL_ (3) + *MHD_DynamicContentCreator) (void *dyn_cont_cls, uint64_t pos, void *buf, - size_t max); + size_t max, + struct MHD_DynamicContentCreatorAction *action); // add pointer to struct with command /** - * This method is called by libmicrohttpd if we are done with a - * content reader. It should be used to free resources associated - * with the content reader. + * Create a response. The response object can be extended with + * header information. * - * @param[in] cls closure + * @param sc status code to return + * @param size size of the data portion of the response, #MHD_SIZE_UNKNOWN for unknown + * @param block_size preferred block size for querying crc (advisory only, + * MHD may still call @a crc using smaller chunks); this + * is essentially the buffer size used for IO, clients + * should pick a value that is appropriate for IO and + * memory performance requirements + * @param dyn_cont callback to use to obtain response data + * @param dyn_cont_cls extra argument to @a crc + * @param dyn_cont_fc callback to call to free @a dyn_cont_cls resources + * @return NULL on error (i.e. invalid arguments, out of memory) * @ingroup response */ -typedef void -(*MHD_ContentReaderFreeCallback) (void *cls); +_MHD_EXTERN struct MHD_Response * +MHD_response_from_callback (enum MHD_HTTP_StatusCode sc, + uint64_t size, + size_t block_size, // FIXME: replace with option + MHD_DynamicContentCreator dyn_cont, + void *dyn_cont_cls, + MHD_FreeCallback dyn_cont_fc); + + +enum MHD_DynContentZCAction +{ + MHD_DYN_CONTENT_ZC_ACTION_CONTINUE = 0, + MHD_DYN_CONTENT_ZC_ACTION_END_OF_STREAM = 1, + MHD_DYN_CONTENT_ZC_ACTION_STOP_WITH_ERROR = 2, + MHD_DYN_CONTENT_ZC_ACTION_SUSPEND_REQUEST = 3 // TODO: add timeout +}; +// TODO: Doxy +struct MHD_DynContentZCIoVec +{ + /** + * The number of elements in @a iov + */ + unsigned int iov_count; + /** + * The pointer to the array with @a iov_count elements. + */ + const struct MHD_IoVec *iov; + /** + * The callback to free resources. + * It is called once the full array of iov elements is sent. + * No callback is called if NULL. + */ + MHD_FreeCallback iov_fcb; + /** + * The parameter for @a iov_fcb + */ + void *iov_fcb_cls; +}; /** - * Create a response action. The response object can be extended with - * header information and then be used any number of times. + * Callback used by libmicrohttpd in order to obtain content. The + * callback is to copy at most @a max bytes of content into @a buf. The + * total number of bytes that has been placed into @a buf should be + * returned. + * + * If total data size set in @a iov_data by this callback is zero and + * internal polling thread(s) is used then it is interpreted like + * return of #MHD_DYN_CONTENT_ZC_ACTION_STOP_WITH_ERROR. + * + * @param dyn_cont_zc_cls extra argument to the callback + * @param pos position in the datastream to access; + * note that if a `struct MHD_Response` object is re-used, + * it is possible for the same content reader to + * be queried multiple times for the same data; + * however, if a `struct MHD_Response` is not re-used, + * libmicrohttpd guarantees that "pos" will be + * the sum of all data provided so far. + * @param[out] iov_data the parameters + * @return the requested next action + */ +typedef enum MHD_DynContentZCAction +(*MHD_DynamicContentCreatorZC) (void *dyn_cont_zc_cls, + uint64_t pos, + struct MHD_DynContentZCIoVec iov_data); + + +/** + * Create a response. The response object can be extended with + * header information. * * @param sc status code to return * @param size size of the data portion of the response, #MHD_SIZE_UNKNOWN for unknown @@ -3577,21 +4694,21 @@ typedef void * is essentially the buffer size used for IO, clients * should pick a value that is appropriate for IO and * memory performance requirements - * @param crc callback to use to obtain response data - * @param crc_cls extra argument to @a crc - * @param crfc callback to call to free @a crc_cls resources + * @param dyn_cont_zc callback to use to obtain response data + * @param dyn_cont_zc_cls extra argument to @a crc + * @param dyn_cont_zc_fc callback to call to free @a dyn_cont_zc_cls resources * @return NULL on error (i.e. invalid arguments, out of memory) * @ingroup response */ _MHD_EXTERN struct MHD_Response * -MHD_response_from_callback (enum MHD_HTTP_StatusCode sc, - uint64_t size, - size_t block_size, - MHD_ContentReaderCallback crc, - void *crc_cls, - MHD_ContentReaderFreeCallback crfc); - +MHD_response_from_callback_zc (enum MHD_HTTP_StatusCode sc, + uint64_t size, + MHD_DynamicContentCreatorZC dyn_cont_zc, + void *dyn_cont_zc_cls, + MHD_FreeCallback dyn_cont_zc_fc); +// FIXME: alt version +#ifdef ORIG_VERSION /** * Specification for how MHD should treat the memory buffer * given for the response. @@ -3606,7 +4723,7 @@ enum MHD_ResponseMemoryMode * it, not free it, not copy it, just keep an alias to it. * @ingroup response */ - MHD_RESPMEM_PERSISTENT, + MHD_RESPMEM_PERSISTENT = 0, /** * Buffer is in transient memory, but not on the heap (for example, @@ -3615,7 +4732,7 @@ enum MHD_ResponseMemoryMode * own private copy of the data for processing. * @ingroup response */ - MHD_RESPMEM_MUST_COPY + MHD_RESPMEM_MUST_COPY = 1 }; @@ -3635,9 +4752,56 @@ enum MHD_ResponseMemoryMode _MHD_EXTERN struct MHD_Response * MHD_response_from_buffer (enum MHD_HTTP_StatusCode sc, size_t buffer_size, - const char buffer[MHD_C99 (static buffer_size)], + const char buffer[MHD_C99_ (static buffer_size)], enum MHD_ResponseMemoryMode mode); +#else + + +/** + * 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; + * @param size the size of the data portion of the response + * @param buffer the @a size bytes containing the response's data portion, + * needs to be valid while the response is used + * @param free_cb the callback to free any allocated data, called + * when response is being destroyed, can be NULL + * to skip callback + * @param free_cb_cls the parameter for @a free_cb + * @return NULL on error (i.e. invalid arguments, out of memory) + * @ingroup response + */ +_MHD_EXTERN struct MHD_Response * +MHD_response_from_buffer (enum MHD_HTTP_StatusCode sc, + size_t buffer_size, + const char buffer[MHD_C99_ (static buffer_size)], + MHD_FreeCallback free_cb, + void *free_cb_cls); + + +/** + * 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 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 + * keep this data after return from this function + * @return NULL on error (i.e. invalid arguments, out of memory) + * @ingroup response + */ +_MHD_EXTERN struct MHD_Response * +MHD_response_from_buffer_copy ( + enum MHD_HTTP_StatusCode sc, + size_t buffer_size, + const char buffer[MHD_C99_ (static buffer_size)]); + +#endif /** * Create a response object with empty (zero size) body. @@ -3656,8 +4820,7 @@ MHD_response_from_buffer (enum MHD_HTTP_StatusCode sc, * Create a response object with an array of memory buffers * used as the response body. * - * The response object can be extended with header information and then - * be used any number of times. + * The response object can be extended with header information. * * If response object is used to answer HEAD request then the body * of the response is not used, while all headers (including automatic @@ -3670,51 +4833,21 @@ MHD_response_from_buffer (enum MHD_HTTP_StatusCode sc, * the response is destroyed. * @param free_cb_cls the argument passed to @a free_cb * @return NULL on error (i.e. invalid arguments, out of memory) - * @note Available since #MHD_VERSION 0x00097204 * @ingroup response */ _MHD_EXTERN struct MHD_Response * MHD_response_from_iovec ( enum MHD_HTTP_StatusCode sc, unsigned int iov_count, - const struct MHD_IoVec iov[MHD_C99 (iov_count)], - MHD_ContentReaderFreeCallback free_cb, + const struct MHD_IoVec iov[MHD_C99_ (iov_count)], + MHD_FreeCallback free_cb, void *free_cb_cls); /** - * Create a response object with the content of provided buffer used as - * the response body. - * - * The response object can be extended with header information and then - * be used any number of times. - * - * If response object is used to answer HEAD request then the body - * of the response is not used, while all headers (including automatic - * headers) are used. - * - * @param size size of the data portion of the response - * @param buffer size bytes containing the response's data portion - * @param crfc function to call to cleanup, if set to NULL then callback - * is not called - * @param crfc_cls an argument for @a crfc - * @return NULL on error (i.e. invalid arguments, out of memory) - * @note 'const' qualifier is used for @a buffer since #MHD_VERSION 0x00097701 - * @ingroup response - */ -_MHD_EXTERN struct MHD_Response * -MHD_response_from_buffer_with_free_callback ( - enum MHD_HTTP_StatusCode sc, - size_t size, - const char buffer[MHD_C99 (static buffer_size)], - MHD_ContentReaderFreeCallback crfc, - void *crfc_cls); - - -/** * Create a response object based on an @a fd from which * data is read. The response object can be extended with - * header information and then be used any number of times. + * header information. * * @param sc status code to return * @param fd file descriptor referring to a file on disk with the @@ -3757,23 +4890,21 @@ MHD_response_from_pipe (enum MHD_HTTP_StatusCode sc, int fd); +// FIXME: corrected /** - * Explicitly decrease reference counter of a response object. If the - * counter hits zero, destroys a response object and associated - * resources. Usually, this is implicitly done by converting a - * response to an action and returning the action to MHD. + * Destroy response. + * Should be called if response was created but not consumed. + * Also must be called if response has #MHD_RESP_OPT_BOOL_REUSABLE + * set. The actual destroy can be happen later, if the response + * is still being used in any request. + * The function does not block. * - * @param[in] response response to decrement RC of + * @param[in] response the response to destroy * @ingroup response */ _MHD_EXTERN void -MHD_response_queue_for_destroy (struct MHD_Response *response) -MHD_NONNULL (1); - - -_MHD_EXTERN struct MHD_Response * -MHD_response_incref (struct MHD_Response *response) -MHD_NONNULL (1); +MHD_response_destroy (struct MHD_Response *response) +MHD_FUNC_PARAM_NONNULL_ (1); /** @@ -3790,16 +4921,38 @@ _MHD_EXTERN enum MHD_StatusCode MHD_response_add_header (struct MHD_Response *response, const char *header, const char *content) -MHD_NONNULL (1,2,3); +MHD_FUNC_PARAM_NONNULL_(1) MHD_FUNC_PARAM_NONNULL_(2) +MHD_FUNC_PARAM_NONNULL_(3); + +// FIXME: duplication - remove +/** + * Add a header line to the response. + * + * This function uses application-provided length of string. When using + * large strings or many headers this case save some CPU cycles. + * + * @param response response to add a header to + * @param header the header to add + * @param content value to add + * @return #MHD_NO on error (i.e. invalid header or content format), + * or out of memory + * @ingroup response + */ +_MHD_EXTERN enum MHD_StatusCode +MHD_response_add_header_str (struct MHD_Response *response, + const struct MHD_String *header_str, + const struct MHD_String *content_str) +MHD_FUNC_PARAM_NONNULL_(1) MHD_FUNC_PARAM_NONNULL_(2) +MHD_FUNC_PARAM_NONNULL_(3); _MHD_EXTERN enum MHD_StatusCode -MHD_response_add_static_header (struct MHD_Response *response, - enum MHD_StaticTableKey stk, +MHD_response_add_predef_header (struct MHD_Response *response, + enum MHD_PredefinedHeader stk, const char *content) -MHD_NONNULL (1,3); - +MHD_FUNC_PARAM_NONNULL_ (1) MHD_FUNC_PARAM_NONNULL_(3); +// TODO remove /** * Delete a header (or footer) line from the response. * @@ -3813,7 +4966,7 @@ _MHD_EXTERN enum MHD_StatusCode MHD_response_del_header (struct MHD_Response *response, const char *header, const char *content) -MHD_NONNULL (1,2,3); +MHD_FUNC_PARAM_NONNULL_ (1,2,3); /** @@ -3830,7 +4983,7 @@ _MHD_EXTERN unsigned int MHD_response_get_headers (const struct MHD_Response *response, MHD_KeyValueIterator iterator, void *iterator_cls) -MHD_NONNULL (1); +MHD_FUNC_PARAM_NONNULL_ (1); /** @@ -3846,9 +4999,10 @@ MHD_NONNULL (1); _MHD_EXTERN const struct MHD_String * MHD_response_get_header (const struct MHD_Response *response, const char *key) -MHD_NONNULL (1,2); +MHD_FUNC_PARAM_NONNULL_ (1) MHD_FUNC_PARAM_NONNULL_ (2); +// FIXME: Removed trailer function, chunk ext - add /** * Add a tailer line to the response for this request. * Usually called within a MHD_ContentReaderCallback. @@ -3865,7 +5019,7 @@ MHD_request_set_response_trailer ( struct MHD_Request *request, const char *footer, const char *content) -MHD_NONNULL (1,2,3); +MHD_FUNC_PARAM_NONNULL_ (1,2,3); /* ************ (b) Upload and PostProcessor functions ********************** */ @@ -3903,7 +5057,7 @@ MHD_request_set_value (struct MHD_Request *request, enum MHD_ValueKind kind, const char *key, const char *value) -MHD_NONNULL (1,3,4); +MHD_FUNC_PARAM_NONNULL_ (1,3,4); /** @@ -3932,11 +5086,25 @@ MHD_action_continue (void); * * @param cls argument given together with the function * pointer when the handler was registered with MHD - * @param upload_data_size set to the size of the - * @a upload_data provided - * @param upload_data the data being uploaded (excluding headers) - * uploaded data MAY be made available incrementally via - * multiple callbacks depending on request settings + * @param path the requested uri (without arguments after "?") + * @param method the HTTP method used (#MHD_HTTP_METHOD_GET, + * #MHD_HTTP_METHOD_PUT, etc.) + * @param content_total_size the size of the message content payload, + * #MHD_SIZE_UNKNOWN for chunked uploads + * when the final chunk has not been + * processed yet. + * @param uploaded_content_size the size of already uploaded + * content in @a content_data + * @param[in] content_data the uploaded content data, + * may be modified in ..... + * must not be freed + * NULL if no content has been + * processed yet, + * not NULL if any content has been + * processed even if content is + * zero size + * @param content_processed_size the size of previously provided and + * processes content data * @return action specifying how to proceed, often * #MHD_action_continue() if all is well, * #MHD_action_suspend() to stop reading the upload until @@ -3945,10 +5113,11 @@ MHD_action_continue (void); * to discard the rest of the upload and return the data given */ typedef const struct MHD_Action * -(*MHD_UploadCallback) ( - void *cls, - size_t upload_data_size, - const char upload_data[MHD_C99 (static upload_data_size)]); +(MHD_FUNC_PARAM_NONNULL_ (2) MHD_FUNC_PARAM_NONNULL_ (3) + *MHD_UploadCallback) (void *upload_cls, + struct MHD_Request *request, + size_t content_data_size, + void *content_data); /** @@ -3974,7 +5143,7 @@ MHD_action_process_upload ( bool call_when_full, MHD_UploadCallback uc, void *uc_cls) -MHD_NONNULL (1); +MHD_FUNC_PARAM_NONNULL_ (1); /** @@ -4035,7 +5204,7 @@ MHD_action_post_processor (struct MHD_Request *req, void *iter_cls, MHD_PostDataFinished done_cb, void *done_cb_cls) -MHD_NONNULL (2); +MHD_FUNC_PARAM_NONNULL_ (2); // @a kind can be filename, content_type, transfer_encoding or (raw) data @@ -4044,7 +5213,7 @@ _MHD_EXTERN const struct MHD_String * MHD_request_get_post_processor_value (struct MHD_Request *req, enum MHD_ValueKind kind, const char *key) -MHD_NONNULL (2); +MHD_FUNC_PARAM_NONNULL_ (2); /* ***************** (c) WebSocket support ********** */ @@ -4095,7 +5264,7 @@ _MHD_EXTERN struct MHD_Action *// ??? MHD_upgrade_operation (struct MHD_UpgradeResponseHandle *urh, enum MHD_UpgradeOperation operation, ...) -MHD_NONNULL (1); +MHD_FUNC_PARAM_NONNULL_ (1); /** @@ -4188,7 +5357,7 @@ typedef void _MHD_EXTERN struct MHD_Response * MHD_response_for_upgrade (MHD_UpgradeHandler upgrade_handler, void *upgrade_handler_cls) -MHD_NONNULL (1); +MHD_FUNC_PARAM_NONNULL_ (1); /* ********************** (e) Client auth ********************** */ @@ -5612,7 +6781,7 @@ _MHD_EXTERN void MHD_daemon_digest_auth_random (struct MHD_Daemon *daemon, size_t buf_size, const void *buf) -MHD_NONNULL (1,3); +MHD_FUNC_PARAM_NONNULL_ (1,3); /** @@ -5625,7 +6794,7 @@ MHD_NONNULL (1,3); _MHD_EXTERN enum MHD_StatusCode MHD_daemon_digest_auth_nc_length (struct MHD_Daemon *daemon, size_t nc_length) -MHD_NONNULL (1); +MHD_FUNC_PARAM_NONNULL_ (1); /* ********************** (f) Introspection ********************** */ @@ -5794,9 +6963,10 @@ union MHD_ConnectionInformation _MHD_EXTERN enum MHD_Bool MHD_connection_get_information_sz (struct MHD_Connection *connection, enum MHD_ConnectionInformationType info_type, - union MHD_ConnectionInformation *return_value, + union MHD_ConnectionInformation *return_value + , size_t return_value_size) -MHD_NONNULL (1,3); +MHD_FUNC_PARAM_NONNULL_ (1,3); /** @@ -5910,7 +7080,7 @@ 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_NONNULL (1,3); +MHD_FUNC_PARAM_NONNULL_ (1,3); /** @@ -6018,7 +7188,7 @@ MHD_daemon_get_information_sz (struct MHD_Daemon *daemon, enum MHD_DaemonInformationType info_type, union MHD_DaemonInformation *return_value, size_t return_value_size) -MHD_NONNULL (1,3); +MHD_FUNC_PARAM_NONNULL_ (1,3); /** * Obtain information about the given daemon. @@ -6087,7 +7257,7 @@ MHD_set_panic_func (MHD_PanicCallback cb, */ _MHD_EXTERN size_t MHD_http_unescape (char *val) -MHD_NONNULL (1); +MHD_FUNC_PARAM_NONNULL_ (1); /**