libmicrohttpd2

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

microhttpd2.h (404512B)


      1 /* SPDX-License-Identifier: LGPL-2.1-or-later OR (GPL-2.0-or-later WITH eCos-exception-2.0) */
      2 /*
      3   This file is part of GNU libmicrohttpd.
      4   Copyright (C) 2006-2026 Christian Grothoff, Karlson2k (Evgeny Grin)
      5   (and other contributing authors)
      6 
      7   GNU libmicrohttpd is free software; you can redistribute it and/or
      8   modify it under the terms of the GNU Lesser General Public
      9   License as published by the Free Software Foundation; either
     10   version 2.1 of the License, or (at your option) any later version.
     11 
     12   GNU libmicrohttpd is distributed in the hope that it will be useful,
     13   but WITHOUT ANY WARRANTY; without even the implied warranty of
     14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15   Lesser General Public License for more details.
     16 
     17   Alternatively, you can redistribute GNU libmicrohttpd and/or
     18   modify it under the terms of the GNU General Public License as
     19   published by the Free Software Foundation; either version 2 of
     20   the License, or (at your option) any later version, together
     21   with the eCos exception, as follows:
     22 
     23     As a special exception, if other files instantiate templates or
     24     use macros or inline functions from this file, or you compile this
     25     file and link it with other works to produce a work based on this
     26     file, this file does not by itself cause the resulting work to be
     27     covered by the GNU General Public License. However the source code
     28     for this file must still be made available in accordance with
     29     section (3) of the GNU General Public License v2.
     30 
     31     This exception does not invalidate any other reasons why a work
     32     based on this file might be covered by the GNU General Public
     33     License.
     34 
     35   You should have received copies of the GNU Lesser General Public
     36   License and the GNU General Public License along with this library;
     37   if not, see <https://www.gnu.org/licenses/>.
     38 */
     39 
     40 /*
     41   Main goals for the libmicrohttpd 2.0 API:
     42 
     43   - simplify application callbacks by splitting header/upload/post
     44     functionality currently provided by calling the same
     45     MHD_AccessHandlerCallback 3+ times into separate callbacks.
     46   - keep the API very simple for simple requests, but allow
     47     more complex logic to be incrementally introduced
     48     (via new struct MHD_Action construction)
     49   - avoid repeated scans for URL matches via the new
     50     struct MHD_Action construction
     51   - better types, in particular avoid varargs for options
     52   - make it harder to pass inconsistent options
     53   - combine options and flags into more uniform API (at least
     54     exterally!)
     55   - simplify API use by using sane defaults (benefiting from
     56     breaking backwards compatibility) and making all options
     57     really optional, and where applicable avoid having options
     58     where the default works if nothing is specified
     59   - simplify API by moving rarely used http_version into
     60     MHD_request_get_info_fixed()
     61   - avoid 'int' for MHD_YES/MHD_NO by introducing `enum MHD_Bool`
     62   - improve terminology by eliminating confusion between
     63     'request' and 'connection'; add 'session' for HTTP2/3;
     64     use clear separation between connection and request. Do not mix the kind
     65     data in the callbacks.  Currently we are mixing things in
     66     MHD_AccessHandlerCallback and MHD_RequestCompletedCallback. Instead of
     67     pointers to struct MHD_Connection we should use pointers to (new) struct
     68     MHD_Request.
     69   - prepare API for having multiple TLS backends
     70   - use more consistent prefixes for related functions
     71     by using MHD_subject_verb_object naming convention, also
     72     at the same time avoid symbol conflict with legacy names
     73     (so we can have one binary implementing old and new
     74     library API at the same time via compatibility layer).
     75   - make it impossible to queue a response at the wrong time
     76   - make it impossible to suspend a connection/request at the
     77     wrong time (improves thread-safety)
     78   - make it clear which response status codes are "properly"
     79     supported (include the descriptive string) by using an enum;
     80   - simplify API for common-case of one-shot responses by
     81     eliminating need for destroy response in most cases;
     82   - avoid fixed types, like uint32_t. They may not exist on some
     83     platforms. Instead use uint_fast32_t.
     84     It is also better for future-proof.
     85   - check portability for embedded platforms. Some of them support
     86     64 bits, but 'int' could be just 16 bits resulting of silently
     87     dropping enum values higher than 65535.
     88     => in general, more functions, fewer enums for setup
     89   - Avoid returning pointers to internal members. It is not thread-safe and
     90     even in single thread the value could change over the time. Prefer pointers to
     91     app-allocated memory with the size, like MHD_daemon_get_static_info(enum
     92     MHD_enum_name info_type, void *buf, size_t buf_size).
     93     => Except in cases where zero-copy matters.
     94   - Use separate app calls/functions for data the will not change for the
     95     lifetime of the object and dynamic data. The only difference should be the
     96     name. Like MHD_daemon_get_static_info(enum MHD_enum_name info_type, void *buf,
     97     size_t buf_size) MHD_daemon_get_dynamic_info(enum MHD_enum_name info_type,
     98     void *buf, size_t buf_size) Examples of static data: listen socket, number of
     99     workers, daemon flags.  Examples of dynamic data: number of connections,
    100     quiesce status.  It should give a clear idea whether the data could be changed
    101     over the time (could be not obvious for some data) and thus may change the
    102     approach how to use the data in app.  The same for: library, daemon,
    103     connection, request. Not sure that dynamic data makes sense for the library.
    104   - Define response code in response object. There are a very little
    105     chance that response body designed for 404 or 403 codes will be used with
    106     200 code. However, the responses body for 307 and 308 could be the same. So:
    107     Add default response code in response object.
    108   - Make responses unmodifiable after first use. It is not thread-safe.
    109     MHD-generated headers (Date, Connection/Keep-Alive) are again
    110     part of the *request* and do not count as part of the "response" here.
    111   - Remove "footers" from responses. With unmodifiable responses everything should
    112     be "headers". Add footers to *requests* instead.
    113   - Add API for adding request-specific response headers and footers. To
    114     simplify the things it should just copy the strings (to avoid dealing with
    115     complicated deinit of possible dynamic strings).  After this change it should
    116     be possible to simplify DAuth handling as response could be reused (currently
    117     403 responses are modified for each reply).
    118   - Control response behaviour mainly by response flags, not by additional
    119     headers (like MHD_RF_FORCE_CLOSE instead of "Connection: close").
    120     It is easier&faster for both: app and MHD.
    121   - Move response codes from MHD_HTTP_xxx namespace to MHD_HTTP_CODE_xxx
    122     namespace. It already may clash with other HTTP values.
    123   - Postprocessor is unusable night-mare when doing "stream processing"
    124     for tiny values where the application basically has to copy together
    125     the stream back into a single compact heap value, just making the
    126     parsing highly more complicated (see examples in Challenger)
    127   - non-stream processing variant for request bodies, give apps a
    128     way to request the full body in one buffer; give apps a way
    129     to request a 'large new allocation' for such buffers; give apps
    130     a way to specify a global quota for large allocations to ensure
    131     memory usage has a hard bound
    132 
    133   - Internals: carefully check where locking is really required. Probably
    134     separate locks. Check out-of-thread value reading. Currently code assumes
    135     atomic reading of values used in other threads, which mostly true on x86,
    136     but not OK on other arches. Probably use read/write locking to minimize
    137     the threads interference.
    138   - Internals: figure out how to do portable variant of cork/uncork
    139   - Internals: remove request data from memory pool when response is queued
    140     (IF no callbacks and thus data cannot be used anymore, or IF
    141      application permits explicitly per daemon) to get more space
    142     for building response;
    143   - Internals: Fix TCP FIN graceful closure issue for upgraded
    144     connections (API implications?)
    145 
    146 */
    147 
    148 #ifndef MICROHTTPD2_H
    149 #define MICROHTTPD2_H
    150 
    151 #ifndef __cplusplus
    152 #  define MHD_C_DECLARATIONS_START_HERE_   /* Empty */
    153 #  define MHD_C_DECLARATIONS_FINISH_HERE_  /* Empty */
    154 #else  /* __cplusplus */
    155 /* *INDENT-OFF* */
    156 #  define MHD_C_DECLARATIONS_START_HERE_   extern "C" {
    157 #  define MHD_C_DECLARATIONS_FINISH_HERE_  }
    158 /* *INDENT-ON* */
    159 #endif /* __cplusplus */
    160 
    161 MHD_C_DECLARATIONS_START_HERE_
    162 
    163 /**
    164  * Current version of the library in packed BCD form.
    165  * (For example, version 1.9.30-1 would be 0x01093001)
    166  */
    167 #define MHD_VERSION 0x01990001
    168 
    169 #include "microhttpd2_portability.h"
    170 
    171 /* If generic headers do not work on your platform, include headers that
    172    define 'va_list', 'size_t', 'uint_least16_t', 'uint_fast32_t',
    173    'uint_fast64_t', and 'struct sockaddr', and then
    174    add "#define MHD_HAVE_SYS_HEADERS_INCLUDED" before including "microhttpd2.h".
    175    When 'MHD_HAVE_SYS_HEADERS_INCLUDED' is defined, the following "standard"
    176    includes will not be used (which might be a good idea, especially on
    177    platforms where they do not exist).
    178    */
    179 #ifndef MHD_HAVE_SYS_HEADERS_INCLUDED
    180 #  include <stdarg.h>
    181 #  ifndef MHD_SYS_BASE_TYPES_H
    182 /* Headers for uint_fastXX_t, size_t */
    183 #    include <stdint.h>
    184 #    include <stddef.h>
    185 #    include <sys/types.h> /* This header is actually optional */
    186 #  endif
    187 #  ifndef MHD_SYS_SOCKET_TYPES_H
    188 /* Headers for 'struct sockaddr' */
    189 #    if !defined(_WIN32) || defined(__CYGWIN__)
    190 #      include <sys/socket.h>
    191 #    else
    192 /* Prevent conflict of <winsock.h> and <winsock2.h> */
    193 #      if !defined(_WINSOCK2API_) && !defined(_WINSOCKAPI_)
    194 #        ifndef WIN32_LEAN_AND_MEAN
    195 /* Do not use unneeded parts of W32 headers. */
    196 #          define WIN32_LEAN_AND_MEAN 1
    197 #        endif /* !WIN32_LEAN_AND_MEAN */
    198 #        include <winsock2.h>
    199 #      endif
    200 #    endif
    201 #  endif
    202 #endif
    203 
    204 #ifndef MHD_BOOL_DEFINED
    205 
    206 /**
    207  * Representation of 'bool' in the public API as stdbool.h may not
    208  * always be available and presence of 'bool' keyword may depend on
    209  * used C version.
    210  * It is always safe to cast 'MHD_Bool' variable to 'bool' and vice versa.
    211  * Note: it may be UNSAFE to cast pointers 'MHD_Bool*' to 'bool*' and
    212  *       vice versa.
    213  */
    214 enum MHD_Bool
    215 {
    216 
    217   /**
    218    * MHD-internal return code for "NO".
    219    */
    220   MHD_NO = 0
    221   ,
    222   /**
    223    * MHD-internal return code for "YES".  All non-zero values
    224    * will be interpreted as "YES", but MHD will only ever
    225    * return #MHD_YES or #MHD_NO.
    226    */
    227   MHD_YES = 1
    228 };
    229 
    230 
    231 #  define MHD_BOOL_DEFINED 1
    232 #endif /* ! MHD_BOOL_DEFINED */
    233 
    234 #ifndef MHD_STRINGS_DEFINED
    235 
    236 
    237 /**
    238  * String with length data.
    239  * This type should always have valid @a cstr pointer.
    240  */
    241 struct MHD_String
    242 {
    243   /**
    244    * Number of characters in @e str, not counting 0-termination.
    245    */
    246   size_t len;
    247 
    248   /**
    249    * 0-terminated C-string.
    250    * Must not be NULL.
    251    */
    252   const char *cstr;
    253 };
    254 
    255 /**
    256  * String with length data.
    257  * This type of data may have NULL as the @a cstr pointer.
    258  */
    259 struct MHD_StringNullable
    260 {
    261   /**
    262    * Number of characters in @e cstr, not counting 0-termination.
    263    * If @a cstr is NULL, it must be zero.
    264    */
    265   size_t len;
    266 
    267   /**
    268    * 0-terminated C-string.
    269    * In some cases it could be NULL.
    270    */
    271   const char *cstr;
    272 };
    273 
    274 #  define MHD_STRINGS_DEFINED 1
    275 #endif /* ! MHD_STRINGS_DEFINED */
    276 
    277 
    278 #ifndef MHD_INVALID_SOCKET
    279 #  if !defined(_WIN32) || defined(_SYS_TYPES_FD_SET)
    280 #    define MHD_SOCKETS_KIND_POSIX 1
    281 /**
    282  * MHD_Socket is a type for socket FDs
    283  */
    284 typedef int MHD_Socket;
    285 #    define MHD_INVALID_SOCKET (-1)
    286 #  else /* !defined(_WIN32) || defined(_SYS_TYPES_FD_SET) */
    287 #    define MHD_SOCKETS_KIND_WINSOCK 1
    288 /**
    289  * MHD_Socket is a type for socket FDs
    290  */
    291 typedef SOCKET MHD_Socket;
    292 #    define MHD_INVALID_SOCKET (INVALID_SOCKET)
    293 #  endif /* !defined(_WIN32) || defined(_SYS_TYPES_FD_SET) */
    294 #endif /* MHD_INVALID_SOCKET */
    295 
    296 
    297 /**
    298  * Constant used to indicate unknown size (use when creating a response).
    299  * Any possible larger sizes are interpreted as the same value.
    300  */
    301 #ifdef UINT64_MAX
    302 #  define MHD_SIZE_UNKNOWN UINT64_MAX
    303 #else
    304 #  define MHD_SIZE_UNKNOWN \
    305           MHD_STATIC_CAST_ (uint_fast64_t,0xffffffffffffffffU)
    306 #endif
    307 
    308 
    309 /**
    310  * Constant used to indicate unlimited wait time.
    311  * Any possible larger values are interpreted as this value.
    312  */
    313 #ifdef UINT64_MAX
    314 #  define MHD_WAIT_INDEFINITELY UINT64_MAX
    315 #else
    316 #  define MHD_WAIT_INDEFINITELY \
    317           MHD_STATIC_CAST_ (uint_fast64_t,0xffffffffffffffffU)
    318 #endif
    319 
    320 
    321 /* ********** (a) Core HTTP Processing ************ */
    322 
    323 
    324 /**
    325  * @brief Handle for a daemon that listens for requests.
    326  *
    327  * Manages the listen socket, event loop, optional threads and server
    328  * settings.
    329  *
    330  * @defgroup daemon HTTP server handling client connections
    331  */
    332 struct MHD_Daemon;
    333 
    334 
    335 /**
    336  * @brief Handle/identifier of a network connection abstraction.
    337  *
    338  * A single network (i.e. TCP) connection can be used for
    339  * a single (in HTTP/1.1) data stream.
    340  *
    341  * @defgroup connection client connection with streams
    342  */
    343 struct MHD_Connection;
    344 
    345 
    346 /**
    347  * @brief Handle/identifier of a data stream over network
    348  * connection.
    349  *
    350  * A data stream may be used for multiple requests, which
    351  * in HTTP/1.1 must be processed sequentially.
    352  *
    353  * @defgroup stream stream of HTTP requests
    354  */
    355 struct MHD_Stream;
    356 
    357 /**
    358  * @brief Handle representing an HTTP request.
    359  *
    360  * With HTTP/1.1, multiple requests can be run over the same
    361  * stream.  However, MHD will only show one request per data
    362  * stream to the client at any given time.
    363  *
    364  * Replaces `struct MHD_Connection` in the API prior to version 2.0.0,
    365  * renamed to better reflect what this object truly represents to
    366  * the application using MHD.
    367  *
    368  * @defgroup request HTTP requests
    369  */
    370 struct MHD_Request;
    371 
    372 
    373 /**
    374  * @brief Actions are returned by the application when processed client header
    375  * to drive the request handling of MHD.
    376  *
    377  * @defgroup action Request actions
    378  */
    379 struct MHD_Action;
    380 
    381 
    382 /**
    383  * @brief Actions are returned by the application when processing client upload
    384  * to drive the request handling of MHD.
    385  *
    386  * @defgroup action Request actions
    387  */
    388 struct MHD_UploadAction;
    389 
    390 /**
    391  * @defgroup general Primary MHD functions and data
    392  */
    393 
    394 /**
    395  * @defgroup specialized Introspection and other special control
    396  */
    397 
    398 /**
    399  * @defgroup authentication Digest and other HTTP authentications
    400  */
    401 
    402 
    403 /**
    404  * Status codes returned by API functions, also used for logging.
    405  *
    406  * As a return value, zero (#MHD_SC_OK) always indicates success.
    407  * Values 00001-09999 must be handled explicitly by the application.
    408  * Values 10000-19999 are informational events.
    409  * Values 20000-29999 indicate successful operations.
    410  * Values 30000-39999 indicate unsuccessful but normal operations.
    411  * Values 40000-49999 indicate client (or network) errors.
    412  * Values 50000-59999 indicate MHD-internal (or platform) errors.
    413  * Values 60000-65535 indicate application errors.
    414  *
    415  * @ingroup general
    416  */
    417 enum MHD_FIXED_ENUM_MHD_SET_ MHD_StatusCode
    418 {
    419 
    420   /* 00000-level codes are return values the application must handle.
    421      The zero code always means success. */
    422 
    423   /**
    424    * Successful operation (not used for logging).
    425    * The code is guaranteed to be always zero.
    426    */
    427   MHD_SC_OK = 0
    428   ,
    429 
    430   /* 10000-level codes are purely informational events. */
    431 
    432   /**
    433    * Informational event, MHD started.
    434    */
    435   MHD_SC_DAEMON_STARTED = 10000
    436   ,
    437   /**
    438    * Informational event, we accepted a connection.
    439    */
    440   MHD_SC_CONNECTION_ACCEPTED = 10001
    441   ,
    442   /**
    443    * Informational event, thread processing connection terminates.
    444    */
    445   MHD_SC_THREAD_TERMINATING = 10002
    446   ,
    447   /**
    448    * Informational event, state machine status for a connection.
    449    */
    450   MHD_SC_STATE_MACHINE_STATUS_REPORT = 10003
    451   ,
    452   /**
    453    * accept() returned transient error.
    454    */
    455   MHD_SC_ACCEPT_FAILED_EAGAIN = 10004
    456   ,
    457   /**
    458    * Accepted socket is unknown type (probably non-IP).
    459    */
    460   MHD_SC_ACCEPTED_UNKNOWN_TYPE = 10040
    461   ,
    462   /**
    463    * The sockaddr for the accepted socket does not fit the buffer.
    464    * (Strange)
    465    */
    466   MHD_SC_ACCEPTED_SOCKADDR_TOO_LARGE = 10041
    467   ,
    468 
    469   /* 20000-level codes indicate successful operations. */
    470   /* Examples: a connection has been closed normally, the response data
    471      generation has been completed. */
    472 
    473   /**
    474    * MHD is closing a connection after the client closed it
    475    * (perfectly normal end).
    476    */
    477   MHD_SC_CONNECTION_CLOSED = 20000
    478   ,
    479   /**
    480    * MHD is closing a connection because the application
    481    * logic to generate the response data completed.
    482    */
    483   MHD_SC_APPLICATION_DATA_GENERATION_FINISHED = 20001
    484   ,
    485   /**
    486    * The request does not contain a particular type of Authentication
    487    * credentials
    488    */
    489   MHD_SC_AUTH_ABSENT = 20060
    490   ,
    491 
    492   /* 30000-level codes indicate unsuccessful but normal operations. */
    493   /* Examples: a connections limit has been reached, the accept policy
    494      callback has rejected a connection, a memory pool is exhausted. */
    495 
    496 
    497   /**
    498    * Resource limit in terms of number of parallel connections
    499    * hit.
    500    */
    501   MHD_SC_LIMIT_CONNECTIONS_REACHED = 30000
    502   ,
    503   /**
    504    * The operation failed because the respective
    505    * daemon is already too deep inside of the shutdown
    506    * activity.
    507    */
    508   MHD_SC_DAEMON_ALREADY_SHUTDOWN = 30020
    509   ,
    510   /**
    511    * Failed to start new thread because of system limits.
    512    */
    513   MHD_SC_CONNECTION_THREAD_SYS_LIMITS_REACHED = 30030
    514   ,
    515   /**
    516    * Failed to start a thread.
    517    */
    518   MHD_SC_CONNECTION_THREAD_LAUNCH_FAILURE = 30031
    519   ,
    520   /**
    521    * The operation failed because we either have no
    522    * listen socket or were already quiesced.
    523    */
    524   MHD_SC_DAEMON_ALREADY_QUIESCED = 30040
    525   ,
    526   /**
    527    * The operation failed because client disconnected
    528    * faster than we could accept().
    529    */
    530   MHD_SC_ACCEPT_FAST_DISCONNECT = 30050
    531   ,
    532   /**
    533    * Operating resource limits hit on accept().
    534    */
    535   MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED = 30060
    536   ,
    537   /**
    538    * Connection was refused by accept policy callback.
    539    */
    540   MHD_SC_ACCEPT_POLICY_REJECTED = 30070
    541   ,
    542   /**
    543    * Failed to allocate memory for the daemon resources.
    544    * TODO: combine similar error codes for daemon
    545    */
    546   MHD_SC_DAEMON_MEM_ALLOC_FAILURE = 30081
    547   ,
    548   /**
    549    * We failed to allocate memory for the connection.
    550    * (May be transient.)
    551    */
    552   MHD_SC_CONNECTION_MEM_ALLOC_FAILURE = 30082
    553   ,
    554   /**
    555    * We failed to allocate memory for the connection's memory pool.
    556    * (May be transient.)
    557    */
    558   MHD_SC_POOL_MEM_ALLOC_FAILURE = 30083
    559   ,
    560   /**
    561    * We failed to allocate memory for the HTTP/2 connection's resources.
    562    * (May be transient.)
    563    */
    564   MHD_SC_H2_CONN_MEM_ALLOC_FAILURE = 30084
    565   ,
    566   /**
    567    * We failed to forward data from a Web socket to the
    568    * application to the remote side due to the socket
    569    * being closed prematurely. (May be transient.)
    570    */
    571   MHD_SC_UPGRADE_FORWARD_INCOMPLETE = 30100
    572   ,
    573   /**
    574    * Failed to allocate memory from our memory pool for processing
    575    * the request.  Likely the request fields are too large to leave
    576    * enough room.
    577    */
    578   MHD_SC_CONNECTION_POOL_NO_MEM_REQ = 30130
    579   ,
    580   /**
    581    * Failed to allocate memory from our memory pool to store GET parameter.
    582    * Likely the request URI or header fields are too large to leave enough room.
    583    */
    584   MHD_SC_CONNECTION_POOL_NO_MEM_GET_PARAM = 30131
    585   ,
    586   /**
    587    * Failed to allocate memory from our memory pool to store parsed cookie.
    588    */
    589   MHD_SC_CONNECTION_POOL_NO_MEM_COOKIE = 30132
    590   ,
    591   /**
    592    * Failed to allocate memory from connection memory pool to store
    593    * parsed Authentication data.
    594    */
    595   MHD_SC_CONNECTION_POOL_NO_MEM_AUTH_DATA = 30133
    596   ,
    597   /**
    598    * Detected jump back of system clock
    599    */
    600   MHD_SC_SYS_CLOCK_JUMP_BACK_LARGE = 30140
    601   ,
    602   /**
    603    * Detected correctable jump back of system clock
    604    */
    605   MHD_SC_SYS_CLOCK_JUMP_BACK_CORRECTED = 30141
    606   ,
    607   /**
    608    * Timeout waiting for communication operation for HTTP-Upgraded connection
    609    */
    610   MHD_SC_UPGRADED_NET_TIMEOUT = 30161
    611   ,
    612   /**
    613    * Not enough system resources
    614    */
    615   MHD_SC_NO_SYS_RESOURCES = 30180
    616   ,
    617 
    618   /* 40000-level errors are caused by the HTTP client or the network. */
    619 
    620   /**
    621    * MHD is closing a connection because parsing the
    622    * request failed.
    623    */
    624   MHD_SC_CONNECTION_PARSE_FAIL_CLOSED = 40000
    625   ,
    626   /**
    627    * MHD is returning an error because the header provided
    628    * by the client is too big.
    629    */
    630   MHD_SC_CLIENT_HEADER_TOO_BIG = 40020
    631   ,
    632   /**
    633    * An HTTP/1.1 request was sent without the "Host:" header.
    634    */
    635   MHD_SC_HOST_HEADER_MISSING = 40060
    636   ,
    637   /**
    638    * Request has more than one "Host:" header.
    639    */
    640   MHD_SC_HOST_HEADER_SEVERAL = 40061
    641   ,
    642   /**
    643    * The value of the "Host:" header is invalid.
    644    */
    645   MHD_SC_HOST_HEADER_MALFORMED = 40062
    646   ,
    647   /**
    648    * The given content length was not a number.
    649    */
    650   MHD_SC_CONTENT_LENGTH_MALFORMED = 40065
    651   ,
    652   /**
    653    * Request has more than one "Content-Length:" header with the same value.
    654    */
    655   MHD_SC_CONTENT_LENGTH_SEVERAL_SAME = 40066
    656   ,
    657   /**
    658    * Request has more than one "Content-Length:" header with the different
    659    * values.
    660    */
    661   MHD_SC_CONTENT_LENGTH_SEVERAL_DIFFERENT = 40067
    662   ,
    663   /**
    664    * The BOTH Content-Length and Transfer-Encoding headers are used.
    665    */
    666   MHD_SC_CONTENT_LENGTH_AND_TR_ENC = 40068
    667   ,
    668   /**
    669    * The Content-Length is too large to be handled.
    670    */
    671   MHD_SC_CONTENT_LENGTH_TOO_LARGE = 40069
    672   ,
    673   /**
    674    * Transfer encoding in request is unsupported or invalid.
    675    */
    676   MHD_SC_TRANSFER_ENCODING_UNSUPPORTED = 40075
    677   ,
    678   /**
    679    * "Expect:" value in request is unsupported or invalid.
    680    */
    681   MHD_SC_EXPECT_HEADER_VALUE_UNSUPPORTED = 40076
    682   ,
    683   /**
    684    * The given uploaded, chunked-encoded body was malformed.
    685    */
    686   MHD_SC_CHUNKED_ENCODING_MALFORMED = 40080
    687   ,
    688   /**
    689    * The first header line has whitespace at the start
    690    */
    691   MHD_SC_REQ_FIRST_HEADER_LINE_SPACE_PREFIXED = 40100
    692   ,
    693   /**
    694    * The request target (URI) has whitespace character
    695    */
    696   MHD_SC_REQ_TARGET_HAS_WHITESPACE = 40101
    697   ,
    698   /**
    699    * Wrong bare CR characters has been replaced with space.
    700    */
    701   MHD_SC_REQ_HEADER_CR_REPLACED = 40120
    702   ,
    703   /**
    704    * Header line has not colon and skipped.
    705    */
    706   MHD_SC_REQ_HEADER_LINE_NO_COLON = 40121
    707   ,
    708   /**
    709    * Wrong bare CR characters has been replaced with space.
    710    */
    711   MHD_SC_REQ_FOOTER_CR_REPLACED = 40140
    712   ,
    713   /**
    714    * Footer line has not colon and skipped.
    715    */
    716   MHD_SC_REQ_FOOTER_LINE_NO_COLON = 40141
    717   ,
    718   /**
    719    * The request is malformed.
    720    */
    721   MHD_SC_REQ_MALFORMED = 40155
    722   ,
    723   /**
    724    * The cookie string has been parsed, but it is not fully compliant with
    725    * specifications
    726    */
    727   MHD_SC_REQ_COOKIE_PARSED_NOT_COMPLIANT = 40160
    728   ,
    729   /**
    730    * The cookie string has been parsed only partially
    731    */
    732   MHD_SC_REQ_COOKIE_PARSED_PARTIALLY = 40161
    733   ,
    734   /**
    735    * The cookie string is ignored, as it is not fully compliant with
    736    * specifications
    737    */
    738   MHD_SC_REQ_COOKIE_IGNORED_NOT_COMPLIANT = 40162
    739   ,
    740   /**
    741    * The cookie string has been ignored as it is invalid
    742    */
    743   MHD_SC_REQ_COOKIE_INVALID = 40163
    744   ,
    745   /**
    746    * The POST data parsed successfully, but has missing or incorrect
    747    * termination.
    748    * The last parsed field may have incorrect data.
    749    */
    750   MHD_SC_REQ_POST_PARSE_OK_BAD_TERMINATION = 40202
    751   ,
    752   /**
    753    * Parsing of the POST data is incomplete because client used incorrect
    754    * format of POST encoding.
    755    * Some POST data is available or has been provided via callback.
    756    */
    757   MHD_SC_REQ_POST_PARSE_PARTIAL_INVALID_POST_FORMAT = 40203
    758   ,
    759   /**
    760    * The request does not have "Content-Type:" header and POST data cannot
    761    * be parsed
    762    */
    763   MHD_SC_REQ_POST_PARSE_FAILED_NO_CNTN_TYPE = 40280
    764   ,
    765   /**
    766    * The request has unknown POST encoding specified by "Content-Type:" header
    767    */
    768   MHD_SC_REQ_POST_PARSE_FAILED_UNKNOWN_CNTN_TYPE = 40281
    769   ,
    770   /**
    771    * The request has "Content-Type: multipart/form-data" header without
    772    * "boundary" parameter
    773    */
    774   MHD_SC_REQ_POST_PARSE_FAILED_HEADER_NO_BOUNDARY = 40282
    775   ,
    776   /**
    777    * The request has "Content-Type: multipart/form-data" header with misformed
    778    * data
    779    */
    780   MHD_SC_REQ_POST_PARSE_FAILED_HEADER_MISFORMED = 40283
    781   ,
    782   /**
    783    * The POST data cannot be parsed because client used incorrect format
    784    * of POST encoding.
    785    */
    786   MHD_SC_REQ_POST_PARSE_FAILED_INVALID_POST_FORMAT = 40290
    787   ,
    788   /**
    789    * The data in Auth request header has invalid format.
    790    * For example, for Basic Authentication base64 decoding failed.
    791    */
    792   MHD_SC_REQ_AUTH_DATA_BROKEN = 40320
    793   ,
    794   /**
    795    * The request cannot be processed. Sending error reply.
    796    */
    797   MHD_SC_REQ_PROCESSING_ERR_REPLY = 41000
    798   ,
    799   /**
    800    * MHD is closing a connection because of timeout.
    801    */
    802   MHD_SC_CONNECTION_TIMEOUT = 42000
    803   ,
    804   /**
    805    * MHD is closing a connection because receiving the
    806    * request failed.
    807    */
    808   MHD_SC_CONNECTION_RECV_FAIL_CLOSED = 42020
    809   ,
    810   /**
    811    * MHD is closing a connection because sending the response failed.
    812    */
    813   MHD_SC_CONNECTION_SEND_FAIL_CLOSED = 42021
    814   ,
    815   /**
    816    * MHD is closing a connection because remote client shut down its sending
    817    * side before full request was sent.
    818    */
    819   MHD_SC_CLIENT_SHUTDOWN_EARLY = 42040
    820   ,
    821   /**
    822    * MHD is closing a connection because remote client closed connection
    823    * early.
    824    */
    825   MHD_SC_CLIENT_CLOSED_CONN_EARLY = 42041
    826   ,
    827   /**
    828    * MHD is closing a connection connection has been (remotely) aborted.
    829    */
    830   MHD_SC_CONNECTION_ABORTED = 42042
    831   ,
    832   /**
    833    * MHD is closing a connection because it was reset.
    834    */
    835   MHD_SC_CONNECTION_RESET = 42060
    836   ,
    837   /**
    838    * MHD is closing a connection connection (or connection socket) has
    839    * been broken.
    840    */
    841   MHD_SC_CONNECTION_BROKEN = 42061
    842   ,
    843   /**
    844    * ALPN in TLS connection selected HTTP/2 (as advertised by the client),
    845    * but the client did not send a valid HTTP/2 connection preface.
    846    */
    847   MHD_SC_ALPN_H2_NO_PREFACE = 43001
    848   ,
    849 
    850   /* 50000-level errors are internal MHD or platform failures,
    851      not caused by the application (see 60000-level). */
    852   /* Examples: a socket error on a broken connection, a read failure for
    853      a file-backed response, an unexpected accept() error. */
    854 
    855   /**
    856    * This build of MHD does not support TLS, but the application
    857    * requested TLS.
    858    */
    859   MHD_SC_TLS_DISABLED = 50000
    860   ,
    861   /**
    862    * The selected TLS backend does not support this operation.
    863    */
    864   MHD_SC_TLS_BACKEND_OPERATION_UNSUPPORTED = 50004
    865   ,
    866   /**
    867    * Failed to setup ITC channel.
    868    */
    869   MHD_SC_ITC_INITIALIZATION_FAILED = 50005
    870   ,
    871   /**
    872    * File descriptor for ITC cannot be used because the FD number is higher
    873    * than the limit set by FD_SETSIZE (if internal polling with select is used)
    874    * or by application.
    875    */
    876   MHD_SC_ITC_FD_OUTSIDE_OF_SET_RANGE = 50006
    877   ,
    878   /**
    879    * The specified value for the NC length is way too large
    880    * for this platform (integer overflow on `size_t`).
    881    */
    882   MHD_SC_DIGEST_AUTH_NC_LENGTH_TOO_BIG = 50010
    883   ,
    884   /**
    885    * We failed to allocate memory for the specified nonce
    886    * counter array.  The option was not set.
    887    */
    888   MHD_SC_DIGEST_AUTH_NC_ALLOCATION_FAILURE = 50011
    889   ,
    890   /**
    891    * This build of the library does not support
    892    * digest authentication.
    893    */
    894   MHD_SC_DIGEST_AUTH_NOT_SUPPORTED_BY_BUILD = 50012
    895   ,
    896   /**
    897    * IPv6 requested but not supported by this build.
    898    * @sa #MHD_SC_AF_NOT_SUPPORTED_BY_BUILD
    899    */
    900   MHD_SC_IPV6_NOT_SUPPORTED_BY_BUILD = 50020
    901   ,
    902   /**
    903    * Specified address/protocol family is not supported by this build.
    904    * @sa MHD_SC_IPV6_NOT_SUPPORTED_BY_BUILD
    905    */
    906   MHD_SC_AF_NOT_SUPPORTED_BY_BUILD = 50021
    907   ,
    908   /**
    909    * The requested address/protocol family is rejected by the OS.
    910    * @sa #MHD_SC_AF_NOT_SUPPORTED_BY_BUILD
    911    */
    912   MHD_SC_AF_NOT_AVAILABLE = 50022
    913   ,
    914   /**
    915    * We failed to open the listen socket.
    916    */
    917   MHD_SC_FAILED_TO_OPEN_LISTEN_SOCKET = 50040
    918   ,
    919   /**
    920    * Failed to enable listen port reuse.
    921    */
    922   MHD_SC_LISTEN_PORT_REUSE_ENABLE_FAILED = 50041
    923   ,
    924   /**
    925    * Failed to enable listen port reuse.
    926    */
    927   MHD_SC_LISTEN_PORT_REUSE_ENABLE_NOT_SUPPORTED = 50042
    928   ,
    929   /**
    930    * Failed to enable listen address reuse.
    931    */
    932   MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED = 50043
    933   ,
    934   /**
    935    * Enabling listen address reuse is not supported by this platform.
    936    */
    937   MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_NOT_SUPPORTED = 50044
    938   ,
    939   /**
    940    * Failed to enable exclusive use of listen address.
    941    */
    942   MHD_SC_LISTEN_ADDRESS_EXCLUSIVE_ENABLE_FAILED = 50045
    943   ,
    944   /**
    945    * Dual stack configuration is not possible for provided sockaddr.
    946    */
    947   MHD_SC_LISTEN_DUAL_STACK_NOT_SUITABLE = 50046
    948   ,
    949   /**
    950    * Failed to enable or disable dual stack for the IPv6 listen socket.
    951    * The OS default dual-stack setting is different from what is requested.
    952    */
    953   MHD_SC_LISTEN_DUAL_STACK_CONFIGURATION_REJECTED = 50047
    954   ,
    955   /**
    956    * Failed to enable or disable dual stack for the IPv6 listen socket.
    957    * The socket will be used in whatever the default is the OS uses.
    958    */
    959   MHD_SC_LISTEN_DUAL_STACK_CONFIGURATION_UNKNOWN = 50048
    960   ,
    961   /**
    962    * On this platform, MHD does not support explicitly configuring
    963    * dual stack behaviour.
    964    */
    965   MHD_SC_LISTEN_DUAL_STACK_CONFIGURATION_NOT_SUPPORTED = 50049
    966   ,
    967   /**
    968    * Failed to enable TCP FAST OPEN option.
    969    */
    970   MHD_SC_LISTEN_FAST_OPEN_FAILURE = 50050
    971   ,
    972   /**
    973    * TCP FAST OPEN is not supported by the platform or by this MHD build.
    974    */
    975   MHD_SC_FAST_OPEN_NOT_SUPPORTED = 50051
    976   ,
    977   /**
    978    * We failed to set the listen socket to non-blocking.
    979    */
    980   MHD_SC_LISTEN_SOCKET_NONBLOCKING_FAILURE = 50052
    981   ,
    982   /**
    983    * Failed to configure listen socket to be non-inheritable.
    984    */
    985   MHD_SC_LISTEN_SOCKET_NOINHERIT_FAILED = 50053
    986   ,
    987   /**
    988    * Listen socket FD cannot be used because the FD number is higher than
    989    * the limit set by FD_SETSIZE (if internal polling with select is used) or
    990    * by application.
    991    */
    992   MHD_SC_LISTEN_FD_OUTSIDE_OF_SET_RANGE = 50054
    993   ,
    994   /**
    995    * We failed to bind the listen socket.
    996    */
    997   MHD_SC_LISTEN_SOCKET_BIND_FAILED = 50055
    998   ,
    999   /**
   1000    * Failed to start listening on listen socket.
   1001    */
   1002   MHD_SC_LISTEN_FAILURE = 50056
   1003   ,
   1004   /**
   1005    * Failed to detect the port number on the listening socket
   1006    */
   1007   MHD_SC_LISTEN_PORT_DETECT_FAILURE = 50057
   1008   ,
   1009   /**
   1010    * We failed to create control socket for the epoll().
   1011    */
   1012   MHD_SC_EPOLL_CTL_CREATE_FAILED = 50060
   1013   ,
   1014   /**
   1015    * We failed to configure control socket for the epoll()
   1016    * to be non-inheritable.
   1017    */
   1018   MHD_SC_EPOLL_CTL_CONFIGURE_NOINHERIT_FAILED = 50061
   1019   ,
   1020   /**
   1021    * The epoll() control FD cannot be used because the FD number is higher
   1022    * than the limit set by application.
   1023    */
   1024   MHD_SC_EPOLL_CTL_OUTSIDE_OF_SET_RANGE = 50062
   1025   ,
   1026   /**
   1027    * Failed to allocate memory for daemon's events data, like fd_sets,
   1028    * poll, epoll or kqueue structures.
   1029    */
   1030   MHD_SC_EVENTS_MEMORY_ALLOCATE_FAILURE = 50063
   1031   ,
   1032   /**
   1033    * Failed to add daemon's FDs (ITC and/or listening) to the internal events
   1034    * monitoring
   1035    */
   1036   MHD_SC_EVENTS_REG_DAEMON_FDS_FAILURE = 50065
   1037   ,
   1038   /**
   1039    * Failed to register daemon's FDs (ITC or listening) in the application
   1040    * (external event) monitoring
   1041    */
   1042   MHD_SC_EXT_EVENT_REG_DAEMON_FDS_FAILURE = 50066
   1043   ,
   1044   /**
   1045    * Failed to create kqueue FD
   1046    */
   1047   MHD_SC_KQUEUE_FD_CREATE_FAILED = 50067
   1048   ,
   1049   /**
   1050    * Failed to configure kqueue FD to be non-inheritable.
   1051    */
   1052   MHD_SC_KQUEUE_FD_SET_NOINHERIT_FAILED = 50068
   1053   ,
   1054   /**
   1055    * The kqueue FD cannot be used because the FD number is higher
   1056    * than the limit set by application.
   1057    */
   1058   MHD_SC_KQUEUE_FD_OUTSIDE_OF_SET_RANGE = 50069
   1059   ,
   1060   /**
   1061    * The select() syscall is not available on this platform or in this MHD
   1062    * build.
   1063    */
   1064   MHD_SC_SELECT_SYSCALL_NOT_AVAILABLE = 50070
   1065   ,
   1066   /**
   1067    * The poll() syscall is not available on this platform or in this MHD
   1068    * build.
   1069    */
   1070   MHD_SC_POLL_SYSCALL_NOT_AVAILABLE = 50071
   1071   ,
   1072   /**
   1073    * The epoll syscalls are not available on this platform or in this MHD
   1074    * build.
   1075    */
   1076   MHD_SC_EPOLL_SYSCALL_NOT_AVAILABLE = 50072
   1077   ,
   1078   /**
   1079    * The kqueue syscalls are not available on this platform or in this MHD
   1080    * build.
   1081    */
   1082   MHD_SC_KQUEUE_SYSCALL_NOT_AVAILABLE = 50073
   1083   ,
   1084   /**
   1085    * Failed to obtain our listen port via introspection.
   1086    * FIXME: remove?
   1087    */
   1088   MHD_SC_LISTEN_PORT_INTROSPECTION_FAILURE = 50080
   1089   ,
   1090   /**
   1091    * Failed to obtain our listen port via introspection
   1092    * due to unsupported address family being used.
   1093    */
   1094   MHD_SC_LISTEN_PORT_INTROSPECTION_UNKNOWN_AF = 50081
   1095   ,
   1096   /**
   1097    * Failed to initialise mutex or RW-lock.
   1098    */
   1099   MHD_SC_MUTEX_INIT_FAILURE = 50085
   1100   ,
   1101   /**
   1102    * Failed to allocate memory for the thread pool.
   1103    */
   1104   MHD_SC_THREAD_POOL_MEM_ALLOC_FAILURE = 50090
   1105   ,
   1106   /**
   1107    * We failed to allocate mutex for thread pool worker.
   1108    */
   1109   MHD_SC_THREAD_POOL_CREATE_MUTEX_FAILURE = 50093
   1110   ,
   1111   /**
   1112    * Failed to start the main daemon thread.
   1113    */
   1114   MHD_SC_THREAD_MAIN_LAUNCH_FAILURE = 50095
   1115   ,
   1116   /**
   1117    * Failed to start the daemon thread for listening.
   1118    */
   1119   MHD_SC_THREAD_LISTENING_LAUNCH_FAILURE = 50096
   1120   ,
   1121   /**
   1122    * Failed to start the worker thread for the thread pool.
   1123    */
   1124   MHD_SC_THREAD_WORKER_LAUNCH_FAILURE = 50097
   1125   ,
   1126   /**
   1127    * There was an attempt to upgrade a connection on
   1128    * a daemon where upgrades are disallowed.
   1129    */
   1130   MHD_SC_UPGRADE_ON_DAEMON_WITH_UPGRADE_DISALLOWED = 50100
   1131   ,
   1132   /**
   1133    * Failed to signal via ITC channel.
   1134    */
   1135   MHD_SC_ITC_USE_FAILED = 50101
   1136   ,
   1137   /**
   1138    * Failed to check for the signal on the ITC channel.
   1139    */
   1140   MHD_SC_ITC_CHECK_FAILED = 50102
   1141   ,
   1142   /**
   1143    * System reported error conditions on the ITC FD.
   1144    */
   1145   MHD_SC_ITC_STATUS_ERROR = 50104
   1146   ,
   1147   /**
   1148    * Failed to add a socket to the epoll set.
   1149    */
   1150   MHD_SC_EPOLL_CTL_ADD_FAILED = 50110
   1151   ,
   1152   /**
   1153    * Socket FD cannot be used because the FD number is higher than the limit set
   1154    * by FD_SETSIZE (if internal polling with select is used) or by application.
   1155    */
   1156   MHD_SC_SOCKET_OUTSIDE_OF_SET_RANGE = 50111
   1157   ,
   1158   /**
   1159    * The daemon cannot be started with the specified settings as no space
   1160    * left for the connections sockets within limits set by FD_SETSIZE.
   1161    * Consider use another sockets polling syscall (only select() has such
   1162    * limitations)
   1163    */
   1164   MHD_SC_SYS_FD_SETSIZE_TOO_STRICT = 50112
   1165   ,
   1166   /**
   1167    * This daemon was not configured with options that
   1168    * would allow us to obtain a meaningful timeout.
   1169    */
   1170   MHD_SC_CONFIGURATION_MISMATCH_FOR_GET_TIMEOUT = 50113
   1171   ,
   1172   /**
   1173    * This daemon was not configured with options that
   1174    * would allow us to run with select() data.
   1175    */
   1176   MHD_SC_CONFIGURATION_MISMATCH_FOR_RUN_SELECT = 50114
   1177   ,
   1178   /**
   1179    * This daemon was not configured to run with an
   1180    * external event loop.
   1181    */
   1182   MHD_SC_CONFIGURATION_MISMATCH_FOR_RUN_EXTERNAL = 50115
   1183   ,
   1184   /**
   1185    * Encountered an unexpected error from select()
   1186    * (should never happen).
   1187    */
   1188   MHD_SC_UNEXPECTED_SELECT_ERROR = 50116
   1189   ,
   1190   /**
   1191    * Failed to remove a connection socket to the epoll or kqueue monitoring.
   1192    */
   1193   MHD_SC_EVENTS_CONN_REMOVE_FAILED = 50117
   1194   ,
   1195   /**
   1196    * poll() is not supported.
   1197    */
   1198   MHD_SC_POLL_NOT_SUPPORTED = 50120
   1199   ,
   1200   /**
   1201    * Encountered a (potentially) recoverable error from poll().
   1202    */
   1203   MHD_SC_POLL_SOFT_ERROR = 50121
   1204   ,
   1205   /**
   1206    * Encountered an unrecoverable error from poll().
   1207    */
   1208   MHD_SC_POLL_HARD_ERROR = 50122
   1209   ,
   1210   /**
   1211    * Encountered a (potentially) recoverable error from select().
   1212    */
   1213   MHD_SC_SELECT_SOFT_ERROR = 50123
   1214   ,
   1215   /**
   1216    * Encountered an unrecoverable error from select().
   1217    */
   1218   MHD_SC_SELECT_HARD_ERROR = 50124
   1219   ,
   1220   /**
   1221    * System reported error conditions on the listening socket.
   1222    */
   1223   MHD_SC_LISTEN_STATUS_ERROR = 50129
   1224   ,
   1225   /**
   1226    * Encountered an unrecoverable error from epoll function.
   1227    */
   1228   MHD_SC_EPOLL_HARD_ERROR = 50130
   1229   ,
   1230   /**
   1231    * Encountered an unrecoverable error from kevent() function.
   1232    */
   1233   MHD_SC_KQUEUE_HARD_ERROR = 50131
   1234   ,
   1235   /**
   1236    * We failed to configure accepted socket
   1237    * to not use a SIGPIPE.
   1238    */
   1239   MHD_SC_ACCEPT_CONFIGURE_NOSIGPIPE_FAILED = 50140
   1240   ,
   1241   /**
   1242    * We failed to configure accepted socket
   1243    * to be non-inheritable.
   1244    */
   1245   MHD_SC_ACCEPT_CONFIGURE_NOINHERIT_FAILED = 50141
   1246   ,
   1247   /**
   1248    * We failed to configure accepted socket
   1249    * to be non-blocking.
   1250    */
   1251   MHD_SC_ACCEPT_CONFIGURE_NONBLOCKING_FAILED = 50142
   1252   ,
   1253   /**
   1254    * The accepted socket FD value is too large.
   1255    */
   1256   MHD_SC_ACCEPT_OUTSIDE_OF_SET_RANGE = 50143
   1257   ,
   1258   /**
   1259    * accept() returned unexpected error.
   1260    */
   1261   MHD_SC_ACCEPT_FAILED_UNEXPECTEDLY = 50144
   1262   ,
   1263   /**
   1264    * Operating resource limits hit on accept() while
   1265    * zero connections are active. Oopsie.
   1266    */
   1267   MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED_INSTANTLY = 50145
   1268   ,
   1269   /**
   1270    * The daemon sockets polling mode requires non-blocking sockets.
   1271    */
   1272   MHD_SC_NONBLOCKING_REQUIRED = 50146
   1273   ,
   1274   /**
   1275    * Encountered an unexpected error from epoll_wait()
   1276    * (should never happen).
   1277    */
   1278   MHD_SC_UNEXPECTED_EPOLL_WAIT_ERROR = 50150
   1279   ,
   1280   /**
   1281    * epoll file descriptor is invalid (strange)
   1282    */
   1283   MHD_SC_EPOLL_FD_INVALID = 50151
   1284   ,
   1285   /**
   1286    * Unexpected socket error (strange)
   1287    */
   1288   MHD_SC_UNEXPECTED_SOCKET_ERROR = 50152
   1289   ,
   1290   /**
   1291    * Failed to add IP address to per-IP counter for
   1292    * some reason.
   1293    */
   1294   MHD_SC_IP_COUNTER_FAILURE = 50160
   1295   ,
   1296   /**
   1297    * Application violated our API by calling shutdown
   1298    * while having an upgrade connection still open.
   1299    */
   1300   MHD_SC_SHUTDOWN_WITH_OPEN_UPGRADED_CONNECTION = 50180
   1301   ,
   1302   /**
   1303    * Due to an unexpected internal error with the
   1304    * state machine, we closed the connection.
   1305    */
   1306   MHD_SC_STATEMACHINE_FAILURE_CONNECTION_CLOSED = 50200
   1307   ,
   1308   /**
   1309    * Failed to allocate memory in connection's pool
   1310    * to parse the cookie header.
   1311    */
   1312   MHD_SC_COOKIE_POOL_ALLOCATION_FAILURE = 50220
   1313   ,
   1314   /**
   1315    * MHD failed to build the reply header.
   1316    */
   1317   MHD_SC_REPLY_HEADER_GENERATION_FAILED = 50230
   1318   ,
   1319   /**
   1320    * Failed to allocate memory in connection's pool for the reply.
   1321    */
   1322   MHD_SC_REPLY_POOL_ALLOCATION_FAILURE = 50231
   1323   ,
   1324   /**
   1325    * Failed to read the file for file-backed response.
   1326    */
   1327   MHD_SC_REPLY_FILE_READ_ERROR = 50232
   1328   ,
   1329   /**
   1330    * Failed to generate the nonce for the Digest Auth.
   1331    */
   1332   MHD_SC_REPLY_NONCE_ERROR = 50233
   1333   ,
   1334   /**
   1335    * Failed to allocate memory in connection's pool for the reply.
   1336    */
   1337   MHD_SC_REPLY_ALLOCATION_FAILED = 50250
   1338   ,
   1339   /**
   1340    * The request POST data cannot be parsed because stream has not enough
   1341    * pool memory free.
   1342    */
   1343   MHD_SC_REQ_POST_PARSE_FAILED_NO_POOL_MEM = 50260
   1344   ,
   1345   /**
   1346    * The POST data cannot be parsed completely because no "large shared buffer"
   1347    * space is available.
   1348    * Some POST data may be parsed.
   1349    */
   1350   MHD_SC_REQ_POST_PARSE_FAILED_NO_LARGE_BUF_MEM = 50261
   1351   ,
   1352   /**
   1353    * The application set POST encoding to "multipart/form-data", but the request
   1354    * has no "Content-Type: multipart/form-data" header which is required
   1355    * to find "boundary" used in this encoding
   1356    */
   1357   MHD_SC_REQ_POST_PARSE_FAILED_HEADER_NOT_MPART = 50284
   1358   ,
   1359   /**
   1360    * The feature is not supported by this MHD build (either
   1361    * disabled by configure parameters or build platform
   1362    * did not support it, because headers are missing or
   1363    * so kernel does not have such feature).
   1364    * The feature will not be enabled if the same MHD binary
   1365    * will be run on another kernel, computer or system
   1366    * configuration.
   1367    */
   1368   MHD_SC_FEATURE_DISABLED = 50300
   1369   ,
   1370   /**
   1371    * The feature is not supported by this platform, while
   1372    * supported by MHD build.
   1373    * The feature can be enabled by changing the kernel or
   1374    * running on another computer or with other system
   1375    * configuration.
   1376    */
   1377   MHD_SC_FEATURE_NOT_AVAILABLE = 50320
   1378   ,
   1379   /**
   1380    * Failed to stop the thread
   1381    */
   1382   MHD_SC_DAEMON_THREAD_STOP_ERROR = 50350
   1383   ,
   1384   /**
   1385    * Unexpected reasons for thread stop
   1386    */
   1387   MHD_SC_DAEMON_THREAD_STOP_UNEXPECTED = 50351
   1388   ,
   1389   /**
   1390    * Daemon system data is broken (like listen socket was unexpectedly closed).
   1391    * The daemon needs to be closed.
   1392    * A new daemon can be started as a replacement after closing the current
   1393    * daemon.
   1394    */
   1395   MHD_SC_DAEMON_SYS_DATA_BROKEN = 50370
   1396   ,
   1397   /**
   1398    * Failed to acquire response mutex lock
   1399    */
   1400   MHD_SC_RESP_MUTEX_LOCK_FAILED = 50500
   1401   ,
   1402   /**
   1403    * Failed to initialise response mutex
   1404    */
   1405   MHD_SC_RESP_MUTEX_INIT_FAILED = 50501
   1406   ,
   1407   /**
   1408    * Unable to allocate memory for the response header
   1409    */
   1410   MHD_SC_RESP_HEADER_MEM_ALLOC_FAILED = 50540
   1411   ,
   1412   /**
   1413    * Failed to switch TCP_NODELAY option for the socket
   1414    */
   1415   MHD_SC_SOCKET_TCP_NODELAY_FAILED = 50600
   1416   ,
   1417   /**
   1418    * Failed to switch TCP_CORK or TCP_NOPUSH option for the socket
   1419    */
   1420   MHD_SC_SOCKET_TCP_CORK_NOPUSH_FAILED = 50601
   1421   ,
   1422   /**
   1423    * Failed to force flush the last part of the response header or
   1424    * the response content
   1425    */
   1426   MHD_SC_SOCKET_FLUSH_LAST_PART_FAILED = 50620
   1427   ,
   1428   /**
   1429    * Failed to push buffered data by zero-sized send()
   1430    */
   1431   MHD_SC_SOCKET_ZERO_SEND_FAILED = 50621
   1432   ,
   1433   /**
   1434    * The HTTP-Upgraded network connection has been closed / disconnected
   1435    */
   1436   MHD_SC_UPGRADED_NET_CONN_CLOSED = 50800
   1437   ,
   1438   /**
   1439    * The HTTP-Upgraded network connection has been broken
   1440    */
   1441   MHD_SC_UPGRADED_NET_CONN_BROKEN = 50801
   1442   ,
   1443   /**
   1444    * The TLS communication error on HTTP-Upgraded connection
   1445    */
   1446   MHD_SC_UPGRADED_TLS_ERROR = 50802
   1447   ,
   1448   /**
   1449    * Unrecoverable sockets communication error on HTTP-Upgraded connection
   1450    */
   1451   MHD_SC_UPGRADED_NET_HARD_ERROR = 50840
   1452   ,
   1453   /**
   1454    * MHD cannot wait for the data on the HTTP-Upgraded connection, because
   1455    * current build or the platform does not support required functionality.
   1456    * Communication with zero timeout is fully supported.
   1457    */
   1458   MHD_SC_UPGRADED_WAITING_NOT_SUPPORTED = 50860
   1459   ,
   1460   /**
   1461    * Global initialisation of MHD library failed
   1462    */
   1463   MHD_SC_LIB_INIT_GLOBAL_FAILED = 51000
   1464   ,
   1465   /**
   1466    * Failed to initialise TLS context for the daemon
   1467    */
   1468   MHD_SC_TLS_DAEMON_INIT_FAILED = 51200
   1469   ,
   1470   /**
   1471    * Failed to initialise TLS context for the new connection
   1472    */
   1473   MHD_SC_TLS_CONNECTION_INIT_FAILED = 51201
   1474   ,
   1475   /**
   1476    * Warning about TLS backend configuration
   1477    */
   1478   MHD_SC_TLS_LIB_CONF_WARNING = 51202
   1479   ,
   1480   /**
   1481    * Failed to perform TLS handshake
   1482    */
   1483   MHD_SC_TLS_CONNECTION_HANDSHAKED_FAILED = 51220
   1484   ,
   1485   /**
   1486    * Hashing failed.
   1487    * Internal hashing function can never fail (and this code is never returned
   1488    * for them). External hashing function (like TLS backend-based) may fail
   1489    * for various reasons, like failure of hardware acccelerated hashing.
   1490    */
   1491   MHD_SC_HASH_FAILED = 51260
   1492   ,
   1493   /**
   1494    * Failed to acquire a mutex or RW-lock.
   1495    */
   1496   MHD_SC_MUTEX_LOCK_FAILED = 51400
   1497   ,
   1498   /**
   1499    * Unspecified error in the TLS backend.
   1500    */
   1501   MHD_SC_TLS_BACKEND_ERROR = 52000
   1502   ,
   1503   /**
   1504    * Something wrong in the internal MHD logic.
   1505    * This error should be never returned if MHD works as expected.
   1506    * If this code is ever returned, please report to MHD maintainers.
   1507    */
   1508   MHD_SC_INTERNAL_ERROR = 59900
   1509   ,
   1510 
   1511   /* 60000-level errors are caused by the application
   1512      (callbacks, settings or API misuse). */
   1513 
   1514   /**
   1515    * The application called function too early.
   1516    * For example, a header value was requested before the headers
   1517    * had been received.
   1518    */
   1519   MHD_SC_TOO_EARLY = 60000
   1520   ,
   1521   /**
   1522    * The application called this function too late.
   1523    * For example, MHD has already started sending reply.
   1524    */
   1525   MHD_SC_TOO_LATE = 60001
   1526   ,
   1527   /**
   1528    * MHD does not support the requested combination of
   1529    * the sockets polling syscall and the work mode.
   1530    */
   1531   MHD_SC_SYSCALL_WORK_MODE_COMBINATION_INVALID = 60010
   1532   ,
   1533   /**
   1534    * MHD does not support quiescing if ITC was disabled
   1535    * and threads are used.
   1536    */
   1537   MHD_SC_SYSCALL_QUIESCE_REQUIRES_ITC = 60011
   1538   ,
   1539   /**
   1540    * The option provided or function called can be used only with "external
   1541    * events" modes.
   1542    */
   1543   MHD_SC_EXTERNAL_EVENT_ONLY = 60012
   1544   ,
   1545   /**
   1546    * MHD is closing a connection because the application
   1547    * logic to generate the response data failed.
   1548    */
   1549   MHD_SC_APPLICATION_DATA_GENERATION_FAILURE_CLOSED = 60015
   1550   ,
   1551   /**
   1552    * MHD is closing a connection because the application
   1553    * callback told it to do so.
   1554    */
   1555   MHD_SC_APPLICATION_CALLBACK_ABORT_ACTION = 60016
   1556   ,
   1557   /**
   1558    * Application only partially processed upload and did
   1559    * not suspend connection. This may result in a hung
   1560    * connection.
   1561    */
   1562   MHD_SC_APPLICATION_HUNG_CONNECTION = 60017
   1563   ,
   1564   /**
   1565    * Application only partially processed upload and did
   1566    * not suspend connection and the read buffer was maxxed
   1567    * out, so MHD closed the connection.
   1568    */
   1569   MHD_SC_APPLICATION_HUNG_CONNECTION_CLOSED = 60018
   1570   ,
   1571   /**
   1572    * Attempted to set an option that conflicts with another option
   1573    * already set.
   1574    */
   1575   MHD_SC_OPTIONS_CONFLICT = 60020
   1576   ,
   1577   /**
   1578    * Attempted to set an option that not recognised by MHD.
   1579    */
   1580   MHD_SC_OPTION_UNKNOWN = 60021
   1581   ,
   1582   /**
   1583    * Parameter specified unknown work mode.
   1584    */
   1585   MHD_SC_CONFIGURATION_UNEXPECTED_WM = 60022
   1586   ,
   1587   /**
   1588    * Parameter specified unknown Sockets Polling Syscall (SPS).
   1589    */
   1590   MHD_SC_CONFIGURATION_UNEXPECTED_SPS = 60023
   1591   ,
   1592   /**
   1593    * The size of the provided sockaddr does not match address family.
   1594    */
   1595   MHD_SC_CONFIGURATION_WRONG_SA_SIZE = 60024
   1596   ,
   1597   /**
   1598    * The number set by #MHD_D_O_FD_NUMBER_LIMIT is too strict to run
   1599    * the daemon
   1600    */
   1601   MHD_SC_MAX_FD_NUMBER_LIMIT_TOO_STRICT = 60025
   1602   ,
   1603   /**
   1604    * The number set by #MHD_D_O_GLOBAL_CONNECTION_LIMIT is too small for
   1605    * the daemon configuration
   1606    */
   1607   MHD_SC_CONFIGURATION_CONN_LIMIT_TOO_SMALL = 60026
   1608   ,
   1609   /**
   1610    * The provided configuration parameter is NULL, but it must be non-NULL
   1611    */
   1612   MHD_SC_CONFIGURATION_PARAM_NULL = 60027
   1613   ,
   1614   /**
   1615    * The size of the provided configuration parameter is too large
   1616    */
   1617   MHD_SC_CONFIGURATION_PARAM_TOO_LARGE = 60028
   1618   ,
   1619   /**
   1620    * The application requested an unsupported TLS backend to be used.
   1621    */
   1622   MHD_SC_TLS_BACKEND_UNSUPPORTED = 60030
   1623   ,
   1624   /**
   1625    * The application attempted to setup TLS parameters before
   1626    * enabling TLS.
   1627    */
   1628   MHD_SC_TLS_BACKEND_UNINITIALIZED = 60031
   1629   ,
   1630   /**
   1631    * The application requested a TLS backend which cannot be used due
   1632    * to missing TLS dynamic library or backend initialisation problem.
   1633    */
   1634   MHD_SC_TLS_BACKEND_UNAVAILABLE = 60032
   1635   ,
   1636   /**
   1637    * Provided TLS certificate and/or private key are incorrect
   1638    */
   1639   MHD_SC_TLS_CONF_BAD_CERT = 60033
   1640   ,
   1641   /**
   1642    * The application requested a daemon setting that cannot be used with
   1643    * selected TLS backend
   1644    */
   1645   MHD_SC_TLS_BACKEND_DAEMON_INCOMPATIBLE_SETTINGS = 60034
   1646   ,
   1647   /**
   1648    * The TLS support is disabled in daemon
   1649    */
   1650   MHD_SC_DAEMON_HAS_TLS_DISABLED = 60055
   1651   ,
   1652   /**
   1653    * The daemon supports TLS connections only
   1654    */
   1655   MHD_SC_DAEMON_HAS_TLS_ENABLED = 60056
   1656   ,
   1657   /**
   1658    * The pointer to the response object is NULL
   1659    */
   1660   MHD_SC_RESP_POINTER_NULL = 60060
   1661   ,
   1662   /**
   1663    * The response HTTP status code is not suitable
   1664    */
   1665   MHD_SC_RESP_HTTP_CODE_NOT_SUITABLE = 60061
   1666   ,
   1667   /**
   1668    * The provided MHD_Action is invalid
   1669    */
   1670   MHD_SC_ACTION_INVALID = 60080
   1671   ,
   1672   /**
   1673    * The provided MHD_UploadAction is invalid
   1674    */
   1675   MHD_SC_UPLOAD_ACTION_INVALID = 60081
   1676   ,
   1677   /**
   1678    * The provided Dynamic Content Creator action is invalid
   1679    */
   1680   MHD_SC_DCC_ACTION_INVALID = 60082
   1681   ,
   1682   /**
   1683    * The response must be empty
   1684    */
   1685   MHD_SC_REPLY_NOT_EMPTY_RESPONSE = 60101
   1686   ,
   1687   /**
   1688    * The "Content-Length" header is not allowed in the reply
   1689    */
   1690   MHD_SC_REPLY_CONTENT_LENGTH_NOT_ALLOWED = 60102
   1691   ,
   1692   /**
   1693    * The provided reply headers do not fit the connection buffer
   1694    */
   1695   MHD_SC_REPLY_HEADERS_TOO_LARGE = 60103
   1696   ,
   1697   /**
   1698    * Specified offset in file-backed response is too large and not supported
   1699    * by the platform
   1700    */
   1701   MHD_SC_REPLY_FILE_OFFSET_TOO_LARGE = 60104
   1702   ,
   1703   /**
   1704    * File-backed response has file smaller than specified combination of
   1705    * the file offset and the response size.
   1706    */
   1707   MHD_SC_REPLY_FILE_TOO_SHORT = 60105
   1708   ,
   1709   /**
   1710    * The new connection cannot be used because the FD number is higher than
   1711    * the limit set by FD_SETSIZE (if internal polling with select is used) or
   1712    * by application.
   1713    */
   1714   MHD_SC_NEW_CONN_FD_OUTSIDE_OF_SET_RANGE = 60140
   1715   ,
   1716   /**
   1717    * The daemon is being destroyed, while not all HTTP-Upgraded connections
   1718    * has been closed.
   1719    */
   1720   MHD_SC_DAEMON_DESTROYED_WITH_UNCLOSED_UPGRADED = 60160
   1721   ,
   1722   /**
   1723    * The provided pointer to 'struct MHD_UpgradedHandle' is invalid
   1724    */
   1725   MHD_SC_UPGRADED_HANDLE_INVALID = 60161
   1726   ,
   1727   /**
   1728    * The provided output buffer is too small.
   1729    */
   1730   MHD_SC_OUT_BUFF_TOO_SMALL = 60180
   1731   ,
   1732   /**
   1733    * The requested type of information is not recognised.
   1734    */
   1735   MHD_SC_INFO_GET_TYPE_UNKNOWN = 60200
   1736   ,
   1737   /**
   1738    * The information of the requested type is too large to fit into
   1739    * the provided buffer.
   1740    */
   1741   MHD_SC_INFO_GET_BUFF_TOO_SMALL = 60201
   1742   ,
   1743   /**
   1744    * The type of the information is not supported by this MHD build.
   1745    * It can be information not supported on the current platform or related
   1746    * to feature disabled for this build.
   1747    */
   1748   MHD_SC_INFO_GET_TYPE_NOT_SUPP_BY_BUILD = 60202
   1749   ,
   1750   /**
   1751    * The type of the information is not available due to configuration
   1752    * or state of the object.
   1753    */
   1754   MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE = 60203
   1755   ,
   1756   /**
   1757    * The type of the information should be available for the object, but
   1758    * cannot be provided due to some error or other reasons.
   1759    */
   1760   MHD_SC_INFO_GET_TYPE_UNOBTAINABLE = 60204
   1761   ,
   1762   /**
   1763    * The type of the Digest Auth algorithm is unknown or not supported.
   1764    */
   1765   MHD_SC_AUTH_DIGEST_ALGO_NOT_SUPPORTED = 60240
   1766   ,
   1767   /**
   1768    * The Digest Auth QOP value is unknown or not supported.
   1769    */
   1770   MHD_SC_AUTH_DIGEST_QOP_NOT_SUPPORTED = 60241
   1771   ,
   1772   /**
   1773    * The Digest Auth is not supported due to configuration
   1774    */
   1775   MHD_SC_AUTH_DIGEST_UNSUPPORTED = 60242
   1776   ,
   1777   /**
   1778    * The application failed to register FD for the external events monitoring
   1779    */
   1780   MHD_SC_EXTR_EVENT_REG_FAILED = 60243
   1781   ,
   1782   /**
   1783    * The application failed to de-register FD for the external events monitoring
   1784    */
   1785   MHD_SC_EXTR_EVENT_DEREG_FAILED = 60244
   1786   ,
   1787   /**
   1788    * The application called #MHD_daemon_event_update() with broken data
   1789    */
   1790   MHD_SC_EXTR_EVENT_BROKEN_DATA = 60250
   1791   ,
   1792   /**
   1793    * The application called #MHD_daemon_event_update() with status that
   1794    * has not been requested
   1795    */
   1796   MHD_SC_EXTR_EVENT_UNEXPECTED_STATUS = 60251
   1797   ,
   1798   /**
   1799    * Unable to clear "reusable" flag.
   1800    * Once this flag is set, it cannot be removed for the response lifetime.
   1801    */
   1802   MHD_SC_RESP_REUSABLE_CANNOT_CLEAR = 60300
   1803   ,
   1804   /**
   1805    * The response header name has forbidden characters or token
   1806    */
   1807   MHD_SC_RESP_HEADER_NAME_INVALID = 60320
   1808   ,
   1809   /**
   1810    * The response header value has forbidden characters or token
   1811    */
   1812   MHD_SC_RESP_HEADER_VALUE_INVALID = 60321
   1813   ,
   1814   /**
   1815    * An attempt to add header conflicting with other response header
   1816    */
   1817   MHD_SC_RESP_HEADERS_CONFLICT = 60330
   1818   ,
   1819   /**
   1820    * The application tried to add second DATE header.
   1821    */
   1822   MHD_SC_RESP_HEADER_DATE_DUPLICATE = 60340
   1823   ,
   1824   /**
   1825    * The application tried to add second CONNECTION header.
   1826    */
   1827   MHD_SC_RESP_HEADER_CONNECTION_DUPLICATE = 60341
   1828   ,
   1829   /**
   1830    * The provided parameter is empty (for example, a zero-length string),
   1831    * but a non-empty value is required.
   1832    */
   1833   MHD_SC_PARAM_EMPTY = 61000
   1834   ,
   1835   /**
   1836    * The requested item was not found
   1837    */
   1838   MHD_SC_ITEM_NOT_FOUND = 61001
   1839 };
   1840 
   1841 /**
   1842  * Get text description for the MHD error code.
   1843  *
   1844  * This function works for @b MHD error codes, not for @b HTTP status codes.
   1845  * @param code the MHD code to get description for
   1846  * @return the pointer to the text description,
   1847  *         NULL if MHD code in not known.
   1848  *
   1849  * @ingroup general
   1850  */
   1851 MHD_EXTERN_ const struct MHD_String *
   1852 MHD_status_code_to_string (enum MHD_StatusCode code)
   1853 MHD_FN_CONST_;
   1854 
   1855 /**
   1856  * Get the pointer to the C string for the MHD error code, never NULL.
   1857  */
   1858 #define MHD_status_code_to_string_lazy(code) \
   1859         (MHD_status_code_to_string ((code)) ? \
   1860          ((MHD_status_code_to_string (code))->cstr) : ("[No code]") )
   1861 
   1862 #ifndef MHD_HTTP_METHOD_DEFINED
   1863 
   1864 /**
   1865  * @brief HTTP request methods
   1866  *
   1867  * @defgroup methods HTTP methods
   1868  *
   1869  * See: https://www.iana.org/assignments/http-methods/http-methods.xml
   1870  * Registry export date: 2023-10-02
   1871  * @{
   1872  */
   1873 
   1874 /**
   1875  * HTTP methods explicitly supported by MHD.  Note that for non-canonical
   1876  * methods, MHD will return #MHD_HTTP_METHOD_OTHER and you can use
   1877  * #MHD_REQUEST_INFO_FIXED_HTTP_METHOD to get the original string.
   1878  *
   1879  * However, applications must check for #MHD_HTTP_METHOD_OTHER *or* any enum-value
   1880  * above those in this list, as future versions of MHD may add additional
   1881  * methods (as per IANA registry), thus even if the API returns
   1882  * #MHD_HTTP_METHOD_OTHER today, it may return a method-specific header in the
   1883  * future!
   1884  */
   1885 enum MHD_FIXED_ENUM_MHD_SET_ MHD_HTTP_Method
   1886 {
   1887 
   1888   /**
   1889    * Method did not match any of the methods given below.
   1890    */
   1891   MHD_HTTP_METHOD_OTHER = 255
   1892   ,
   1893   /* Main HTTP methods. */
   1894 
   1895   /**
   1896    * "GET"
   1897    * Safe.     Idempotent.     RFC9110, Section 9.3.1.
   1898    */
   1899   MHD_HTTP_METHOD_GET = 1
   1900   ,
   1901   /**
   1902    * "HEAD"
   1903    * Safe.     Idempotent.     RFC9110, Section 9.3.2.
   1904    */
   1905   MHD_HTTP_METHOD_HEAD = 2
   1906   ,
   1907   /**
   1908    * "POST"
   1909    * Not safe. Not idempotent. RFC9110, Section 9.3.3.
   1910    */
   1911   MHD_HTTP_METHOD_POST = 3
   1912   ,
   1913   /**
   1914    * "PUT"
   1915    * Not safe. Idempotent.     RFC9110, Section 9.3.4.
   1916    */
   1917   MHD_HTTP_METHOD_PUT = 4
   1918   ,
   1919   /**
   1920    * "DELETE"
   1921    * Not safe. Idempotent.     RFC9110, Section 9.3.5.
   1922    */
   1923   MHD_HTTP_METHOD_DELETE = 5
   1924   ,
   1925   /**
   1926    * "CONNECT"
   1927    * Not safe. Not idempotent. RFC9110, Section 9.3.6.
   1928    */
   1929   MHD_HTTP_METHOD_CONNECT = 6
   1930   ,
   1931   /**
   1932    * "OPTIONS"
   1933    * Safe.     Idempotent.     RFC9110, Section 9.3.7.
   1934    */
   1935   MHD_HTTP_METHOD_OPTIONS = 7
   1936   ,
   1937   /**
   1938    * "TRACE"
   1939    * Safe.     Idempotent.     RFC9110, Section 9.3.8.
   1940    */
   1941   MHD_HTTP_METHOD_TRACE = 8
   1942   ,
   1943   /**
   1944    * "*"
   1945    * Not safe. Not idempotent. RFC9110, Section 18.2.
   1946    */
   1947   MHD_HTTP_METHOD_ASTERISK = 9
   1948 };
   1949 
   1950 #  define MHD_HTTP_METHOD_DEFINED 1
   1951 #endif /* ! MHD_HTTP_METHOD_DEFINED */
   1952 
   1953 /**
   1954  * Get text version of the method name.
   1955  * @param method the method to get the text version
   1956  * @return the pointer to the text version,
   1957  *         NULL if method is MHD_HTTP_METHOD_OTHER
   1958  *         or not known.
   1959  */
   1960 MHD_EXTERN_ const struct MHD_String *
   1961 MHD_http_method_to_string (enum MHD_HTTP_Method method)
   1962 MHD_FN_CONST_;
   1963 
   1964 
   1965 /* Main HTTP methods. */
   1966 /* Safe.     Idempotent.     RFC9110, Section 9.3.1. */
   1967 #define MHD_HTTP_METHOD_STR_GET      "GET"
   1968 /* Safe.     Idempotent.     RFC9110, Section 9.3.2. */
   1969 #define MHD_HTTP_METHOD_STR_HEAD     "HEAD"
   1970 /* Not safe. Not idempotent. RFC9110, Section 9.3.3. */
   1971 #define MHD_HTTP_METHOD_STR_POST     "POST"
   1972 /* Not safe. Idempotent.     RFC9110, Section 9.3.4. */
   1973 #define MHD_HTTP_METHOD_STR_PUT      "PUT"
   1974 /* Not safe. Idempotent.     RFC9110, Section 9.3.5. */
   1975 #define MHD_HTTP_METHOD_STR_DELETE   "DELETE"
   1976 /* Not safe. Not idempotent. RFC9110, Section 9.3.6. */
   1977 #define MHD_HTTP_METHOD_STR_CONNECT  "CONNECT"
   1978 /* Safe.     Idempotent.     RFC9110, Section 9.3.7. */
   1979 #define MHD_HTTP_METHOD_STR_OPTIONS  "OPTIONS"
   1980 /* Safe.     Idempotent.     RFC9110, Section 9.3.8. */
   1981 #define MHD_HTTP_METHOD_STR_TRACE    "TRACE"
   1982 /* Not safe. Not idempotent. RFC9110, Section 18.2. */
   1983 #define MHD_HTTP_METHOD_STR_ASTERISK  "*"
   1984 
   1985 /* Additional HTTP methods. */
   1986 /* Not safe. Idempotent.     RFC3744, Section 8.1. */
   1987 #define MHD_HTTP_METHOD_STR_ACL            "ACL"
   1988 /* Not safe. Idempotent.     RFC3253, Section 12.6. */
   1989 #define MHD_HTTP_METHOD_STR_BASELINE_CONTROL "BASELINE-CONTROL"
   1990 /* Not safe. Idempotent.     RFC5842, Section 4. */
   1991 #define MHD_HTTP_METHOD_STR_BIND           "BIND"
   1992 /* Not safe. Idempotent.     RFC3253, Section 4.4, Section 9.4. */
   1993 #define MHD_HTTP_METHOD_STR_CHECKIN        "CHECKIN"
   1994 /* Not safe. Idempotent.     RFC3253, Section 4.3, Section 8.8. */
   1995 #define MHD_HTTP_METHOD_STR_CHECKOUT       "CHECKOUT"
   1996 /* Not safe. Idempotent.     RFC4918, Section 9.8. */
   1997 #define MHD_HTTP_METHOD_STR_COPY           "COPY"
   1998 /* Not safe. Idempotent.     RFC3253, Section 8.2. */
   1999 #define MHD_HTTP_METHOD_STR_LABEL          "LABEL"
   2000 /* Not safe. Idempotent.     RFC2068, Section 19.6.1.2. */
   2001 #define MHD_HTTP_METHOD_STR_LINK           "LINK"
   2002 /* Not safe. Not idempotent. RFC4918, Section 9.10. */
   2003 #define MHD_HTTP_METHOD_STR_LOCK           "LOCK"
   2004 /* Not safe. Idempotent.     RFC3253, Section 11.2. */
   2005 #define MHD_HTTP_METHOD_STR_MERGE          "MERGE"
   2006 /* Not safe. Idempotent.     RFC3253, Section 13.5. */
   2007 #define MHD_HTTP_METHOD_STR_MKACTIVITY     "MKACTIVITY"
   2008 /* Not safe. Idempotent.     RFC4791, Section 5.3.1; RFC8144, Section 2.3. */
   2009 #define MHD_HTTP_METHOD_STR_MKCALENDAR     "MKCALENDAR"
   2010 /* Not safe. Idempotent.     RFC4918, Section 9.3; RFC5689, Section 3; RFC8144, Section 2.3. */
   2011 #define MHD_HTTP_METHOD_STR_MKCOL          "MKCOL"
   2012 /* Not safe. Idempotent.     RFC4437, Section 6. */
   2013 #define MHD_HTTP_METHOD_STR_MKREDIRECTREF  "MKREDIRECTREF"
   2014 /* Not safe. Idempotent.     RFC3253, Section 6.3. */
   2015 #define MHD_HTTP_METHOD_STR_MKWORKSPACE    "MKWORKSPACE"
   2016 /* Not safe. Idempotent.     RFC4918, Section 9.9. */
   2017 #define MHD_HTTP_METHOD_STR_MOVE           "MOVE"
   2018 /* Not safe. Idempotent.     RFC3648, Section 7. */
   2019 #define MHD_HTTP_METHOD_STR_ORDERPATCH     "ORDERPATCH"
   2020 /* Not safe. Not idempotent. RFC5789, Section 2. */
   2021 #define MHD_HTTP_METHOD_STR_PATCH          "PATCH"
   2022 /* Safe.     Idempotent.     RFC9113, Section 3.4. */
   2023 #define MHD_HTTP_METHOD_STR_PRI            "PRI"
   2024 /* Safe.     Idempotent.     RFC4918, Section 9.1; RFC8144, Section 2.1. */
   2025 #define MHD_HTTP_METHOD_STR_PROPFIND       "PROPFIND"
   2026 /* Not safe. Idempotent.     RFC4918, Section 9.2; RFC8144, Section 2.2. */
   2027 #define MHD_HTTP_METHOD_STR_PROPPATCH      "PROPPATCH"
   2028 /* Not safe. Idempotent.     RFC5842, Section 6. */
   2029 #define MHD_HTTP_METHOD_STR_REBIND         "REBIND"
   2030 /* Safe.     Idempotent.     RFC3253, Section 3.6; RFC8144, Section 2.1. */
   2031 #define MHD_HTTP_METHOD_STR_REPORT         "REPORT"
   2032 /* Safe.     Idempotent.     RFC5323, Section 2. */
   2033 #define MHD_HTTP_METHOD_STR_SEARCH         "SEARCH"
   2034 /* Not safe. Idempotent.     RFC5842, Section 5. */
   2035 #define MHD_HTTP_METHOD_STR_UNBIND         "UNBIND"
   2036 /* Not safe. Idempotent.     RFC3253, Section 4.5. */
   2037 #define MHD_HTTP_METHOD_STR_UNCHECKOUT     "UNCHECKOUT"
   2038 /* Not safe. Idempotent.     RFC2068, Section 19.6.1.3. */
   2039 #define MHD_HTTP_METHOD_STR_UNLINK         "UNLINK"
   2040 /* Not safe. Idempotent.     RFC4918, Section 9.11. */
   2041 #define MHD_HTTP_METHOD_STR_UNLOCK         "UNLOCK"
   2042 /* Not safe. Idempotent.     RFC3253, Section 7.1. */
   2043 #define MHD_HTTP_METHOD_STR_UPDATE         "UPDATE"
   2044 /* Not safe. Idempotent.     RFC4437, Section 7. */
   2045 #define MHD_HTTP_METHOD_STR_UPDATEREDIRECTREF "UPDATEREDIRECTREF"
   2046 /* Not safe. Idempotent.     RFC3253, Section 3.5. */
   2047 #define MHD_HTTP_METHOD_STR_VERSION_CONTROL "VERSION-CONTROL"
   2048 
   2049 /** @} */ /* end of group methods */
   2050 
   2051 #ifndef MHD_HTTP_POSTENCODING_DEFINED
   2052 
   2053 
   2054 /**
   2055  * @brief Possible encodings for HTML forms submitted as HTTP POST requests
   2056  *
   2057  * @defgroup postenc HTTP POST encodings
   2058  * See also: https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#form-submission-2
   2059  * @{
   2060  */
   2061 enum MHD_FIXED_ENUM_MHD_APP_SET_ MHD_HTTP_PostEncoding
   2062 {
   2063   /**
   2064    * No post encoding / broken data / unknown encoding
   2065    */
   2066   MHD_HTTP_POST_ENCODING_OTHER = 0
   2067   ,
   2068   /**
   2069    * "application/x-www-form-urlencoded"
   2070    * See https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#url-encoded-form-data
   2071    * See https://url.spec.whatwg.org/#application/x-www-form-urlencoded
   2072    * See https://datatracker.ietf.org/doc/html/rfc3986#section-2
   2073    */
   2074   MHD_HTTP_POST_ENCODING_FORM_URLENCODED = 1
   2075   ,
   2076   /**
   2077    * "multipart/form-data"
   2078    * See https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#multipart-form-data
   2079    * See https://www.rfc-editor.org/rfc/rfc7578.html
   2080    */
   2081   MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA = 2
   2082   ,
   2083   /**
   2084    * "text/plain"
   2085    * Introduced by HTML5
   2086    * See https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#plain-text-form-data
   2087    * @warning Format is ambiguous. Do not use unless there is a very strong reason.
   2088    */
   2089   MHD_HTTP_POST_ENCODING_TEXT_PLAIN = 3
   2090 };
   2091 
   2092 
   2093 /** @} */ /* end of group postenc */
   2094 
   2095 #  define MHD_HTTP_POSTENCODING_DEFINED 1
   2096 #endif /* ! MHD_HTTP_POSTENCODING_DEFINED */
   2097 
   2098 
   2099 /**
   2100  * @brief Standard headers found in HTTP requests and responses.
   2101  *
   2102  * See: https://www.iana.org/assignments/http-fields/http-fields.xhtml
   2103  *
   2104  * @defgroup headers HTTP headers
   2105  * Registry export date: 2023-10-02
   2106  * @{
   2107  */
   2108 
   2109 /* Main HTTP headers. */
   2110 /* Permanent.     RFC9110, Section 12.5.1: HTTP Semantics */
   2111 #define MHD_HTTP_HEADER_ACCEPT       "Accept"
   2112 /* Deprecated.    RFC9110, Section 12.5.2: HTTP Semantics */
   2113 #define MHD_HTTP_HEADER_ACCEPT_CHARSET "Accept-Charset"
   2114 /* Permanent.     RFC9110, Section 12.5.3: HTTP Semantics */
   2115 #define MHD_HTTP_HEADER_ACCEPT_ENCODING "Accept-Encoding"
   2116 /* Permanent.     RFC9110, Section 12.5.4: HTTP Semantics */
   2117 #define MHD_HTTP_HEADER_ACCEPT_LANGUAGE "Accept-Language"
   2118 /* Permanent.     RFC9110, Section 14.3: HTTP Semantics */
   2119 #define MHD_HTTP_HEADER_ACCEPT_RANGES "Accept-Ranges"
   2120 /* Permanent.     RFC9111, Section 5.1: HTTP Caching */
   2121 #define MHD_HTTP_HEADER_AGE          "Age"
   2122 /* Permanent.     RFC9110, Section 10.2.1: HTTP Semantics */
   2123 #define MHD_HTTP_HEADER_ALLOW        "Allow"
   2124 /* Permanent.     RFC9110, Section 11.6.3: HTTP Semantics */
   2125 #define MHD_HTTP_HEADER_AUTHENTICATION_INFO "Authentication-Info"
   2126 /* Permanent.     RFC9110, Section 11.6.2: HTTP Semantics */
   2127 #define MHD_HTTP_HEADER_AUTHORIZATION "Authorization"
   2128 /* Permanent.     RFC9111, Section 5.2 */
   2129 #define MHD_HTTP_HEADER_CACHE_CONTROL "Cache-Control"
   2130 /* Permanent.     RFC9112, Section 9.6: HTTP/1.1 */
   2131 #define MHD_HTTP_HEADER_CLOSE        "Close"
   2132 /* Permanent.     RFC9110, Section 7.6.1: HTTP Semantics */
   2133 #define MHD_HTTP_HEADER_CONNECTION   "Connection"
   2134 /* Permanent.     RFC9110, Section 8.4: HTTP Semantics */
   2135 #define MHD_HTTP_HEADER_CONTENT_ENCODING "Content-Encoding"
   2136 /* Permanent.     RFC9110, Section 8.5: HTTP Semantics */
   2137 #define MHD_HTTP_HEADER_CONTENT_LANGUAGE "Content-Language"
   2138 /* Permanent.     RFC9110, Section 8.6: HTTP Semantics */
   2139 #define MHD_HTTP_HEADER_CONTENT_LENGTH "Content-Length"
   2140 /* Permanent.     RFC9110, Section 8.7: HTTP Semantics */
   2141 #define MHD_HTTP_HEADER_CONTENT_LOCATION "Content-Location"
   2142 /* Permanent.     RFC9110, Section 14.4: HTTP Semantics */
   2143 #define MHD_HTTP_HEADER_CONTENT_RANGE "Content-Range"
   2144 /* Permanent.     RFC9110, Section 8.3: HTTP Semantics */
   2145 #define MHD_HTTP_HEADER_CONTENT_TYPE "Content-Type"
   2146 /* Permanent.     RFC9110, Section 6.6.1: HTTP Semantics */
   2147 #define MHD_HTTP_HEADER_DATE         "Date"
   2148 /* Permanent.     RFC9110, Section 8.8.3: HTTP Semantics */
   2149 #define MHD_HTTP_HEADER_ETAG         "ETag"
   2150 /* Permanent.     RFC9110, Section 10.1.1: HTTP Semantics */
   2151 #define MHD_HTTP_HEADER_EXPECT       "Expect"
   2152 /* Permanent.     RFC9111, Section 5.3: HTTP Caching */
   2153 #define MHD_HTTP_HEADER_EXPIRES      "Expires"
   2154 /* Permanent.     RFC9110, Section 10.1.2: HTTP Semantics */
   2155 #define MHD_HTTP_HEADER_FROM         "From"
   2156 /* Permanent.     RFC9110, Section 7.2: HTTP Semantics */
   2157 #define MHD_HTTP_HEADER_HOST         "Host"
   2158 /* Permanent.     RFC9110, Section 13.1.1: HTTP Semantics */
   2159 #define MHD_HTTP_HEADER_IF_MATCH     "If-Match"
   2160 /* Permanent.     RFC9110, Section 13.1.3: HTTP Semantics */
   2161 #define MHD_HTTP_HEADER_IF_MODIFIED_SINCE "If-Modified-Since"
   2162 /* Permanent.     RFC9110, Section 13.1.2: HTTP Semantics */
   2163 #define MHD_HTTP_HEADER_IF_NONE_MATCH "If-None-Match"
   2164 /* Permanent.     RFC9110, Section 13.1.5: HTTP Semantics */
   2165 #define MHD_HTTP_HEADER_IF_RANGE     "If-Range"
   2166 /* Permanent.     RFC9110, Section 13.1.4: HTTP Semantics */
   2167 #define MHD_HTTP_HEADER_IF_UNMODIFIED_SINCE "If-Unmodified-Since"
   2168 /* Permanent.     RFC9110, Section 8.8.2: HTTP Semantics */
   2169 #define MHD_HTTP_HEADER_LAST_MODIFIED "Last-Modified"
   2170 /* Permanent.     RFC9110, Section 10.2.2: HTTP Semantics */
   2171 #define MHD_HTTP_HEADER_LOCATION     "Location"
   2172 /* Permanent.     RFC9110, Section 7.6.2: HTTP Semantics */
   2173 #define MHD_HTTP_HEADER_MAX_FORWARDS "Max-Forwards"
   2174 /* Permanent.     RFC9112, Appendix B.1: HTTP/1.1 */
   2175 #define MHD_HTTP_HEADER_MIME_VERSION "MIME-Version"
   2176 /* Deprecated.    RFC9111, Section 5.4: HTTP Caching */
   2177 #define MHD_HTTP_HEADER_PRAGMA       "Pragma"
   2178 /* Permanent.     RFC9110, Section 11.7.1: HTTP Semantics */
   2179 #define MHD_HTTP_HEADER_PROXY_AUTHENTICATE "Proxy-Authenticate"
   2180 /* Permanent.     RFC9110, Section 11.7.3: HTTP Semantics */
   2181 #define MHD_HTTP_HEADER_PROXY_AUTHENTICATION_INFO "Proxy-Authentication-Info"
   2182 /* Permanent.     RFC9110, Section 11.7.2: HTTP Semantics */
   2183 #define MHD_HTTP_HEADER_PROXY_AUTHORIZATION "Proxy-Authorization"
   2184 /* Permanent.     RFC9110, Section 14.2: HTTP Semantics */
   2185 #define MHD_HTTP_HEADER_RANGE        "Range"
   2186 /* Permanent.     RFC9110, Section 10.1.3: HTTP Semantics */
   2187 #define MHD_HTTP_HEADER_REFERER      "Referer"
   2188 /* Permanent.     RFC9110, Section 10.2.3: HTTP Semantics */
   2189 #define MHD_HTTP_HEADER_RETRY_AFTER  "Retry-After"
   2190 /* Permanent.     RFC9110, Section 10.2.4: HTTP Semantics */
   2191 #define MHD_HTTP_HEADER_SERVER       "Server"
   2192 /* Permanent.     RFC9110, Section 10.1.4: HTTP Semantics */
   2193 #define MHD_HTTP_HEADER_TE           "TE"
   2194 /* Permanent.     RFC9110, Section 6.6.2: HTTP Semantics */
   2195 #define MHD_HTTP_HEADER_TRAILER      "Trailer"
   2196 /* Permanent.     RFC9112, Section 6.1: HTTP Semantics */
   2197 #define MHD_HTTP_HEADER_TRANSFER_ENCODING "Transfer-Encoding"
   2198 /* Permanent.     RFC9110, Section 7.8: HTTP Semantics */
   2199 #define MHD_HTTP_HEADER_UPGRADE      "Upgrade"
   2200 /* Permanent.     RFC9110, Section 10.1.5: HTTP Semantics */
   2201 #define MHD_HTTP_HEADER_USER_AGENT   "User-Agent"
   2202 /* Permanent.     RFC9110, Section 12.5.5: HTTP Semantics */
   2203 #define MHD_HTTP_HEADER_VARY         "Vary"
   2204 /* Permanent.     RFC9110, Section 7.6.3: HTTP Semantics */
   2205 #define MHD_HTTP_HEADER_VIA          "Via"
   2206 /* Permanent.     RFC9110, Section 11.6.1: HTTP Semantics */
   2207 #define MHD_HTTP_HEADER_WWW_AUTHENTICATE "WWW-Authenticate"
   2208 /* Permanent.     RFC9110, Section 12.5.5: HTTP Semantics */
   2209 #define MHD_HTTP_HEADER_ASTERISK     "*"
   2210 
   2211 /* Additional HTTP headers. */
   2212 /* Permanent.     RFC 3229: Delta encoding in HTTP */
   2213 #define MHD_HTTP_HEADER_A_IM         "A-IM"
   2214 /* Permanent.     RFC 2324: Hyper Text Coffee Pot Control Protocol (HTCPCP/1.0) */
   2215 #define MHD_HTTP_HEADER_ACCEPT_ADDITIONS "Accept-Additions"
   2216 /* Permanent.     RFC 8942, Section 3.1: HTTP Client Hints */
   2217 #define MHD_HTTP_HEADER_ACCEPT_CH    "Accept-CH"
   2218 /* Permanent.     RFC 7089: HTTP Framework for Time-Based Access to Resource States -- Memento */
   2219 #define MHD_HTTP_HEADER_ACCEPT_DATETIME "Accept-Datetime"
   2220 /* Permanent.     RFC 2295: Transparent Content Negotiation in HTTP */
   2221 #define MHD_HTTP_HEADER_ACCEPT_FEATURES "Accept-Features"
   2222 /* Permanent.     RFC 5789: PATCH Method for HTTP */
   2223 #define MHD_HTTP_HEADER_ACCEPT_PATCH "Accept-Patch"
   2224 /* Permanent.     Linked Data Platform 1.0 */
   2225 #define MHD_HTTP_HEADER_ACCEPT_POST  "Accept-Post"
   2226 /* Permanent.     RFC-ietf-httpbis-message-signatures-19, Section 5.1: HTTP Message Signatures */
   2227 #define MHD_HTTP_HEADER_ACCEPT_SIGNATURE "Accept-Signature"
   2228 /* Permanent.     Fetch */
   2229 #define MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS \
   2230         "Access-Control-Allow-Credentials"
   2231 /* Permanent.     Fetch */
   2232 #define MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_HEADERS \
   2233         "Access-Control-Allow-Headers"
   2234 /* Permanent.     Fetch */
   2235 #define MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_METHODS \
   2236         "Access-Control-Allow-Methods"
   2237 /* Permanent.     Fetch */
   2238 #define MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN \
   2239         "Access-Control-Allow-Origin"
   2240 /* Permanent.     Fetch */
   2241 #define MHD_HTTP_HEADER_ACCESS_CONTROL_EXPOSE_HEADERS \
   2242         "Access-Control-Expose-Headers"
   2243 /* Permanent.     Fetch */
   2244 #define MHD_HTTP_HEADER_ACCESS_CONTROL_MAX_AGE "Access-Control-Max-Age"
   2245 /* Permanent.     Fetch */
   2246 #define MHD_HTTP_HEADER_ACCESS_CONTROL_REQUEST_HEADERS \
   2247         "Access-Control-Request-Headers"
   2248 /* Permanent.     Fetch */
   2249 #define MHD_HTTP_HEADER_ACCESS_CONTROL_REQUEST_METHOD \
   2250         "Access-Control-Request-Method"
   2251 /* Permanent.     RFC 7639, Section 2: The ALPN HTTP Header Field */
   2252 #define MHD_HTTP_HEADER_ALPN         "ALPN"
   2253 /* Permanent.     RFC 7838: HTTP Alternative Services */
   2254 #define MHD_HTTP_HEADER_ALT_SVC      "Alt-Svc"
   2255 /* Permanent.     RFC 7838: HTTP Alternative Services */
   2256 #define MHD_HTTP_HEADER_ALT_USED     "Alt-Used"
   2257 /* Permanent.     RFC 2295: Transparent Content Negotiation in HTTP */
   2258 #define MHD_HTTP_HEADER_ALTERNATES   "Alternates"
   2259 /* Permanent.     RFC 4437: Web Distributed Authoring and Versioning (WebDAV) Redirect Reference Resources */
   2260 #define MHD_HTTP_HEADER_APPLY_TO_REDIRECT_REF "Apply-To-Redirect-Ref"
   2261 /* Permanent.     RFC 8053, Section 4: HTTP Authentication Extensions for Interactive Clients */
   2262 #define MHD_HTTP_HEADER_AUTHENTICATION_CONTROL "Authentication-Control"
   2263 /* Permanent.     RFC9211: The Cache-Status HTTP Response Header Field */
   2264 #define MHD_HTTP_HEADER_CACHE_STATUS "Cache-Status"
   2265 /* Permanent.     RFC 8607, Section 5.1: Calendaring Extensions to WebDAV (CalDAV): Managed Attachments */
   2266 #define MHD_HTTP_HEADER_CAL_MANAGED_ID "Cal-Managed-ID"
   2267 /* Permanent.     RFC 7809, Section 7.1: Calendaring Extensions to WebDAV (CalDAV): Time Zones by Reference */
   2268 #define MHD_HTTP_HEADER_CALDAV_TIMEZONES "CalDAV-Timezones"
   2269 /* Permanent.     RFC9297 */
   2270 #define MHD_HTTP_HEADER_CAPSULE_PROTOCOL "Capsule-Protocol"
   2271 /* Permanent.     RFC9213: Targeted HTTP Cache Control */
   2272 #define MHD_HTTP_HEADER_CDN_CACHE_CONTROL "CDN-Cache-Control"
   2273 /* Permanent.     RFC 8586: Loop Detection in Content Delivery Networks (CDNs) */
   2274 #define MHD_HTTP_HEADER_CDN_LOOP     "CDN-Loop"
   2275 /* Permanent.     RFC 8739, Section 3.3: Support for Short-Term, Automatically Renewed (STAR) Certificates in the Automated Certificate Management Environment (ACME) */
   2276 #define MHD_HTTP_HEADER_CERT_NOT_AFTER "Cert-Not-After"
   2277 /* Permanent.     RFC 8739, Section 3.3: Support for Short-Term, Automatically Renewed (STAR) Certificates in the Automated Certificate Management Environment (ACME) */
   2278 #define MHD_HTTP_HEADER_CERT_NOT_BEFORE "Cert-Not-Before"
   2279 /* Permanent.     Clear Site Data */
   2280 #define MHD_HTTP_HEADER_CLEAR_SITE_DATA "Clear-Site-Data"
   2281 /* Permanent.     RFC9440, Section 2: Client-Cert HTTP Header Field */
   2282 #define MHD_HTTP_HEADER_CLIENT_CERT  "Client-Cert"
   2283 /* Permanent.     RFC9440, Section 2: Client-Cert HTTP Header Field */
   2284 #define MHD_HTTP_HEADER_CLIENT_CERT_CHAIN "Client-Cert-Chain"
   2285 /* Permanent.     RFC-ietf-httpbis-digest-headers-13, Section 2: Digest Fields */
   2286 #define MHD_HTTP_HEADER_CONTENT_DIGEST "Content-Digest"
   2287 /* Permanent.     RFC 6266: Use of the Content-Disposition Header Field in the Hypertext Transfer Protocol (HTTP) */
   2288 #define MHD_HTTP_HEADER_CONTENT_DISPOSITION "Content-Disposition"
   2289 /* Permanent.     The HTTP Distribution and Replication Protocol */
   2290 #define MHD_HTTP_HEADER_CONTENT_ID   "Content-ID"
   2291 /* Permanent.     Content Security Policy Level 3 */
   2292 #define MHD_HTTP_HEADER_CONTENT_SECURITY_POLICY "Content-Security-Policy"
   2293 /* Permanent.     Content Security Policy Level 3 */
   2294 #define MHD_HTTP_HEADER_CONTENT_SECURITY_POLICY_REPORT_ONLY \
   2295         "Content-Security-Policy-Report-Only"
   2296 /* Permanent.     RFC 6265: HTTP State Management Mechanism */
   2297 #define MHD_HTTP_HEADER_COOKIE       "Cookie"
   2298 /* Permanent.     HTML */
   2299 #define MHD_HTTP_HEADER_CROSS_ORIGIN_EMBEDDER_POLICY \
   2300         "Cross-Origin-Embedder-Policy"
   2301 /* Permanent.     HTML */
   2302 #define MHD_HTTP_HEADER_CROSS_ORIGIN_EMBEDDER_POLICY_REPORT_ONLY \
   2303         "Cross-Origin-Embedder-Policy-Report-Only"
   2304 /* Permanent.     HTML */
   2305 #define MHD_HTTP_HEADER_CROSS_ORIGIN_OPENER_POLICY "Cross-Origin-Opener-Policy"
   2306 /* Permanent.     HTML */
   2307 #define MHD_HTTP_HEADER_CROSS_ORIGIN_OPENER_POLICY_REPORT_ONLY \
   2308         "Cross-Origin-Opener-Policy-Report-Only"
   2309 /* Permanent.     Fetch */
   2310 #define MHD_HTTP_HEADER_CROSS_ORIGIN_RESOURCE_POLICY \
   2311         "Cross-Origin-Resource-Policy"
   2312 /* Permanent.     RFC 5323: Web Distributed Authoring and Versioning (WebDAV) SEARCH */
   2313 #define MHD_HTTP_HEADER_DASL         "DASL"
   2314 /* Permanent.     RFC 4918: HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV) */
   2315 #define MHD_HTTP_HEADER_DAV          "DAV"
   2316 /* Permanent.     RFC 3229: Delta encoding in HTTP */
   2317 #define MHD_HTTP_HEADER_DELTA_BASE   "Delta-Base"
   2318 /* Permanent.     RFC 4918: HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV) */
   2319 #define MHD_HTTP_HEADER_DEPTH        "Depth"
   2320 /* Permanent.     RFC 4918: HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV) */
   2321 #define MHD_HTTP_HEADER_DESTINATION  "Destination"
   2322 /* Permanent.     The HTTP Distribution and Replication Protocol */
   2323 #define MHD_HTTP_HEADER_DIFFERENTIAL_ID "Differential-ID"
   2324 /* Permanent.     RFC9449: OAuth 2.0 Demonstrating Proof of Possession (DPoP) */
   2325 #define MHD_HTTP_HEADER_DPOP         "DPoP"
   2326 /* Permanent.     RFC9449: OAuth 2.0 Demonstrating Proof of Possession (DPoP) */
   2327 #define MHD_HTTP_HEADER_DPOP_NONCE   "DPoP-Nonce"
   2328 /* Permanent.     RFC 8470: Using Early Data in HTTP */
   2329 #define MHD_HTTP_HEADER_EARLY_DATA   "Early-Data"
   2330 /* Permanent.     RFC9163: Expect-CT Extension for HTTP */
   2331 #define MHD_HTTP_HEADER_EXPECT_CT    "Expect-CT"
   2332 /* Permanent.     RFC 7239: Forwarded HTTP Extension */
   2333 #define MHD_HTTP_HEADER_FORWARDED    "Forwarded"
   2334 /* Permanent.     RFC 7486, Section 6.1.1: HTTP Origin-Bound Authentication (HOBA) */
   2335 #define MHD_HTTP_HEADER_HOBAREG      "Hobareg"
   2336 /* Permanent.     RFC 4918: HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV) */
   2337 #define MHD_HTTP_HEADER_IF           "If"
   2338 /* Permanent.      RFC 6338: Scheduling Extensions to CalDAV */
   2339 #define MHD_HTTP_HEADER_IF_SCHEDULE_TAG_MATCH "If-Schedule-Tag-Match"
   2340 /* Permanent.     RFC 3229: Delta encoding in HTTP */
   2341 #define MHD_HTTP_HEADER_IM           "IM"
   2342 /* Permanent.     RFC 8473: Token Binding over HTTP */
   2343 #define MHD_HTTP_HEADER_INCLUDE_REFERRED_TOKEN_BINDING_ID \
   2344         "Include-Referred-Token-Binding-ID"
   2345 /* Permanent.     RFC 2068: Hypertext Transfer Protocol -- HTTP/1.1 */
   2346 #define MHD_HTTP_HEADER_KEEP_ALIVE   "Keep-Alive"
   2347 /* Permanent.     RFC 3253: Versioning Extensions to WebDAV: (Web Distributed Authoring and Versioning) */
   2348 #define MHD_HTTP_HEADER_LABEL        "Label"
   2349 /* Permanent.     HTML */
   2350 #define MHD_HTTP_HEADER_LAST_EVENT_ID "Last-Event-ID"
   2351 /* Permanent.     RFC 8288: Web Linking */
   2352 #define MHD_HTTP_HEADER_LINK         "Link"
   2353 /* Permanent.     RFC 4918: HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV) */
   2354 #define MHD_HTTP_HEADER_LOCK_TOKEN   "Lock-Token"
   2355 /* Permanent.     RFC 7089: HTTP Framework for Time-Based Access to Resource States -- Memento */
   2356 #define MHD_HTTP_HEADER_MEMENTO_DATETIME "Memento-Datetime"
   2357 /* Permanent.     RFC 2227: Simple Hit-Metering and Usage-Limiting for HTTP */
   2358 #define MHD_HTTP_HEADER_METER        "Meter"
   2359 /* Permanent.     RFC 2295: Transparent Content Negotiation in HTTP */
   2360 #define MHD_HTTP_HEADER_NEGOTIATE    "Negotiate"
   2361 /* Permanent.     Network Error Logging */
   2362 #define MHD_HTTP_HEADER_NEL          "NEL"
   2363 /* Permanent.     OData Version 4.01 Part 1: Protocol; OASIS; Chet_Ensign */
   2364 #define MHD_HTTP_HEADER_ODATA_ENTITYID "OData-EntityId"
   2365 /* Permanent.     OData Version 4.01 Part 1: Protocol; OASIS; Chet_Ensign */
   2366 #define MHD_HTTP_HEADER_ODATA_ISOLATION "OData-Isolation"
   2367 /* Permanent.     OData Version 4.01 Part 1: Protocol; OASIS; Chet_Ensign */
   2368 #define MHD_HTTP_HEADER_ODATA_MAXVERSION "OData-MaxVersion"
   2369 /* Permanent.     OData Version 4.01 Part 1: Protocol; OASIS; Chet_Ensign */
   2370 #define MHD_HTTP_HEADER_ODATA_VERSION "OData-Version"
   2371 /* Permanent.     RFC 8053, Section 3: HTTP Authentication Extensions for Interactive Clients */
   2372 #define MHD_HTTP_HEADER_OPTIONAL_WWW_AUTHENTICATE "Optional-WWW-Authenticate"
   2373 /* Permanent.     RFC 3648: Web Distributed Authoring and Versioning (WebDAV) Ordered Collections Protocol */
   2374 #define MHD_HTTP_HEADER_ORDERING_TYPE "Ordering-Type"
   2375 /* Permanent.     RFC 6454: The Web Origin Concept */
   2376 #define MHD_HTTP_HEADER_ORIGIN       "Origin"
   2377 /* Permanent.     HTML */
   2378 #define MHD_HTTP_HEADER_ORIGIN_AGENT_CLUSTER "Origin-Agent-Cluster"
   2379 /* Permanent.     RFC 8613, Section 11.1: Object Security for Constrained RESTful Environments (OSCORE) */
   2380 #define MHD_HTTP_HEADER_OSCORE       "OSCORE"
   2381 /* Permanent.     OASIS Project Specification 01; OASIS; Chet_Ensign */
   2382 #define MHD_HTTP_HEADER_OSLC_CORE_VERSION "OSLC-Core-Version"
   2383 /* Permanent.     RFC 4918: HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV) */
   2384 #define MHD_HTTP_HEADER_OVERWRITE    "Overwrite"
   2385 /* Permanent.     HTML */
   2386 #define MHD_HTTP_HEADER_PING_FROM    "Ping-From"
   2387 /* Permanent.     HTML */
   2388 #define MHD_HTTP_HEADER_PING_TO      "Ping-To"
   2389 /* Permanent.     RFC 3648: Web Distributed Authoring and Versioning (WebDAV) Ordered Collections Protocol */
   2390 #define MHD_HTTP_HEADER_POSITION     "Position"
   2391 /* Permanent.     RFC 7240: Prefer Header for HTTP */
   2392 #define MHD_HTTP_HEADER_PREFER       "Prefer"
   2393 /* Permanent.     RFC 7240: Prefer Header for HTTP */
   2394 #define MHD_HTTP_HEADER_PREFERENCE_APPLIED "Preference-Applied"
   2395 /* Permanent.     RFC9218: Extensible Prioritization Scheme for HTTP */
   2396 #define MHD_HTTP_HEADER_PRIORITY     "Priority"
   2397 /* Permanent.     RFC9209: The Proxy-Status HTTP Response Header Field */
   2398 #define MHD_HTTP_HEADER_PROXY_STATUS "Proxy-Status"
   2399 /* Permanent.     RFC 7469: Public Key Pinning Extension for HTTP */
   2400 #define MHD_HTTP_HEADER_PUBLIC_KEY_PINS "Public-Key-Pins"
   2401 /* Permanent.     RFC 7469: Public Key Pinning Extension for HTTP */
   2402 #define MHD_HTTP_HEADER_PUBLIC_KEY_PINS_REPORT_ONLY \
   2403         "Public-Key-Pins-Report-Only"
   2404 /* Permanent.     RFC 4437: Web Distributed Authoring and Versioning (WebDAV) Redirect Reference Resources */
   2405 #define MHD_HTTP_HEADER_REDIRECT_REF "Redirect-Ref"
   2406 /* Permanent.     HTML */
   2407 #define MHD_HTTP_HEADER_REFRESH      "Refresh"
   2408 /* Permanent.     RFC 8555, Section 6.5.1: Automatic Certificate Management Environment (ACME) */
   2409 #define MHD_HTTP_HEADER_REPLAY_NONCE "Replay-Nonce"
   2410 /* Permanent.     RFC-ietf-httpbis-digest-headers-13, Section 3: Digest Fields */
   2411 #define MHD_HTTP_HEADER_REPR_DIGEST  "Repr-Digest"
   2412 /* Permanent.     RFC 6638: Scheduling Extensions to CalDAV */
   2413 #define MHD_HTTP_HEADER_SCHEDULE_REPLY "Schedule-Reply"
   2414 /* Permanent.     RFC 6338: Scheduling Extensions to CalDAV */
   2415 #define MHD_HTTP_HEADER_SCHEDULE_TAG "Schedule-Tag"
   2416 /* Permanent.     Fetch */
   2417 #define MHD_HTTP_HEADER_SEC_PURPOSE  "Sec-Purpose"
   2418 /* Permanent.     RFC 8473: Token Binding over HTTP */
   2419 #define MHD_HTTP_HEADER_SEC_TOKEN_BINDING "Sec-Token-Binding"
   2420 /* Permanent.     RFC 6455: The WebSocket Protocol */
   2421 #define MHD_HTTP_HEADER_SEC_WEBSOCKET_ACCEPT "Sec-WebSocket-Accept"
   2422 /* Permanent.     RFC 6455: The WebSocket Protocol */
   2423 #define MHD_HTTP_HEADER_SEC_WEBSOCKET_EXTENSIONS "Sec-WebSocket-Extensions"
   2424 /* Permanent.     RFC 6455: The WebSocket Protocol */
   2425 #define MHD_HTTP_HEADER_SEC_WEBSOCKET_KEY "Sec-WebSocket-Key"
   2426 /* Permanent.     RFC 6455: The WebSocket Protocol */
   2427 #define MHD_HTTP_HEADER_SEC_WEBSOCKET_PROTOCOL "Sec-WebSocket-Protocol"
   2428 /* Permanent.     RFC 6455: The WebSocket Protocol */
   2429 #define MHD_HTTP_HEADER_SEC_WEBSOCKET_VERSION "Sec-WebSocket-Version"
   2430 /* Permanent.     Server Timing */
   2431 #define MHD_HTTP_HEADER_SERVER_TIMING "Server-Timing"
   2432 /* Permanent.     RFC 6265: HTTP State Management Mechanism */
   2433 #define MHD_HTTP_HEADER_SET_COOKIE   "Set-Cookie"
   2434 /* Permanent.     RFC-ietf-httpbis-message-signatures-19, Section 4.2: HTTP Message Signatures */
   2435 #define MHD_HTTP_HEADER_SIGNATURE    "Signature"
   2436 /* Permanent.     RFC-ietf-httpbis-message-signatures-19, Section 4.1: HTTP Message Signatures */
   2437 #define MHD_HTTP_HEADER_SIGNATURE_INPUT "Signature-Input"
   2438 /* Permanent.     RFC 5023: The Atom Publishing Protocol */
   2439 #define MHD_HTTP_HEADER_SLUG         "SLUG"
   2440 /* Permanent.     Simple Object Access Protocol (SOAP) 1.1 */
   2441 #define MHD_HTTP_HEADER_SOAPACTION   "SoapAction"
   2442 /* Permanent.     RFC 2518: HTTP Extensions for Distributed Authoring -- WEBDAV */
   2443 #define MHD_HTTP_HEADER_STATUS_URI   "Status-URI"
   2444 /* Permanent.     RFC 6797: HTTP Strict Transport Security (HSTS) */
   2445 #define MHD_HTTP_HEADER_STRICT_TRANSPORT_SECURITY "Strict-Transport-Security"
   2446 /* Permanent.     RFC 8594: The Sunset HTTP Header Field */
   2447 #define MHD_HTTP_HEADER_SUNSET       "Sunset"
   2448 /* Permanent.     Edge Architecture Specification */
   2449 #define MHD_HTTP_HEADER_SURROGATE_CAPABILITY "Surrogate-Capability"
   2450 /* Permanent.     Edge Architecture Specification */
   2451 #define MHD_HTTP_HEADER_SURROGATE_CONTROL "Surrogate-Control"
   2452 /* Permanent.     RFC 2295: Transparent Content Negotiation in HTTP */
   2453 #define MHD_HTTP_HEADER_TCN          "TCN"
   2454 /* Permanent.     RFC 4918: HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV) */
   2455 #define MHD_HTTP_HEADER_TIMEOUT      "Timeout"
   2456 /* Permanent.     RFC 8030, Section 5.4: Generic Event Delivery Using HTTP Push */
   2457 #define MHD_HTTP_HEADER_TOPIC        "Topic"
   2458 /* Permanent.     Trace Context */
   2459 #define MHD_HTTP_HEADER_TRACEPARENT  "Traceparent"
   2460 /* Permanent.     Trace Context */
   2461 #define MHD_HTTP_HEADER_TRACESTATE   "Tracestate"
   2462 /* Permanent.     RFC 8030, Section 5.2: Generic Event Delivery Using HTTP Push */
   2463 #define MHD_HTTP_HEADER_TTL          "TTL"
   2464 /* Permanent.     RFC 8030, Section 5.3: Generic Event Delivery Using HTTP Push */
   2465 #define MHD_HTTP_HEADER_URGENCY      "Urgency"
   2466 /* Permanent.     RFC 2295: Transparent Content Negotiation in HTTP */
   2467 #define MHD_HTTP_HEADER_VARIANT_VARY "Variant-Vary"
   2468 /* Permanent.     RFC-ietf-httpbis-digest-headers-13, Section 4: Digest Fields */
   2469 #define MHD_HTTP_HEADER_WANT_CONTENT_DIGEST "Want-Content-Digest"
   2470 /* Permanent.     RFC-ietf-httpbis-digest-headers-13, Section 4: Digest Fields */
   2471 #define MHD_HTTP_HEADER_WANT_REPR_DIGEST "Want-Repr-Digest"
   2472 /* Permanent.     Fetch */
   2473 #define MHD_HTTP_HEADER_X_CONTENT_TYPE_OPTIONS "X-Content-Type-Options"
   2474 /* Permanent.     HTML */
   2475 #define MHD_HTTP_HEADER_X_FRAME_OPTIONS "X-Frame-Options"
   2476 /* Provisional.   AMP-Cache-Transform HTTP request header */
   2477 #define MHD_HTTP_HEADER_AMP_CACHE_TRANSFORM "AMP-Cache-Transform"
   2478 /* Provisional.   OSLC Configuration Management Version 1.0. Part 3: Configuration Specification */
   2479 #define MHD_HTTP_HEADER_CONFIGURATION_CONTEXT "Configuration-Context"
   2480 /* Provisional.   RFC 6017: Electronic Data Interchange - Internet Integration (EDIINT) Features Header Field */
   2481 #define MHD_HTTP_HEADER_EDIINT_FEATURES "EDIINT-Features"
   2482 /* Provisional.   OData Version 4.01 Part 1: Protocol; OASIS; Chet_Ensign */
   2483 #define MHD_HTTP_HEADER_ISOLATION    "Isolation"
   2484 /* Provisional.   Permissions Policy */
   2485 #define MHD_HTTP_HEADER_PERMISSIONS_POLICY "Permissions-Policy"
   2486 /* Provisional.   Repeatable Requests Version 1.0; OASIS; Chet_Ensign */
   2487 #define MHD_HTTP_HEADER_REPEATABILITY_CLIENT_ID "Repeatability-Client-ID"
   2488 /* Provisional.   Repeatable Requests Version 1.0; OASIS; Chet_Ensign */
   2489 #define MHD_HTTP_HEADER_REPEATABILITY_FIRST_SENT "Repeatability-First-Sent"
   2490 /* Provisional.   Repeatable Requests Version 1.0; OASIS; Chet_Ensign */
   2491 #define MHD_HTTP_HEADER_REPEATABILITY_REQUEST_ID "Repeatability-Request-ID"
   2492 /* Provisional.   Repeatable Requests Version 1.0; OASIS; Chet_Ensign */
   2493 #define MHD_HTTP_HEADER_REPEATABILITY_RESULT "Repeatability-Result"
   2494 /* Provisional.   Reporting API */
   2495 #define MHD_HTTP_HEADER_REPORTING_ENDPOINTS "Reporting-Endpoints"
   2496 /* Provisional.   Global Privacy Control (GPC) */
   2497 #define MHD_HTTP_HEADER_SEC_GPC      "Sec-GPC"
   2498 /* Provisional.   Resource Timing Level 1 */
   2499 #define MHD_HTTP_HEADER_TIMING_ALLOW_ORIGIN "Timing-Allow-Origin"
   2500 /* Deprecated.    PEP - an Extension Mechanism for HTTP; status-change-http-experiments-to-historic */
   2501 #define MHD_HTTP_HEADER_C_PEP_INFO   "C-PEP-Info"
   2502 /* Deprecated.    White Paper: Joint Electronic Payment Initiative */
   2503 #define MHD_HTTP_HEADER_PROTOCOL_INFO "Protocol-Info"
   2504 /* Deprecated.    White Paper: Joint Electronic Payment Initiative */
   2505 #define MHD_HTTP_HEADER_PROTOCOL_QUERY "Protocol-Query"
   2506 /* Obsoleted.     Access Control for Cross-site Requests */
   2507 #define MHD_HTTP_HEADER_ACCESS_CONTROL "Access-Control"
   2508 /* Obsoleted.     RFC 2774: An HTTP Extension Framework; status-change-http-experiments-to-historic */
   2509 #define MHD_HTTP_HEADER_C_EXT        "C-Ext"
   2510 /* Obsoleted.     RFC 2774: An HTTP Extension Framework; status-change-http-experiments-to-historic */
   2511 #define MHD_HTTP_HEADER_C_MAN        "C-Man"
   2512 /* Obsoleted.     RFC 2774: An HTTP Extension Framework; status-change-http-experiments-to-historic */
   2513 #define MHD_HTTP_HEADER_C_OPT        "C-Opt"
   2514 /* Obsoleted.     PEP - an Extension Mechanism for HTTP; status-change-http-experiments-to-historic */
   2515 #define MHD_HTTP_HEADER_C_PEP        "C-PEP"
   2516 /* Obsoleted.     RFC 2068: Hypertext Transfer Protocol -- HTTP/1.1; RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1 */
   2517 #define MHD_HTTP_HEADER_CONTENT_BASE "Content-Base"
   2518 /* 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 */
   2519 #define MHD_HTTP_HEADER_CONTENT_MD5  "Content-MD5"
   2520 /* Obsoleted.     HTML 4.01 Specification */
   2521 #define MHD_HTTP_HEADER_CONTENT_SCRIPT_TYPE "Content-Script-Type"
   2522 /* Obsoleted.     HTML 4.01 Specification */
   2523 #define MHD_HTTP_HEADER_CONTENT_STYLE_TYPE "Content-Style-Type"
   2524 /* Obsoleted.     RFC 2068: Hypertext Transfer Protocol -- HTTP/1.1 */
   2525 #define MHD_HTTP_HEADER_CONTENT_VERSION "Content-Version"
   2526 /* Obsoleted.     RFC 2965: HTTP State Management Mechanism; RFC 6265: HTTP State Management Mechanism */
   2527 #define MHD_HTTP_HEADER_COOKIE2      "Cookie2"
   2528 /* Obsoleted.     HTML 4.01 Specification */
   2529 #define MHD_HTTP_HEADER_DEFAULT_STYLE "Default-Style"
   2530 /* Obsoleted.     RFC 2068: Hypertext Transfer Protocol -- HTTP/1.1 */
   2531 #define MHD_HTTP_HEADER_DERIVED_FROM "Derived-From"
   2532 /* Obsoleted.     RFC 3230: Instance Digests in HTTP; RFC-ietf-httpbis-digest-headers-13, Section 1.3: Digest Fields */
   2533 #define MHD_HTTP_HEADER_DIGEST       "Digest"
   2534 /* Obsoleted.     RFC 2774: An HTTP Extension Framework; status-change-http-experiments-to-historic */
   2535 #define MHD_HTTP_HEADER_EXT          "Ext"
   2536 /* Obsoleted.     Implementation of OPS Over HTTP */
   2537 #define MHD_HTTP_HEADER_GETPROFILE   "GetProfile"
   2538 /* Obsoleted.     RFC 7540, Section 3.2.1: Hypertext Transfer Protocol Version 2 (HTTP/2) */
   2539 #define MHD_HTTP_HEADER_HTTP2_SETTINGS "HTTP2-Settings"
   2540 /* Obsoleted.     RFC 2774: An HTTP Extension Framework; status-change-http-experiments-to-historic */
   2541 #define MHD_HTTP_HEADER_MAN          "Man"
   2542 /* Obsoleted.     Access Control for Cross-site Requests */
   2543 #define MHD_HTTP_HEADER_METHOD_CHECK "Method-Check"
   2544 /* Obsoleted.     Access Control for Cross-site Requests */
   2545 #define MHD_HTTP_HEADER_METHOD_CHECK_EXPIRES "Method-Check-Expires"
   2546 /* Obsoleted.     RFC 2774: An HTTP Extension Framework; status-change-http-experiments-to-historic */
   2547 #define MHD_HTTP_HEADER_OPT          "Opt"
   2548 /* Obsoleted.     The Platform for Privacy Preferences 1.0 (P3P1.0) Specification */
   2549 #define MHD_HTTP_HEADER_P3P          "P3P"
   2550 /* Obsoleted.     PEP - an Extension Mechanism for HTTP */
   2551 #define MHD_HTTP_HEADER_PEP          "PEP"
   2552 /* Obsoleted.     PEP - an Extension Mechanism for HTTP */
   2553 #define MHD_HTTP_HEADER_PEP_INFO     "Pep-Info"
   2554 /* Obsoleted.     PICS Label Distribution Label Syntax and Communication Protocols */
   2555 #define MHD_HTTP_HEADER_PICS_LABEL   "PICS-Label"
   2556 /* Obsoleted.     Implementation of OPS Over HTTP */
   2557 #define MHD_HTTP_HEADER_PROFILEOBJECT "ProfileObject"
   2558 /* Obsoleted.     PICS Label Distribution Label Syntax and Communication Protocols */
   2559 #define MHD_HTTP_HEADER_PROTOCOL     "Protocol"
   2560 /* Obsoleted.     PICS Label Distribution Label Syntax and Communication Protocols */
   2561 #define MHD_HTTP_HEADER_PROTOCOL_REQUEST "Protocol-Request"
   2562 /* Obsoleted.     Notification for Proxy Caches */
   2563 #define MHD_HTTP_HEADER_PROXY_FEATURES "Proxy-Features"
   2564 /* Obsoleted.     Notification for Proxy Caches */
   2565 #define MHD_HTTP_HEADER_PROXY_INSTRUCTION "Proxy-Instruction"
   2566 /* Obsoleted.     RFC 2068: Hypertext Transfer Protocol -- HTTP/1.1 */
   2567 #define MHD_HTTP_HEADER_PUBLIC       "Public"
   2568 /* Obsoleted.     Access Control for Cross-site Requests */
   2569 #define MHD_HTTP_HEADER_REFERER_ROOT "Referer-Root"
   2570 /* Obsoleted.     RFC 2310: The Safe Response Header Field; status-change-http-experiments-to-historic */
   2571 #define MHD_HTTP_HEADER_SAFE         "Safe"
   2572 /* Obsoleted.     RFC 2660: The Secure HyperText Transfer Protocol; status-change-http-experiments-to-historic */
   2573 #define MHD_HTTP_HEADER_SECURITY_SCHEME "Security-Scheme"
   2574 /* Obsoleted.     RFC 2965: HTTP State Management Mechanism; RFC 6265: HTTP State Management Mechanism */
   2575 #define MHD_HTTP_HEADER_SET_COOKIE2  "Set-Cookie2"
   2576 /* Obsoleted.     Implementation of OPS Over HTTP */
   2577 #define MHD_HTTP_HEADER_SETPROFILE   "SetProfile"
   2578 /* Obsoleted.     RFC 2068: Hypertext Transfer Protocol -- HTTP/1.1 */
   2579 #define MHD_HTTP_HEADER_URI          "URI"
   2580 /* Obsoleted.     RFC 3230: Instance Digests in HTTP; RFC-ietf-httpbis-digest-headers-13, Section 1.3: Digest Fields */
   2581 #define MHD_HTTP_HEADER_WANT_DIGEST  "Want-Digest"
   2582 /* Obsoleted.     RFC9111, Section 5.5: HTTP Caching */
   2583 #define MHD_HTTP_HEADER_WARNING      "Warning"
   2584 
   2585 /* Headers removed from the registry. Do not use! */
   2586 /* Obsoleted.     RFC4229 */
   2587 #define MHD_HTTP_HEADER_COMPLIANCE   "Compliance"
   2588 /* Obsoleted.     RFC4229 */
   2589 #define MHD_HTTP_HEADER_CONTENT_TRANSFER_ENCODING "Content-Transfer-Encoding"
   2590 /* Obsoleted.     RFC4229 */
   2591 #define MHD_HTTP_HEADER_COST         "Cost"
   2592 /* Obsoleted.     RFC4229 */
   2593 #define MHD_HTTP_HEADER_MESSAGE_ID   "Message-ID"
   2594 /* Obsoleted.     RFC4229 */
   2595 #define MHD_HTTP_HEADER_NON_COMPLIANCE "Non-Compliance"
   2596 /* Obsoleted.     RFC4229 */
   2597 #define MHD_HTTP_HEADER_OPTIONAL     "Optional"
   2598 /* Obsoleted.     RFC4229 */
   2599 #define MHD_HTTP_HEADER_RESOLUTION_HINT "Resolution-Hint"
   2600 /* Obsoleted.     RFC4229 */
   2601 #define MHD_HTTP_HEADER_RESOLVER_LOCATION "Resolver-Location"
   2602 /* Obsoleted.     RFC4229 */
   2603 #define MHD_HTTP_HEADER_SUBOK        "SubOK"
   2604 /* Obsoleted.     RFC4229 */
   2605 #define MHD_HTTP_HEADER_SUBST        "Subst"
   2606 /* Obsoleted.     RFC4229 */
   2607 #define MHD_HTTP_HEADER_TITLE        "Title"
   2608 /* Obsoleted.     RFC4229 */
   2609 #define MHD_HTTP_HEADER_UA_COLOR     "UA-Color"
   2610 /* Obsoleted.     RFC4229 */
   2611 #define MHD_HTTP_HEADER_UA_MEDIA     "UA-Media"
   2612 /* Obsoleted.     RFC4229 */
   2613 #define MHD_HTTP_HEADER_UA_PIXELS    "UA-Pixels"
   2614 /* Obsoleted.     RFC4229 */
   2615 #define MHD_HTTP_HEADER_UA_RESOLUTION "UA-Resolution"
   2616 /* Obsoleted.     RFC4229 */
   2617 #define MHD_HTTP_HEADER_UA_WINDOWPIXELS "UA-Windowpixels"
   2618 /* Obsoleted.     RFC4229 */
   2619 #define MHD_HTTP_HEADER_VERSION      "Version"
   2620 /* Obsoleted.     W3C Mobile Web Best Practices Working Group */
   2621 #define MHD_HTTP_HEADER_X_DEVICE_ACCEPT "X-Device-Accept"
   2622 /* Obsoleted.     W3C Mobile Web Best Practices Working Group */
   2623 #define MHD_HTTP_HEADER_X_DEVICE_ACCEPT_CHARSET "X-Device-Accept-Charset"
   2624 /* Obsoleted.     W3C Mobile Web Best Practices Working Group */
   2625 #define MHD_HTTP_HEADER_X_DEVICE_ACCEPT_ENCODING "X-Device-Accept-Encoding"
   2626 /* Obsoleted.     W3C Mobile Web Best Practices Working Group */
   2627 #define MHD_HTTP_HEADER_X_DEVICE_ACCEPT_LANGUAGE "X-Device-Accept-Language"
   2628 /* Obsoleted.     W3C Mobile Web Best Practices Working Group */
   2629 #define MHD_HTTP_HEADER_X_DEVICE_USER_AGENT "X-Device-User-Agent"
   2630 
   2631 
   2632 /**
   2633  * Predefined list of headers
   2634  * To be filled with HPACK static data
   2635  */
   2636 enum MHD_PredefinedHeader
   2637 {
   2638   MHD_PREDEF_ACCEPT_CHARSET = 15,
   2639   MHD_PREDEF_ACCEPT_LANGUAGE = 17
   2640 };
   2641 
   2642 
   2643 /** @} */ /* end of group headers */
   2644 
   2645 /**
   2646  * A client has requested the given url using the given method
   2647  * (#MHD_HTTP_METHOD_GET, #MHD_HTTP_METHOD_PUT,
   2648  * #MHD_HTTP_METHOD_DELETE, #MHD_HTTP_METHOD_POST, etc).
   2649  * If @a upload_size is not zero and response action is provided by this
   2650  * callback, then upload will be discarded and the stream (the connection for
   2651  * HTTP/1.1) will be closed after sending the response.
   2652  *
   2653  * @param cls argument given together with the function
   2654  *        pointer when the handler was registered with MHD
   2655  * @param request the request object
   2656  * @param path the requested uri (without arguments after "?")
   2657  * @param method the HTTP method used (#MHD_HTTP_METHOD_GET,
   2658  *        #MHD_HTTP_METHOD_PUT, etc.)
   2659  * @param upload_size the size of the message upload content payload,
   2660  *                    #MHD_SIZE_UNKNOWN for chunked uploads (if the
   2661  *                    final chunk has not been processed yet)
   2662  * @return action how to proceed, NULL
   2663  *         if the request must be aborted due to a serious
   2664  *         error while handling the request (implies closure
   2665  *         of underling data stream, for HTTP/1.1 it means
   2666  *         socket closure).
   2667  */
   2668 typedef const struct MHD_Action *
   2669 (MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_NONNULL_ (3)
   2670  *MHD_RequestCallback)(void *cls,
   2671                        struct MHD_Request *MHD_RESTRICT request,
   2672                        const struct MHD_String *MHD_RESTRICT path,
   2673                        enum MHD_HTTP_Method method,
   2674                        uint_fast64_t upload_size);
   2675 
   2676 
   2677 /**
   2678  * Create (but do not yet start) an MHD daemon.
   2679  * Usually, various options are set before
   2680  * starting the daemon with #MHD_daemon_start().
   2681  *
   2682  * @param req_cb the function to be called for incoming requests
   2683  * @param req_cb_cls the closure for @a cb
   2684  * @return the pointer to the new object on success,
   2685  *         NULL on error (like out-of-memory)
   2686  */
   2687 MHD_EXTERN_ struct MHD_Daemon *
   2688 MHD_daemon_create (MHD_RequestCallback req_cb,
   2689                    void *req_cb_cls)
   2690 MHD_FN_MUST_CHECK_RESULT_;
   2691 
   2692 
   2693 /**
   2694  * Start a webserver.
   2695  * This function:
   2696  * + checks the combination of set options,
   2697  * + initialises the TLS library (if TLS is requested),
   2698  * + creates the listen socket (if not provided and if allowed),
   2699  * + starts the daemon internal threads (if allowed)
   2700  *
   2701  * @param[in,out] daemon daemon to start; you can no longer set
   2702  *        options on this daemon after this call!
   2703  * @return #MHD_SC_OK on success
   2704  * @ingroup daemon
   2705  */
   2706 MHD_EXTERN_ enum MHD_StatusCode
   2707 MHD_daemon_start (struct MHD_Daemon *daemon)
   2708 MHD_FN_PAR_NONNULL_ (1) MHD_FN_MUST_CHECK_RESULT_;
   2709 
   2710 
   2711 /**
   2712  * Stop accepting connections from the listening socket.  Allows
   2713  * clients to continue processing, but stops accepting new
   2714  * connections.  Note that the caller is responsible for closing the
   2715  * returned socket; however, if MHD is run using threads (anything but
   2716  * external select mode), it must not be closed until AFTER
   2717  * #MHD_daemon_destroy() has been called (as it is theoretically possible
   2718  * that an existing thread is still using it).
   2719  *
   2720  * @param[in,out] daemon the daemon to stop accepting new connections for
   2721  * @return the old listen socket on success, #MHD_INVALID_SOCKET if
   2722  *         the daemon was already not listening anymore, or
   2723  *         was never started, or has no listen socket.
   2724  * @ingroup daemon
   2725  */
   2726 MHD_EXTERN_ MHD_Socket
   2727 MHD_daemon_quiesce (struct MHD_Daemon *daemon)
   2728 MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_INOUT_ (1);
   2729 
   2730 
   2731 /**
   2732  * Shutdown and destroy an HTTP daemon.
   2733  *
   2734  * @param[in] daemon daemon to stop
   2735  * @ingroup daemon
   2736  */
   2737 MHD_EXTERN_ void
   2738 MHD_daemon_destroy (struct MHD_Daemon *daemon)
   2739 MHD_FN_PAR_NONNULL_ALL_;
   2740 
   2741 /* ******************* ACME daemon control ************************ */
   2742 
   2743 /**
   2744  * @defgroup acme ACME protocol handling
   2745  */
   2746 
   2747 /**
   2748  * The path prefix of the resource used by the ACME HTTP-01 challenge.
   2749  *
   2750  * The complete path is this prefix immediately followed by the challenge
   2751  * token provided by the ACME server.  The resource is requested by
   2752  * plain HTTP (not HTTPS) on port 80 of the domain being validated. The
   2753  * path is case-sensitive and has to be matched exactly.
   2754  * See RFC 8555, section 8.3.
   2755  *
   2756  * @ingroup acme
   2757  */
   2758 #define MHD_ACME_HTTP_01_CHALLENGE_PATH_PREFIX \
   2759         "/.well-known/acme-challenge/"
   2760 
   2761 /**
   2762  * Add or replace special certificate for ALPN challenge for ACME.
   2763  *
   2764  * Takes effect for connections accepted after this function returns.
   2765  *
   2766  * Note: the fallback (@p domain is NULL) certificate can be removed only
   2767  * together with all other certificates.
   2768  *
   2769  * Must be called only for started daemons.
   2770  *
   2771  * @param daemon the daemon to update
   2772  * @param domain the SNI domain for ACME challenge in ASCII/ACE (Punycode)
   2773  *               format (case is ignored),
   2774  *               NULL makes @p cert match any domain (used last, when no
   2775  *               specific domain matches),
   2776  *               must be a non-empty string if non-NULL
   2777  * @param cert the ACME challenge certificate in PEM format for
   2778  *             the @p domain (certificate match is not checked)
   2779  * @param key the private key for @p cert in PEM format
   2780  * @param password the password for @p key, can be NULL
   2781  * @return #MHD_SC_OK on success,
   2782  *         #MHD_SC_TOO_EARLY if the @p daemon has not been started yet,
   2783  *         #MHD_SC_TOO_LATE if the @p daemon is failed,
   2784  *         #MHD_SC_DAEMON_HAS_TLS_DISABLED if the @p daemon has
   2785  *         no TLS backend enabled,
   2786  *         #MHD_SC_PARAM_EMPTY if @p domain is a zero-length string,
   2787  *         #MHD_SC_TLS_CONF_BAD_CERT if @p cert or @p key is empty,
   2788  *         malformed or does not match @p password,
   2789  *         #MHD_SC_TLS_BACKEND_OPERATION_UNSUPPORTED if ACME ALPN challenge
   2790  *         is not supported by this MHD build or by the selected TLS
   2791  *         backend,
   2792  *         #MHD_SC_TLS_BACKEND_ERROR if the TLS backend failed to create
   2793  *         the credentials,
   2794  *         #MHD_SC_DAEMON_MEM_ALLOC_FAILURE if memory allocation failed,
   2795  *         or other error code if failed for other reasons
   2796  * @ingroup acme
   2797  */
   2798 MHD_EXTERN_ enum MHD_StatusCode
   2799 MHD_daemon_acme_alpn_cert_add (struct MHD_Daemon *MHD_RESTRICT daemon,
   2800                                const char *MHD_RESTRICT domain,
   2801                                const char *MHD_RESTRICT cert,
   2802                                const char *MHD_RESTRICT key,
   2803                                const char *MHD_RESTRICT password)
   2804 MHD_FN_PAR_NONNULL_ (1) MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_NONNULL_ (4)
   2805 MHD_FN_PAR_CSTR_ (2) MHD_FN_PAR_CSTR_ (3) MHD_FN_PAR_CSTR_ (4)
   2806 MHD_FN_PAR_CSTR_ (5);
   2807 
   2808 /**
   2809  * Remove ACME challenge certificate.
   2810  *
   2811  * Takes effect for connections accepted after this function returns.
   2812  *
   2813  * Must be called only for started daemons.
   2814  *
   2815  * @param daemon the daemon to update
   2816  * @param domain the SNI domain for ACME challenge to remove,
   2817  *               NULL empties the list of special certificates,
   2818  *               must be non-empty string if non-NULL
   2819  * @return #MHD_SC_OK on success,
   2820  *         #MHD_SC_ITEM_NOT_FOUND if no certificate is set for the
   2821  *         specified @p domain,
   2822  *         #MHD_SC_TOO_EARLY if the @p daemon has not been started yet,
   2823  *         #MHD_SC_TOO_LATE if the @p daemon is not running,
   2824  *         #MHD_SC_DAEMON_HAS_TLS_DISABLED if the @p daemon has no TLS
   2825  *         enabled,
   2826  *         #MHD_SC_PARAM_EMPTY if @p domain is a zero-length string,
   2827  *         #MHD_SC_TLS_BACKEND_OPERATION_UNSUPPORTED if ACME ALPN challenge
   2828  *         is not supported by this MHD build or by the selected TLS
   2829  *         backend,
   2830  *         or other error code if failed for other reasons
   2831  * @ingroup acme
   2832  */
   2833 MHD_EXTERN_ enum MHD_StatusCode
   2834 MHD_daemon_acme_alpn_cert_del (struct MHD_Daemon *MHD_RESTRICT daemon,
   2835                                const char *domain)
   2836 MHD_FN_PAR_NONNULL_ (1) MHD_FN_PAR_CSTR_ (2);
   2837 
   2838 
   2839 /* ******************* External event loop ************************ */
   2840 
   2841 /**
   2842  * @defgroup event External network events processing
   2843  */
   2844 
   2845 /**
   2846  * The network status of the socket.
   2847  * When set by MHD (by #MHD_SocketRegistrationUpdateCallback or
   2848  * similar) it indicates a request to watch for specific socket state:
   2849  * watch for readiness for receiving the data, watch for readiness for sending
   2850  * the data and/or watch for exception state of the socket.
   2851  * When set by application (and provided for #MHD_daemon_event_update() and
   2852  * similar) it must indicate the actual status of the socket.
   2853  *
   2854  * Any actual state is a bitwise OR combination of #MHD_FD_STATE_RECV,
   2855  * #MHD_FD_STATE_SEND, #MHD_FD_STATE_EXCEPT.
   2856  * @ingroup event
   2857  */
   2858 enum MHD_FIXED_ENUM_ MHD_FdState
   2859 {
   2860   /**
   2861    * The socket is not ready for receiving or sending and
   2862    * does not have any exceptional state.
   2863    * The state never set by MHD, except de-registration of the sockets
   2864    * in a #MHD_SocketRegistrationUpdateCallback.
   2865    */
   2866   MHD_FD_STATE_NONE = 0
   2867   ,
   2868   /* ** Three bit-flags ** */
   2869 
   2870   /**
   2871    * Indicates that socket should be watched for incoming data
   2872    * (when set by #MHD_SocketRegistrationUpdateCallback)
   2873    * / socket has incoming data ready to read (when used for
   2874    * #MHD_daemon_event_update())
   2875    */
   2876   MHD_FD_STATE_RECV = 1 << 0
   2877   ,
   2878   /**
   2879    * Indicates that socket should be watched for availability for sending
   2880    * (when set by #MHD_SocketRegistrationUpdateCallback)
   2881    * / socket has ability to send data (when used for
   2882    * #MHD_daemon_event_update())
   2883    */
   2884   MHD_FD_STATE_SEND = 1 << 1
   2885   ,
   2886   /**
   2887    * Indicates that socket should be watched for disconnect, out-of-band
   2888    * data available or high priority data available (when set by
   2889    * #MHD_SocketRegistrationUpdateCallback)
   2890    * / socket has been disconnected, has out-of-band data available or
   2891    * has high priority data available (when used for
   2892    * #MHD_daemon_event_update()). This status must not include "remote
   2893    * peer shut down writing" status.
   2894    * Note: #MHD_SocketRegistrationUpdateCallback() always set it as exceptions
   2895    * must be always watched.
   2896    */
   2897   MHD_FD_STATE_EXCEPT = 1 << 2
   2898   ,
   2899 
   2900   /* The rest of the list is a bit-wise combination of three main
   2901    * states. Application may use three main states directly as
   2902    * a bit-mask instead of using of the following values
   2903    */
   2904 
   2905   /**
   2906    * Combination of #MHD_FD_STATE_RECV and #MHD_FD_STATE_SEND states.
   2907    */
   2908   MHD_FD_STATE_RECV_SEND = MHD_FD_STATE_RECV | MHD_FD_STATE_SEND
   2909   ,
   2910   /**
   2911    * Combination of #MHD_FD_STATE_RECV and #MHD_FD_STATE_EXCEPT states.
   2912    */
   2913   MHD_FD_STATE_RECV_EXCEPT = MHD_FD_STATE_RECV | MHD_FD_STATE_EXCEPT
   2914   ,
   2915   /**
   2916    * Combination of #MHD_FD_STATE_RECV and #MHD_FD_STATE_EXCEPT states.
   2917    */
   2918   MHD_FD_STATE_SEND_EXCEPT = MHD_FD_STATE_RECV | MHD_FD_STATE_EXCEPT
   2919   ,
   2920   /**
   2921    * Combination of #MHD_FD_STATE_RECV, #MHD_FD_STATE_SEND and
   2922    * #MHD_FD_STATE_EXCEPT states.
   2923    */
   2924   MHD_FD_STATE_RECV_SEND_EXCEPT = \
   2925     MHD_FD_STATE_RECV | MHD_FD_STATE_SEND | MHD_FD_STATE_EXCEPT
   2926 };
   2927 
   2928 /**
   2929  * Checks whether specific @a state is enabled/set in the @a var
   2930  */
   2931 #define MHD_FD_STATE_IS_SET(var, state)              \
   2932         (MHD_FD_STATE_NONE !=                        \
   2933          ((enum MHD_FdState) (((unsigned int) (var)) \
   2934                               & ((unsigned int) (state)))))
   2935 
   2936 /**
   2937  * Checks whether RECV is enabled/set in the @a var
   2938  */
   2939 #define MHD_FD_STATE_IS_SET_RECV(var) \
   2940         MHD_FD_STATE_IS_SET ((var),MHD_FD_STATE_RECV)
   2941 /**
   2942  * Checks whether SEND is enabled/set in the @a var
   2943  */
   2944 #define MHD_FD_STATE_IS_SET_SEND(var) \
   2945         MHD_FD_STATE_IS_SET ((var),MHD_FD_STATE_SEND)
   2946 /**
   2947  * Checks whether EXCEPT is enabled/set in the @a var
   2948  */
   2949 #define MHD_FD_STATE_IS_SET_EXCEPT(var) \
   2950         MHD_FD_STATE_IS_SET ((var),MHD_FD_STATE_EXCEPT)
   2951 
   2952 
   2953 /**
   2954  * Set/enable specific @a state in the @a var
   2955  */
   2956 #define MHD_FD_STATE_SET(var, state) \
   2957         ((var) =                     \
   2958            (enum MHD_FdState) (((unsigned int) var) | ((unsigned int) state)))
   2959 /**
   2960  * Set/enable RECV state in the @a var
   2961  */
   2962 #define MHD_FD_STATE_SET_RECV(var) MHD_FD_STATE_SET ((var),MHD_FD_STATE_RECV)
   2963 /**
   2964  * Set/enable SEND state in the @a var
   2965  */
   2966 #define MHD_FD_STATE_SET_SEND(var) MHD_FD_STATE_SET ((var),MHD_FD_STATE_SEND)
   2967 /**
   2968  * Set/enable EXCEPT state in the @a var
   2969  */
   2970 #define MHD_FD_STATE_SET_EXCEPT(var) \
   2971         MHD_FD_STATE_SET ((var),MHD_FD_STATE_EXCEPT)
   2972 
   2973 /**
   2974  * Clear/disable specific @a state in the @a var
   2975  */
   2976 #define MHD_FD_STATE_CLEAR(var, state) \
   2977         ( (var) =                      \
   2978             (enum MHD_FdState)         \
   2979             (((unsigned int) var)      \
   2980              & ((enum MHD_FdState) (~((unsigned int) state)))) \
   2981         )
   2982 /**
   2983  * Clear/disable RECV state in the @a var
   2984  */
   2985 #define MHD_FD_STATE_CLEAR_RECV(var) \
   2986         MHD_FD_STATE_CLEAR ((var),MHD_FD_STATE_RECV)
   2987 /**
   2988  * Clear/disable SEND state in the @a var
   2989  */
   2990 #define MHD_FD_STATE_CLEAR_SEND(var) \
   2991         MHD_FD_STATE_CLEAR ((var),MHD_FD_STATE_SEND)
   2992 /**
   2993  * Clear/disable EXCEPT state in the @a var
   2994  */
   2995 #define MHD_FD_STATE_CLEAR_EXCEPT(var) \
   2996         MHD_FD_STATE_CLEAR ((var),MHD_FD_STATE_EXCEPT)
   2997 
   2998 
   2999 /**
   3000  * The context data to be used for updates of the socket state
   3001  */
   3002 struct MHD_EventUpdateContext;
   3003 
   3004 
   3005 /* Define MHD_APP_SOCKET_CNTX_TYPE to the socket context type before
   3006  * including this header.
   3007  * This is optional, but improves the types safety.
   3008  * For example:
   3009  * #define MHD_APP_SOCKET_CNTX_TYPE struct my_structure
   3010  */
   3011 #ifndef MHD_APP_SOCKET_CNTX_TYPE
   3012 #  define MHD_APP_SOCKET_CNTX_TYPE void
   3013 #endif
   3014 
   3015 /**
   3016  * The callback for registration/de-registration of the sockets to watch.
   3017  *
   3018  * This callback must not call #MHD_daemon_destroy(), #MHD_daemon_quiesce(),
   3019  * #MHD_daemon_add_connection().
   3020  *
   3021  * @param cls the closure
   3022  * @param fd the socket to watch
   3023  * @param watch_for the states of the @a fd to watch, if set to
   3024  *                  #MHD_FD_STATE_NONE the socket must be de-registred
   3025  * @param app_cntx_old the old application defined context for the socket,
   3026  *                     NULL if @a fd socket was not registered before
   3027  * @param ecb_cntx the context handle to be used
   3028  *                 with #MHD_daemon_event_update()
   3029  * @return must be NULL for the removed (de-registred) sockets,
   3030  *         for new and updated sockets: NULL in case of error (the connection
   3031  *         will be aborted or daemon failed to start if FD does not belong to
   3032  *         connection)
   3033  *         or the new socket context (opaque for MHD, must be non-NULL)
   3034  * @sa #MHD_D_OPTION_REREGISTER_ALL
   3035  * @ingroup event
   3036  */
   3037 typedef MHD_APP_SOCKET_CNTX_TYPE *
   3038 (MHD_FN_PAR_NONNULL_ (5)
   3039  *MHD_SocketRegistrationUpdateCallback)(
   3040   void *cls,
   3041   MHD_Socket fd,
   3042   enum MHD_FdState watch_for,
   3043   MHD_APP_SOCKET_CNTX_TYPE *app_cntx_old,
   3044   struct MHD_EventUpdateContext *ecb_cntx);
   3045 
   3046 
   3047 /**
   3048  * Update the sockets state.
   3049  * Must be called for every socket that got state updated.
   3050  * For #MHD_D_OPTION_WM_EXTERNAL_EVENT_LOOP_CB_LEVEL() mode
   3051  * this function must be called for each socket between any two calls of
   3052  * #MHD_daemon_process_reg_events() function.
   3053  * Available only for daemons started in
   3054  * #MHD_D_OPTION_WM_EXTERNAL_EVENT_LOOP_CB_LEVEL or
   3055  * #MHD_D_OPTION_WM_EXTERNAL_EVENT_LOOP_CB_EDGE modes.
   3056  * @param daemon the daemon handle
   3057  * @param ecb_cntx the context handle provided
   3058  *                 for #MHD_SocketRegistrationUpdateCallback
   3059  * @param fd_current_state the current state of the socket
   3060  * @ingroup event
   3061  */
   3062 MHD_EXTERN_ void
   3063 MHD_daemon_event_update (
   3064   struct MHD_Daemon *MHD_RESTRICT daemon,
   3065   struct MHD_EventUpdateContext *MHD_RESTRICT ecb_cntx,
   3066   enum MHD_FdState fd_current_state)
   3067 MHD_FN_PAR_NONNULL_ (1) MHD_FN_PAR_NONNULL_ (2);
   3068 
   3069 
   3070 /**
   3071  * Perform all daemon activities based on FDs events provided earlier by
   3072  * application via #MHD_daemon_event_update().
   3073  *
   3074  * This function accepts new connections (if any), performs HTTP communications
   3075  * on all active connections, closes connections as needed and performs FDs
   3076  * registration updates by calling #MHD_SocketRegistrationUpdateCallback
   3077  * callback for every socket that needs to be added/updated/removed.
   3078  *
   3079  * Available only for daemons started in #MHD_WM_EXTERNAL_EVENT_LOOP_CB_LEVEL or
   3080  * #MHD_WM_EXTERNAL_EVENT_LOOP_CB_EDGE modes.
   3081  *
   3082  * When used in #MHD_WM_EXTERNAL_EVENT_LOOP_CB_LEVEL mode, application must
   3083  * provide all updates by calling #MHD_daemon_event_update() for every
   3084  * registered FD between any two calls of this function.
   3085  *
   3086  * @param daemon the daemon handle
   3087  * @param[out] next_max_wait_milsec the optional pointer to receive the
   3088                                     next maximum wait time in milliseconds
   3089                                     to be used for the sockets polling
   3090                                     function, can be NULL
   3091  * @return #MHD_SC_OK on success,
   3092  *         error code otherwise
   3093  * @sa #MHD_D_OPTION_REREGISTER_ALL
   3094  * @ingroup event
   3095  */
   3096 MHD_EXTERN_ enum MHD_StatusCode
   3097 MHD_daemon_process_reg_events (
   3098   struct MHD_Daemon *MHD_RESTRICT daemon,
   3099   uint_fast64_t *MHD_RESTRICT next_max_wait_milsec)
   3100 MHD_FN_PAR_NONNULL_ (1);
   3101 
   3102 /* ********************* daemon options ************** */
   3103 
   3104 
   3105 /**
   3106  * Which threading and polling mode should be used by MHD?
   3107  */
   3108 enum MHD_FIXED_ENUM_APP_SET_ MHD_WorkMode
   3109 {
   3110   /**
   3111    * Work mode with no internal threads.
   3112    * The application periodically calls #MHD_daemon_process_blocking(), where
   3113    * MHD internally checks all sockets automatically.
   3114    * This is the default mode.
   3115    * Use helper macro #MHD_D_OPTION_WM_EXTERNAL_PERIODIC() to enable
   3116    * this mode.
   3117    */
   3118   MHD_WM_EXTERNAL_PERIODIC = 0
   3119   ,
   3120   /**
   3121    * Work mode with an external event loop with level triggers.
   3122    * MHD provides registration of all FDs to be monitored by using
   3123    * #MHD_SocketRegistrationUpdateCallback, application performs level triggered
   3124    * FDs polling (like select() or poll()), calls function
   3125    * #MHD_daemon_event_update() for every registered FD and then calls main
   3126    * function MHD_daemon_process_reg_events() to process the data.
   3127    * Use helper macro #MHD_D_OPTION_WM_EXTERNAL_EVENT_LOOP_CB_LEVEL() to enable
   3128    * this mode.
   3129    * @sa #MHD_D_OPTION_REREGISTER_ALL
   3130    */
   3131   MHD_WM_EXTERNAL_EVENT_LOOP_CB_LEVEL = 8
   3132   ,
   3133   /**
   3134    * Work mode with an external event loop with edge triggers.
   3135    * MHD provides registration of all FDs to be monitored by using
   3136    * #MHD_SocketRegistrationUpdateCallback, application performs edge triggered
   3137    * sockets polling (like epoll with EPOLLET), calls function
   3138    * #MHD_daemon_event_update() for FDs with updated states and then calls main
   3139    * function MHD_daemon_process_reg_events() to process the data.
   3140    * Use helper macro #MHD_D_OPTION_WM_EXTERNAL_EVENT_LOOP_CB_EDGE() to enable
   3141    * this mode.
   3142    * @sa #MHD_D_OPTION_REREGISTER_ALL
   3143    */
   3144   MHD_WM_EXTERNAL_EVENT_LOOP_CB_EDGE = 9
   3145   ,
   3146   /**
   3147    * Work mode with no internal threads and aggregate watch FD.
   3148    * Application uses #MHD_DAEMON_INFO_FIXED_AGGREAGATE_FD to get single FD
   3149    * that gets triggered by any MHD event.
   3150    * This FD can be watched as an aggregate indicator for all MHD events.
   3151    * This mode is available only on selected platforms (currently
   3152    * GNU/Linux and OpenIndiana only), see #MHD_LIB_INFO_FIXED_HAS_AGGREGATE_FD.
   3153    * When the FD is triggered, #MHD_daemon_process_nonblocking() should
   3154    * be called.
   3155    * Use helper macro #MHD_D_OPTION_WM_EXTERNAL_SINGLE_FD_WATCH() to enable
   3156    * this mode.
   3157    */
   3158   MHD_WM_EXTERNAL_SINGLE_FD_WATCH = 16
   3159   ,
   3160   /**
   3161    * Work mode with one or more worker threads.
   3162    * If specified number of threads is one, then daemon starts with single
   3163    * worker thread that handles all connections.
   3164    * If number of threads is larger than one, then that number of worker
   3165    * threads, and handling of connection is distributed among the workers.
   3166    * Use helper macro #MHD_D_OPTION_WM_WORKER_THREADS() to enable
   3167    * this mode.
   3168    */
   3169   MHD_WM_WORKER_THREADS = 24
   3170   ,
   3171   /**
   3172    * Work mode with one internal thread for listening and additional threads
   3173    * per every connection.  Use this if handling requests is CPU-intensive or
   3174    * blocking, your application is thread-safe and you have plenty of
   3175    * memory (per connection).
   3176    * Use helper macro #MHD_D_OPTION_WM_THREAD_PER_CONNECTION() to enable
   3177    * this mode.
   3178    */
   3179   MHD_WM_THREAD_PER_CONNECTION = 32
   3180 };
   3181 
   3182 /**
   3183  * Work mode parameters for #MHD_WM_EXTERNAL_EVENT_LOOP_CB_LEVEL and
   3184  * #MHD_WM_EXTERNAL_EVENT_LOOP_CB_EDGE modes
   3185  */
   3186 struct MHD_WorkModeExternalEventLoopCBParam
   3187 {
   3188   /**
   3189    * Socket registration callback
   3190    */
   3191   MHD_SocketRegistrationUpdateCallback reg_cb;
   3192   /**
   3193    * Closure for the @a reg_cb
   3194    */
   3195   void *reg_cb_cls;
   3196 };
   3197 
   3198 /**
   3199  * MHD work mode parameters
   3200  */
   3201 union MHD_WorkModeParam
   3202 {
   3203   /**
   3204    * Work mode parameters for #MHD_WM_EXTERNAL_EVENT_LOOP_CB_LEVEL and
   3205    * #MHD_WM_EXTERNAL_EVENT_LOOP_CB_EDGE modes
   3206    */
   3207   struct MHD_WorkModeExternalEventLoopCBParam v_external_event_loop_cb;
   3208   /**
   3209    * Number of worker threads for #MHD_WM_WORKER_THREADS.
   3210    * If set to one, then daemon starts with single worker thread that process
   3211    * all connections.
   3212    * If set to value larger than one, then that number of worker threads
   3213    * and distributed handling of requests among the workers.
   3214    * Zero is treated as one.
   3215    */
   3216   unsigned int num_worker_threads;
   3217 };
   3218 
   3219 /**
   3220  * Parameter for #MHD_D_O_WORK_MODE().
   3221  * Not recommended to be used directly, better use macro/functions to create it:
   3222  * #MHD_WM_OPTION_EXTERNAL_PERIODIC(),
   3223  * #MHD_WM_OPTION_EXTERNAL_EVENT_LOOP_CB_LEVEL(),
   3224  * #MHD_WM_OPTION_EXTERNAL_EVENT_LOOP_CB_EDGE(),
   3225  * #MHD_WM_OPTION_EXTERNAL_SINGLE_FD_WATCH(),
   3226  * #MHD_WM_OPTION_WORKER_THREADS(),
   3227  * #MHD_WM_OPTION_THREAD_PER_CONNECTION()
   3228  */
   3229 struct MHD_WorkModeWithParam
   3230 {
   3231   /**
   3232    * The work mode for MHD
   3233    */
   3234   enum MHD_WorkMode mode;
   3235   /**
   3236    * The parameters used for specified work mode
   3237    */
   3238   union MHD_WorkModeParam params;
   3239 };
   3240 
   3241 
   3242 #if defined(MHD_USE_COMPOUND_LITERALS) && defined(MHD_USE_DESIG_NEST_INIT)
   3243 /**
   3244  * Create parameter for #MHD_D_O_WORK_MODE() for work mode with
   3245  * no internal threads.
   3246  * The application periodically calls #MHD_daemon_process_blocking(), where
   3247  * MHD internally checks all sockets automatically.
   3248  * This is the default mode.
   3249  * @return the object of struct MHD_WorkModeWithParam with requested values
   3250  */
   3251 #  define MHD_WM_OPTION_EXTERNAL_PERIODIC()      \
   3252           MHD_NOWARN_COMPOUND_LITERALS_          \
   3253             (const struct MHD_WorkModeWithParam) \
   3254           {                                      \
   3255             .mode = (MHD_WM_EXTERNAL_PERIODIC)   \
   3256           }                                      \
   3257           MHD_RESTORE_WARN_COMPOUND_LITERALS_
   3258 
   3259 /**
   3260  * Create parameter for #MHD_D_O_WORK_MODE() for work mode with
   3261  * an external event loop with level triggers.
   3262  * Application uses #MHD_SocketRegistrationUpdateCallback, level triggered
   3263  * sockets polling (like select() or poll()) and #MHD_daemon_event_update().
   3264  * @param cb_val the callback for sockets registration
   3265  * @param cb_cls_val the closure for the @a cv_val callback
   3266  * @return the object of struct MHD_WorkModeWithParam with requested values
   3267  */
   3268 #  define MHD_WM_OPTION_EXTERNAL_EVENT_LOOP_CB_LEVEL(cb_val, cb_cls_val) \
   3269           MHD_NOWARN_COMPOUND_LITERALS_                                  \
   3270             (const struct MHD_WorkModeWithParam)                         \
   3271           {                                                              \
   3272             .mode = (MHD_WM_EXTERNAL_EVENT_LOOP_CB_LEVEL),               \
   3273             .params.v_external_event_loop_cb.reg_cb = (cb_val),          \
   3274             .params.v_external_event_loop_cb.reg_cb_cls = (cb_cls_val)   \
   3275           }                                                              \
   3276           MHD_RESTORE_WARN_COMPOUND_LITERALS_
   3277 
   3278 /**
   3279  * Create parameter for #MHD_D_O_WORK_MODE() for work mode with
   3280  * an external event loop with edge triggers.
   3281  * Application uses #MHD_SocketRegistrationUpdateCallback, edge triggered
   3282  * sockets polling (like epoll with EPOLLET) and #MHD_daemon_event_update().
   3283  * @param cb_val the callback for sockets registration
   3284  * @param cb_cls_val the closure for the @a cv_val callback
   3285  * @return the object of struct MHD_WorkModeWithParam with requested values
   3286  */
   3287 #  define MHD_WM_OPTION_EXTERNAL_EVENT_LOOP_CB_EDGE(cb_val, cb_cls_val) \
   3288           MHD_NOWARN_COMPOUND_LITERALS_                                 \
   3289             (const struct MHD_WorkModeWithParam)                        \
   3290           {                                                             \
   3291             .mode = (MHD_WM_EXTERNAL_EVENT_LOOP_CB_EDGE),               \
   3292             .params.v_external_event_loop_cb.reg_cb = (cb_val),         \
   3293             .params.v_external_event_loop_cb.reg_cb_cls = (cb_cls_val)  \
   3294           }                                                             \
   3295           MHD_RESTORE_WARN_COMPOUND_LITERALS_
   3296 
   3297 /**
   3298  * Create parameter for #MHD_D_O_WORK_MODE() for work mode with
   3299  * no internal threads and aggregate watch FD.
   3300  * Application uses #MHD_DAEMON_INFO_FIXED_AGGREAGATE_FD to get single FD
   3301  * that gets triggered by any MHD event.
   3302  * This FD can be watched as an aggregate indicator for all MHD events.
   3303  * This mode is available only on selected platforms (currently
   3304  * GNU/Linux only), see #MHD_LIB_INFO_FIXED_HAS_AGGREGATE_FD.
   3305  * When the FD is triggered, #MHD_daemon_process_nonblocking() should
   3306  * be called.
   3307  * @return the object of struct MHD_WorkModeWithParam with requested values
   3308  */
   3309 #  define MHD_WM_OPTION_EXTERNAL_SINGLE_FD_WATCH()    \
   3310           MHD_NOWARN_COMPOUND_LITERALS_               \
   3311             (const struct MHD_WorkModeWithParam)      \
   3312           {                                           \
   3313             .mode = (MHD_WM_EXTERNAL_SINGLE_FD_WATCH) \
   3314           }                                           \
   3315           MHD_RESTORE_WARN_COMPOUND_LITERALS_
   3316 
   3317 /**
   3318  * Create parameter for #MHD_D_O_WORK_MODE() for work mode with
   3319  * one or more worker threads.
   3320  * If number of threads is one, then daemon starts with single worker thread
   3321  * that handles all connections.
   3322  * If number of threads is larger than one, then that number of worker threads,
   3323  * and handling of connection is distributed among the workers.
   3324  * @param num_workers the number of worker threads, zero is treated as one
   3325  * @return the object of struct MHD_WorkModeWithParam with requested values
   3326  */
   3327 #  define MHD_WM_OPTION_WORKER_THREADS(num_workers)    \
   3328           MHD_NOWARN_COMPOUND_LITERALS_                \
   3329             (const struct MHD_WorkModeWithParam)       \
   3330           {                                            \
   3331             .mode = (MHD_WM_WORKER_THREADS),           \
   3332             .params.num_worker_threads = (num_workers) \
   3333           }                                            \
   3334           MHD_RESTORE_WARN_COMPOUND_LITERALS_
   3335 
   3336 /**
   3337  * Create parameter for #MHD_D_O_WORK_MODE() for work mode with
   3338  * one internal thread for listening and additional threads per every
   3339  * connection.  Use this if handling requests is CPU-intensive or blocking,
   3340  * your application is thread-safe and you have plenty of memory (per
   3341  * connection).
   3342  * @return the object of struct MHD_WorkModeWithParam with requested values
   3343  */
   3344 #  define MHD_WM_OPTION_THREAD_PER_CONNECTION()    \
   3345           MHD_NOWARN_COMPOUND_LITERALS_            \
   3346             (const struct MHD_WorkModeWithParam)   \
   3347           {                                        \
   3348             .mode = (MHD_WM_THREAD_PER_CONNECTION) \
   3349           }                                        \
   3350           MHD_RESTORE_WARN_COMPOUND_LITERALS_
   3351 
   3352 #else  /* !MHD_USE_COMPOUND_LITERALS || !MHD_USE_DESIG_NEST_INIT */
   3353 MHD_NOWARN_UNUSED_FUNC_
   3354 
   3355 /**
   3356  * Create parameter for #MHD_D_O_WORK_MODE() for work mode with
   3357  * no internal threads.
   3358  * The application periodically calls #MHD_daemon_process_blocking(), where
   3359  * MHD internally checks all sockets automatically.
   3360  * This is the default mode.
   3361  * @return the object of struct MHD_WorkModeWithParam with requested values
   3362  */
   3363 static MHD_INLINE struct MHD_WorkModeWithParam
   3364 MHD_WM_OPTION_EXTERNAL_PERIODIC (void)
   3365 {
   3366   struct MHD_WorkModeWithParam wm_val;
   3367 
   3368   wm_val.mode = MHD_WM_EXTERNAL_PERIODIC;
   3369 
   3370   return wm_val;
   3371 }
   3372 
   3373 
   3374 /**
   3375  * Create parameter for #MHD_D_O_WORK_MODE() for work mode with
   3376  * an external event loop with level triggers.
   3377  * Application uses #MHD_SocketRegistrationUpdateCallback, level triggered
   3378  * sockets polling (like select() or poll()) and #MHD_daemon_event_update().
   3379  * @param cb_val the callback for sockets registration
   3380  * @param cb_cls_val the closure for the @a cv_val callback
   3381  * @return the object of struct MHD_WorkModeWithParam with requested values
   3382  */
   3383 static MHD_INLINE struct MHD_WorkModeWithParam
   3384 MHD_WM_OPTION_EXTERNAL_EVENT_LOOP_CB_LEVEL (
   3385   MHD_SocketRegistrationUpdateCallback cb_val,
   3386   void *cb_cls_val)
   3387 {
   3388   struct MHD_WorkModeWithParam wm_val;
   3389 
   3390   wm_val.mode = MHD_WM_EXTERNAL_EVENT_LOOP_CB_LEVEL;
   3391   wm_val.params.v_external_event_loop_cb.reg_cb = cb_val;
   3392   wm_val.params.v_external_event_loop_cb.reg_cb_cls = cb_cls_val;
   3393 
   3394   return wm_val;
   3395 }
   3396 
   3397 
   3398 /**
   3399  * Create parameter for #MHD_D_O_WORK_MODE() for work mode with
   3400  * an external event loop with edge triggers.
   3401  * Application uses #MHD_SocketRegistrationUpdateCallback, edge triggered
   3402  * sockets polling (like epoll with EPOLLET) and #MHD_daemon_event_update().
   3403  * @param cb_val the callback for sockets registration
   3404  * @param cb_cls_val the closure for the @a cv_val callback
   3405  * @return the object of struct MHD_WorkModeWithParam with requested values
   3406  */
   3407 static MHD_INLINE struct MHD_WorkModeWithParam
   3408 MHD_WM_OPTION_EXTERNAL_EVENT_LOOP_CB_EDGE (
   3409   MHD_SocketRegistrationUpdateCallback cb_val,
   3410   void *cb_cls_val)
   3411 {
   3412   struct MHD_WorkModeWithParam wm_val;
   3413 
   3414   wm_val.mode = MHD_WM_EXTERNAL_EVENT_LOOP_CB_EDGE;
   3415   wm_val.params.v_external_event_loop_cb.reg_cb = cb_val;
   3416   wm_val.params.v_external_event_loop_cb.reg_cb_cls = cb_cls_val;
   3417 
   3418   return wm_val;
   3419 }
   3420 
   3421 
   3422 /**
   3423  * Create parameter for #MHD_D_O_WORK_MODE() for work mode with
   3424  * no internal threads and aggregate watch FD.
   3425  * Application uses #MHD_DAEMON_INFO_FIXED_AGGREAGATE_FD to get single FD
   3426  * that gets triggered by any MHD event.
   3427  * This FD can be watched as an aggregate indicator for all MHD events.
   3428  * This mode is available only on selected platforms (currently
   3429  * GNU/Linux only), see #MHD_LIB_INFO_FIXED_HAS_AGGREGATE_FD.
   3430  * When the FD is triggered, #MHD_daemon_process_nonblocking() should
   3431  * be called.
   3432  * @return the object of struct MHD_WorkModeWithParam with requested values
   3433  */
   3434 static MHD_INLINE struct MHD_WorkModeWithParam
   3435 MHD_WM_OPTION_EXTERNAL_SINGLE_FD_WATCH (void)
   3436 {
   3437   struct MHD_WorkModeWithParam wm_val;
   3438 
   3439   wm_val.mode = MHD_WM_EXTERNAL_SINGLE_FD_WATCH;
   3440 
   3441   return wm_val;
   3442 }
   3443 
   3444 
   3445 /**
   3446  * Create parameter for #MHD_D_O_WORK_MODE() for work mode with
   3447  * one or more worker threads.
   3448  * If number of threads is one, then daemon starts with single worker thread
   3449  * that handles all connections.
   3450  * If number of threads is larger than one, then that number of worker threads,
   3451  * and handling of connection is distributed among the workers.
   3452  * @param num_workers the number of worker threads, zero is treated as one
   3453  * @return the object of struct MHD_WorkModeWithParam with requested values
   3454  */
   3455 static MHD_INLINE struct MHD_WorkModeWithParam
   3456 MHD_WM_OPTION_WORKER_THREADS (unsigned int num_workers)
   3457 {
   3458   struct MHD_WorkModeWithParam wm_val;
   3459 
   3460   wm_val.mode = MHD_WM_WORKER_THREADS;
   3461   wm_val.params.num_worker_threads = num_workers;
   3462 
   3463   return wm_val;
   3464 }
   3465 
   3466 
   3467 /**
   3468  * Create parameter for #MHD_D_O_WORK_MODE() for work mode with
   3469  * one internal thread for listening and additional threads per every
   3470  * connection.  Use this if handling requests is CPU-intensive or blocking,
   3471  * your application is thread-safe and you have plenty of memory (per
   3472  * connection).
   3473  * @return the object of struct MHD_WorkModeWithParam with requested values
   3474  */
   3475 static MHD_INLINE struct MHD_WorkModeWithParam
   3476 MHD_WM_OPTION_THREAD_PER_CONNECTION (void)
   3477 {
   3478   struct MHD_WorkModeWithParam wm_val;
   3479 
   3480   wm_val.mode = MHD_WM_THREAD_PER_CONNECTION;
   3481 
   3482   return wm_val;
   3483 }
   3484 
   3485 
   3486 MHD_RESTORE_WARN_UNUSED_FUNC_
   3487 #endif /* !MHD_USE_COMPOUND_LITERALS || !MHD_USE_DESIG_NEST_INIT */
   3488 
   3489 /**
   3490  * @defgroup logging Log events and control
   3491  */
   3492 
   3493 
   3494 /**
   3495  * Type of a callback function used for logging by MHD.
   3496  *
   3497  * @param cls closure
   3498  * @param sc status code of the event
   3499  * @param fm format string (`printf()`-style)
   3500  * @param ap arguments to @a fm
   3501  * @ingroup logging
   3502  */
   3503 typedef void
   3504 (MHD_FN_PAR_NONNULL_ (3)
   3505  MHD_FN_PAR_CSTR_ (3)
   3506  *MHD_LoggingCallback)(void *cls,
   3507                        enum MHD_StatusCode sc,
   3508                        const char *fm,
   3509                        va_list ap);
   3510 
   3511 /**
   3512  * Parameter for listen socket binding type
   3513  */
   3514 enum MHD_FIXED_ENUM_APP_SET_ MHD_DaemonOptionBindType
   3515 {
   3516   /**
   3517    * The listen socket bind to the networks address with sharing the address.
   3518    * Several sockets can bind to the same address.
   3519    */
   3520   MHD_D_OPTION_BIND_TYPE_SHARED = -1
   3521   ,
   3522   /**
   3523    * The listen socket bind to the networks address without sharing the address,
   3524    * except allowing binding to port/address which has TIME_WAIT state (the
   3525    * state after closing connection).
   3526    * On some platforms it may also allow to bind to specific address if other
   3527    * socket already bond to the same port of wildcard address (or bind to
   3528    * wildcard address when other socket already bond to specific address
   3529    * with the same port).
   3530    * Typically achieved by enabling 'SO_REUSEADDR' socket option.
   3531    * Default.
   3532    */
   3533   MHD_D_OPTION_BIND_TYPE_NOT_SHARED = 0
   3534   ,
   3535   /**
   3536    * The listen socket bind to the networks address without sharing the address.
   3537    * The daemon way fail to start when any sockets still in "TIME_WAIT" state
   3538    * on the same port, which effectively prevents quick restart of the daemon
   3539    * on the same port.
   3540    * On W32 systems it works like #MHD_D_OPTION_BIND_TYPE_NOT_SHARED due to
   3541    * the OS limitations.
   3542    */
   3543   MHD_D_OPTION_BIND_TYPE_NOT_SHARED_STRICTER = 1
   3544   ,
   3545   /**
   3546    * The list socket bind to the networks address in explicit exclusive mode.
   3547    * Works as #MHD_D_OPTION_BIND_TYPE_NOT_SHARED_STRICTER on platforms without
   3548    * support for the explicit exclusive socket use.
   3549    */
   3550   MHD_D_OPTION_BIND_TYPE_EXCLUSIVE = 2
   3551 };
   3552 
   3553 
   3554 /**
   3555  * Possible levels of enforcement for TCP_FASTOPEN.
   3556  */
   3557 enum MHD_FIXED_ENUM_APP_SET_ MHD_TCPFastOpenType
   3558 {
   3559   /**
   3560    * Disable use of TCP_FASTOPEN.
   3561    */
   3562   MHD_FOM_DISABLE = -1
   3563   ,
   3564   /**
   3565    * Enable TCP_FASTOPEN where supported.
   3566    * On GNU/Linux it works with a kernel >= 3.6.
   3567    * This is the default.
   3568    */
   3569   MHD_FOM_AUTO = 0
   3570   ,
   3571   /**
   3572    * Require TCP_FASTOPEN.
   3573    * Also causes #MHD_daemon_start() to fail if TCP_FASTOPEN cannot be enabled.
   3574    */
   3575   MHD_FOM_REQUIRE = 1
   3576 };
   3577 
   3578 
   3579 /**
   3580  * Address family to be used by MHD.
   3581  */
   3582 enum MHD_FIXED_ENUM_APP_SET_ MHD_AddressFamily
   3583 {
   3584   /**
   3585    * Option not given, do not listen at all
   3586    * (unless listen socket or address specified by
   3587    * other means).
   3588    */
   3589   MHD_AF_NONE = 0
   3590   ,
   3591   /**
   3592    * Pick "best" available method automatically.
   3593    */
   3594   MHD_AF_AUTO = 1
   3595   ,
   3596   /**
   3597    * Use IPv4 only.
   3598    */
   3599   MHD_AF_INET4 = 2
   3600   ,
   3601   /**
   3602    * Use IPv6 only.
   3603    */
   3604   MHD_AF_INET6 = 3
   3605   ,
   3606   /**
   3607    * Use dual stack (IPv4 and IPv6 on the same socket).
   3608    */
   3609   MHD_AF_DUAL = 4
   3610   ,
   3611   /**
   3612    * Use dual stack (IPv4 and IPv6 on the same socket),
   3613    * fallback to pure IPv6 if dual stack is not possible.
   3614    */
   3615   MHD_AF_DUAL_v4_OPTIONAL = 5
   3616   ,
   3617   /**
   3618    * Use dual stack (IPv4 and IPv6 on the same socket),
   3619    * fallback to pure IPv4 if dual stack is not possible.
   3620    */
   3621   MHD_AF_DUAL_v6_OPTIONAL = 6
   3622 
   3623 };
   3624 
   3625 
   3626 /**
   3627  * Sockets polling internal syscalls used by MHD.
   3628  */
   3629 enum MHD_FIXED_ENUM_APP_SET_ MHD_SockPollSyscall
   3630 {
   3631   /**
   3632    * Automatic selection of best-available method. This is also the
   3633    * default.
   3634    */
   3635   MHD_SPS_AUTO = 0
   3636   ,
   3637   /**
   3638    * Use select().
   3639    */
   3640   MHD_SPS_SELECT = 1
   3641   ,
   3642   /**
   3643    * Use poll().
   3644    */
   3645   MHD_SPS_POLL = 2
   3646   ,
   3647   /**
   3648    * Use epoll.
   3649    */
   3650   MHD_SPS_EPOLL = 3
   3651   ,
   3652   /**
   3653    * Use kqueue.
   3654    */
   3655   MHD_SPS_KQUEUE = 4
   3656 };
   3657 
   3658 
   3659 /**
   3660  * Protocol strictness levels enforced by MHD on clients.
   3661  * Each level applies different parsing settings for HTTP headers and other
   3662  * protocol elements.
   3663  */
   3664 enum MHD_FIXED_ENUM_APP_SET_ MHD_ProtocolStrictLevel
   3665 {
   3666 
   3667   /* * Basic levels * */
   3668   /**
   3669    * A sane default level of protocol enforcement for production use.
   3670    * Provides a balance between enhanced security and broader compatibility,
   3671    * as permitted by RFCs for HTTP servers.
   3672    */
   3673   MHD_PSL_DEFAULT = 0
   3674   ,
   3675   /**
   3676    * Apply stricter protocol interpretation while remaining within
   3677    * RFC-defined limits for HTTP servers.
   3678    *
   3679    * At this level (and stricter), using a bare LF instead of CRLF is forbidden,
   3680    * and requests that include both a "Transfer-Encoding:" and
   3681    * a "Content-Length:" headers are rejected.
   3682    *
   3683    * Suitable for public servers.
   3684    */
   3685   MHD_PSL_STRICT = 1
   3686   ,
   3687   /**
   3688    * Be more permissive in interpreting the protocol, while still
   3689    * operating within the RFC-defined limits for HTTP servers.
   3690    */
   3691   MHD_PSL_PERMISSIVE = -1
   3692   ,
   3693   /* * Special levels * */
   3694   /**
   3695    * A stricter protocol interpretation than what is allowed by RFCs for HTTP
   3696    * servers. However, it should remain fully compatible with clients correctly
   3697    * following all RFC "MUST" requirements for HTTP clients.
   3698    *
   3699    * For chunked encoding, this level (and more restrictive ones) forbids
   3700    * whitespace in chunk extensions.
   3701    * For cookie parsing, this level (and more restrictive ones) rejects
   3702    * the entire cookie if even a single value within it is incorrectly encoded.
   3703    *
   3704    * Recommended for testing clients against MHD. Can also be used for
   3705    * security-centric applications, though doing so slightly violates
   3706    * relevant RFC requirements for HTTP servers.
   3707    */
   3708   MHD_PSL_VERY_STRICT = 2
   3709   ,
   3710   /**
   3711    * The strictest interpretation of the HTTP protocol, even stricter than
   3712    * allowed by RFCs for HTTP servers.
   3713    * However, it should remain fully compatible with clients complying with both
   3714    * RFC "SHOULD" and "MUST" requirements for HTTP clients.
   3715    *
   3716    * This level can be used for testing clients against MHD.
   3717    * It is not recommended for public services, as it may reject legitimate
   3718    * clients that do not follow RFC "SHOULD" requirements.
   3719    */
   3720   MHD_PSL_EXTRA_STRICT = 3
   3721   ,
   3722   /**
   3723    * A more relaxed protocol interpretation that violates some RFC "SHOULD"
   3724    * restrictions for HTTP servers.
   3725    * For cookie parsing, this level (and more permissive levels) allows
   3726    * whitespace in cookie values.
   3727    *
   3728    * This level may be used in isolated environments.
   3729    */
   3730   MHD_PSL_VERY_PERMISSIVE = -2
   3731   ,
   3732   /**
   3733    * The most flexible protocol interpretation, going beyond RFC "MUST"
   3734    * requirements for HTTP servers.
   3735    *
   3736    * This level allows HTTP/1.1 requests without a "Host:" header.
   3737    * For cookie parsing, whitespace is allowed before and after
   3738    * the '=' character.
   3739    *
   3740    * Not recommended unless absolutely necessary to communicate with clients
   3741    * that have severely broken HTTP implementations.
   3742    */
   3743   MHD_PSL_EXTRA_PERMISSIVE = -3
   3744 };
   3745 
   3746 /**
   3747  * The way Strict Level is enforced.
   3748  * MHD can be compiled with limited set of strictness levels.
   3749  * These values instructs MHD how to apply the request level.
   3750  */
   3751 enum MHD_FIXED_ENUM_APP_SET_ MHD_UseStictLevel
   3752 {
   3753   /**
   3754    * Use requested level if available or the nearest stricter
   3755    * level.
   3756    * Fail if only more permissive levels available.
   3757    * Recommended value.
   3758    */
   3759   MHD_USL_THIS_OR_STRICTER = 0
   3760   ,
   3761   /**
   3762    * Use requested level only.
   3763    * Fail if this level is not available.
   3764    */
   3765   MHD_USL_PRECISE = 1
   3766   ,
   3767   /**
   3768    * Use requested level if available or the nearest level (stricter
   3769    * or more permissive).
   3770    */
   3771   MHD_USL_NEAREST = 2
   3772 };
   3773 
   3774 
   3775 /**
   3776  * Connection memory buffer zeroing mode.
   3777  * Works as a hardening measure.
   3778  */
   3779 enum MHD_FIXED_ENUM_APP_SET_ MHD_ConnBufferZeroingMode
   3780 {
   3781   /**
   3782    * Do not perform zeroing of connection memory buffer.
   3783    * Default mode.
   3784    */
   3785   MHD_CONN_BUFFER_ZEROING_DISABLED = 0
   3786   ,
   3787   /**
   3788    * Perform connection memory buffer zeroing before processing request.
   3789    */
   3790   MHD_CONN_BUFFER_ZEROING_BASIC = 1
   3791   ,
   3792   /**
   3793    * Perform connection memory buffer zeroing before processing request and
   3794    * when reusing buffer memory areas during processing request.
   3795    */
   3796   MHD_CONN_BUFFER_ZEROING_HEAVY = 2
   3797 };
   3798 
   3799 
   3800 /* ********************** (d) TLS support ********************** */
   3801 
   3802 /**
   3803  * The TLS backend choice
   3804  */
   3805 enum MHD_FIXED_ENUM_APP_SET_ MHD_TlsBackend
   3806 {
   3807   /**
   3808    * Disable TLS, use plain TCP connections (default)
   3809    */
   3810   MHD_TLS_BACKEND_NONE = 0
   3811   ,
   3812   /**
   3813    * Use best available TLS backend.
   3814    */
   3815   MHD_TLS_BACKEND_ANY = 1
   3816   ,
   3817   /**
   3818    * Use GnuTLS as TLS backend.
   3819    */
   3820   MHD_TLS_BACKEND_GNUTLS = 2
   3821   ,
   3822   /**
   3823    * Use OpenSSL as TLS backend.
   3824    */
   3825   MHD_TLS_BACKEND_OPENSSL = 3
   3826   ,
   3827   /**
   3828    * Use MbedTLS as TLS backend.
   3829    */
   3830   MHD_TLS_BACKEND_MBEDTLS = 4
   3831 };
   3832 
   3833 /**
   3834  * Values for #MHD_D_O_DAUTH_NONCE_BIND_TYPE.
   3835  *
   3836  * These values can limit the scope of validity of MHD-generated nonces.
   3837  * Values can be combined with bitwise OR.
   3838  * Any value, except #MHD_D_OPTION_VALUE_DAUTH_BIND_NONCE_NONE, enforce function
   3839  * #MHD_digest_auth_check() (and similar functions) to check nonce by
   3840  * re-generating it again with the same parameters, which is CPU-intensive
   3841  * operation.
   3842  */
   3843 enum MHD_FIXED_FLAGS_ENUM_APP_SET_ MHD_DaemonOptionValueDAuthBindNonce
   3844 {
   3845   /**
   3846    * Generated nonces are valid for any request from any client until expired.
   3847    * This is default and recommended value.
   3848    * #MHD_digest_auth_check() (and similar functions) would check only whether
   3849    * the nonce value that is used by client has been generated by MHD and not
   3850    * expired yet.
   3851    * It is recommended because RFC 7616 allows clients to use the same nonce
   3852    * for any request in the same "protection space".
   3853    * When checking client's authorisation requests CPU is loaded less if this
   3854    * value is used.
   3855    * This mode gives MHD maximum flexibility for nonces generation and can
   3856    * prevent possible nonce collisions (and corresponding log warning messages)
   3857    * when clients' requests are intensive.
   3858    * This value cannot be biwise-OR combined with other values.
   3859    */
   3860   MHD_D_OPTION_VALUE_DAUTH_BIND_NONCE_NONE = 0
   3861   ,
   3862   /**
   3863    * Generated nonces are valid only for the same realm.
   3864    */
   3865   MHD_D_OPTION_VALUE_DAUTH_BIND_NONCE_REALM = (1 << 0)
   3866   ,
   3867   /**
   3868    * Generated nonces are valid only for the same URI (excluding parameters
   3869    * after '?' in URI) and request method (GET, POST etc).
   3870    * Not recommended unless "protection space" is limited to a single URI as
   3871    * RFC 7616 allows clients to reuse server-generated nonces for any URI
   3872    * in the same "protection space" which by default consists of all server
   3873    * URIs.
   3874    */
   3875   MHD_D_OPTION_VALUE_DAUTH_BIND_NONCE_URI = (1 << 1)
   3876   ,
   3877 
   3878   /**
   3879    * Generated nonces are valid only for the same URI including URI parameters
   3880    * and request method (GET, POST etc).
   3881    * This value implies #MHD_D_OPTION_VALUE_DAUTH_BIND_NONCE_URI.
   3882    * Not recommended for that same reasons as
   3883    * #MHD_D_OPTION_VALUE_DAUTH_BIND_NONCE_URI.
   3884    */
   3885   MHD_D_OPTION_VALUE_DAUTH_BIND_NONCE_URI_PARAMS = (1 << 2)
   3886   ,
   3887 
   3888   /**
   3889    * Generated nonces are valid only for the single client's IP.
   3890    * While it looks like security improvement, in practice the same client may
   3891    * jump from one IP to another (mobile or Wi-Fi handover, DHCP re-assignment,
   3892    * Multi-NAT, different proxy chain and other reasons), while IP address
   3893    * spoofing could be used relatively easily.
   3894    */
   3895   MHD_D_OPTION_VALUE_DAUTH_BIND_NONCE_CLIENT_IP = (1 << 3)
   3896 };
   3897 
   3898 
   3899 struct MHD_ServerCredentialsContext;
   3900 
   3901 
   3902 /**
   3903  * Context required to provide a pre-shared key to the
   3904  * server.
   3905  *
   3906  * @param mscc the context
   3907  * @param psk_size the number of bytes in @a psk,
   3908  *                 must be zero if @a psk is NULL
   3909  * @param psk the pre-shared-key; should be allocated with malloc(),
   3910  *            will be freed by MHD; can be NULL if @a psk_size is zero
   3911  */
   3912 MHD_EXTERN_ enum MHD_StatusCode
   3913 MHD_connection_set_psk (
   3914   struct MHD_ServerCredentialsContext *mscc,
   3915   size_t psk_size,
   3916   const /*void? */ char *psk)
   3917 MHD_FN_PAR_NONNULL_IF_NONZERO_ (3, 2)
   3918 MHD_FN_PAR_IN_SIZE_ (3, 2);
   3919 
   3920 #define MHD_connection_set_psk_unavailable(mscc) \
   3921         MHD_connection_set_psk (mscc, 0, NULL)
   3922 
   3923 
   3924 /**
   3925  * Function called to lookup the pre-shared key (PSK) for a given
   3926  * HTTP connection based on the @a username.  MHD will suspend handling of
   3927  * the @a connection until the application calls #MHD_connection_set_psk().
   3928  * If looking up the PSK fails, the application must still call
   3929  * #MHD_connection_set_psk_unavailable().
   3930  *
   3931  * @param cls closure
   3932  * @param connection the HTTPS connection
   3933  * @param username the user name claimed by the other side
   3934  * @param mscc context to pass to #MHD_connection_set_psk().
   3935  */
   3936 typedef void
   3937 (*MHD_PskServerCredentialsCallback)(
   3938   void *cls,
   3939   const struct MHD_Connection *MHD_RESTRICT connection,
   3940   const struct MHD_String *MHD_RESTRICT username,
   3941   struct MHD_ServerCredentialsContext *mscc);
   3942 
   3943 
   3944 /**
   3945  * The specified callback will be called one time,
   3946  * after network initialisation, TLS pre-initialisation, but before
   3947  * the start of the internal threads (if allowed).
   3948  *
   3949  * This callback may use introspection call to retrieve and adjust
   3950  * some of the daemon aspects. For example, TLS backend handler can be used
   3951  * to configure some TLS aspects.
   3952  * @param cls the callback closure
   3953  */
   3954 typedef void
   3955 (*MHD_DaemonReadyCallback)(void *cls);
   3956 
   3957 
   3958 /**
   3959  * Allow or deny a client to connect.
   3960  *
   3961  * @param cls closure
   3962  * @param addr_len length of @a addr
   3963  * @param addr address information from the client
   3964  * @see #MHD_D_OPTION_ACCEPT_POLICY()
   3965  * @return #MHD_YES if connection is allowed, #MHD_NO if not
   3966  */
   3967 typedef enum MHD_Bool
   3968 (*MHD_AcceptPolicyCallback)(void *cls,
   3969                             size_t addr_len,
   3970                             const struct sockaddr *addr);
   3971 
   3972 
   3973 /**
   3974  * The data for the #MHD_EarlyUriLogCallback
   3975  */
   3976 struct MHD_EarlyUriCbData
   3977 {
   3978   /**
   3979    * The request handle.
   3980    * Headers are not yet available.
   3981    */
   3982   struct MHD_Request *request;
   3983 
   3984   /**
   3985    * The full URI ("request target") from the HTTP request, including URI
   3986    * parameters (the part after '?')
   3987    */
   3988   struct MHD_String full_uri;
   3989 
   3990   /**
   3991    * The request HTTP method
   3992    */
   3993   enum MHD_HTTP_Method method;
   3994 };
   3995 
   3996 /**
   3997  * Function called by MHD to allow the application to log the @a full_uri
   3998  * of the new request.
   3999  * This is the only moment when unmodified URI is provided.
   4000  * After this callback MHD parses the URI and modifies it by extracting
   4001  * GET parameters in-place.
   4002  *
   4003  * If this callback is set then it is the first application function called
   4004  * for the new request.
   4005  *
   4006  * If #MHD_RequestEndedCallback is also set then it is guaranteed that
   4007  * #MHD_RequestEndedCallback is called for the same request. Application
   4008  * may allocate request specific data in this callback and de-allocate
   4009  * the data in #MHD_RequestEndedCallback.
   4010  *
   4011  * @param cls client-defined closure
   4012  * @param req_data the request data
   4013  * @param request_app_context_ptr the pointer to variable that can be set to
   4014  *                                the application context for the request;
   4015  *                                initially the variable set to NULL
   4016  */
   4017 typedef void
   4018 (MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_INOUT_ (3)
   4019  *MHD_EarlyUriLogCallback)(void *cls,
   4020                            const struct MHD_EarlyUriCbData *req_data,
   4021                            void **request_app_context_ptr);
   4022 
   4023 
   4024 /**
   4025  * The `enum MHD_ConnectionNotificationCode` specifies types
   4026  * of connection notifications.
   4027  * @ingroup request
   4028  */
   4029 enum MHD_FIXED_ENUM_MHD_SET_ MHD_ConnectionNotificationCode
   4030 {
   4031 
   4032   /**
   4033    * A new connection has been started.
   4034    * @ingroup request
   4035    */
   4036   MHD_CONNECTION_NOTIFY_STARTED = 0
   4037   ,
   4038   /**
   4039    * A connection is closed.
   4040    * @ingroup request
   4041    */
   4042   MHD_CONNECTION_NOTIFY_CLOSED = 1
   4043 
   4044 };
   4045 
   4046 /**
   4047  * Extra details for connection notifications.
   4048  * Currently not used
   4049  */
   4050 union MHD_ConnectionNotificationDetails
   4051 {
   4052   /**
   4053    * Unused
   4054    */
   4055   int reserved1;
   4056 };
   4057 
   4058 
   4059 /**
   4060  * The connection notification data structure
   4061  */
   4062 struct MHD_ConnectionNotificationData
   4063 {
   4064   /**
   4065    * The connection handle
   4066    */
   4067   struct MHD_Connection *connection;
   4068   /**
   4069    * The connection-specific application context data (opaque for MHD).
   4070    * Initially set to NULL (for connections added by MHD) or set by
   4071    * @a connection_cntx parameter for connections added by
   4072    * #MHD_daemon_add_connection().
   4073    */
   4074   void *application_context;
   4075   /**
   4076    * The code of the event
   4077    */
   4078   enum MHD_ConnectionNotificationCode code;
   4079   /**
   4080    * Event details
   4081    */
   4082   union MHD_ConnectionNotificationDetails details;
   4083 };
   4084 
   4085 
   4086 /**
   4087  * Signature of the callback used by MHD to notify the
   4088  * application about started/stopped network connections
   4089  *
   4090  * @param cls client-defined closure
   4091  * @param[in,out]  data the details about the event
   4092  * @see #MHD_D_OPTION_NOTIFY_CONNECTION()
   4093  * @ingroup request
   4094  */
   4095 typedef void
   4096 (MHD_FN_PAR_NONNULL_ (2)
   4097  *MHD_NotifyConnectionCallback)(void *cls,
   4098                                 struct MHD_ConnectionNotificationData *data);
   4099 
   4100 
   4101 /**
   4102  * The type of stream notifications.
   4103  * @ingroup request
   4104  */
   4105 enum MHD_FIXED_ENUM_MHD_SET_ MHD_StreamNotificationCode
   4106 {
   4107   /**
   4108    * A new stream has been started.
   4109    * @ingroup request
   4110    */
   4111   MHD_STREAM_NOTIFY_STARTED = 0
   4112   ,
   4113   /**
   4114    * A stream is closed.
   4115    * @ingroup request
   4116    */
   4117   MHD_STREAM_NOTIFY_CLOSED = 1
   4118 };
   4119 
   4120 /**
   4121  * Additional information about stream started event
   4122  */
   4123 struct MHD_StreamNotificationDetailStarted
   4124 {
   4125   /**
   4126    * Set to #MHD_YES of the stream was started by client
   4127    */
   4128   enum MHD_Bool by_client;
   4129 };
   4130 
   4131 /**
   4132  * Additional information about stream events
   4133  */
   4134 union MHD_StreamNotificationDetail
   4135 {
   4136   /**
   4137    * Information for event #MHD_STREAM_NOTIFY_STARTED
   4138    */
   4139   struct MHD_StreamNotificationDetailStarted started;
   4140 };
   4141 
   4142 /**
   4143  * Stream notification data structure
   4144  */
   4145 struct MHD_StreamNotificationData
   4146 {
   4147   /**
   4148    * The handle of the stream
   4149    */
   4150   struct MHD_Stream *stream;
   4151   /**
   4152    * The code of the event
   4153    */
   4154   enum MHD_StreamNotificationCode code;
   4155   /**
   4156    * Detailed information about notification event
   4157    */
   4158   union MHD_StreamNotificationDetail details;
   4159 };
   4160 
   4161 
   4162 /**
   4163  * Signature of the callback used by MHD to notify the
   4164  * application about started/stopped data stream
   4165  * For HTTP/1.1 it is the same like network connection
   4166  * with 1:1 match.
   4167  *
   4168  * @param cls client-defined closure
   4169  * @param data the details about the event
   4170  * @see #MHD_D_OPTION_NOTIFY_STREAM()
   4171  * @ingroup request
   4172  */
   4173 typedef void
   4174 (MHD_FN_PAR_NONNULL_ (2)
   4175  *MHD_NotifyStreamCallback)(
   4176   void *cls,
   4177   const struct MHD_StreamNotificationData *data);
   4178 
   4179 #include "microhttpd2_generated_daemon_options.h"
   4180 
   4181 
   4182 /**
   4183  * The `enum MHD_RequestEndedCode` specifies reasons
   4184  * why a request has been ended.
   4185  * @ingroup request
   4186  */
   4187 enum MHD_FIXED_ENUM_MHD_SET_ MHD_RequestEndedCode
   4188 {
   4189 
   4190   /**
   4191    * The response was successfully sent.
   4192    * @ingroup request
   4193    */
   4194   MHD_REQUEST_ENDED_COMPLETED_OK = 0
   4195   ,
   4196   /**
   4197    * The response was successfully sent and connection is being switched
   4198    * to another protocol.
   4199    * @ingroup request
   4200    */
   4201   MHD_REQUEST_ENDED_COMPLETED_OK_UPGRADE = 1
   4202   ,
   4203   /**
   4204    * No activity on the connection for the number of seconds specified using
   4205    * #MHD_C_OPTION_TIMEOUT().
   4206    * @ingroup request
   4207    */
   4208   MHD_REQUEST_ENDED_TIMEOUT_REACHED = 10
   4209   ,
   4210   /**
   4211    * The connection was broken or TLS protocol error.
   4212    * @ingroup request
   4213    */
   4214   MHD_REQUEST_ENDED_CONNECTION_ERROR = 20
   4215   ,
   4216   /**
   4217    * The client terminated the connection by closing the socket either
   4218    * completely or for writing (TCP half-closed) before sending complete
   4219    * request.
   4220    * @ingroup request
   4221    */
   4222   MHD_REQUEST_ENDED_CLIENT_ABORT = 30
   4223   ,
   4224   /**
   4225    * The request is not valid according to HTTP specifications.
   4226    * @ingroup request
   4227    */
   4228   MHD_REQUEST_ENDED_HTTP_PROTOCOL_ERROR = 31
   4229   ,
   4230   /**
   4231    * The application aborted request without response.
   4232    * @ingroup request
   4233    */
   4234   MHD_REQUEST_ENDED_BY_APP_ABORT = 40
   4235   ,
   4236   /**
   4237    * The request was aborted due to the application failed to provide a valid
   4238    * response.
   4239    * @ingroup request
   4240    */
   4241   MHD_REQUEST_ENDED_BY_APP_ERROR = 41
   4242   ,
   4243   /**
   4244    * The request was aborted due to the application failed to register external
   4245    * event monitoring for the connection.
   4246    * @ingroup request
   4247    */
   4248   MHD_REQUEST_ENDED_BY_EXT_EVENT_ERROR = 42
   4249   ,
   4250   /**
   4251    * Error handling the connection due to resources exhausted.
   4252    * @ingroup request
   4253    */
   4254   MHD_REQUEST_ENDED_NO_RESOURCES = 50
   4255   ,
   4256   /**
   4257    * The request was aborted due to error reading file for file-backed response
   4258    * @ingroup request
   4259    */
   4260   MHD_REQUEST_ENDED_FILE_ERROR = 51
   4261   ,
   4262   /**
   4263    * The request was aborted due to error generating valid nonce for Digest Auth
   4264    * @ingroup request
   4265    */
   4266   MHD_REQUEST_ENDED_NONCE_ERROR = 52
   4267   ,
   4268   /**
   4269    * Closing the session since MHD is being shut down.
   4270    * @ingroup request
   4271    */
   4272   MHD_REQUEST_ENDED_DAEMON_SHUTDOWN = 60
   4273 };
   4274 
   4275 /**
   4276  * Additional information about request ending
   4277  */
   4278 union MHD_RequestEndedDetail
   4279 {
   4280   /**
   4281    * Reserved member.
   4282    * Do not use.
   4283    */
   4284   void *reserved;
   4285 };
   4286 
   4287 /**
   4288  * Request termination data structure
   4289  */
   4290 struct MHD_RequestEndedData
   4291 {
   4292   /**
   4293    * The request handle.
   4294    * Note that most of the request data may be already unvailable.
   4295    */
   4296   struct MHD_Request *req;
   4297   /**
   4298    * The code of the event
   4299    */
   4300   enum MHD_RequestEndedCode code;
   4301   /**
   4302    * Detailed information about the event
   4303    */
   4304   union MHD_RequestEndedDetail details;
   4305 };
   4306 
   4307 
   4308 /**
   4309  * Signature of the callback used by MHD to notify the application
   4310  * about completed requests.
   4311  *
   4312  * This is the last callback called for any request (if provided by
   4313  * the application).
   4314  *
   4315  * @param cls client-defined closure
   4316  * @param data the details about the event
   4317  * @param request_app_context the application request context, as possibly set
   4318                               by the #MHD_EarlyUriLogCallback
   4319  * @see #MHD_R_OPTION_TERMINATION_CALLBACK()
   4320  * @ingroup request
   4321  */
   4322 typedef void
   4323 (*MHD_RequestEndedCallback)(void *cls,
   4324                             const struct MHD_RequestEndedData *data,
   4325                             void *request_app_context);
   4326 
   4327 
   4328 #include "microhttpd2_generated_response_options.h"
   4329 /* Beginning of generated code documenting how to use options.
   4330    You should treat the following functions *as if* they were
   4331    part of the header/API. The actual declarations are more
   4332    complex, so these here are just for documentation!
   4333    We do not actually *build* this code... */
   4334 #if 0
   4335 
   4336 /**
   4337  * Set MHD work (threading and polling) mode.
   4338  * Consider use of #MHD_D_OPTION_WM_EXTERNAL_PERIODIC(), #MHD_D_OPTION_WM_EXTERNAL_EVENT_LOOP_CB_LEVEL(), #MHD_D_OPTION_WM_EXTERNAL_EVENT_LOOP_CB_EDGE(), #MHD_D_OPTION_WM_EXTERNAL_SINGLE_FD_WATCH(), #MHD_D_OPTION_WM_WORKER_THREADS() or #MHD_D_OPTION_WM_THREAD_PER_CONNECTION() instead of direct use of this parameter.
   4339  * @param wmp the object created by one of the next functions/macros: #MHD_WM_OPTION_EXTERNAL_PERIODIC(), #MHD_WM_OPTION_EXTERNAL_EVENT_LOOP_CB_LEVEL(), #MHD_WM_OPTION_EXTERNAL_EVENT_LOOP_CB_EDGE(), #MHD_WM_OPTION_EXTERNAL_SINGLE_FD_WATCH(), #MHD_WM_OPTION_WORKER_THREADS(), #MHD_WM_OPTION_THREAD_PER_CONNECTION()
   4340  * @return structure with the requested setting
   4341  */
   4342 struct MHD_DaemonOptionAndValue
   4343 MHD_D_OPTION_WORK_MODE (
   4344   struct MHD_WorkModeWithParam wmp
   4345   );
   4346 
   4347 /**
   4348  * Select a sockets watch system call used for internal polling.
   4349  * @param els FIXME
   4350  * @return structure with the requested setting
   4351  */
   4352 struct MHD_DaemonOptionAndValue
   4353 MHD_D_OPTION_POLL_SYSCALL (
   4354   enum MHD_SockPollSyscall els
   4355   );
   4356 
   4357 /**
   4358  * Instruct MHD to register all sockets every processing round.
   4359  *
   4360 By default (this options is not enabled) every processing round (every time
   4361  * when #MHD_daemon_event_update() is called) MHD calls
   4362  * #MHD_SocketRegistrationUpdateCallback only for the new sockets, for
   4363  * the removed sockets and for the updated sockets.
   4364  * Some sockets are registered when #MHD_daemon_start() is called.
   4365  *
   4366 If this options is enabled, then #MHD_SocketRegistrationUpdateCallback is
   4367  * called for every socket each processing round. No sockets are registered when
   4368  * the daemon is being started.
   4369  * @param value the value of the parameter * @return structure with the requested setting
   4370  */
   4371 struct MHD_DaemonOptionAndValue
   4372 MHD_D_OPTION_REREGISTER_ALL (
   4373   enum MHD_Bool value
   4374   );
   4375 
   4376 /**
   4377  * Set a callback to use for logging
   4378  * @param log_cb the callback to use for logging,
   4379  *   NULL to disable logging.
   4380  *   The logging to stderr is enabled by default.
   4381  * @param log_cb_cls the closure for the logging callback
   4382  * @return structure with the requested setting
   4383  */
   4384 struct MHD_DaemonOptionAndValue
   4385 MHD_D_OPTION_LOG_CALLBACK (
   4386   MHD_LoggingCallback log_cb,
   4387   void *log_cb_cls
   4388   );
   4389 
   4390 /**
   4391  * Bind to the given TCP port and address family.
   4392  *
   4393 Does not work with #MHD_D_OPTION_BIND_SA() or #MHD_D_OPTION_LISTEN_SOCKET().
   4394  *
   4395 If no listen socket optins (#MHD_D_OPTION_BIND_PORT(), #MHD_D_OPTION_BIND_SA(), #MHD_D_OPTION_LISTEN_SOCKET()) are used, MHD does not listen for incoming connection.
   4396  * @param af the address family to use,
   4397  *   the #MHD_AF_NONE to disable listen socket (the same effect as if this option is not used)
   4398  * @param port port to use, 0 to let system assign any free port,
   4399  *   ignored if @a af is #MHD_AF_NONE
   4400  * @return structure with the requested setting
   4401  */
   4402 struct MHD_DaemonOptionAndValue
   4403 MHD_D_OPTION_BIND_PORT (
   4404   enum MHD_AddressFamily af,
   4405   uint_least16_t port
   4406   );
   4407 
   4408 /**
   4409  * Bind to the given socket address.
   4410  *
   4411 Does not work with #MHD_D_OPTION_BIND_PORT() or #MHD_D_OPTION_LISTEN_SOCKET().
   4412  *
   4413 If no listen socket optins (#MHD_D_OPTION_BIND_PORT(), #MHD_D_OPTION_BIND_SA(), #MHD_D_OPTION_LISTEN_SOCKET()) are used, MHD does not listen for incoming connection.
   4414  * @param sa_len the size of the socket address pointed by @a sa.
   4415  * @param sa the address to bind to; can be IPv4 (AF_INET), IPv6 (AF_INET6) or even a UNIX domain socket (AF_UNIX)
   4416  * @param dual When a previous version of the protocol exist (like IPv4 when @a v_sa is IPv6) bind to both protocols (IPv6 and IPv4).
   4417  * @return structure with the requested setting
   4418  */
   4419 struct MHD_DaemonOptionAndValue
   4420 MHD_D_OPTION_BIND_SA (
   4421   size_t sa_len,
   4422   /* const */ struct sockaddr *sa,
   4423   enum MHD_Bool dual
   4424   );
   4425 
   4426 /**
   4427  * Accept connections from the given socket.  Socket
   4428  * must be a TCP or UNIX domain (SOCK_STREAM) socket.
   4429  *
   4430 Does not work with #MHD_D_OPTION_BIND_PORT() or #MHD_D_OPTION_BIND_SA().
   4431  *
   4432 If no listen socket optins (#MHD_D_OPTION_BIND_PORT(), #MHD_D_OPTION_BIND_SA(), #MHD_D_OPTION_LISTEN_SOCKET()) are used, MHD does not listen for incoming connection.
   4433  * @param listen_fd the listen socket to use, ignored if set to #MHD_INVALID_SOCKET
   4434  * @return structure with the requested setting
   4435  */
   4436 struct MHD_DaemonOptionAndValue
   4437 MHD_D_OPTION_LISTEN_SOCKET (
   4438   MHD_Socket listen_fd
   4439   );
   4440 
   4441 /**
   4442  * Select mode of reusing address:port listen address.
   4443  *
   4444 Works only when #MHD_D_OPTION_BIND_PORT() or #MHD_D_OPTION_BIND_SA() are used.
   4445  * @param reuse_type FIXME
   4446  * @return structure with the requested setting
   4447  */
   4448 struct MHD_DaemonOptionAndValue
   4449 MHD_D_OPTION_LISTEN_ADDR_REUSE (
   4450   enum MHD_DaemonOptionBindType reuse_type
   4451   );
   4452 
   4453 /**
   4454  * Configure TCP_FASTOPEN option, including setting a
   4455  * custom @a queue_length.
   4456  *
   4457 Note that having a larger queue size can cause resource exhaustion
   4458  * attack as the TCP stack has to now allocate resources for the SYN
   4459  * packet along with its DATA.
   4460  *
   4461 Works only when #MHD_D_OPTION_BIND_PORT() or #MHD_D_OPTION_BIND_SA() are used.
   4462  * @param option the type use of of TCP FastOpen
   4463  * @param queue_length the length of the queue, zero to use system or MHD default,
   4464  *   silently ignored on platforms without support for custom queue size
   4465  * @return structure with the requested setting
   4466  */
   4467 struct MHD_DaemonOptionAndValue
   4468 MHD_D_OPTION_TCP_FASTOPEN (
   4469   enum MHD_TCPFastOpenType option,
   4470   unsigned int queue_length
   4471   );
   4472 
   4473 /**
   4474  * Use the given backlog for the listen() call.
   4475  *
   4476 Works only when #MHD_D_OPTION_BIND_PORT() or #MHD_D_OPTION_BIND_SA() are used.
   4477  * Zero parameter treated as MHD/system default.
   4478  * @param backlog_size FIXME
   4479  * @return structure with the requested setting
   4480  */
   4481 struct MHD_DaemonOptionAndValue
   4482 MHD_D_OPTION_LISTEN_BACKLOG (
   4483   unsigned int backlog_size
   4484   );
   4485 
   4486 /**
   4487  * Inform that SIGPIPE is suppressed or handled by application.
   4488  * If suppressed/handled, MHD uses network functions that could generate SIGPIPE, like `sendfile()`.
   4489  * Silently ignored when MHD creates internal threads as for them SIGPIPE is suppressed automatically.
   4490  * @param value the value of the parameter * @return structure with the requested setting
   4491  */
   4492 struct MHD_DaemonOptionAndValue
   4493 MHD_D_OPTION_SIGPIPE_SUPPRESSED (
   4494   enum MHD_Bool value
   4495   );
   4496 
   4497 /**
   4498  * Enable TLS (HTTPS) and select TLS backend
   4499  * @param backend the TLS backend to use,
   4500  *   #MHD_TLS_BACKEND_NONE for non-TLS (plain TCP) connections
   4501  * @return structure with the requested setting
   4502  */
   4503 struct MHD_DaemonOptionAndValue
   4504 MHD_D_OPTION_TLS (
   4505   enum MHD_TlsBackend backend
   4506   );
   4507 
   4508 /**
   4509  * Provide TLS key and certificate data in-memory.
   4510  * Works only if TLS mode is enabled.
   4511  * @param mem_cert The X.509 certificates chain in PEM format loaded into memory (not a filename).
   4512  *   The first certificate must be the server certificate, following by the chain of signing
   4513  *   certificates up to (but not including) CA root certificate.
   4514  * @param mem_key the private key in PEM format loaded into memory (not a filename)
   4515  * @param mem_pass the option passphrase phrase to decrypt the private key,
   4516  *   could be NULL if private key does not need a password
   4517  * @return structure with the requested setting
   4518  */
   4519 struct MHD_DaemonOptionAndValue
   4520 MHD_D_OPTION_TLS_CERT_KEY (
   4521   /* const */ char *mem_cert,
   4522   const char *mem_key,
   4523   const char *mem_pass
   4524   );
   4525 
   4526 /**
   4527  * Provide the certificate of the certificate authority (CA) to be used by the MHD daemon for client authentication.
   4528  * Works only if TLS mode is enabled.
   4529  * @param mem_client_ca the CA certificate in memory (not a filename)
   4530  * @return structure with the requested setting
   4531  */
   4532 struct MHD_DaemonOptionAndValue
   4533 MHD_D_OPTION_TLS_CLIENT_CA (
   4534   const char *mem_client_ca
   4535   );
   4536 
   4537 /**
   4538  * Configure PSK to use for the TLS key exchange.
   4539  * @param psk_cb the function to call to obtain pre-shared key
   4540  * @param psk_cb_cls the closure for @a psk_cb
   4541  * @return structure with the requested setting
   4542  */
   4543 struct MHD_DaemonOptionAndValue
   4544 MHD_D_OPTION_TLS_PSK_CALLBACK (
   4545   MHD_PskServerCredentialsCallback psk_cb,
   4546   void *psk_cb_cls
   4547   );
   4548 
   4549 /**
   4550  * Control ALPN for TLS connection.
   4551  * Silently ignored for non-TLS.
   4552  * By default ALPN is automatically used for TLS connections.
   4553  * @param value the value of the parameter * @return structure with the requested setting
   4554  */
   4555 struct MHD_DaemonOptionAndValue
   4556 MHD_D_OPTION_NO_ALPN (
   4557   enum MHD_Bool value
   4558   );
   4559 
   4560 /**
   4561  * Require ACME ALPN challenge support in TLS backend.
   4562  * If this option is enabled then TLS backends without ACME ALPN challenge
   4563  * support will not be selected automatically. The daemon will fail to start
   4564  * if no TLS backend with ACME ALPN is available.
   4565  * @param value the value of the parameter * @return structure with the requested setting
   4566  */
   4567 struct MHD_DaemonOptionAndValue
   4568 MHD_D_OPTION_ACME_ALPN_REQUIRED (
   4569   enum MHD_Bool value
   4570   );
   4571 
   4572 /**
   4573  * Provide application name to load dedicated section in TLS backend's configuration file.
   4574  * Search for "System-wide configuration of the library" for GnuTLS documentation or
   4575  * for "config, OPENSSL LIBRARY CONFIGURATION" for OpenSSL documentation.
   4576  * If not specified the default backend configuration is used:
   4577  * "@LIBMICROHTTPD" (if available), then "@SYSTEM" (if available) then default priorities, then "NORMAL" for GnuTLS;
   4578  * "libmicrohttpd" (if available), then default name ("openssl_conf") for OpenSSL.
   4579  * Ignored when MbedTLS is used as daemon's TLS backend.
   4580  * @param app_name the name of the application, used as converted to
   4581  *   uppercase (with '@'-prefixed) for GnuTLS and as converted to
   4582  *   lowercase for OpenSSL; must not be longer than 127 characters
   4583  * @param disable_fallback forbid use fallback/default configuration if specified
   4584  *   configuration is not found; also forbid ignoring errors in the
   4585  *   configuration on TLS backends, which may ignoring configuration
   4586  *   errors
   4587  * @return structure with the requested setting
   4588  */
   4589 struct MHD_DaemonOptionAndValue
   4590 MHD_D_OPTION_TLS_APP_NAME (
   4591   char *app_name,
   4592   enum MHD_Bool disable_fallback
   4593   );
   4594 
   4595 /**
   4596  * Set the configuration pathname for OpenSSL configuration file
   4597  * Ignored OpenSSL is not used as daemon's TLS backend.
   4598  * @param pathname the path and the name of the OpenSSL configuration file,
   4599  *   if only the name is provided then standard path for
   4600  *   configuration files is used,
   4601  *   could be NULL to use default configuration file pathname
   4602  *   or an empty (zero-size) string to disable file loading
   4603  * @param disable_fallback forbid use of fallback/default location and name of
   4604  *   the OpenSSL configuration file; also forbid initialisation without
   4605  *   configuration file
   4606  * @return structure with the requested setting
   4607  */
   4608 struct MHD_DaemonOptionAndValue
   4609 MHD_D_OPTION_TLS_OPENSSL_DEF_FILE (
   4610   char *pathname,
   4611   enum MHD_Bool disable_fallback
   4612   );
   4613 
   4614 /**
   4615  * Specify the inactivity timeout for a connection in milliseconds.
   4616  * If a connection remains idle (no activity) for this many
   4617  * milliseconds, it is closed automatically.
   4618  * Use zero for no timeout; this is also the (unsafe!)
   4619  * default.
   4620  * Values larger than 1209600000 (two weeks) are silently
   4621  * clamped to 1209600000.
   4622  * Precise closing time is not guaranteed and depends on
   4623  * system clock granularity and amount of time spent on
   4624  * processing other connections. Typical precision is
   4625  * within +/- 30 milliseconds, while the worst case could
   4626  * be greater than +/- 1 second.
   4627  * Values below 1500 milliseconds are risky as they
   4628  * may cause valid connections to be aborted and may
   4629  * increase load the server load due to clients' repetitive
   4630  * automatic retries.
   4631  * @param timeout the timeout in milliseconds, zero for no timeout
   4632  * @return structure with the requested setting
   4633  */
   4634 struct MHD_DaemonOptionAndValue
   4635 MHD_D_OPTION_DEFAULT_TIMEOUT_MILSEC (
   4636   uint_fast32_t timeout
   4637   );
   4638 
   4639 /**
   4640  * Maximum number of (concurrent) network connections served by daemon.
   4641  * @note The real maximum number of network connections could be smaller
   4642  *       than requested due to the system limitations, like FD_SETSIZE when
   4643  *       polling by select() is used.
   4644  * @param glob_limit FIXME
   4645  * @return structure with the requested setting
   4646  */
   4647 struct MHD_DaemonOptionAndValue
   4648 MHD_D_OPTION_GLOBAL_CONNECTION_LIMIT (
   4649   unsigned int glob_limit
   4650   );
   4651 
   4652 /**
   4653  * Limit on the number of (concurrent) network connections made to the server from the same IP address.
   4654  * 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.
   4655  * @param limit FIXME
   4656  * @return structure with the requested setting
   4657  */
   4658 struct MHD_DaemonOptionAndValue
   4659 MHD_D_OPTION_PER_IP_LIMIT (
   4660   unsigned int limit
   4661   );
   4662 
   4663 /**
   4664  * Set a policy callback that accepts/rejects connections based on the client's IP address.  The callbeck function will be called before servicing any new incoming connection.
   4665  * @param apc the accept policy callback
   4666  * @param apc_cls the closure for the callback
   4667  * @return structure with the requested setting
   4668  */
   4669 struct MHD_DaemonOptionAndValue
   4670 MHD_D_OPTION_ACCEPT_POLICY (
   4671   MHD_AcceptPolicyCallback apc,
   4672   void *apc_cls
   4673   );
   4674 
   4675 /**
   4676  * Set mode of connection memory buffer zeroing
   4677  * @param buff_zeroing buffer zeroing mode
   4678  * @return structure with the requested setting
   4679  */
   4680 struct MHD_DaemonOptionAndValue
   4681 MHD_D_OPTION_CONN_BUFF_ZEROING (
   4682   enum MHD_ConnBufferZeroingMode buff_zeroing
   4683   );
   4684 
   4685 /**
   4686  * Set how strictly MHD will enforce the HTTP protocol.
   4687  * @param sl the level of strictness
   4688  * @param how the way how to use the requested level
   4689  * @return structure with the requested setting
   4690  */
   4691 struct MHD_DaemonOptionAndValue
   4692 MHD_D_OPTION_PROTOCOL_STRICT_LEVEL (
   4693   enum MHD_ProtocolStrictLevel sl,
   4694   enum MHD_UseStictLevel how
   4695   );
   4696 
   4697 /**
   4698  * Set a callback to be called first for every request when the request line is received (before any parsing of the header).
   4699  * This callback is the only way to get raw (unmodified) request URI as URI is parsed and modified by MHD in-place.
   4700  * Mandatory URI modification may apply before this call, like binary zero replacement, as required by RFCs.
   4701  * @param cb the early URI callback
   4702  * @param cls the closure for the callback
   4703  * @return structure with the requested setting
   4704  */
   4705 struct MHD_DaemonOptionAndValue
   4706 MHD_D_OPTION_EARLY_URI_LOGGER (
   4707   MHD_EarlyUriLogCallback cb,
   4708   void *cls
   4709   );
   4710 
   4711 /**
   4712  * Disable converting plus ('+') character to space in GET parameters (URI part after '?').
   4713  * Plus conversion is not required by HTTP RFCs, however it required by HTML specifications, see https://url.spec.whatwg.org/#application/x-www-form-urlencoded for details.
   4714  * By default plus is converted to space in the query part of URI.
   4715  * @param value the value of the parameter * @return structure with the requested setting
   4716  */
   4717 struct MHD_DaemonOptionAndValue
   4718 MHD_D_OPTION_DISABLE_URI_QUERY_PLUS_AS_SPACE (
   4719   enum MHD_Bool value
   4720   );
   4721 
   4722 /**
   4723  * Suppresse use of 'Date:' header.
   4724  * According to RFC should be suppressed only if the system has no RTC.
   4725  * The 'Date:' is not suppressed (the header is enabled) by default.
   4726  * @param value the value of the parameter * @return structure with the requested setting
   4727  */
   4728 struct MHD_DaemonOptionAndValue
   4729 MHD_D_OPTION_SUPPRESS_DATE_HEADER (
   4730   enum MHD_Bool value
   4731   );
   4732 
   4733 /**
   4734  * Use SHOUTcast for responses.
   4735  * This will cause *all* responses to begin with the SHOUTcast 'ICY' line instead of 'HTTP'.
   4736  * @param value the value of the parameter * @return structure with the requested setting
   4737  */
   4738 struct MHD_DaemonOptionAndValue
   4739 MHD_D_OPTION_ENABLE_SHOUTCAST (
   4740   enum MHD_Bool value
   4741   );
   4742 
   4743 /**
   4744  * Maximum memory size per connection.
   4745  * Default is 32kb.
   4746  * Values above 128kb 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.
   4747  * The size should be large enough to fit all request headers (together with internal parsing information).
   4748  * @param value the value of the parameter * @return structure with the requested setting
   4749  */
   4750 struct MHD_DaemonOptionAndValue
   4751 MHD_D_OPTION_CONN_MEMORY_LIMIT (
   4752   size_t value
   4753   );
   4754 
   4755 /**
   4756  * The size of the shared memory pool for accamulated upload processing.
   4757  * The same large pool is shared for all connections server by MHD and used when application requests avoiding of incremental upload processing to accamulate complete content upload before giving it to the application.
   4758  * Default is 8Mb.
   4759  * Can be set to zero to disable share pool.
   4760  * @param value the value of the parameter * @return structure with the requested setting
   4761  */
   4762 struct MHD_DaemonOptionAndValue
   4763 MHD_D_OPTION_LARGE_POOL_SIZE (
   4764   size_t value
   4765   );
   4766 
   4767 /**
   4768  * Desired size of the stack for the threads started by MHD.
   4769  * Use 0 for system default, which is also MHD default.
   4770  * Works only with #MHD_D_OPTION_WM_WORKER_THREADS() or #MHD_D_OPTION_WM_THREAD_PER_CONNECTION().
   4771  * @param value the value of the parameter * @return structure with the requested setting
   4772  */
   4773 struct MHD_DaemonOptionAndValue
   4774 MHD_D_OPTION_STACK_SIZE (
   4775   size_t value
   4776   );
   4777 
   4778 /**
   4779  * The the maximum FD value.
   4780  * The limit is applied to all sockets used by MHD.
   4781  * If listen socket FD is equal or higher that specified value, the daemon fail to start.
   4782  * If new connection FD is equal or higher that specified value, the connection is rejected.
   4783  * Useful if application uses select() for polling the sockets, system FD_SETSIZE is good value for this option in such case.
   4784  * Silently ignored on W32 (WinSock sockets).
   4785  * @param max_fd FIXME
   4786  * @return structure with the requested setting
   4787  */
   4788 struct MHD_DaemonOptionAndValue
   4789 MHD_D_OPTION_FD_NUMBER_LIMIT (
   4790   MHD_Socket max_fd
   4791   );
   4792 
   4793 /**
   4794  * Enable `turbo`.
   4795  * Disables certain calls to `shutdown()`, enables aggressive non-blocking optimistic reads and other potentially unsafe optimisations.
   4796  * Most effects only happen with internal threads with epoll.
   4797  * The 'turbo' mode is not enabled (mode is disabled) by default.
   4798  * @param value the value of the parameter * @return structure with the requested setting
   4799  */
   4800 struct MHD_DaemonOptionAndValue
   4801 MHD_D_OPTION_TURBO (
   4802   enum MHD_Bool value
   4803   );
   4804 
   4805 /**
   4806  * Disable some internal thread safety.
   4807  * Indicates that MHD daemon will be used by application in single-threaded mode only.  When this flag is set then application must call any MHD function only within a single thread.
   4808  * This flag turns off some internal thread-safety and allows MHD making some of the internal optimisations suitable only for single-threaded environment.
   4809  * Not compatible with any internal threads modes.
   4810  * If MHD is compiled with custom configuration for embedded projects without threads support, this option is mandatory.
   4811  * Thread safety is not disabled (safety is enabled) by default.
   4812  * @param value the value of the parameter * @return structure with the requested setting
   4813  */
   4814 struct MHD_DaemonOptionAndValue
   4815 MHD_D_OPTION_DISABLE_THREAD_SAFETY (
   4816   enum MHD_Bool value
   4817   );
   4818 
   4819 /**
   4820  * You need to set this option if you want to disable use of HTTP Upgrade.
   4821  * Upgrade may require usage of additional internal resources, which we can avoid providing if they will not be used.
   4822  * You should only use this option if you do not use upgrade functionality and need a generally minor boost in performance and resources saving.
   4823  * The upgrade is not disallowed (upgrade is allowed) by default.
   4824  * @param value the value of the parameter * @return structure with the requested setting
   4825  */
   4826 struct MHD_DaemonOptionAndValue
   4827 MHD_D_OPTION_DISALLOW_UPGRADE (
   4828   enum MHD_Bool value
   4829   );
   4830 
   4831 /**
   4832  * Disable #MHD_action_suspend() functionality.
   4833  *
   4834 You should only use this function if you do not use suspend functionality and need a generally minor boost in performance.
   4835  * The suspend is not disallowed (suspend is allowed) by default.
   4836  * @param value the value of the parameter * @return structure with the requested setting
   4837  */
   4838 struct MHD_DaemonOptionAndValue
   4839 MHD_D_OPTION_DISALLOW_SUSPEND_RESUME (
   4840   enum MHD_Bool value
   4841   );
   4842 
   4843 /**
   4844  * Disable cookies parsing.
   4845  *
   4846 Disable automatic cookies processing if cookies are not used.
   4847  * Cookies are automatically parsed by default.
   4848  * @param value the value of the parameter * @return structure with the requested setting
   4849  */
   4850 struct MHD_DaemonOptionAndValue
   4851 MHD_D_OPTION_DISABLE_COOKIES (
   4852   enum MHD_Bool value
   4853   );
   4854 
   4855 /**
   4856  * Set a callback to be called for pre-start finalisation.
   4857  *
   4858 The specified callback will be called one time, after network initialisation, TLS pre-initialisation, but before the start of the internal threads (if allowed)
   4859  * @param cb the pre-start callback
   4860  * @param cb_cls the closure for the callback
   4861  * @return structure with the requested setting
   4862  */
   4863 struct MHD_DaemonOptionAndValue
   4864 MHD_D_OPTION_DAEMON_READY_CALLBACK (
   4865   MHD_DaemonReadyCallback cb,
   4866   void *cb_cls
   4867   );
   4868 
   4869 /**
   4870  * Set a function that should be called whenever a connection is started or closed.
   4871  * @param ncc the callback for notifications
   4872  * @param cls the closure for the callback
   4873  * @return structure with the requested setting
   4874  */
   4875 struct MHD_DaemonOptionAndValue
   4876 MHD_D_OPTION_NOTIFY_CONNECTION (
   4877   MHD_NotifyConnectionCallback ncc,
   4878   void *cls
   4879   );
   4880 
   4881 /**
   4882  * Register a function that should be called whenever a stream is started or closed.
   4883  * For HTTP/1.1 this callback is called one time for every connection.
   4884  * @param nsc the callback for notifications
   4885  * @param cls the closure for the callback
   4886  * @return structure with the requested setting
   4887  */
   4888 struct MHD_DaemonOptionAndValue
   4889 MHD_D_OPTION_NOTIFY_STREAM (
   4890   MHD_NotifyStreamCallback nsc,
   4891   void *cls
   4892   );
   4893 
   4894 /**
   4895  * Set strong random data to be used by MHD.
   4896  * Currently the data is only needed for Digest Auth module.
   4897  * Daemon support for Digest Auth is enabled automatically if this option is used.
   4898  * The recommended size is between 8 and 32 bytes. Security can be lower for sizes less or equal four.
   4899  * Sizes larger then 32 (or, probably, larger than 16 - debatable) will not increase the security.
   4900  * @param buf_size the size of the buffer
   4901  * @param buf the buffer with strong random data, the content will be copied by MHD
   4902  * @return structure with the requested setting
   4903  */
   4904 struct MHD_DaemonOptionAndValue
   4905 MHD_D_OPTION_RANDOM_ENTROPY (
   4906   size_t buf_size,
   4907   /* const */ void *buf
   4908   );
   4909 
   4910 /**
   4911  * Specify the size of the internal hash map array that tracks generated digest nonces usage.
   4912  * When the size of the map is too small then need to handle concurrent DAuth requests, a lot of stale nonce results will be produced.
   4913  * By default the size is 1000 entries.
   4914  * @param size the size of the map array
   4915  * @return structure with the requested setting
   4916  */
   4917 struct MHD_DaemonOptionAndValue
   4918 MHD_D_OPTION_AUTH_DIGEST_MAP_SIZE (
   4919   size_t size
   4920   );
   4921 
   4922 /**
   4923  * Nonce validity time (in seconds) used for Digest Auth.
   4924  * If followed by zero value the value is silently ignored.
   4925  * @see #MHD_digest_auth_check(), MHD_digest_auth_check_digest()
   4926  * @param timeout FIXME
   4927  * @return structure with the requested setting
   4928  */
   4929 struct MHD_DaemonOptionAndValue
   4930 MHD_D_OPTION_AUTH_DIGEST_NONCE_TIMEOUT (
   4931   unsigned int timeout
   4932   );
   4933 
   4934 /**
   4935  * Default maximum nc (nonce count) value used for Digest Auth.
   4936  * If followed by zero value the value is silently ignored.
   4937  * @see #MHD_digest_auth_check(), MHD_digest_auth_check_digest()
   4938  * @param max_nc FIXME
   4939  * @return structure with the requested setting
   4940  */
   4941 struct MHD_DaemonOptionAndValue
   4942 MHD_D_OPTION_AUTH_DIGEST_DEF_MAX_NC (
   4943   uint_fast32_t max_nc
   4944   );
   4945 
   4946 /* End of generated code documenting how to use options */
   4947 #endif
   4948 
   4949 /* Beginning of generated code documenting how to use options.
   4950    You should treat the following functions *as if* they were
   4951    part of the header/API. The actual declarations are more
   4952    complex, so these here are just for documentation!
   4953    We do not actually *build* this code... */
   4954 #if 0
   4955 
   4956 /**
   4957  * Make the response object re-usable.
   4958  * The response will not be consumed by MHD_action_from_response() and must be destroyed by MHD_response_destroy().
   4959  * Useful if the same response is often used to reply.
   4960  * @param value the value of the parameter * @return structure with the requested setting
   4961  */
   4962 struct MHD_ResponseOptionAndValue
   4963 MHD_R_OPTION_REUSABLE (
   4964   enum MHD_Bool value
   4965   );
   4966 
   4967 /**
   4968  * Enable special processing of the response as body-less (with undefined body size). No automatic 'Content-Length' or 'Transfer-Encoding: chunked' headers are added when the response is used with #MHD_HTTP_STATUS_NOT_MODIFIED code or to respond to HEAD request.
   4969  * The flag also allow to set arbitrary 'Content-Length' by #MHD_response_add_header() function.
   4970  * This flag value can be used only with responses created without body (zero-size body).
   4971  * Responses with this flag enabled cannot be used in situations where reply body must be sent to the client.
   4972  * This flag is primarily intended to be used when automatic 'Content-Length' header is undesirable in response to HEAD requests.
   4973  * @param value the value of the parameter * @return structure with the requested setting
   4974  */
   4975 struct MHD_ResponseOptionAndValue
   4976 MHD_R_OPTION_HEAD_ONLY_RESPONSE (
   4977   enum MHD_Bool value
   4978   );
   4979 
   4980 /**
   4981  * Force use of chunked encoding even if the response content size is known.
   4982  * Ignored when the reply cannot have body/content.
   4983  * @param value the value of the parameter * @return structure with the requested setting
   4984  */
   4985 struct MHD_ResponseOptionAndValue
   4986 MHD_R_OPTION_CHUNKED_ENC (
   4987   enum MHD_Bool value
   4988   );
   4989 
   4990 /**
   4991  * Force close connection after sending the response, prevents keep-alive connections and adds 'Connection: close' header.
   4992  * @param value the value of the parameter * @return structure with the requested setting
   4993  */
   4994 struct MHD_ResponseOptionAndValue
   4995 MHD_R_OPTION_CONN_CLOSE (
   4996   enum MHD_Bool value
   4997   );
   4998 
   4999 /**
   5000  * Only respond in conservative (dumb) HTTP/1.0-compatible mode.
   5001  * 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.
   5002  * You can also set the #MHD_R_O_HTTP_1_0_SERVER flag to force HTTP/1.0 version in the response.
   5003  * Responses are still compatible with HTTP/1.1.
   5004  * Summary:
   5005  * + declared reply version: HTTP/1.1
   5006  * + keep-alive: no
   5007  * + chunked: no
   5008  *
   5009 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.
   5010  * @param value the value of the parameter * @return structure with the requested setting
   5011  */
   5012 struct MHD_ResponseOptionAndValue
   5013 MHD_R_OPTION_HTTP_1_0_COMPATIBLE_STRICT (
   5014   enum MHD_Bool value
   5015   );
   5016 
   5017 /**
   5018  * Only respond in HTTP/1.0-mode.
   5019  * Contrary to the #MHD_R_O_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.
   5020  * The 'Connection:' header will be added for both 'close' and 'keep-alive' connections.
   5021  * Chunked encoding will not be used for the response.
   5022  * Due to backward compatibility, responses still can be used with HTTP/1.1 clients.
   5023  * 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).
   5024  * Summary:
   5025  * + declared reply version: HTTP/1.0
   5026  * + keep-alive: possible
   5027  * + chunked: no
   5028  *
   5029 With this option HTTP/1.0 server is emulated (with support for 'keep-alive' connections).
   5030  * @param value the value of the parameter * @return structure with the requested setting
   5031  */
   5032 struct MHD_ResponseOptionAndValue
   5033 MHD_R_OPTION_HTTP_1_0_SERVER (
   5034   enum MHD_Bool value
   5035   );
   5036 
   5037 /**
   5038  * Disable sanity check preventing clients from manually setting the HTTP content length option.
   5039  * Allow to set several 'Content-Length' headers. These headers will be used even with replies without body.
   5040  * @param value the value of the parameter * @return structure with the requested setting
   5041  */
   5042 struct MHD_ResponseOptionAndValue
   5043 MHD_R_OPTION_INSANITY_HEADER_CONTENT_LENGTH (
   5044   enum MHD_Bool value
   5045   );
   5046 
   5047 /**
   5048  * Set a function to be called once MHD is finished with the request.
   5049  * @param ended_cb the function to call,
   5050  *   NULL to not use the callback
   5051  * @param ended_cb_cls the closure for the callback
   5052  * @return structure with the requested setting
   5053  */
   5054 struct MHD_ResponseOptionAndValue
   5055 MHD_R_OPTION_TERMINATION_CALLBACK (
   5056   MHD_RequestEndedCallback ended_cb,
   5057   void *ended_cb_cls
   5058   );
   5059 
   5060 /* End of generated code documenting how to use options */
   5061 #endif
   5062 
   5063 /**
   5064  * Create parameter for #MHD_daemon_set_options() for work mode with
   5065  * no internal threads.
   5066  * The application periodically calls #MHD_daemon_process_blocking(), where
   5067  * MHD internally checks all sockets automatically.
   5068  * This is the default mode.
   5069  * @return the object of struct MHD_DaemonOptionAndValue with requested values
   5070  */
   5071 #define MHD_D_OPTION_WM_EXTERNAL_PERIODIC() \
   5072         MHD_D_OPTION_WORK_MODE (MHD_WM_OPTION_EXTERNAL_PERIODIC ())
   5073 
   5074 /**
   5075 * Create parameter for #MHD_daemon_set_options() for work mode with
   5076 * an external event loop with level triggers.
   5077 * Application uses #MHD_SocketRegistrationUpdateCallback, level triggered
   5078 * sockets polling (like select() or poll()) and #MHD_daemon_event_update().
   5079 * @param cb_val the callback for sockets registration
   5080 * @param cb_cls_val the closure for the @a cv_val callback
   5081 * @return the object of struct MHD_DaemonOptionAndValue with requested values
   5082 */
   5083 #define MHD_D_OPTION_WM_EXTERNAL_EVENT_LOOP_CB_LEVEL(cb_val, cb_cls_val) \
   5084         MHD_D_OPTION_WORK_MODE ( \
   5085           MHD_WM_OPTION_EXTERNAL_EVENT_LOOP_CB_LEVEL ((cb_val),(cb_cls_val)))
   5086 
   5087 /**
   5088  * Create parameter for #MHD_daemon_set_options() for work mode with
   5089  * an external event loop with edge triggers.
   5090  * Application uses #MHD_SocketRegistrationUpdateCallback, edge triggered
   5091  * sockets polling (like epoll with EPOLLET) and #MHD_daemon_event_update().
   5092  * @param cb_val the callback for sockets registration
   5093  * @param cb_cls_val the closure for the @a cv_val callback
   5094  * @return the object of struct MHD_DaemonOptionAndValue with requested values
   5095  */
   5096 #define MHD_D_OPTION_WM_EXTERNAL_EVENT_LOOP_CB_EDGE(cb_val, cb_cls_val) \
   5097         MHD_D_OPTION_WORK_MODE ( \
   5098           MHD_WM_OPTION_EXTERNAL_EVENT_LOOP_CB_EDGE ((cb_val),(cb_cls_val)))
   5099 
   5100 /**
   5101  * Create parameter for #MHD_daemon_set_options() for work mode with
   5102  * no internal threads and aggregate watch FD.
   5103  * Application uses #MHD_DAEMON_INFO_FIXED_AGGREAGATE_FD to get single FD
   5104  * that gets triggered by any MHD event.
   5105  * This FD can be watched as an aggregate indicator for all MHD events.
   5106  * This mode is available only on selected platforms (currently
   5107  * GNU/Linux only), see #MHD_LIB_INFO_FIXED_HAS_AGGREGATE_FD.
   5108  * When the FD is triggered, #MHD_daemon_process_nonblocking() should
   5109  * be called.
   5110  * @return the object of struct MHD_DaemonOptionAndValue with requested values
   5111  */
   5112 #define MHD_D_OPTION_WM_EXTERNAL_SINGLE_FD_WATCH() \
   5113         MHD_D_OPTION_WORK_MODE (MHD_WM_OPTION_EXTERNAL_SINGLE_FD_WATCH ())
   5114 
   5115 /**
   5116  * Create parameter for #MHD_daemon_set_options() for work mode with
   5117  * one or more worker threads.
   5118  * If number of threads is one, then daemon starts with single worker thread
   5119  * that handles all connections.
   5120  * If number of threads is larger than one, then that number of worker threads,
   5121  * and handling of connection is distributed among the workers.
   5122  * @param num_workers the number of worker threads, zero is treated as one
   5123  * @return the object of struct MHD_DaemonOptionAndValue with requested values
   5124  */
   5125 #define MHD_D_OPTION_WM_WORKER_THREADS(num_workers) \
   5126         MHD_D_OPTION_WORK_MODE (MHD_WM_OPTION_WORKER_THREADS (num_workers))
   5127 
   5128 /**
   5129  * Create parameter for #MHD_daemon_set_options() for work mode with
   5130  * one internal thread for listening and additional threads per every
   5131  * connection.  Use this if handling requests is CPU-intensive or blocking,
   5132  * your application is thread-safe and you have plenty of memory (per
   5133  * connection).
   5134  * @return the object of struct MHD_DaemonOptionAndValue with requested values
   5135  */
   5136 #define MHD_D_OPTION_WM_THREAD_PER_CONNECTION() \
   5137         MHD_D_OPTION_WORK_MODE (MHD_WM_OPTION_THREAD_PER_CONNECTION ())
   5138 
   5139 /**
   5140  * Set the requested options for the daemon.
   5141  *
   5142  * If any option fail other options may be or may be not applied.
   5143  * @param daemon the daemon to set the options
   5144  * @param[in] options the pointer to the array with the options;
   5145  *                    the array processing stops at the first ::MHD_D_O_END
   5146  *                    option, but not later than after processing
   5147  *                    @a options_max_num entries
   5148  * @param options_max_num the maximum number of entries in the @a options,
   5149  *                        use #MHD_OPTIONS_ARRAY_MAX_SIZE if options processing
   5150  *                        must stop only at zero-termination option
   5151  * @return ::MHD_SC_OK on success,
   5152  *         error code otherwise
   5153  */
   5154 MHD_EXTERN_ enum MHD_StatusCode
   5155 MHD_daemon_set_options (
   5156   struct MHD_Daemon *MHD_RESTRICT daemon,
   5157   const struct MHD_DaemonOptionAndValue *MHD_RESTRICT options,
   5158   size_t options_max_num)
   5159 MHD_FN_PAR_NONNULL_ALL_;
   5160 
   5161 
   5162 /**
   5163  * Set the requested single option for the daemon.
   5164  *
   5165  * @param daemon the daemon to set the option
   5166  * @param[in] option_ptr the pointer to the option
   5167  * @return ::MHD_SC_OK on success,
   5168  *         error code otherwise
   5169  */
   5170 #define MHD_daemon_set_option(daemon, option_ptr) \
   5171         MHD_daemon_set_options (daemon, option_ptr, 1)
   5172 
   5173 
   5174 /* *INDENT-OFF* */
   5175 #ifdef MHD_USE_VARARG_MACROS
   5176 MHD_NOWARN_VARIADIC_MACROS_
   5177 #  if defined(MHD_USE_COMPOUND_LITERALS) && \
   5178   defined(MHD_USE_COMP_LIT_FUNC_PARAMS)
   5179 /**
   5180  * Set the requested options for the daemon.
   5181  *
   5182  * If any option fail other options may be or may be not applied.
   5183  *
   5184  * It should be used with helpers that creates required options, for example:
   5185  *
   5186  * MHD_DAEMON_SET_OPTIONS(d, MHD_D_OPTION_SUPPRESS_DATE_HEADER(MHD_YES),
   5187  *                        MHD_D_OPTION_SOCK_ADDR(sa_len, sa))
   5188  *
   5189  * @param daemon the daemon to set the options
   5190  * @param ... the list of the options, each option must be created
   5191  *            by helpers MHD_D_OPTION_NameOfOption(option_value)
   5192  * @return ::MHD_SC_OK on success,
   5193  *         error code otherwise
   5194  */
   5195 #    define MHD_DAEMON_SET_OPTIONS(daemon,...)          \
   5196             MHD_NOWARN_COMPOUND_LITERALS_                   \
   5197             MHD_NOWARN_AGGR_DYN_INIT_                       \
   5198             MHD_daemon_set_options (                        \
   5199               daemon,                                       \
   5200               ((const struct MHD_DaemonOptionAndValue[])    \
   5201                {__VA_ARGS__, MHD_D_OPTION_TERMINATE ()}),   \
   5202               MHD_OPTIONS_ARRAY_MAX_SIZE)                   \
   5203             MHD_RESTORE_WARN_AGGR_DYN_INIT_                 \
   5204             MHD_RESTORE_WARN_COMPOUND_LITERALS_
   5205 #  elif defined(MHD_USE_CPP_INIT_LIST)
   5206 MHD_C_DECLARATIONS_FINISH_HERE_
   5207 #    include <vector>
   5208 MHD_C_DECLARATIONS_START_HERE_
   5209 /**
   5210  * Set the requested options for the daemon.
   5211  *
   5212  * If any option fail other options may be or may be not applied.
   5213  *
   5214  * It should be used with helpers that creates required options, for example:
   5215  *
   5216  * MHD_DAEMON_SET_OPTIONS(d, MHD_D_OPTION_SUPPRESS_DATE_HEADER(MHD_YES),
   5217  *                        MHD_D_OPTION_SOCK_ADDR(sa_len, sa))
   5218  *
   5219  * @param daemon the daemon to set the options
   5220  * @param ... the list of the options, each option must be created
   5221  *            by helpers MHD_D_OPTION_NameOfOption(option_value)
   5222  * @return ::MHD_SC_OK on success,
   5223  *         error code otherwise
   5224  */
   5225 #    define MHD_DAEMON_SET_OPTIONS(daemon,...)                  \
   5226             MHD_NOWARN_CPP_INIT_LIST_                               \
   5227             MHD_daemon_set_options (                                \
   5228               daemon,                                               \
   5229               (std::vector<struct MHD_DaemonOptionAndValue>         \
   5230                {__VA_ARGS__,MHD_D_OPTION_TERMINATE ()}).data (),    \
   5231               MHD_OPTIONS_ARRAY_MAX_SIZE)                           \
   5232             MHD_RESTORE_WARN_CPP_INIT_LIST_
   5233 #  endif
   5234 MHD_RESTORE_WARN_VARIADIC_MACROS_
   5235 #endif /* MHD_USE_VARARG_MACROS && MHD_USE_COMP_LIT_FUNC_PARAMS */
   5236 /* *INDENT-ON* */
   5237 
   5238 
   5239 /* ******************* Event loop ************************ */
   5240 
   5241 
   5242 /**
   5243  * Run websever operation with possible blocking.
   5244  *
   5245  * Supported only in #MHD_WM_EXTERNAL_PERIODIC and
   5246  * #MHD_WM_EXTERNAL_SINGLE_FD_WATCH modes.
   5247  *
   5248  * This function does the following: waits for any network event not more than
   5249  * specified number of microseconds, processes all incoming and outgoing data,
   5250  * processes new connections, processes any timed-out connection, and does
   5251  * other things required to run webserver.
   5252  * Once all connections are processed, function returns.
   5253  *
   5254  * This function is useful for quick and simple (lazy) webserver implementation
   5255  * if application needs to run a single thread only and does not have any other
   5256  * network activity.
   5257  *
   5258  * In #MHD_WM_EXTERNAL_PERIODIC mode if @a microsec parameter is not zero
   5259  * this function determines the internal daemon timeout and use returned value
   5260  * as maximum wait time if it less than value of @a microsec parameter.
   5261  *
   5262  * @param daemon the daemon to run
   5263  * @param microsec the maximum time in microseconds to wait for network and
   5264  *                 other events. Note: there is no guarantee that function
   5265  *                 blocks for the specified amount of time. The real processing
   5266  *                 time can be shorter (if some data or connection timeout
   5267  *                 comes earlier) or longer (if data processing requires more
   5268  *                 time, especially in user callbacks).
   5269  *                 If set to '0' then function does not block and processes
   5270  *                 only already available data (if any). Zero value is
   5271  *                 recommended when used in #MHD_WM_EXTERNAL_SINGLE_FD_WATCH
   5272  *                 and the watched FD has been triggered.
   5273  *                 If set to #MHD_WAIT_INDEFINITELY then function waits
   5274  *                 for events indefinitely (blocks until next network activity
   5275  *                 or connection timeout).
   5276  *                 Always used as zero value in
   5277  *                 #MHD_WM_EXTERNAL_SINGLE_FD_WATCH mode.
   5278  * @return #MHD_SC_OK on success, otherwise
   5279  *         an error code
   5280  * @ingroup event
   5281  */
   5282 MHD_EXTERN_ enum MHD_StatusCode
   5283 MHD_daemon_process_blocking (struct MHD_Daemon *daemon,
   5284                              uint_fast64_t microsec)
   5285 MHD_FN_PAR_NONNULL_ (1);
   5286 
   5287 /**
   5288  * Run webserver operations (without blocking unless in client
   5289  * callbacks).
   5290  *
   5291  * Supported only in #MHD_WM_EXTERNAL_SINGLE_FD_WATCH mode.
   5292  *
   5293  * This function does the following: processes all incoming and outgoing data,
   5294  * processes new connections, processes any timed-out connection, and does
   5295  * other things required to run webserver.
   5296  * Once all connections are processed, function returns.
   5297  *
   5298  * @param daemon the daemon to run
   5299  * @return #MHD_SC_OK on success, otherwise
   5300  *         an error code
   5301  * @ingroup event
   5302  */
   5303 #define MHD_daemon_process_nonblocking(daemon) \
   5304         MHD_daemon_process_blocking (daemon, 0)
   5305 
   5306 
   5307 /**
   5308  * Add another client connection to the set of connections managed by
   5309  * MHD.  This API is usually not needed (since MHD will accept inbound
   5310  * connections on the server socket).  Use this API in special cases,
   5311  * for example if your HTTP server is behind NAT and needs to connect
   5312  * out to the HTTP client, or if you are building a proxy.
   5313  *
   5314  * The given client socket will be managed (and closed!) by MHD after
   5315  * this call and must no longer be used directly by the application
   5316  * afterwards.
   5317  * The client socket will be closed by MHD even if error returned.
   5318  *
   5319  * @param daemon daemon that manages the connection
   5320  * @param new_socket socket to manage (MHD will expect to receive an
   5321                      HTTP request from this socket next).
   5322  * @param addr_size number of bytes in @a addr
   5323  * @param addr IP address of the client, ignored when @a addrlen is zero
   5324  * @param connection_cntx meta data the application wants to
   5325  *        associate with the new connection object
   5326  * @return #MHD_SC_OK on success,
   5327  *         error on failure (the @a new_socket is closed)
   5328  * @ingroup specialized
   5329  */
   5330 MHD_EXTERN_ enum MHD_StatusCode
   5331 MHD_daemon_add_connection (struct MHD_Daemon *MHD_RESTRICT daemon,
   5332                            MHD_Socket new_socket,
   5333                            size_t addr_size,
   5334                            const struct sockaddr *MHD_RESTRICT addr,
   5335                            void *connection_cntx)
   5336 MHD_FN_PAR_NONNULL_ (1)
   5337 MHD_FN_PAR_IN_ (4);
   5338 
   5339 
   5340 /* ********************* connection options ************** */
   5341 
   5342 enum MHD_FIXED_ENUM_APP_SET_ MHD_ConnectionOption
   5343 {
   5344   /**
   5345    * Not a real option.
   5346    * Should not be used directly.
   5347    * This value indicates the end of the list of the options.
   5348    */
   5349   MHD_C_O_END = 0
   5350   ,
   5351   /**
   5352    * Set custom timeout for the given connection.
   5353    * Specified as the number of seconds.  Use zero for no timeout.
   5354    * Setting this option resets connection timeout timer.
   5355    */
   5356   MHD_C_O_TIMEOUT = 1
   5357   ,
   5358 
   5359 
   5360   /* * Sentinel * */
   5361   /**
   5362    * The sentinel value.
   5363    * This value enforces specific underlying integer type for the enum.
   5364    * Do not use.
   5365    */
   5366   MHD_C_O_SENTINEL = 65535
   5367 };
   5368 
   5369 
   5370 /**
   5371  * Dummy-struct for space allocation.
   5372  * Do not use in application logic.
   5373  */
   5374 struct MHD_ReservedStruct
   5375 {
   5376   uint_fast64_t reserved1;
   5377   void *reserved2;
   5378 };
   5379 
   5380 
   5381 /**
   5382  * Parameters for MHD connection options
   5383  */
   5384 union MHD_ConnectionOptionValue
   5385 {
   5386   /**
   5387    * Value for #MHD_C_O_TIMEOUT
   5388    */
   5389   unsigned int v_timeout;
   5390   /**
   5391    * Reserved member. Do not use.
   5392    */
   5393   struct MHD_ReservedStruct reserved;
   5394 };
   5395 
   5396 /**
   5397  * Combination of MHD connection option with parameters values
   5398  */
   5399 struct MHD_ConnectionOptionAndValue
   5400 {
   5401   /**
   5402    * The connection configuration option
   5403    */
   5404   enum MHD_ConnectionOption opt;
   5405   /**
   5406    * The value for the @a opt option
   5407    */
   5408   union MHD_ConnectionOptionValue val;
   5409 };
   5410 
   5411 #if defined(MHD_USE_COMPOUND_LITERALS) && defined(MHD_USE_DESIG_NEST_INIT)
   5412 /**
   5413  * Set custom timeout for the given connection.
   5414  * Specified as the number of seconds.  Use zero for no timeout.
   5415  * Setting this option resets connection timeout timer.
   5416  * @param timeout the in seconds, zero for no timeout
   5417  * @return the object of struct MHD_ConnectionOptionAndValue with the requested
   5418  *         values
   5419  */
   5420 #  define MHD_C_OPTION_TIMEOUT(timeout)         \
   5421           MHD_NOWARN_COMPOUND_LITERALS_                 \
   5422             (const struct MHD_ConnectionOptionAndValue) \
   5423           {                                             \
   5424             .opt = (MHD_C_O_TIMEOUT),                   \
   5425             .val.v_timeout = (timeout)                  \
   5426           }                                             \
   5427           MHD_RESTORE_WARN_COMPOUND_LITERALS_
   5428 
   5429 /**
   5430  * Terminate the list of the options
   5431  * @return the terminating object of struct MHD_ConnectionOptionAndValue
   5432  */
   5433 #  define MHD_C_OPTION_TERMINATE()              \
   5434           MHD_NOWARN_COMPOUND_LITERALS_                 \
   5435             (const struct MHD_ConnectionOptionAndValue) \
   5436           {                                             \
   5437             .opt = (MHD_C_O_END)                        \
   5438           }                                             \
   5439           MHD_RESTORE_WARN_COMPOUND_LITERALS_
   5440 
   5441 #else  /* !MHD_USE_COMPOUND_LITERALS || !MHD_USE_DESIG_NEST_INIT */
   5442 MHD_NOWARN_UNUSED_FUNC_
   5443 
   5444 /**
   5445  * Set custom timeout for the given connection.
   5446  * Specified as the number of seconds.  Use zero for no timeout.
   5447  * Setting this option resets connection timeout timer.
   5448  * @param timeout the in seconds, zero for no timeout
   5449  * @return the object of struct MHD_ConnectionOptionAndValue with the requested
   5450  *         values
   5451  */
   5452 static MHD_INLINE struct MHD_ConnectionOptionAndValue
   5453 MHD_C_OPTION_TIMEOUT (unsigned int timeout)
   5454 {
   5455   struct MHD_ConnectionOptionAndValue opt_val;
   5456 
   5457   opt_val.opt = MHD_C_O_TIMEOUT;
   5458   opt_val.val.v_timeout = timeout;
   5459 
   5460   return opt_val;
   5461 }
   5462 
   5463 
   5464 /**
   5465  * Terminate the list of the options
   5466  * @return the terminating object of struct MHD_ConnectionOptionAndValue
   5467  */
   5468 static MHD_INLINE struct MHD_ConnectionOptionAndValue
   5469 MHD_C_OPTION_TERMINATE (void)
   5470 {
   5471   struct MHD_ConnectionOptionAndValue opt_val;
   5472 
   5473   opt_val.opt = MHD_C_O_END;
   5474 
   5475   return opt_val;
   5476 }
   5477 
   5478 
   5479 MHD_RESTORE_WARN_UNUSED_FUNC_
   5480 #endif /* !MHD_USE_COMPOUND_LITERALS || !MHD_USE_DESIG_NEST_INIT */
   5481 
   5482 /**
   5483  * Set the requested options for the connection.
   5484  *
   5485  * If any option fail other options may be or may be not applied.
   5486  * @param connection the connection to set the options
   5487  * @param[in] options the pointer to the array with the options;
   5488  *                    the array processing stops at the first ::MHD_D_O_END
   5489  *                    option, but not later than after processing
   5490  *                    @a options_max_num entries
   5491  * @param options_max_num the maximum number of entries in the @a options,
   5492  *                        use #MHD_OPTIONS_ARRAY_MAX_SIZE if options processing
   5493  *                        must stop only at zero-termination option
   5494  * @return ::MHD_SC_OK on success,
   5495  *         error code otherwise
   5496  */
   5497 MHD_EXTERN_ enum MHD_StatusCode
   5498 MHD_connection_set_options (
   5499   struct MHD_Connection *MHD_RESTRICT connection,
   5500   const struct MHD_ConnectionOptionAndValue *MHD_RESTRICT options,
   5501   size_t options_max_num)
   5502 MHD_FN_PAR_NONNULL_ALL_;
   5503 
   5504 
   5505 /**
   5506  * Set the requested single option for the connection.
   5507  *
   5508  * @param connection the connection to set the options
   5509  * @param[in] option_ptr the pointer to the option
   5510  * @return ::MHD_SC_OK on success,
   5511  *         error code otherwise
   5512  */
   5513 #define MHD_connection_set_option(connection, option_ptr) \
   5514         MHD_connection_set_options (connection, options_ptr, 1)
   5515 
   5516 
   5517 /* *INDENT-OFF* */
   5518 #ifdef MHD_USE_VARARG_MACROS
   5519 MHD_NOWARN_VARIADIC_MACROS_
   5520 #  if defined(MHD_USE_COMPOUND_LITERALS) && defined(MHD_USE_COMP_LIT_FUNC_PARAMS \
   5521                                                     )
   5522 /**
   5523  * Set the requested options for the connection.
   5524  *
   5525  * If any option fail other options may be or may be not applied.
   5526  *
   5527  * It should be used with helpers that creates required options, for example:
   5528  *
   5529  * MHD_CONNECTION_SET_OPTIONS(d, MHD_C_OPTION_TIMEOUT(30))
   5530  *
   5531  * @param connection the connection to set the options
   5532  * @param ... the list of the options, each option must be created
   5533  *            by helpers MHD_C_OPTION_NameOfOption(option_value)
   5534  * @return ::MHD_SC_OK on success,
   5535  *         error code otherwise
   5536  */
   5537 #    define MHD_CONNECTION_SET_OPTIONS(connection,...)          \
   5538             MHD_NOWARN_COMPOUND_LITERALS_                           \
   5539             MHD_connection_set_options (                            \
   5540               daemon,                                               \
   5541               ((const struct MHD_ConnectionOptionAndValue [])       \
   5542                {__VA_ARGS__, MHD_C_OPTION_TERMINATE ()}),           \
   5543               MHD_OPTIONS_ARRAY_MAX_SIZE)                           \
   5544             MHD_RESTORE_WARN_COMPOUND_LITERALS_
   5545 #  elif defined(MHD_USE_CPP_INIT_LIST)
   5546 MHD_C_DECLARATIONS_FINISH_HERE_
   5547 #    include <vector>
   5548 MHD_C_DECLARATIONS_START_HERE_
   5549 /**
   5550  * Set the requested options for the connection.
   5551  *
   5552  * If any option fail other options may be or may be not applied.
   5553  *
   5554  * It should be used with helpers that creates required options, for example:
   5555  *
   5556  * MHD_CONNECTION_SET_OPTIONS(d, MHD_C_OPTION_TIMEOUT(30))
   5557  *
   5558  * @param connection the connection to set the options
   5559  * @param ... the list of the options, each option must be created
   5560  *            by helpers MHD_C_OPTION_NameOfOption(option_value)
   5561  * @return ::MHD_SC_OK on success,
   5562  *         error code otherwise
   5563  */
   5564 #    define MHD_CONNECTION_SET_OPTIONS(daemon,...)              \
   5565             MHD_NOWARN_CPP_INIT_LIST_                               \
   5566             MHD_daemon_set_options (                                \
   5567               daemon,                                               \
   5568               (std::vector<struct MHD_ConnectionOptionAndValue>     \
   5569                {__VA_ARGS__,MHD_C_OPTION_TERMINATE ()}).data (),    \
   5570               MHD_OPTIONS_ARRAY_MAX_SIZE)                           \
   5571             MHD_RESTORE_WARN_CPP_INIT_LIST_
   5572 #  endif
   5573 MHD_RESTORE_WARN_VARIADIC_MACROS_
   5574 #endif /* MHD_USE_VARARG_MACROS && MHD_USE_COMP_LIT_FUNC_PARAMS */
   5575 /* *INDENT-ON* */
   5576 
   5577 
   5578 /* **************** Request handling functions ***************** */
   5579 
   5580 
   5581 /**
   5582  * The `enum MHD_ValueKind` specifies the source of
   5583  * the name-value pairs in the HTTP protocol.
   5584  */
   5585 enum MHD_FLAGS_ENUM_ MHD_ValueKind
   5586 {
   5587 
   5588   /**
   5589    * HTTP header.
   5590    * The 'value' for this kind is mandatory.
   5591    */
   5592   MHD_VK_HEADER = (1u << 0)
   5593   ,
   5594   /**
   5595    * Cookies.  Note that the original HTTP header containing
   5596    * the cookie(s) will still be available and intact.
   5597    * The 'value' for this kind is optional.
   5598    */
   5599   MHD_VK_COOKIE = (1u << 1)
   5600   ,
   5601   /**
   5602    * URI query parameter.
   5603    * The 'value' for this kind is optional.
   5604    */
   5605   MHD_VK_URI_QUERY_PARAM = (1u << 2)
   5606   ,
   5607   /**
   5608    * POST data.
   5609    * This is available only if #MHD_action_parse_post() action is used,
   5610    * a content encoding is supported by MHD, and only if the posted content
   5611    * fits within the specified memory buffers.
   5612    *
   5613    * @warning The encoding "multipart/form-data" has more fields than just
   5614    * "name" and "value". See #MHD_request_get_post_data_cb() and
   5615    * #MHD_request_get_post_data_list(). In particular it could be important
   5616    * to check used "Transfer-Encoding". While it is deprecated and not used
   5617    * by modern clients, formally it can be used.
   5618    */
   5619   MHD_VK_POSTDATA = (1u << 3)
   5620   ,
   5621   /**
   5622    * HTTP trailer (only for HTTP 1.1 chunked encodings, "footer").
   5623    * The 'value' for this kind is mandatory.
   5624    */
   5625   MHD_VK_TRAILER = (1u << 4)
   5626   ,
   5627   /**
   5628    * Header and trailer values.
   5629    */
   5630   MHD_VK_HEADER_TRAILER = MHD_VK_HEADER | MHD_VK_TRAILER
   5631   ,
   5632   /**
   5633    * Values from URI query parameters or post data.
   5634    */
   5635   MHD_VK_URI_QUERY_POST = MHD_VK_POSTDATA | MHD_VK_URI_QUERY_PARAM
   5636 };
   5637 
   5638 /**
   5639  * Name with value pair
   5640  */
   5641 struct MHD_NameAndValue
   5642 {
   5643   /**
   5644    * The name (key) of the field.
   5645    * The pointer to the C string must never be NULL.
   5646    * Some types (kinds) allow empty strings.
   5647    */
   5648   struct MHD_String name;
   5649   /**
   5650    * The value of the field.
   5651    * Some types (kinds) allow absence of the value. The absence is indicated
   5652    * by NULL pointer to the C string.
   5653    */
   5654   struct MHD_StringNullable value;
   5655 };
   5656 
   5657 /**
   5658  * Name, value and kind (type) of data
   5659  */
   5660 struct MHD_NameValueKind
   5661 {
   5662   /**
   5663    * The name and the value of the field
   5664    */
   5665   struct MHD_NameAndValue nv;
   5666   /**
   5667    * The kind (type) of the field
   5668    */
   5669   enum MHD_ValueKind kind;
   5670 };
   5671 
   5672 /**
   5673  * Iterator over name-value pairs.  This iterator can be used to
   5674  * iterate over all of the cookies, headers, footers or POST-data fields
   5675  * of a request.
   5676  *
   5677  * The @a nv pointer is valid only until return from this function.
   5678  *
   5679  * The strings in @a nv are valid until any MHD_Action or MHD_UploadAction
   5680  * is provided.
   5681  * If the data is needed beyond this point, it should be copied.
   5682  *
   5683  * @param cls closure
   5684  * @param nv the name and the value of the element, the pointer is valid only until
   5685  *           return from this function
   5686  * @param kind the type (kind) of the element
   5687  * @return #MHD_YES to continue iterating,
   5688  *         #MHD_NO to abort the iteration
   5689  * @ingroup request
   5690  */
   5691 typedef enum MHD_Bool
   5692 (MHD_FN_PAR_NONNULL_ (3)
   5693  *MHD_NameValueIterator)(void *cls,
   5694                          enum MHD_ValueKind kind,
   5695                          const struct MHD_NameAndValue *nv);
   5696 
   5697 
   5698 /**
   5699  * Get all of the headers (or other kind of request data) via callback.
   5700  *
   5701  * @param[in,out] request request to get values from
   5702  * @param kind types of values to iterate over, can be a bitmask
   5703  * @param iterator callback to call on each header;
   5704  *        maybe NULL (then just count headers)
   5705  * @param iterator_cls extra argument to @a iterator
   5706  * @return number of entries iterated over
   5707  * @ingroup request
   5708  */
   5709 MHD_EXTERN_ size_t
   5710 MHD_request_get_values_cb (struct MHD_Request *request,
   5711                            enum MHD_ValueKind kind,
   5712                            MHD_NameValueIterator iterator,
   5713                            void *iterator_cls)
   5714 MHD_FN_PAR_NONNULL_ (1);
   5715 
   5716 
   5717 /**
   5718  * Get all of the headers (or other kind of request data) from the request.
   5719  *
   5720  * The pointers to the strings in @a elements are valid until any
   5721  * MHD_Action or MHD_UploadAction is provided. If the data is needed beyond
   5722  * this point, it should be copied.
   5723  *
   5724  * @param[in] request request to get values from
   5725  * @param kind the types of values to get, can be a bitmask
   5726  * @param num_elements the number of elements in @a elements array
   5727  * @param[out] elements the array of @a num_elements strings to be filled with
   5728  *                      the key-value pairs; if @a request has more elements
   5729  *                      than @a num_elements than any @a num_elements are
   5730  *                      stored
   5731  * @return the number of elements stored in @a elements, the
   5732  *         number cannot be larger then @a num_elements,
   5733  *         zero if there is no such values or any error occurs
   5734  */
   5735 MHD_EXTERN_ size_t
   5736 MHD_request_get_values_list (
   5737   struct MHD_Request *request,
   5738   enum MHD_ValueKind kind,
   5739   size_t num_elements,
   5740   struct MHD_NameValueKind *elements)
   5741 MHD_FN_PAR_NONNULL_ (1)
   5742 MHD_FN_PAR_NONNULL_ (4) MHD_FN_PAR_OUT_SIZE_ (4, 3);
   5743 
   5744 
   5745 /**
   5746  * Get a particular header (or other kind of request data) value.
   5747  * If multiple values match the kind, return any one of them.
   5748  *
   5749  * The data in the @a value_out is valid until any MHD_Action or
   5750  * MHD_UploadAction is provided. If the data is needed beyond this point,
   5751  * it should be copied.
   5752  *
   5753  * @param request request to get values from
   5754  * @param kind what kind of value are we looking for
   5755  * @param key the name of the value looking for (used for case-insensetive
   5756  *            match), empty to lookup 'trailing' value without a key
   5757  * @param[out] value_out set to the value of the header if succeed,
   5758  *                       the @a cstr pointer could be NULL even if succeed
   5759  *                       if the requested item found, but has no value
   5760  * @return #MHD_YES if succeed, the @a value_out is set;
   5761  *         #MHD_NO if no such item was found, the @a value_out string pointer
   5762  *                 set to NULL
   5763  * @ingroup request
   5764  */
   5765 MHD_EXTERN_ enum MHD_Bool
   5766 MHD_request_get_value (struct MHD_Request *MHD_RESTRICT request,
   5767                        enum MHD_ValueKind kind,
   5768                        const char *MHD_RESTRICT key,
   5769                        struct MHD_StringNullable *MHD_RESTRICT value_out)
   5770 MHD_FN_PAR_NONNULL_ (1)
   5771 MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_CSTR_ (3)
   5772 MHD_FN_PAR_OUT_ (4);
   5773 
   5774 
   5775 /**
   5776  * @brief Status codes defined for HTTP responses.
   5777  *
   5778  * @defgroup httpcode HTTP response codes
   5779  * @{
   5780  */
   5781 /* Registry export date: 2023-09-29 */
   5782 /* See http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml */
   5783 enum MHD_FIXED_ENUM_APP_SET_ MHD_HTTP_StatusCode
   5784 {
   5785   /* 100 "Continue".            RFC9110, Section 15.2.1. */
   5786   MHD_HTTP_STATUS_CONTINUE =                    100
   5787   ,
   5788   /* 101 "Switching Protocols". RFC9110, Section 15.2.2. */
   5789   MHD_HTTP_STATUS_SWITCHING_PROTOCOLS =         101
   5790   ,
   5791   /* 102 "Processing".          RFC2518. */
   5792   MHD_HTTP_STATUS_PROCESSING =                  102
   5793   ,
   5794   /* 103 "Early Hints".         RFC8297. */
   5795   MHD_HTTP_STATUS_EARLY_HINTS =                 103
   5796   ,
   5797 
   5798   /* 200 "OK".                  RFC9110, Section 15.3.1. */
   5799   MHD_HTTP_STATUS_OK =                          200
   5800   ,
   5801   /* 201 "Created".             RFC9110, Section 15.3.2. */
   5802   MHD_HTTP_STATUS_CREATED =                     201
   5803   ,
   5804   /* 202 "Accepted".            RFC9110, Section 15.3.3. */
   5805   MHD_HTTP_STATUS_ACCEPTED =                    202
   5806   ,
   5807   /* 203 "Non-Authoritative Information". RFC9110, Section 15.3.4. */
   5808   MHD_HTTP_STATUS_NON_AUTHORITATIVE_INFORMATION = 203
   5809   ,
   5810   /* 204 "No Content".          RFC9110, Section 15.3.5. */
   5811   MHD_HTTP_STATUS_NO_CONTENT =                  204
   5812   ,
   5813   /* 205 "Reset Content".       RFC9110, Section 15.3.6. */
   5814   MHD_HTTP_STATUS_RESET_CONTENT =               205
   5815   ,
   5816   /* 206 "Partial Content".     RFC9110, Section 15.3.7. */
   5817   MHD_HTTP_STATUS_PARTIAL_CONTENT =             206
   5818   ,
   5819   /* 207 "Multi-Status".        RFC4918. */
   5820   MHD_HTTP_STATUS_MULTI_STATUS =                207
   5821   ,
   5822   /* 208 "Already Reported".    RFC5842. */
   5823   MHD_HTTP_STATUS_ALREADY_REPORTED =            208
   5824   ,
   5825 
   5826   /* 226 "IM Used".             RFC3229. */
   5827   MHD_HTTP_STATUS_IM_USED =                     226
   5828   ,
   5829 
   5830   /* 300 "Multiple Choices".    RFC9110, Section 15.4.1. */
   5831   MHD_HTTP_STATUS_MULTIPLE_CHOICES =            300
   5832   ,
   5833   /* 301 "Moved Permanently".   RFC9110, Section 15.4.2. */
   5834   MHD_HTTP_STATUS_MOVED_PERMANENTLY =           301
   5835   ,
   5836   /* 302 "Found".               RFC9110, Section 15.4.3. */
   5837   MHD_HTTP_STATUS_FOUND =                       302
   5838   ,
   5839   /* 303 "See Other".           RFC9110, Section 15.4.4. */
   5840   MHD_HTTP_STATUS_SEE_OTHER =                   303
   5841   ,
   5842   /* 304 "Not Modified".        RFC9110, Section 15.4.5. */
   5843   MHD_HTTP_STATUS_NOT_MODIFIED =                304
   5844   ,
   5845   /* 305 "Use Proxy".           RFC9110, Section 15.4.6. */
   5846   MHD_HTTP_STATUS_USE_PROXY =                   305
   5847   ,
   5848   /* 306 "Switch Proxy".        Not used! RFC9110, Section 15.4.7. */
   5849   MHD_HTTP_STATUS_SWITCH_PROXY =                306
   5850   ,
   5851   /* 307 "Temporary Redirect".  RFC9110, Section 15.4.8. */
   5852   MHD_HTTP_STATUS_TEMPORARY_REDIRECT =          307
   5853   ,
   5854   /* 308 "Permanent Redirect".  RFC9110, Section 15.4.9. */
   5855   MHD_HTTP_STATUS_PERMANENT_REDIRECT =          308
   5856   ,
   5857 
   5858   /* 400 "Bad Request".         RFC9110, Section 15.5.1. */
   5859   MHD_HTTP_STATUS_BAD_REQUEST =                 400
   5860   ,
   5861   /* 401 "Unauthorized".        RFC9110, Section 15.5.2. */
   5862   MHD_HTTP_STATUS_UNAUTHORIZED =                401
   5863   ,
   5864   /* 402 "Payment Required".    RFC9110, Section 15.5.3. */
   5865   MHD_HTTP_STATUS_PAYMENT_REQUIRED =            402
   5866   ,
   5867   /* 403 "Forbidden".           RFC9110, Section 15.5.4. */
   5868   MHD_HTTP_STATUS_FORBIDDEN =                   403
   5869   ,
   5870   /* 404 "Not Found".           RFC9110, Section 15.5.5. */
   5871   MHD_HTTP_STATUS_NOT_FOUND =                   404
   5872   ,
   5873   /* 405 "Method Not Allowed".  RFC9110, Section 15.5.6. */
   5874   MHD_HTTP_STATUS_METHOD_NOT_ALLOWED =          405
   5875   ,
   5876   /* 406 "Not Acceptable".      RFC9110, Section 15.5.7. */
   5877   MHD_HTTP_STATUS_NOT_ACCEPTABLE =              406
   5878   ,
   5879   /* 407 "Proxy Authentication Required". RFC9110, Section 15.5.8. */
   5880   MHD_HTTP_STATUS_PROXY_AUTHENTICATION_REQUIRED = 407
   5881   ,
   5882   /* 408 "Request Timeout".     RFC9110, Section 15.5.9. */
   5883   MHD_HTTP_STATUS_REQUEST_TIMEOUT =             408
   5884   ,
   5885   /* 409 "Conflict".            RFC9110, Section 15.5.10. */
   5886   MHD_HTTP_STATUS_CONFLICT =                    409
   5887   ,
   5888   /* 410 "Gone".                RFC9110, Section 15.5.11. */
   5889   MHD_HTTP_STATUS_GONE =                        410
   5890   ,
   5891   /* 411 "Length Required".     RFC9110, Section 15.5.12. */
   5892   MHD_HTTP_STATUS_LENGTH_REQUIRED =             411
   5893   ,
   5894   /* 412 "Precondition Failed". RFC9110, Section 15.5.13. */
   5895   MHD_HTTP_STATUS_PRECONDITION_FAILED =         412
   5896   ,
   5897   /* 413 "Content Too Large".   RFC9110, Section 15.5.14. */
   5898   MHD_HTTP_STATUS_CONTENT_TOO_LARGE =           413
   5899   ,
   5900   /* 414 "URI Too Long".        RFC9110, Section 15.5.15. */
   5901   MHD_HTTP_STATUS_URI_TOO_LONG =                414
   5902   ,
   5903   /* 415 "Unsupported Media Type". RFC9110, Section 15.5.16. */
   5904   MHD_HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE =      415
   5905   ,
   5906   /* 416 "Range Not Satisfiable". RFC9110, Section 15.5.17. */
   5907   MHD_HTTP_STATUS_RANGE_NOT_SATISFIABLE =       416
   5908   ,
   5909   /* 417 "Expectation Failed".  RFC9110, Section 15.5.18. */
   5910   MHD_HTTP_STATUS_EXPECTATION_FAILED =          417
   5911   ,
   5912 
   5913 
   5914   /* 421 "Misdirected Request". RFC9110, Section 15.5.20. */
   5915   MHD_HTTP_STATUS_MISDIRECTED_REQUEST =         421
   5916   ,
   5917   /* 422 "Unprocessable Content". RFC9110, Section 15.5.21. */
   5918   MHD_HTTP_STATUS_UNPROCESSABLE_CONTENT =       422
   5919   ,
   5920   /* 423 "Locked".              RFC4918. */
   5921   MHD_HTTP_STATUS_LOCKED =                      423
   5922   ,
   5923   /* 424 "Failed Dependency".   RFC4918. */
   5924   MHD_HTTP_STATUS_FAILED_DEPENDENCY =           424
   5925   ,
   5926   /* 425 "Too Early".           RFC8470. */
   5927   MHD_HTTP_STATUS_TOO_EARLY =                   425
   5928   ,
   5929   /* 426 "Upgrade Required".    RFC9110, Section 15.5.22. */
   5930   MHD_HTTP_STATUS_UPGRADE_REQUIRED =            426
   5931   ,
   5932 
   5933   /* 428 "Precondition Required". RFC6585. */
   5934   MHD_HTTP_STATUS_PRECONDITION_REQUIRED =       428
   5935   ,
   5936   /* 429 "Too Many Requests".   RFC6585. */
   5937   MHD_HTTP_STATUS_TOO_MANY_REQUESTS =           429
   5938   ,
   5939 
   5940   /* 431 "Request Header Fields Too Large". RFC6585. */
   5941   MHD_HTTP_STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE = 431
   5942   ,
   5943 
   5944   /* 451 "Unavailable For Legal Reasons". RFC7725. */
   5945   MHD_HTTP_STATUS_UNAVAILABLE_FOR_LEGAL_REASONS = 451
   5946   ,
   5947 
   5948   /* 500 "Internal Server Error". RFC9110, Section 15.6.1. */
   5949   MHD_HTTP_STATUS_INTERNAL_SERVER_ERROR =       500
   5950   ,
   5951   /* 501 "Not Implemented".     RFC9110, Section 15.6.2. */
   5952   MHD_HTTP_STATUS_NOT_IMPLEMENTED =             501
   5953   ,
   5954   /* 502 "Bad Gateway".         RFC9110, Section 15.6.3. */
   5955   MHD_HTTP_STATUS_BAD_GATEWAY =                 502
   5956   ,
   5957   /* 503 "Service Unavailable". RFC9110, Section 15.6.4. */
   5958   MHD_HTTP_STATUS_SERVICE_UNAVAILABLE =         503
   5959   ,
   5960   /* 504 "Gateway Timeout".     RFC9110, Section 15.6.5. */
   5961   MHD_HTTP_STATUS_GATEWAY_TIMEOUT =             504
   5962   ,
   5963   /* 505 "HTTP Version Not Supported". RFC9110, Section 15.6.6. */
   5964   MHD_HTTP_STATUS_HTTP_VERSION_NOT_SUPPORTED =  505
   5965   ,
   5966   /* 506 "Variant Also Negotiates". RFC2295. */
   5967   MHD_HTTP_STATUS_VARIANT_ALSO_NEGOTIATES =     506
   5968   ,
   5969   /* 507 "Insufficient Storage". RFC4918. */
   5970   MHD_HTTP_STATUS_INSUFFICIENT_STORAGE =        507
   5971   ,
   5972   /* 508 "Loop Detected".       RFC5842. */
   5973   MHD_HTTP_STATUS_LOOP_DETECTED =               508
   5974   ,
   5975 
   5976   /* 510 "Not Extended".        (OBSOLETED) RFC2774; status-change-http-experiments-to-historic. */
   5977   MHD_HTTP_STATUS_NOT_EXTENDED =                510
   5978   ,
   5979   /* 511 "Network Authentication Required". RFC6585. */
   5980   MHD_HTTP_STATUS_NETWORK_AUTHENTICATION_REQUIRED = 511
   5981   ,
   5982 
   5983 
   5984   /* Not registered non-standard codes */
   5985   /* 449 "Reply With".          MS IIS extension. */
   5986   MHD_HTTP_STATUS_RETRY_WITH =                  449
   5987   ,
   5988 
   5989   /* 450 "Blocked by Windows Parental Controls". MS extension. */
   5990   MHD_HTTP_STATUS_BLOCKED_BY_WINDOWS_PARENTAL_CONTROLS = 450
   5991   ,
   5992 
   5993   /* 509 "Bandwidth Limit Exceeded". Apache extension. */
   5994   MHD_HTTP_STATUS_BANDWIDTH_LIMIT_EXCEEDED =    509
   5995   ,
   5996 
   5997 
   5998   /**
   5999    * The sentinel value.
   6000    * This value enforces specific underlying integer type for the enum.
   6001    * Do not use.
   6002    */
   6003   MHD_HTTP_STATUS_SENTINEL =                    999
   6004 };
   6005 
   6006 
   6007 /**
   6008  * Returns the string status for a response code.
   6009  *
   6010  * This function works for @b HTTP status code, not for @b MHD error codes/
   6011  * @param code the HTTP code to get text representation for
   6012  * @return the pointer to the text representation,
   6013  *         NULL if HTTP status code in not known.
   6014  */
   6015 MHD_EXTERN_ const struct MHD_String *
   6016 MHD_HTTP_status_code_to_string (enum MHD_HTTP_StatusCode code)
   6017 MHD_FN_CONST_;
   6018 
   6019 /**
   6020  * Get the pointer to the C string for the HTTP response code, never NULL.
   6021  */
   6022 #define MHD_HTTP_status_code_to_string_lazy(code) \
   6023         (MHD_HTTP_status_code_to_string ((code)) ? \
   6024          ((MHD_HTTP_status_code_to_string (code))->cstr) : ("[No status]") )
   6025 
   6026 
   6027 /** @} */ /* end of group httpcode */
   6028 
   6029 #ifndef MHD_HTTP_PROTOCOL_VER_DEFINED
   6030 
   6031 /**
   6032  * @brief HTTP protocol versions
   6033  * @defgroup versions HTTP versions
   6034  * @{
   6035  */
   6036 enum MHD_FIXED_ENUM_MHD_SET_ MHD_HTTP_ProtocolVersion
   6037 {
   6038   MHD_HTTP_VERSION_INVALID = 0  /**< Invalid/unrecognised HTTP version */
   6039   ,
   6040   MHD_HTTP_VERSION_1_0 = 10     /**< HTTP/1.0 */
   6041   ,
   6042   MHD_HTTP_VERSION_1_1 = 11     /**< HTTP/1.1 */
   6043   ,
   6044   MHD_HTTP_VERSION_1_2P = 19    /**< HTTP/1.2 - HTTP/1.9 */
   6045   ,
   6046   MHD_HTTP_VERSION_2 = 20       /**< HTTP/2 */
   6047   ,
   6048   MHD_HTTP_VERSION_3 = 30       /**< HTTP/3 */
   6049   ,
   6050   MHD_HTTP_VERSION_FUTURE = 255 /**< Future HTTP version */
   6051 };
   6052 
   6053 #  define MHD_HTTP_PROTOCOL_VER_DEFINED 1
   6054 #endif /* ! MHD_HTTP_PROTOCOL_VER_DEFINED */
   6055 
   6056 /**
   6057  * Return the string representation of the requested HTTP version.
   6058  * Note: this is suitable mainly for logging and similar purposes as
   6059  * HTTP/2 (and later) is not used inside the HTTP protocol.
   6060  * @param pv the protocol version
   6061  * @return the string representation of the protocol version,
   6062  *         NULL for invalid values
   6063  */
   6064 MHD_EXTERN_ const struct MHD_String *
   6065 MHD_protocol_version_to_string (enum MHD_HTTP_ProtocolVersion pv)
   6066 MHD_FN_CONST_;
   6067 
   6068 /**
   6069  * HTTP/1.0 identification string
   6070  */
   6071 #define MHD_HTTP_VERSION_1_0_STR "HTTP/1.0"
   6072 /**
   6073  * HTTP/1.1 identification string
   6074  */
   6075 #define MHD_HTTP_VERSION_1_1_STR "HTTP/1.1"
   6076 /**
   6077  * Identification string for clients claiming HTTP/1.2 - HTTP/1.9
   6078  * Not used by the HTTP protocol, useful for logs and similar purposes.
   6079  */
   6080 #define MHD_HTTP_VERSION_1_2P_STR "HTTP/1.2+"
   6081 /**
   6082  * HTTP/2 identification string.
   6083  * Not used by the HTTP protocol (except non-TLS handshake), useful for logs and
   6084  * similar purposes.
   6085  */
   6086 #define MHD_HTTP_VERSION_2_STR "HTTP/2"
   6087 /**
   6088  * HTTP/3 identification string.
   6089  * Not used by the HTTP protocol, useful for logs and similar purposes.
   6090  */
   6091 #define MHD_HTTP_VERSION_3_STR "HTTP/3"
   6092 
   6093 /** @} */ /* end of group versions */
   6094 
   6095 
   6096 /**
   6097  * Resume handling of network data for suspended request.
   6098  * It is safe to resume a suspended request at any time.
   6099  * Calling this function on a request that was not previously suspended will
   6100  * result in undefined behaviour.
   6101  *
   6102  * @param[in,out] request the request to resume
   6103  */
   6104 MHD_EXTERN_ void
   6105 MHD_request_resume (struct MHD_Request *request)
   6106 MHD_FN_PAR_NONNULL_ALL_;
   6107 
   6108 
   6109 /* ************** Action and Response manipulation functions **************** */
   6110 
   6111 /**
   6112  * @defgroup response Response objects control
   6113  */
   6114 
   6115 
   6116 /**
   6117  * Name with value pair as C strings
   6118  */
   6119 struct MHD_NameValueCStr
   6120 {
   6121   /**
   6122    * The name (key) of the field.
   6123    * Must never be NULL.
   6124    * Some types (kinds) allow empty strings.
   6125    */
   6126   const char *name;
   6127   /**
   6128    * The value of the field.
   6129    * Some types (kinds) allow absence of the value. The absence is indicated
   6130    * by NULL pointer.
   6131    */
   6132   const char *value;
   6133 };
   6134 
   6135 /**
   6136  * Data transmitted in response to an HTTP request.
   6137  * Usually the final action taken in response to
   6138  * receiving a request.
   6139  */
   6140 struct MHD_Response;
   6141 
   6142 
   6143 /**
   6144  * Suspend handling of network data for a given request.  This can
   6145  * be used to dequeue a request from MHD's event loop for a while.
   6146  *
   6147  * Suspended requests continue to count against the total number of
   6148  * requests allowed (per daemon, as well as per IP, if such limits
   6149  * are set).  Suspended requests will NOT time out; timeouts will
   6150  * restart when the request handling is resumed.  While a
   6151  * request is suspended, MHD may not detect disconnects by the
   6152  * client.
   6153  *
   6154  * At most one action can be created for any request.
   6155  *
   6156  * @param[in,out] request the request for which the action is generated
   6157  * @return action to cause a request to be suspended,
   6158  *         NULL if any action has been already created for the @a request
   6159  * @ingroup action
   6160  */
   6161 MHD_EXTERN_ const struct MHD_Action *
   6162 MHD_action_suspend (struct MHD_Request *request)
   6163 MHD_FN_PAR_NONNULL_ALL_;
   6164 
   6165 
   6166 /**
   6167  * Converts a @a response to an action.  If #MHD_R_O_REUSABLE
   6168  * is not set, the reference to the @a response is consumed
   6169  * by the conversion. If #MHD_R_O_REUSABLE is #MHD_YES,
   6170  * then the @a response can be used again to create actions in
   6171  * the future.
   6172  * However, the @a response is frozen by this step and
   6173  * must no longer be modified (i.e. by setting headers).
   6174  *
   6175  * At most one action can be created for any request.
   6176  *
   6177  * @param request the request to create the action for
   6178  * @param[in] response the response to convert,
   6179  *                     if NULL then this function is equivalent to
   6180  *                     #MHD_action_abort_connection() call
   6181  * @return pointer to the action, the action must be consumed
   6182  *         otherwise response object may leak;
   6183  *         NULL if failed (no memory) or if any action has been already
   6184  *         created for the @a request;
   6185  *         when failed the response object is consumed and need not
   6186  *         to be "destroyed"
   6187  * @ingroup action
   6188  */
   6189 MHD_EXTERN_ const struct MHD_Action *
   6190 MHD_action_from_response (struct MHD_Request *MHD_RESTRICT request,
   6191                           struct MHD_Response *MHD_RESTRICT response)
   6192 MHD_FN_PAR_NONNULL_ (1);
   6193 
   6194 
   6195 /**
   6196  * Action telling MHD to close the connection hard
   6197  * (kind-of breaking HTTP specification).
   6198  *
   6199  * @param req the request to make an action
   6200  * @return action operation, always NULL
   6201  * @ingroup action
   6202  */
   6203 #define MHD_action_abort_request(req) \
   6204         MHD_STATIC_CAST_ (const struct MHD_Action *, NULL)
   6205 
   6206 
   6207 /**
   6208  * Set the requested options for the response.
   6209  *
   6210  * If any option fail other options may be or may be not applied.
   6211  * @param response the response to set the options
   6212  * @param[in] options the pointer to the array with the options;
   6213  *                    the array processing stops at the first ::MHD_D_O_END
   6214  *                    option, but not later than after processing
   6215  *                    @a options_max_num entries
   6216  * @param options_max_num the maximum number of entries in the @a options,
   6217  *                        use #MHD_OPTIONS_ARRAY_MAX_SIZE if options processing
   6218  *                        must stop only at zero-termination option
   6219  * @return ::MHD_SC_OK on success,
   6220  *         error code otherwise
   6221  */
   6222 MHD_EXTERN_ enum MHD_StatusCode
   6223 MHD_response_set_options (
   6224   struct MHD_Response *MHD_RESTRICT response,
   6225   const struct MHD_ResponseOptionAndValue *MHD_RESTRICT options,
   6226   size_t options_max_num)
   6227 MHD_FN_PAR_NONNULL_ALL_;
   6228 
   6229 
   6230 /**
   6231  * Set the requested single option for the response.
   6232  *
   6233  * @param response the response to set the option
   6234  * @param[in] option_ptr the pointer to the option
   6235  * @return ::MHD_SC_OK on success,
   6236  *         error code otherwise
   6237  * @ingroup response
   6238  */
   6239 #define MHD_response_set_option(response, option_ptr) \
   6240         MHD_response_set_options (response,option_ptr,1)
   6241 
   6242 
   6243 /* *INDENT-OFF* */
   6244 #ifdef MHD_USE_VARARG_MACROS
   6245 MHD_NOWARN_VARIADIC_MACROS_
   6246 #  if defined(MHD_USE_COMPOUND_LITERALS) && \
   6247   defined(MHD_USE_COMP_LIT_FUNC_PARAMS)
   6248 /**
   6249  * Set the requested options for the response.
   6250  *
   6251  * If any option fail other options may be or may be not applied.
   6252  *
   6253  * It should be used with helpers that creates required options, for example:
   6254  *
   6255  * MHD_RESPONSE_SET_OPTIONS(r, MHD_R_OPTION_REUSABLE(MHD_YES),
   6256  *                          MHD_R_OPTION_TERMINATION_CALLBACK(func, cls))
   6257  *
   6258  * @param response the response to set the option
   6259  * @param ... the list of the options, each option must be created
   6260  *            by helpers MHD_RESPONSE_OPTION_NameOfOption(option_value)
   6261  * @return ::MHD_SC_OK on success,
   6262  *         error code otherwise
   6263  */
   6264 #    define MHD_RESPONSE_SET_OPTIONS(response,...)              \
   6265             MHD_NOWARN_COMPOUND_LITERALS_                           \
   6266             MHD_response_set_options (                              \
   6267               response,                                             \
   6268               ((const struct MHD_ResponseOptionAndValue[])          \
   6269                {__VA_ARGS__, MHD_R_OPTION_TERMINATE ()}),           \
   6270               MHD_OPTIONS_ARRAY_MAX_SIZE)                           \
   6271             MHD_RESTORE_WARN_COMPOUND_LITERALS_
   6272 #  elif defined(MHD_USE_CPP_INIT_LIST)
   6273 MHD_C_DECLARATIONS_FINISH_HERE_
   6274 #    include <vector>
   6275 MHD_C_DECLARATIONS_START_HERE_
   6276 /**
   6277  * Set the requested options for the response.
   6278  *
   6279  * If any option fail other options may be or may be not applied.
   6280  *
   6281  * It should be used with helpers that creates required options, for example:
   6282  *
   6283  * MHD_RESPONSE_SET_OPTIONS(r, MHD_R_OPTION_REUSABLE(MHD_YES),
   6284  *                          MHD_R_OPTION_TERMINATION_CALLBACK(func, cls))
   6285  *
   6286  * @param response the response to set the option
   6287  * @param ... the list of the options, each option must be created
   6288  *            by helpers MHD_RESPONSE_OPTION_NameOfOption(option_value)
   6289  * @return ::MHD_SC_OK on success,
   6290  *         error code otherwise
   6291  */
   6292 #    define MHD_RESPONSE_SET_OPTIONS(response,...)              \
   6293             MHD_NOWARN_CPP_INIT_LIST_                               \
   6294             MHD_response_set_options (                              \
   6295               response,                                             \
   6296               (std::vector<struct MHD_ResponseOptionAndValue>       \
   6297                {__VA_ARGS__,MHD_R_OPTION_TERMINATE ()}).data (),    \
   6298               MHD_OPTIONS_ARRAY_MAX_SIZE)                           \
   6299             MHD_RESTORE_WARN_CPP_INIT_LIST_
   6300 #  endif
   6301 MHD_RESTORE_WARN_VARIADIC_MACROS_
   6302 #endif /* MHD_USE_VARARG_MACROS && MHD_USE_COMP_LIT_FUNC_PARAMS */
   6303 /* *INDENT-ON* */
   6304 
   6305 #ifndef MHD_FREECALLBACK_DEFINED
   6306 
   6307 /**
   6308  * This method is called by libmicrohttpd when response with dynamic content
   6309  * is being destroyed.  It should be used to free resources associated
   6310  * with the dynamic content.
   6311  *
   6312  * @param[in] free_cls closure
   6313  * @ingroup response
   6314  */
   6315 typedef void
   6316 (*MHD_FreeCallback)(void *free_cls);
   6317 
   6318 #  define MHD_FREECALLBACK_DEFINED 1
   6319 #endif /* ! MHD_FREECALLBACK_DEFINED */
   6320 #ifndef MHD_DYNCONTENTZCIOVEC_DEFINED
   6321 
   6322 
   6323 /**
   6324  * Structure for iov type of the response.
   6325  * Used for zero-copy response content data.
   6326  */
   6327 struct MHD_DynContentZCIoVec
   6328 {
   6329   /**
   6330    * The number of elements in @a iov
   6331    */
   6332   unsigned int iov_count;
   6333   /**
   6334    * The pointer to the array with @a iov_count elements.
   6335    */
   6336   const struct MHD_IoVec *iov;
   6337   /**
   6338    * The callback to free resources.
   6339    * It is called once the full array of iov elements is sent.
   6340    * No callback is called if NULL.
   6341    */
   6342   MHD_FreeCallback iov_fcb;
   6343   /**
   6344    * The parameter for @a iov_fcb
   6345    */
   6346   void *iov_fcb_cls;
   6347 };
   6348 
   6349 #  define MHD_DYNCONTENTZCIOVEC_DEFINED 1
   6350 #endif /* ! MHD_DYNCONTENTZCIOVEC_DEFINED */
   6351 
   6352 /**
   6353  * The action type returned by Dynamic Content Creator callback
   6354  */
   6355 struct MHD_DynamicContentCreatorAction;
   6356 
   6357 /**
   6358  * The context used for Dynamic Content Creator callback
   6359  */
   6360 struct MHD_DynamicContentCreatorContext;
   6361 
   6362 
   6363 /**
   6364  * Create "continue processing" action with optional chunk-extension.
   6365  * The data is provided in the buffer and/or in the zero-copy @a iov_data.
   6366  *
   6367  * If data is provided both in the buffer and @a ivo_data then
   6368  * data in the buffer sent first, following the iov data.
   6369  * The total size of the data in the buffer and in @a iov_data must
   6370  * be non-zero.
   6371  * If response content size is known and total size of content provided earlier
   6372  * for this request combined with the size provided by this action is larger
   6373  * then known response content size, then NULL is returned.
   6374  *
   6375  * At most one DCC action can be created for one content callback.
   6376  *
   6377  * @param[in,out] ctx the pointer the context as provided to the callback
   6378  * @param data_size the amount of the data placed to the provided buffer,
   6379  *                  cannot be larger than provided buffer size,
   6380  *                  must be non-zero if @a iov_data is NULL or has no data,
   6381  * @param iov_data the optional pointer to the iov data,
   6382  *                 must not be NULL and have non-zero size data if @a data_size
   6383  *                 is zero,
   6384  * @param chunk_ext the optional pointer to chunk extension string,
   6385  *                  can be NULL to not use chunk extension,
   6386  *                  ignored if chunked encoding is not used
   6387  * @return the pointer to the action if succeed,
   6388  *         NULL (equivalent of MHD_DCC_action_abort())in case of any error
   6389  */
   6390 MHD_EXTERN_ const struct MHD_DynamicContentCreatorAction *
   6391 MHD_DCC_action_continue_zc (
   6392   struct MHD_DynamicContentCreatorContext *ctx,
   6393   size_t data_size,
   6394   const struct MHD_DynContentZCIoVec *iov_data,
   6395   const char *MHD_RESTRICT chunk_ext)
   6396 MHD_FN_PAR_NONNULL_ (1)
   6397 MHD_FN_PAR_CSTR_ (4);
   6398 
   6399 
   6400 /**
   6401  * Create "continue processing" action with optional chunk-extension.
   6402  * The data is provided in the buffer.
   6403  *
   6404  * At most one DCC action can be created for one content callback.
   6405  *
   6406  * @param[in,out] ctx the pointer the context as provided to the callback
   6407  * @param data_size the amount of the data placed to the provided buffer (not @a iov_data),
   6408  *                  cannot be larger than provided buffer size,
   6409  *                  must be non-zero.
   6410  * @param chunk_ext the optional pointer to chunk extension string,
   6411  *                  can be NULL to not use chunk extension,
   6412  *                  ignored if chunked encoding is not used
   6413  * @return the pointer to the action if succeed,
   6414  *         NULL (equivalent of MHD_DCC_action_abort())in case of any error
   6415  */
   6416 #define MHD_DCC_action_continue_ce(ctx, data_size, chunk_ext) \
   6417         MHD_DCC_action_continue_zc ((ctx), (data_size), NULL, (chunk_ext))
   6418 
   6419 
   6420 /**
   6421  * Create "continue processing" action, the data is provided in the buffer.
   6422  *
   6423  * At most one DCC action can be created for one content callback.
   6424  *
   6425  * @param[in,out] ctx the pointer the context as provided to the callback
   6426  * @param data_size the amount of the data placed to the provided buffer;
   6427  *                  cannot be larger than provided buffer size,
   6428  *                  must be non-zero.
   6429  *
   6430  * @return the pointer to the action if succeed,
   6431  *         NULL (equivalent of MHD_DCC_action_abort())in case of any error
   6432  */
   6433 #define MHD_DCC_action_continue(ctx, data_size) \
   6434         MHD_DCC_action_continue_ce ((ctx), (data_size), NULL)
   6435 
   6436 
   6437 /**
   6438  * Create "finished" action with optional footers.
   6439  * If function failed for any reason, the action is automatically
   6440  * set to "stop with error".
   6441  *
   6442  * At most one DCC action can be created for one content callback.
   6443  *
   6444  * @param[in,out] ctx the pointer the context as provided to the callback
   6445  * @param num_footers number of elements in the @a footers array,
   6446  *                    must be zero if @a footers is NULL
   6447  * @param footers the optional pointer to the array of the footers (the strings
   6448  *                are copied and does not need to be valid after return from
   6449  *                this function),
   6450  *                can be NULL if @a num_footers is zero
   6451  * @return the pointer to the action if succeed,
   6452  *         NULL (equivalent of MHD_DCC_action_abort())in case of any error
   6453  */
   6454 MHD_EXTERN_ const struct MHD_DynamicContentCreatorAction *
   6455 MHD_DCC_action_finish_with_footer (
   6456   struct MHD_DynamicContentCreatorContext *ctx,
   6457   size_t num_footers,
   6458   const struct MHD_NameValueCStr *MHD_RESTRICT footers)
   6459 MHD_FN_PAR_NONNULL_ (1)
   6460 MHD_FN_PAR_NONNULL_IF_NONZERO_ (3, 2);
   6461 
   6462 
   6463 /**
   6464  * Create "finished" action.
   6465  * If function failed for any reason, the action is automatically
   6466  * set to "stop with error".
   6467  *
   6468  * At most one DCC action can be created for one content callback.
   6469  *
   6470  * @param[in,out] ctx the pointer the context as provided to the callback
   6471  * @return the pointer to the action if succeed,
   6472  *         NULL (equivalent of MHD_DCC_action_abort())in case of any error
   6473  */
   6474 #define MHD_DCC_action_finish(ctx) \
   6475         MHD_DCC_action_finish_with_footer ((ctx), 0, NULL)
   6476 
   6477 
   6478 /**
   6479  * Create "suspend" action.
   6480  * If function failed for any reason, the action is automatically
   6481  * set to "stop with error".
   6482  *
   6483  * At most one DCC action can be created for one content callback.
   6484  *
   6485  * @param[in,out] ctx the pointer the context as provided to the callback
   6486  * @return the pointer to the action if succeed,
   6487  *         NULL (equivalent of MHD_DCC_action_abort())in case of any error
   6488  */
   6489 MHD_EXTERN_ const struct MHD_DynamicContentCreatorAction *
   6490 MHD_DCC_action_suspend (struct MHD_DynamicContentCreatorContext *ctx)
   6491 MHD_FN_PAR_NONNULL_ (1);
   6492 
   6493 /**
   6494  * Create "stop with error" action.
   6495  * @param[in,out] ctx the pointer the context as provided to the callback
   6496  * @return always NULL (the action "stop with error")
   6497  */
   6498 #define MHD_DCC_action_abort(ctx) \
   6499         MHD_STATIC_CAST_ (const struct MHD_DynamicContentCreatorAction *, NULL)
   6500 
   6501 /**
   6502  * Callback used by libmicrohttpd in order to obtain content.  The
   6503  * callback is to copy at most @a max bytes of content into @a buf or
   6504  * provide zero-copy data for #MHD_DCC_action_continue_zc().
   6505  *
   6506  * @param dyn_cont_cls closure argument to the callback
   6507  * @param ctx the context to produce the action to return,
   6508  *            the pointer is only valid until the callback returns
   6509  * @param pos position in the datastream to access;
   6510  *        note that if a `struct MHD_Response` object is re-used,
   6511  *        it is possible for the same content reader to
   6512  *        be queried multiple times for the same data;
   6513  *        however, if a `struct MHD_Response` is not re-used,
   6514  *        libmicrohttpd guarantees that "pos" will be
   6515  *        the sum of all data sizes provided by this callback
   6516  * @param[out] buf where to copy the data
   6517  * @param max maximum number of bytes to copy to @a buf (size of @a buf),
   6518               if the size of the content of the response is known then size
   6519               of the buffer is never larger than amount of the content left
   6520  * @return action to use,
   6521  *         NULL in case of any error (the response will be aborted)
   6522  */
   6523 typedef const struct MHD_DynamicContentCreatorAction *
   6524 (MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_NONNULL_ (4)
   6525  *MHD_DynamicContentCreator)(void *dyn_cont_cls,
   6526                              struct MHD_DynamicContentCreatorContext *ctx,
   6527                              uint_fast64_t pos,
   6528                              void *buf,
   6529                              size_t max);
   6530 
   6531 
   6532 /**
   6533  * Create a response.  The response object can be extended with
   6534  * header information.
   6535  *
   6536  * @param sc status code to return
   6537  * @param size size of the data portion of the response, #MHD_SIZE_UNKNOWN for unknown
   6538  * @param dyn_cont callback to use to obtain response data
   6539  * @param dyn_cont_cls extra argument to @p dyn_cont
   6540  * @param free_cb callback to call to free @p dyn_cont_cls resources,
   6541  *                can be NULL
   6542  * @param free_cb_cls the parameter for @p free_cb
   6543  * @return new response object on success,
   6544  *         NULL on failure (i.e. invalid arguments, out of memory),
   6545  *         @p free_cb is called automatically in case of failure
   6546  * @ingroup response
   6547  */
   6548 MHD_EXTERN_ struct MHD_Response *
   6549 MHD_response_from_callback_2cls (enum MHD_HTTP_StatusCode sc,
   6550                                  uint_fast64_t size,
   6551                                  MHD_DynamicContentCreator dyn_cont,
   6552                                  void *dyn_cont_cls,
   6553                                  MHD_FreeCallback free_cb,
   6554                                  void *free_cb_cls);
   6555 
   6556 
   6557 /**
   6558  * Create a response.  The response object can be extended with
   6559  * header information.
   6560  *
   6561  * @param sc status code to return
   6562  * @param s size of the data portion of the response, #MHD_SIZE_UNKNOWN for unknown
   6563  * @param d callback to use to obtain response data
   6564  * @param dc extra argument to @p d, evaluated twice!
   6565  * @param f callback to call to free @p dc resources
   6566  * @return new response object on success,
   6567  *         NULL on failure (i.e. invalid arguments, out of memory),
   6568  *         the cleanup callback @p f is called automatically in case
   6569  *         of failure
   6570  * @warning The @p dc parameter is evaluated twice; avoid expressions
   6571  *          with side effects. Alternatively, just call function
   6572  *          #MHD_response_from_callback_2cls() directly.
   6573  * @ingroup response
   6574  */
   6575 #define MHD_response_from_callback(sc, s, d, dc, f) \
   6576         MHD_response_from_callback_2cls((sc),(s),(d),(dc),(f),(dc))
   6577 
   6578 
   6579 /**
   6580  * Create a response object.  The response object can be extended with
   6581  * header information.
   6582  *
   6583  * @param sc status code to use for the response;
   6584  *           #MHD_HTTP_STATUS_NO_CONTENT is only valid if @a buffer_size is 0;
   6585  * @param buffer_size the size of the data portion of the response,
   6586  *                    must be zero if @a buffer is NULL
   6587  * @param buffer the @a buffer_size bytes containing the response's data
   6588  *               portion, can be NULL if @a buffer_size is zero,
   6589  *               needs to be valid while the response is used
   6590  * @param free_cb the callback to free any allocated data, called
   6591  *                when response is being destroyed, can be NULL
   6592  *                to skip the free/cleanup callback;
   6593  * @param free_cb_cls the parameter for @a free_cb
   6594  * @return new response object on success,
   6595  *         NULL on failure (i.e. invalid arguments, out of memory),
   6596  *         @p free_cb is called automatically in case of failure
   6597  * @ingroup response
   6598  */
   6599 MHD_EXTERN_ struct MHD_Response *
   6600 MHD_response_from_buffer (
   6601   enum MHD_HTTP_StatusCode sc,
   6602   size_t buffer_size,
   6603   const char *buffer,
   6604   MHD_FreeCallback free_cb,
   6605   void *free_cb_cls)
   6606 MHD_FN_PAR_NONNULL_IF_NONZERO_ (3, 2)
   6607 MHD_FN_PAR_IN_SIZE_ (3, 2);
   6608 
   6609 
   6610 /**
   6611  * Create a response object with body that is a
   6612  * statically allocated buffer that never needs to
   6613  * be freed as its lifetime exceeds that of the
   6614  * daemon.
   6615  *
   6616  * The response object can be extended with header information and then be used
   6617  * any number of times.
   6618  * @param sc status code to use for the response
   6619  * @param len number of bytes in @a buf
   6620  * @param buf buffer with response payload
   6621  * @return new response object on success,
   6622  *         NULL on failure (i.e. invalid arguments, out of memory)
   6623  */
   6624 #define MHD_response_from_buffer_static(sc, len, buf)       \
   6625         MHD_response_from_buffer (sc, len, buf, NULL, NULL)
   6626 
   6627 
   6628 /**
   6629  * Create a response object with empty (zero size) body.
   6630  *
   6631  * The response object can be extended with header information and then be used
   6632  * any number of times.
   6633  * @param sc status code to use for the response
   6634  * @return new response object on success,
   6635  *         NULL on failure (i.e. invalid arguments, out of memory)
   6636  */
   6637 #define MHD_response_from_empty(sc) \
   6638         MHD_response_from_buffer_static (sc, 0, "")
   6639 
   6640 
   6641 /**
   6642  * Create a response object.  The response object can be extended with
   6643  * header information.
   6644  *
   6645  * @param sc status code to use for the response
   6646  * @param buffer_size the size of the data portion of the response,
   6647  *                    must be zero if @a buffer is NULL
   6648  * @param buffer the @a buffer_size bytes containing the response's data
   6649  *               portion, can be NULL if @a buffer_size is zero,
   6650  *               an internal copy will be made, there is no need to keep this
   6651  *               data after return from this function
   6652  * @return new response object on success,
   6653  *         NULL on failure (i.e. invalid arguments, out of memory)
   6654  * @ingroup response
   6655  */
   6656 MHD_EXTERN_ struct MHD_Response *
   6657 MHD_response_from_buffer_copy (
   6658   enum MHD_HTTP_StatusCode sc,
   6659   size_t buffer_size,
   6660   const char *buffer)
   6661 MHD_FN_PAR_NONNULL_IF_NONZERO_ (3, 2)
   6662 MHD_FN_PAR_IN_SIZE_ (3, 2);
   6663 
   6664 
   6665 /**
   6666  * I/O vector type. Provided for use with #MHD_response_from_iovec().
   6667  * @ingroup response
   6668  */
   6669 struct MHD_IoVec
   6670 {
   6671   /**
   6672    * The pointer to the memory region for I/O.
   6673    */
   6674   const void *iov_base;
   6675 
   6676   /**
   6677    * The size in bytes of the memory region for I/O.
   6678    */
   6679   size_t iov_len;
   6680 };
   6681 
   6682 
   6683 /**
   6684  * Create a response object with an array of memory buffers
   6685  * used as the response body.
   6686  *
   6687  * The response object can be extended with header information.
   6688  *
   6689  * If response object is used to answer HEAD request then the body
   6690  * of the response is not used, while all headers (including automatic
   6691  * headers) are used.
   6692  *
   6693  * @param sc status code to use for the response
   6694  * @param iov_count the number of elements in @a iov,
   6695  *                  must be zero if @a iov is NULL
   6696  * @param iov the array for response data buffers, can be NULL if @a iov_count
   6697  *            is zero, an internal copy of this will be made
   6698  * @param free_cb the callback to clean up any data associated with @a iov when
   6699  *        the response is destroyed.
   6700  * @param free_cb_cls the argument passed to @a free_cb
   6701  * @return new response object on success,
   6702  *         NULL on failure (i.e. invalid arguments, out of memory),
   6703  *         @p free_cb is called automatically in case of failure
   6704  * @ingroup response
   6705  */
   6706 MHD_EXTERN_ struct MHD_Response *
   6707 MHD_response_from_iovec (
   6708   enum MHD_HTTP_StatusCode sc,
   6709   unsigned int iov_count,
   6710   const struct MHD_IoVec *iov,
   6711   MHD_FreeCallback free_cb,
   6712   void *free_cb_cls)
   6713 MHD_FN_PAR_NONNULL_IF_NONZERO_ (3, 2)
   6714 MHD_FN_PAR_IN_SIZE_ (3, 2);
   6715 
   6716 
   6717 /**
   6718  * Create a response object based on an @a fd from which
   6719  * data is read.  The response object can be extended with
   6720  * header information.
   6721  *
   6722  * @param sc status code to return
   6723  * @param fd file descriptor referring to a file on disk with the
   6724  *           data; will be closed when response is destroyed;
   6725  *           fd should be in 'blocking' mode
   6726  * @param offset offset to start reading from in the file,
   6727  *               must not be #MHD_SIZE_UNKNOWN;
   6728  *               reading file beyond 2 GiB may be not supported by OS or
   6729  *               MHD build; see #MHD_LIB_INFO_FIXED_HAS_LARGE_FILE
   6730  * @param size size of the data portion of the response,
   6731  *             #MHD_SIZE_UNKNOWN to send the file to its end; with the
   6732  *             unknown size and @p offset beyond the end of the file the
   6733  *             body is empty;
   6734  *             sizes larger than 2 GiB may be not supported by OS or
   6735  *             MHD build; see #MHD_LIB_INFO_FIXED_HAS_LARGE_FILE
   6736  * @return new response object on success,
   6737  *         NULL on failure (i.e. invalid arguments, out of memory),
   6738  *         @p fd is closed automatically in case of failure
   6739  * @ingroup response
   6740  */
   6741 MHD_EXTERN_ struct MHD_Response *
   6742 MHD_response_from_fd (enum MHD_HTTP_StatusCode sc,
   6743                       int fd,
   6744                       uint_fast64_t offset,
   6745                       uint_fast64_t size)
   6746 MHD_FN_PAR_FD_READ_ (2);
   6747 
   6748 /**
   6749  * Create a response object with the response body created by reading
   6750  * the provided pipe.
   6751  *
   6752  * The response object can be extended with header information and
   6753  * then be used ONLY ONCE.
   6754  *
   6755  * If response object is used to answer HEAD request then the body
   6756  * of the response is not used, while all headers (including automatic
   6757  * headers) are used.
   6758  *
   6759  * @param sc status code to use for the response
   6760  * @param fd file descriptor referring to a read-end of a pipe with the
   6761  *        data; will be closed when response is destroyed;
   6762  *        fd should be in 'blocking' mode
   6763  * @return new response object on success,
   6764  *         NULL on failure (i.e. invalid arguments, out of memory),
   6765  *         @p fd is closed automatically in case of failure
   6766  * @ingroup response
   6767  */
   6768 MHD_EXTERN_ struct MHD_Response *
   6769 MHD_response_from_pipe (enum MHD_HTTP_StatusCode sc,
   6770                         int fd)
   6771 MHD_FN_PAR_FD_READ_ (2);
   6772 
   6773 
   6774 /**
   6775  * Destroy response.
   6776  * Should be called if response was created but not consumed.
   6777  * Also must be called if response has #MHD_R_O_REUSABLE set.
   6778  * The actual destroy can be happen later, if the response
   6779  * is still being used in any request.
   6780  * The function does not block.
   6781  *
   6782  * @param[in] response the response to destroy
   6783  * @ingroup response
   6784  */
   6785 MHD_EXTERN_ void
   6786 MHD_response_destroy (struct MHD_Response *response)
   6787 MHD_FN_PAR_NONNULL_ (1);
   6788 
   6789 
   6790 /**
   6791  * Add a header line to the response.
   6792  *
   6793  * @param response response to add a header to, NULL is tolerated
   6794  * @param name the name of the header to add,
   6795  *             an internal copy of the string will be made
   6796  * @param value the value of the header to add,
   6797  *              an internal copy of the string will be made
   6798  * @return #MHD_SC_OK on success,
   6799  *         error code otherwise
   6800  * @ingroup response
   6801  */
   6802 MHD_EXTERN_ enum MHD_StatusCode
   6803 MHD_response_add_header (struct MHD_Response *MHD_RESTRICT response,
   6804                          const char *MHD_RESTRICT name,
   6805                          const char *MHD_RESTRICT value)
   6806 MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_CSTR_ (2)
   6807 MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_CSTR_ (3);
   6808 
   6809 
   6810 /**
   6811  * Add a header with predefined (standard) name to the response.
   6812  *
   6813  * @param response response to add a header to
   6814  * @param stk the code of the predefined header
   6815  * @param content the value of the header to add,
   6816  *              an internal copy of the string will be made
   6817  * @return #MHD_SC_OK on success,
   6818  *         error code otherwise
   6819  * @ingroup response
   6820  */
   6821 MHD_EXTERN_ enum MHD_StatusCode
   6822 MHD_response_add_predef_header (struct MHD_Response *MHD_RESTRICT response,
   6823                                 enum MHD_PredefinedHeader stk,
   6824                                 const char *MHD_RESTRICT content)
   6825 MHD_FN_PAR_NONNULL_ (1)
   6826 MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_CSTR_ (3);
   6827 
   6828 
   6829 /* ************ (b) Upload and PostProcessor functions ********************** */
   6830 
   6831 
   6832 /**
   6833  * Suspend handling of network data for a given request.  This can
   6834  * be used to dequeue a request from MHD's event loop for a while.
   6835  *
   6836  * Suspended requests continue to count against the total number of
   6837  * requests allowed (per daemon, as well as per IP, if such limits
   6838  * are set).  Suspended requests will NOT time out; timeouts will
   6839  * restart when the request handling is resumed.  While a
   6840  * request is suspended, MHD may not detect disconnects by the
   6841  * client.
   6842  *
   6843  * At most one upload action can be created for one upload callback.
   6844  *
   6845  * @param[in,out] request the request for which the action is generated
   6846  * @return action to cause a request to be suspended,
   6847  *         NULL if any action has been already created for the @a request
   6848  * @ingroup action
   6849  */
   6850 MHD_EXTERN_ const struct MHD_UploadAction *
   6851 MHD_upload_action_suspend (struct MHD_Request *request)
   6852 MHD_FN_PAR_NONNULL_ALL_;
   6853 
   6854 /**
   6855  * Converts a @a response to an action.  If #MHD_R_O_REUSABLE
   6856  * is not set, the reference to the @a response is consumed
   6857  * by the conversion. If #MHD_R_O_REUSABLE is #MHD_YES,
   6858  * then the @a response can be used again to create actions in
   6859  * the future.
   6860  * However, the @a response is frozen by this step and
   6861  * must no longer be modified (i.e. by setting headers).
   6862  *
   6863  * At most one upload action can be created for one upload callback.
   6864  *
   6865  * @param request the request to create the action for
   6866  * @param[in] response the response to convert,
   6867  *                     if NULL then this function is equivalent to
   6868  *                     #MHD_upload_action_abort_request() call
   6869  * @return pointer to the action, the action must be consumed
   6870  *         otherwise response object may leak;
   6871  *         NULL if failed (no memory) or if any action has been already
   6872  *         created for the @a request;
   6873  *         when failed the response object is consumed and need not
   6874  *         to be "destroyed"
   6875  * @ingroup action
   6876  */
   6877 MHD_EXTERN_ const struct MHD_UploadAction *
   6878 MHD_upload_action_from_response (struct MHD_Request *MHD_RESTRICT request,
   6879                                  struct MHD_Response *MHD_RESTRICT response)
   6880 MHD_FN_PAR_NONNULL_ (1);
   6881 
   6882 /**
   6883  * Action telling MHD to continue processing the upload.
   6884  * Valid only for incremental upload processing.
   6885  * Works as #MHD_upload_action_abort_request() if used for full upload callback
   6886  * or for the final (with zero data) incremental callback.
   6887  *
   6888  * At most one upload action can be created for one upload callback.
   6889  *
   6890  * @param request the request to make an action
   6891  * @return action operation,
   6892  *         NULL if any action has been already created for the @a request
   6893  * @ingroup action
   6894  */
   6895 MHD_EXTERN_ const struct MHD_UploadAction *
   6896 MHD_upload_action_continue (struct MHD_Request *request)
   6897 MHD_FN_PAR_NONNULL_ (1);
   6898 
   6899 
   6900 /**
   6901  * Action telling MHD to close the connection hard
   6902  * (kind-of breaking HTTP specification).
   6903  *
   6904  * @param req the request to make an action
   6905  * @return action operation, always NULL
   6906  * @ingroup action
   6907  */
   6908 #define MHD_upload_action_abort_request(req) \
   6909         MHD_STATIC_CAST_ (const struct MHD_UploadAction *, NULL)
   6910 
   6911 #ifndef MHD_UPLOADCALLBACK_DEFINED
   6912 
   6913 /**
   6914  * Function to process data uploaded by a client.
   6915  *
   6916  * @param upload_cls the argument given together with the function
   6917  *                   pointer when the handler was registered with MHD
   6918  * @param request the request is being processed
   6919  * @param content_data_size the size of the @a content_data,
   6920  *                          zero when all data have been processed
   6921  * @param[in] content_data the uploaded content data,
   6922  *                         may be modified in the callback,
   6923  *                         valid only until return from the callback,
   6924  *                         NULL when all data have been processed
   6925  * @return action specifying how to proceed:
   6926  *         #MHD_upload_action_continue() to continue upload (for incremental
   6927  *         upload processing only),
   6928  *         #MHD_upload_action_suspend() to stop reading the upload until
   6929  *         the request is resumed,
   6930  *         #MHD_upload_action_abort_request() to close the socket,
   6931  *         or a response to discard the rest of the upload and transmit
   6932  *         the response
   6933  * @ingroup action
   6934  */
   6935 typedef const struct MHD_UploadAction *
   6936 (MHD_FN_PAR_NONNULL_ (2)  MHD_FN_PAR_NONNULL_IF_NONZERO_ (4, 3)
   6937  MHD_FN_PAR_INOUT_SIZE_ (4, 3)
   6938  *MHD_UploadCallback)(void *upload_cls,
   6939                       struct MHD_Request *request,
   6940                       size_t content_data_size,
   6941                       void *content_data);
   6942 
   6943 #  define MHD_UPLOADCALLBACK_DEFINED 1
   6944 #endif /* ! MHD_UPLOADCALLBACK_DEFINED */
   6945 
   6946 /**
   6947  * Create an action that handles an upload.
   6948  *
   6949  * If @a uc_inc is NULL and upload cannot fit the allocated buffer
   6950  * then request is aborted without response.
   6951  *
   6952  * At most one action can be created for any request.
   6953  *
   6954  * @param request the request to create action for
   6955  * @param large_buffer_size how large should the upload buffer be.
   6956  *                          May allocate memory from the shared "large"
   6957  *                          memory pool if necessary and non-zero is given.
   6958  *                          Must be zero if @a uc_full is NULL.
   6959  * @param uc_full the function to call when complete upload
   6960  *                is received (only if fit @a upload_buffer_size),
   6961  *                can be NULL if uc_inc is not NULL,
   6962  *                must be NULL is @a upload_buffer_size is zero.
   6963  * @param uc_full_cls closure for @a uc_full
   6964  * @param uc_inc the function to incrementally process the upload data
   6965  *               if the upload if larger than @a upload_buffer_size or
   6966  *               @a upload_buffer_size cannot be allocated or
   6967  *               @a uc_full is NULL,
   6968  *               can be NULL if uc_full is not NULL
   6969  * @param uc_inc_cls closure for @a uc_inc
   6970  * @return NULL on error (out of memory, invalid parameters)
   6971  * @return pointer to the action,
   6972  *         NULL if failed (no memory) or if any action has been already
   6973  *         created for the @a request.
   6974  * @sa #MHD_D_OPTION_LARGE_POOL_SIZE()
   6975  * @ingroup action
   6976  */
   6977 MHD_EXTERN_ const struct MHD_Action *
   6978 MHD_action_process_upload (
   6979   struct MHD_Request *request,
   6980   size_t large_buffer_size,
   6981   MHD_UploadCallback uc_full,
   6982   void *uc_full_cls,
   6983   MHD_UploadCallback uc_inc,
   6984   void *uc_inc_cls)
   6985 MHD_FN_PAR_NONNULL_ (1)
   6986 MHD_FN_PAR_NONNULL_IF_NONZERO_ (3, 2);
   6987 
   6988 /**
   6989  * Create an action that handles an upload as full upload data.
   6990  *
   6991  * @param request the request to create action for
   6992  * @param buff_size how large should the upload buffer be. May allocate memory
   6993  *                  from the large memory pool if necessary. Must not be zero.
   6994  * @param uc the function to call when complete upload
   6995  *           is received (only if fit @a upload_buffer_size)
   6996  * @param uc_cls closure for @a uc
   6997  * @return NULL on error (out of memory. both @a uc is NULL)
   6998  * @ingroup action
   6999  */
   7000 #define MHD_action_process_upload_full(request, buff_size, uc, uc_cls) \
   7001         MHD_action_process_upload (request, buff_size, uc, uc_cls, NULL, NULL)
   7002 
   7003 /**
   7004  * Create an action that handles an upload incrementally.
   7005  *
   7006  * @param request the request to create action for
   7007  * @param uc the function to incrementally process the upload data
   7008  * @param uc_cls closure for @a uc
   7009  * @return NULL on error (out of memory. both @a uc is NULL)
   7010  * @ingroup action
   7011  */
   7012 #define MHD_action_process_upload_inc(request, uc, uc_cls) \
   7013         MHD_action_process_upload (request, 0, NULL, NULL, uc, uc_cls)
   7014 
   7015 #ifndef MHD_POST_PARSE_RESULT_DEFINED
   7016 
   7017 /**
   7018  * The result of POST data parsing
   7019  */
   7020 enum MHD_FIXED_ENUM_MHD_SET_ MHD_PostParseResult
   7021 {
   7022   /**
   7023    * The POST data parsed successfully and completely.
   7024    */
   7025   MHD_POST_PARSE_RES_OK = 0
   7026   ,
   7027   /**
   7028    * The POST request has no content or zero-length content.
   7029    */
   7030   MHD_POST_PARSE_RES_REQUEST_EMPTY = 1
   7031   ,
   7032   /**
   7033    * The POST data parsed successfully, but has missing or incorrect
   7034    * termination.
   7035    * The last parsed field may have incorrect data.
   7036    */
   7037   MHD_POST_PARSE_RES_OK_BAD_TERMINATION = 2
   7038   ,
   7039   /**
   7040    * Parsing of the POST data is incomplete because client used incorrect
   7041    * format of POST encoding.
   7042    * The last parsed field may have incorrect data.
   7043    * Some POST data is available or has been provided via callback.
   7044    */
   7045   MHD_POST_PARSE_RES_PARTIAL_INVALID_POST_FORMAT = 3
   7046   ,
   7047   /**
   7048    * The POST data cannot be parsed completely because the stream has
   7049    * no free pool memory.
   7050    * Some POST data may be parsed.
   7051    */
   7052   MHD_POST_PARSE_RES_FAILED_NO_POOL_MEM = 60
   7053   ,
   7054   /**
   7055    * The POST data cannot be parsed completely because no "large shared buffer"
   7056    * space is available.
   7057    * Some POST data may be parsed.
   7058    */
   7059   MHD_POST_PARSE_RES_FAILED_NO_LARGE_BUF_MEM = 61
   7060   ,
   7061   /**
   7062    * The POST data cannot be parsed because 'Content-Type:' is unknown.
   7063    */
   7064   MHD_POST_PARSE_RES_FAILED_UNKNOWN_CNTN_TYPE = 80
   7065   ,
   7066   /**
   7067    * The POST data cannot be parsed because 'Content-Type:' header is not set.
   7068    */
   7069   MHD_POST_PARSE_RES_FAILED_NO_CNTN_TYPE = 81
   7070   ,
   7071   /**
   7072    * The POST data cannot be parsed because "Content-Type:" request header has
   7073    * no "boundary" parameter for "multipart/form-data"
   7074    */
   7075   MHD_POST_PARSE_RES_FAILED_HEADER_NO_BOUNDARY = 82
   7076   ,
   7077   /**
   7078    * The POST data cannot be parsed because "Content-Type: multipart/form-data"
   7079    * request header is misformed
   7080    */
   7081   MHD_POST_PARSE_RES_FAILED_HEADER_MISFORMED = 83
   7082   ,
   7083   /**
   7084    * The application set POST encoding to "multipart/form-data", but the request
   7085    * has no "Content-Type: multipart/form-data" header which is required
   7086    * to find "boundary" used in this encoding
   7087    */
   7088   MHD_POST_PARSE_RES_FAILED_HEADER_NOT_MPART = 84
   7089   ,
   7090   /**
   7091    * The POST data cannot be parsed because client used incorrect format
   7092    * of POST encoding.
   7093    */
   7094   MHD_POST_PARSE_RES_FAILED_INVALID_POST_FORMAT = 90
   7095 
   7096 };
   7097 
   7098 #  define MHD_POST_PARSE_RESULT_DEFINED 1
   7099 #endif /* ! MHD_POST_PARSE_RESULT_DEFINED */
   7100 
   7101 #ifndef MHD_POST_DATA_READER_DEFINED
   7102 
   7103 /**
   7104  * "Stream" reader for POST data.
   7105  * This callback is called to incrementally process parsed POST data sent by
   7106  * the client.
   7107  * The pointers to the MHD_String and MHD_StringNullable are valid only until
   7108  * return from this callback.
   7109  * The pointers to the strings and the @a data are valid only until return from
   7110  * this callback.
   7111  *
   7112  * @param req the request
   7113  * @param cls user-specified closure
   7114  * @param name the name of the POST field
   7115  * @param filename the name of the uploaded file, @a cstr member is NULL if not
   7116  *                 known / not provided
   7117  * @param content_type the mime-type of the data, cstr member is NULL if not
   7118  *                     known / not provided
   7119  * @param encoding the encoding of the data, cstr member is NULL if not known /
   7120  *                 not provided
   7121  * @param size the number of bytes in @a data available, may be zero if
   7122  *             the @a final_data is #MHD_YES
   7123  * @param data the pointer to @a size bytes of data at the specified
   7124  *             @a off offset, NOT zero-terminated
   7125  * @param off the offset of @a data in the overall value, always equal to
   7126  *            the sum of sizes of previous calls for the same field / file;
   7127  *            client may provide more than one field with the same name and
   7128  *            the same filename, the new filed (or file) is indicated by zero
   7129  *            value of @a off (and the end is indicated by @a final_data)
   7130  * @param final_data if set to #MHD_YES then full field data is provided,
   7131  *                   if set to #MHD_NO then more field data may be provided
   7132  * @return action specifying how to proceed:
   7133  *         #MHD_upload_action_continue() if all is well,
   7134  *         #MHD_upload_action_suspend() to stop reading the upload until
   7135  *         the request is resumed,
   7136  *         #MHD_upload_action_abort_request() to close the socket,
   7137  *         or a response to discard the rest of the upload and transmit
   7138  *         the response
   7139  * @ingroup action
   7140  */
   7141 typedef const struct MHD_UploadAction *
   7142 (MHD_FN_PAR_NONNULL_ (1) MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_NONNULL_ (4)
   7143  MHD_FN_PAR_NONNULL_ (5) MHD_FN_PAR_NONNULL_ (6)
   7144  *MHD_PostDataReader) (struct MHD_Request *req,
   7145                        void *cls,
   7146                        const struct MHD_String *name,
   7147                        const struct MHD_StringNullable *filename,
   7148                        const struct MHD_StringNullable *content_type,
   7149                        const struct MHD_StringNullable *encoding,
   7150                        size_t size,
   7151                        const void *data,
   7152                        uint_fast64_t off,
   7153                        enum MHD_Bool final_data);
   7154 
   7155 
   7156 /**
   7157  * The callback to be called when finished with processing
   7158  * of the postprocessor upload data.
   7159  * @param req the request
   7160  * @param cls the closure
   7161  * @param parsing_result the result of POST data parsing
   7162  * @return the action to proceed
   7163  */
   7164 typedef const struct MHD_UploadAction *
   7165 (MHD_FN_PAR_NONNULL_ (1)
   7166  *MHD_PostDataFinished) (struct MHD_Request *req,
   7167                          void *cls,
   7168                          enum MHD_PostParseResult parsing_result);
   7169 
   7170 #  define MHD_POST_DATA_READER_DEFINED 1
   7171 #endif /* ! MHD_POST_DATA_READER_DEFINED */
   7172 
   7173 /**
   7174  * Create an action to parse the POSTed content from the client.
   7175  *
   7176  * The action starts parsing of the POST data. Any value that does not fit
   7177  * @a buffer_size or larger that @a auto_stream_size is given to
   7178  * @a stream_reader (if it is not NULL).
   7179  *
   7180  * If @a buffer_size is zero, then buffers will be limited to the connection's
   7181  * memory pool. To force all POST data process via @a stream_reader
   7182  * set @a auto_stream_size to zero.
   7183  *
   7184  * At most one action can be created for any request.
   7185  *
   7186  * @param request the request to create action for
   7187  * @param buffer_size the maximum size allowed for the buffers to parse this
   7188  *                    request POST data. Within the set limit the buffer is
   7189  *                    allocated automatically from the "large" shared memory
   7190  *                    pool if necessary.
   7191  * @param max_nonstream_size the size of the field (in encoded form) above which
   7192  *                           values are not buffered and provided for
   7193  *                           the @a steam_reader automatically;
   7194  *                           useful to have large data (like file uploads)
   7195  *                           processed incrementally, while keeping buffer space
   7196  *                           for small fields only;
   7197  *                           ignored if @a stream_reader is NULL
   7198  * @param enc the data encoding to use,
   7199  *            use #MHD_HTTP_POST_ENCODING_OTHER to detect automatically
   7200  * @param stream_reader the function to call for "oversize" values in
   7201  *                      the stream; can be NULL if @a auto_stream_size is
   7202  *                      not zero
   7203  * @param reader_cls the closure for the @a stream_reader
   7204  * @param done_cb called once all data has been processed for
   7205  *   the final action; values smaller than @a auto_stream_size that
   7206  *   fit into @a buffer_size will be available via
   7207  *   #MHD_request_get_values_cb(), #MHD_request_get_values_list() and
   7208  *   #MHD_request_get_post_data_cb(), #MHD_request_get_post_data_list()
   7209  * @param done_cb_cls the closure for the @a done_cb
   7210  * @return pointer to the action,
   7211  *         NULL if failed (no memory) or if any action has been already
   7212  *         created for the @a request.
   7213  * @sa #MHD_D_OPTION_LARGE_POOL_SIZE()
   7214  * @ingroup action
   7215  */
   7216 MHD_EXTERN_ const struct MHD_Action *
   7217 MHD_action_parse_post (struct MHD_Request *request,
   7218                        size_t buffer_size,
   7219                        size_t max_nonstream_size,
   7220                        enum MHD_HTTP_PostEncoding enc,
   7221                        MHD_PostDataReader stream_reader,
   7222                        void *reader_cls,
   7223                        MHD_PostDataFinished done_cb,
   7224                        void *done_cb_cls)
   7225 MHD_FN_PAR_NONNULL_ (1);
   7226 
   7227 
   7228 #ifndef MHD_POSTFILED_DEFINED
   7229 
   7230 /**
   7231  * Post data element.
   7232  * If any member is not provided/set then pointer to C string is NULL.
   7233  * If any member is set to empty string then pointer to C string not NULL,
   7234  * but the length is zero.
   7235  */
   7236 struct MHD_PostField
   7237 {
   7238   /**
   7239    * The name of the field
   7240    */
   7241   struct MHD_String name;
   7242   /**
   7243    * The field data
   7244    * If not set or defined then to C string is NULL.
   7245    * If set to empty string then pointer to C string not NULL,
   7246    * but the length is zero.
   7247    */
   7248   struct MHD_StringNullable value;
   7249   /**
   7250    * The filename if provided (only for "multipart/form-data")
   7251    * If not set or defined then to C string is NULL.
   7252    * If set to empty string then pointer to C string not NULL,
   7253    * but the length is zero.
   7254    */
   7255   struct MHD_StringNullable filename;
   7256   /**
   7257    * The Content-Type if provided (only for "multipart/form-data")
   7258    * If not set or defined then to C string is NULL.
   7259    * If set to empty string then pointer to C string not NULL,
   7260    * but the length is zero.
   7261    */
   7262   struct MHD_StringNullable content_type;
   7263   /**
   7264    * The Transfer-Encoding if provided (only for "multipart/form-data")
   7265    * If not set or defined then to C string is NULL.
   7266    * If set to empty string then pointer to C string not NULL,
   7267    * but the length is zero.
   7268    */
   7269   struct MHD_StringNullable transfer_encoding;
   7270 };
   7271 
   7272 #  define MHD_POSTFILED_DEFINED 1
   7273 #endif /* ! MHD_POSTFILED_DEFINED */
   7274 
   7275 
   7276 /**
   7277  * Iterator over POST data.
   7278  *
   7279  * The @a data pointer is valid only until return from this function.
   7280  *
   7281  * The pointers to the strings in @a data are valid until any MHD_UploadAction
   7282  * is provided. If the data is needed beyond this point, it should be copied.
   7283  *
   7284  * @param cls closure
   7285  * @param data the element of the post data, the pointer is valid only until
   7286  *             return from this function
   7287  * @return #MHD_YES to continue iterating,
   7288  *         #MHD_NO to abort the iteration
   7289  * @ingroup request
   7290  */
   7291 typedef enum MHD_Bool
   7292 (MHD_FN_PAR_NONNULL_ (2)
   7293  *MHD_PostDataIterator)(void *cls,
   7294                         const struct MHD_PostField *data);
   7295 
   7296 /**
   7297  * Get all of the post data from the request via request.
   7298  *
   7299  * @param request the request to get data for
   7300  * @param iterator callback to call on each header;
   7301  *        maybe NULL (then just count headers)
   7302  * @param iterator_cls extra argument to @a iterator
   7303  * @return number of entries iterated over
   7304  * @ingroup request
   7305  */
   7306 MHD_EXTERN_ size_t
   7307 MHD_request_get_post_data_cb (struct MHD_Request *request,
   7308                               MHD_PostDataIterator iterator,
   7309                               void *iterator_cls)
   7310 MHD_FN_PAR_NONNULL_ (1);
   7311 
   7312 /**
   7313  * Get all of the post data from the request.
   7314  *
   7315  * The pointers to the strings in @a elements are valid until any
   7316  * MHD_UploadAction is provided. If the data is needed beyond this point,
   7317  * it should be copied.
   7318  * @param request the request to get data for
   7319  * @param num_elements the number of elements in @a elements array
   7320  * @param[out] elements the array of @a num_elements to get the data
   7321  * @return the number of elements stored in @a elements,
   7322  *         zero if no data or postprocessor was not used.
   7323  * @ingroup request
   7324  */
   7325 MHD_EXTERN_ size_t
   7326 MHD_request_get_post_data_list (
   7327   struct MHD_Request *request,
   7328   size_t num_elements,
   7329   struct MHD_PostField *elements)
   7330 MHD_FN_PAR_NONNULL_ (1)
   7331 MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_SIZE_ (3, 2);
   7332 
   7333 /* ***************** (c) WebSocket support ********** */
   7334 
   7335 /**
   7336  * Handle given to the application to manage special
   7337  * actions relating to MHD responses that "upgrade"
   7338  * the HTTP protocol (i.e. to WebSockets).
   7339  */
   7340 struct MHD_UpgradedHandle;
   7341 
   7342 
   7343 #ifndef MHD_UPGRADEHANDLER_DEFINED
   7344 
   7345 /**
   7346  * Function called after a protocol "upgrade" response was sent successfully
   7347  * and the connection is being switched to other protocol.
   7348  *
   7349  * The newly provided handle @a urh can be used to send and receive the data
   7350  * by #MHD_upgraded_send() and #MHD_upgraded_recv(). The handle must be closed
   7351  * by #MHD_upgraded_close() before destroying the daemon.
   7352  *
   7353  * "Upgraded" connection will not time out, but still counted for daemon
   7354  * global connections limit and for per-IP limit (if set).
   7355  *
   7356  * Except when in 'thread-per-connection' mode, implementations
   7357  * of this function should never block (as it will still be called
   7358  * from within the main event loop).
   7359  *
   7360  * @param cls closure, whatever was given to #MHD_action_upgrade().
   7361  * @param request original HTTP request handle,
   7362  *                giving the function a last chance
   7363  *                to inspect the original HTTP request
   7364  * @param urh argument for #MHD_upgrade_operation() on this @a response.
   7365  *        Applications must eventually use this callback to (indirectly)
   7366  *        perform the close() action on the @a sock.
   7367  */
   7368 typedef void
   7369 (MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_NONNULL_ (3)
   7370  *MHD_UpgradeHandler)(void *cls,
   7371                       struct MHD_Request *MHD_RESTRICT request,
   7372                       struct MHD_UpgradedHandle *MHD_RESTRICT urh);
   7373 
   7374 #  define MHD_UPGRADEHANDLER_DEFINED 1
   7375 #endif /* ! MHD_UPGRADEHANDLER_DEFINED */
   7376 
   7377 
   7378 /**
   7379  * Create a action object that can be used for 101 Upgrade
   7380  * responses, for example to implement WebSockets.  After sending the
   7381  * response, control over the data stream is given to the callback (which
   7382  * can then, for example, start some bi-directional communication).
   7383  * The callback will ONLY be called after the response header was successfully
   7384  * passed to the OS; if there are communication errors before, the usual MHD
   7385  * connection error handling code will be performed.
   7386  *
   7387  * At most one action can be created for any request.
   7388  *
   7389  * @param request the request to create action for
   7390  * @param upgrade_hdr_value the value of the "Upgrade:" header, mandatory
   7391                             string
   7392  * @param upgrade_handler function to call with the "upgraded" socket
   7393  * @param upgrade_handler_cls closure for @a upgrade_handler
   7394  * @param num_headers number of elements in the @a headers array,
   7395  *                    must be zero if @a headers is NULL
   7396  * @param headers the optional pointer to the array of the headers (the strings
   7397  *                are copied and does not need to be valid after return from
   7398  *                this function),
   7399  *                can be NULL if @a num_headers is zero
   7400  * @return NULL on error (i.e. invalid arguments, out of memory)
   7401  * @ingroup action
   7402  */
   7403 MHD_EXTERN_ const struct MHD_Action *
   7404 MHD_action_upgrade (struct MHD_Request *MHD_RESTRICT request,
   7405                     const char *MHD_RESTRICT upgrade_hdr_value,
   7406                     MHD_UpgradeHandler upgrade_handler,
   7407                     void *upgrade_handler_cls,
   7408                     size_t num_headers,
   7409                     const struct MHD_NameValueCStr *MHD_RESTRICT headers)
   7410 MHD_FN_PAR_NONNULL_ (1) MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_CSTR_ (2)
   7411 MHD_FN_PAR_NONNULL_IF_NONZERO_ (6, 5)
   7412 MHD_FN_PAR_IN_SIZE_ (6, 5);
   7413 
   7414 
   7415 /**
   7416  * Create a action object that can be used for 101 Upgrade
   7417  * responses, for example to implement WebSockets.  After sending the
   7418  * response, control over the data stream is given to the callback (which
   7419  * can then, for example, start some bi-directional communication).
   7420  * The callback will ONLY be called after the response header was successfully
   7421  * passed to the OS; if there are communication errors before, the usual MHD
   7422  * connection error handling code will be performed.
   7423  *
   7424  * At most one action can be created for any request.
   7425  *
   7426  * @param request the request to create action for
   7427  * @param upgrade_hdr_value the value of the "Upgrade:" header, mandatory
   7428                             string
   7429  * @param upgrade_handler function to call with the "upgraded" socket
   7430  * @param upgrade_handler_cls closure for @a upgrade_handler
   7431  * @param num_headers number of elements in the @a headers array,
   7432  *                    must be zero if @a headers is NULL
   7433  * @param headers the optional pointer to the array of the headers (the strings
   7434  *                are copied and does not need to be valid after return from
   7435  *                this function),
   7436  *                can be NULL if @a num_headers is zero
   7437  * @return NULL on error (i.e. invalid arguments, out of memory)
   7438  * @ingroup action
   7439  */
   7440 MHD_EXTERN_ const struct MHD_UploadAction *
   7441 MHD_upload_action_upgrade (
   7442   struct MHD_Request *MHD_RESTRICT request,
   7443   const char *MHD_RESTRICT upgrade_hdr_value,
   7444   MHD_UpgradeHandler upgrade_handler,
   7445   void *upgrade_handler_cls,
   7446   size_t num_headers,
   7447   const struct MHD_NameValueCStr *MHD_RESTRICT headers)
   7448 MHD_FN_PAR_NONNULL_ (1) MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_CSTR_ (2)
   7449 MHD_FN_PAR_NONNULL_IF_NONZERO_ (6, 5)
   7450 MHD_FN_PAR_IN_SIZE_ (6, 5);
   7451 
   7452 
   7453 /**
   7454  * Receive data on the HTTP-Upgraded connection.
   7455  *
   7456  * The function finished if one of the following happens:
   7457  * + ANY amount of data has been received,
   7458  * + timeout reached,
   7459  * + network error occurs
   7460  *
   7461  * If @a recv_buf_size is zero, no data are received.
   7462  * For a valid @a urh, the function returns #MHD_SC_OK immediately and stores
   7463  * zero in the variable pointed to by @a received_size.
   7464  *
   7465  * @param urh the HTTP-Upgraded handle
   7466  * @param recv_buf_size the size of the @a recv_buf,
   7467  *                      must be zero if @a recv_buf is NULL
   7468  * @param recv_buf the buffer to receive the data,
   7469  *                 can be NULL if @a recv_buf_size is zero
   7470  * @param received_size the pointer to variable to get amount of received data
   7471  * @param max_wait_millisec the maximum wait time for the data,
   7472  *                          non-blocking operation if set to zero,
   7473  *                          wait indefinitely if larger or equal to
   7474  *                          #MHD_WAIT_INDEFINITELY,
   7475  *                          the function may return earlier if waiting is
   7476  *                          interrupted or by other reasons
   7477  * @return #MHD_SC_OK if ANY data received (check the @a received_size),
   7478  *                    remote shut down send side (indicated by @a received_size
   7479  *                    set to zero while @a recv_buf_size is not zero) or
   7480  *                    @a recv_buf_size is zero,
   7481  *         #MHD_SC_UPGRADED_NET_TIMEOUT if NO data received but timeout expired,
   7482  *         #MHD_SC_UPGRADED_NET_CONN_CLOSED if network connection has been
   7483  *                                          closed,
   7484  *         #MHD_SC_UPGRADED_NET_CONN_BROKEN if broken network connection has
   7485  *                                          been detected,
   7486  *         #MHD_SC_UPGRADED_TLS_ERROR if TLS error occurs (only for TLS),
   7487  *         #MHD_SC_UPGRADED_NET_HARD_ERROR if any other network or sockets
   7488  *                                         unrecoverable error occurs,
   7489  *         #MHD_SC_UPGRADED_HANDLE_INVALID if @a urh is invalid,
   7490  *         #MHD_SC_UPGRADED_WAITING_NOT_SUPPORTED if timed wait is not supported
   7491  *                                                by this MHD build or platform
   7492  */
   7493 MHD_EXTERN_ enum MHD_StatusCode
   7494 MHD_upgraded_recv (struct MHD_UpgradedHandle *MHD_RESTRICT urh,
   7495                    size_t recv_buf_size,
   7496                    void *MHD_RESTRICT recv_buf,
   7497                    size_t *MHD_RESTRICT received_size,
   7498                    uint_fast64_t max_wait_millisec)
   7499 MHD_FN_PAR_NONNULL_ (1)
   7500 MHD_FN_PAR_NONNULL_IF_NONZERO_ (3, 2) MHD_FN_PAR_OUT_SIZE_ (3, 2)
   7501 MHD_FN_PAR_NONNULL_ (4) MHD_FN_PAR_OUT_ (4);
   7502 
   7503 
   7504 /**
   7505  * Send data on the HTTP-Upgraded connection.
   7506  *
   7507  * The function finished if one of the following happens:
   7508  * + ALL provided data has been sent,
   7509  * + timeout reached,
   7510  * + network error occurs
   7511  *
   7512  * Parameter @a more_data_to_come controls network buffering. When set to
   7513  * #MHD_YES, the OS waits shortly for additional data and tries to use
   7514  * the network more effeciently delaying the last network packet, if it is
   7515  * incomplete, to combine it with the next data provided.
   7516  *
   7517  * If @a send_buf_size is zero, no data are sent or pushed to the network.
   7518  * For a valid @a urh, the function returns #MHD_SC_OK immediately and stores
   7519  * zero in the variable pointed to by @a sent_size.
   7520  *
   7521  * @param urh the HTTP-Upgraded handle
   7522  * @param send_buf_size the amount of data in the @a send_buf,
   7523  *                      must be zero if @a send_buf is NULL
   7524  * @param send_buf the buffer with the data to send,
   7525  *                 can be NULL if @a send_buf_size is zero
   7526  * @param sent_size the pointer to get the amout of sent data
   7527  * @param max_wait_millisec the maximum wait time for the data,
   7528  *                          non-blocking operation if set to zero,
   7529  *                          wait indefinitely if larger or equal to
   7530  *                          #MHD_WAIT_INDEFINITELY
   7531  * @param more_data_to_come set to #MHD_YES if the provided data in
   7532  *                          the @a send_buf is part of a larger data package,
   7533  *                          like an incomplete message or streamed
   7534  *                          (not the final) part of some file, and more data
   7535  *                          expected to be sent soon over the same connection,
   7536  *                          set to #MHD_NO the data in the @a send_buf is
   7537  *                          the complete message or the final part of
   7538  *                          the message (or file) and it should be pushed
   7539  *                          to the network (and to the client) as soon
   7540  *                          as possible
   7541  * @return #MHD_SC_OK if any data were sent or @a send_buf_size is zero
   7542  *         (check @a sent_size),
   7543  *         #MHD_SC_UPGRADED_NET_TIMEOUT if NO data sent but timeout expired,
   7544  *         #MHD_SC_UPGRADED_NET_CONN_CLOSED if network connection has been
   7545  *                                          closed,
   7546  *         #MHD_SC_UPGRADED_NET_CONN_BROKEN if broken network connection has
   7547  *                                          been detected,
   7548  *         #MHD_SC_UPGRADED_TLS_ERROR if TLS error occurs (only for TLS),
   7549  *         #MHD_SC_UPGRADED_NET_HARD_ERROR if any other network or sockets
   7550  *                                         unrecoverable error occurs,
   7551  *         #MHD_SC_UPGRADED_HANDLE_INVALID if @a urh is invalid,
   7552  *         #MHD_SC_UPGRADED_WAITING_NOT_SUPPORTED if timed wait is not supported
   7553  *                                                by this MHD build or platform
   7554  */
   7555 MHD_EXTERN_ enum MHD_StatusCode
   7556 MHD_upgraded_send (struct MHD_UpgradedHandle *MHD_RESTRICT urh,
   7557                    size_t send_buf_size,
   7558                    const void *MHD_RESTRICT send_buf,
   7559                    size_t *MHD_RESTRICT sent_size,
   7560                    uint_fast64_t max_wait_millisec,
   7561                    enum MHD_Bool more_data_to_come)
   7562 MHD_FN_PAR_NONNULL_ (1)
   7563 MHD_FN_PAR_NONNULL_IF_NONZERO_ (3, 2) MHD_FN_PAR_IN_SIZE_ (3, 2)
   7564 MHD_FN_PAR_NONNULL_ (4) MHD_FN_PAR_OUT_ (4);
   7565 
   7566 
   7567 /**
   7568  * Close HTTP-Upgraded connection handle.
   7569  *
   7570  * The handle cannot be used after successful return from this function.
   7571  *
   7572  * The function cannot fail if called correctly (the daemon is not destroyed
   7573  * and the upgraded connection has not been closed yet).
   7574  *
   7575  * @param urh the handle to close
   7576  * @return #MHD_SC_OK on success,
   7577  *         error code otherwise
   7578  */
   7579 MHD_EXTERN_ enum MHD_StatusCode
   7580 MHD_upgraded_close (struct MHD_UpgradedHandle *urh)
   7581 MHD_FN_PAR_NONNULL_ (1);
   7582 
   7583 
   7584 /* ********************** (e) Client auth ********************** */
   7585 
   7586 
   7587 /**
   7588  * Length of the binary output of the MD5 hash function.
   7589  * @sa #MHD_digest_get_hash_size()
   7590  * @ingroup authentication
   7591  */
   7592 #define MHD_MD5_DIGEST_SIZE 16
   7593 
   7594 /**
   7595  * Length of the binary output of the SHA-256 hash function.
   7596  * @sa #MHD_digest_get_hash_size()
   7597  * @ingroup authentication
   7598  */
   7599 #define MHD_SHA256_DIGEST_SIZE 32
   7600 
   7601 /**
   7602  * Length of the binary output of the SHA-512/256 hash function.
   7603  * @warning While this value is the same as the #MHD_SHA256_DIGEST_SIZE,
   7604  *          the calculated digests for SHA-256 and SHA-512/256 are different.
   7605  * @sa #MHD_digest_get_hash_size()
   7606  * @ingroup authentication
   7607  */
   7608 #define MHD_SHA512_256_DIGEST_SIZE 32
   7609 
   7610 /**
   7611  * Base type of hash calculation.
   7612  * Used as part of #MHD_DigestAuthAlgo values.
   7613  *
   7614  * @warning Not used directly by MHD API.
   7615  */
   7616 enum MHD_FIXED_ENUM_MHD_APP_SET_ MHD_DigestBaseAlgo
   7617 {
   7618   /**
   7619    * Invalid hash algorithm value
   7620    */
   7621   MHD_DIGEST_BASE_ALGO_INVALID = 0
   7622   ,
   7623   /**
   7624    * MD5 hash algorithm.
   7625    * As specified by RFC1321
   7626    */
   7627   MHD_DIGEST_BASE_ALGO_MD5 = (1u << 0)
   7628   ,
   7629   /**
   7630    * SHA-256 hash algorithm.
   7631    * As specified by FIPS PUB 180-4
   7632    */
   7633   MHD_DIGEST_BASE_ALGO_SHA256 = (1u << 1)
   7634   ,
   7635   /**
   7636    * SHA-512/256 hash algorithm.
   7637    * As specified by FIPS PUB 180-4
   7638    */
   7639   MHD_DIGEST_BASE_ALGO_SHA512_256 = (1u << 2)
   7640 };
   7641 
   7642 /**
   7643  * The flag indicating non-session algorithm types,
   7644  * like 'MD5', 'SHA-256' or 'SHA-512-256'.
   7645  */
   7646 #define MHD_DIGEST_AUTH_ALGO_NON_SESSION    (1u << 6)
   7647 
   7648 /**
   7649  * The flag indicating session algorithm types,
   7650  * like 'MD5-sess', 'SHA-256-sess' or 'SHA-512-256-sess'.
   7651  */
   7652 #define MHD_DIGEST_AUTH_ALGO_SESSION        (1u << 7)
   7653 
   7654 /**
   7655  * Digest algorithm identification
   7656  */
   7657 enum MHD_FIXED_ENUM_MHD_APP_SET_ MHD_DigestAuthAlgo
   7658 {
   7659   /**
   7660    * Unknown or wrong algorithm type.
   7661    * Used in struct MHD_AuthDigestInfo to indicate client value that
   7662    * cannot by identified.
   7663    */
   7664   MHD_DIGEST_AUTH_ALGO_INVALID = 0
   7665   ,
   7666   /**
   7667    * The 'MD5' algorithm, non-session version.
   7668    */
   7669   MHD_DIGEST_AUTH_ALGO_MD5 =
   7670     MHD_DIGEST_BASE_ALGO_MD5 | MHD_DIGEST_AUTH_ALGO_NON_SESSION
   7671   ,
   7672   /**
   7673    * The 'MD5-sess' algorithm.
   7674    * Not supported by MHD for authentication.
   7675    */
   7676   MHD_DIGEST_AUTH_ALGO_MD5_SESSION =
   7677     MHD_DIGEST_BASE_ALGO_MD5 | MHD_DIGEST_AUTH_ALGO_SESSION
   7678   ,
   7679   /**
   7680    * The 'SHA-256' algorithm, non-session version.
   7681    */
   7682   MHD_DIGEST_AUTH_ALGO_SHA256 =
   7683     MHD_DIGEST_BASE_ALGO_SHA256 | MHD_DIGEST_AUTH_ALGO_NON_SESSION
   7684   ,
   7685   /**
   7686    * The 'SHA-256-sess' algorithm.
   7687    * Not supported by MHD for authentication.
   7688    */
   7689   MHD_DIGEST_AUTH_ALGO_SHA256_SESSION =
   7690     MHD_DIGEST_BASE_ALGO_SHA256 | MHD_DIGEST_AUTH_ALGO_SESSION
   7691   ,
   7692   /**
   7693    * The 'SHA-512-256' (SHA-512/256) algorithm.
   7694    */
   7695   MHD_DIGEST_AUTH_ALGO_SHA512_256 =
   7696     MHD_DIGEST_BASE_ALGO_SHA512_256 | MHD_DIGEST_AUTH_ALGO_NON_SESSION
   7697   ,
   7698   /**
   7699    * The 'SHA-512-256-sess' (SHA-512/256 session) algorithm.
   7700    * Not supported by MHD for authentication.
   7701    */
   7702   MHD_DIGEST_AUTH_ALGO_SHA512_256_SESSION =
   7703     MHD_DIGEST_BASE_ALGO_SHA512_256 | MHD_DIGEST_AUTH_ALGO_SESSION
   7704 };
   7705 
   7706 
   7707 /**
   7708  * Get digest size in bytes for specified algorithm.
   7709  *
   7710  * The size of the digest specifies the size of the userhash, userdigest
   7711  * and other parameters which size depends on used hash algorithm.
   7712  * @param algo the algorithm to check
   7713  * @return the size (in bytes) of the digest (either #MHD_MD5_DIGEST_SIZE or
   7714  *         #MHD_SHA256_DIGEST_SIZE/MHD_SHA512_256_DIGEST_SIZE)
   7715  *         or zero if the input value is not supported or not valid
   7716  * @sa #MHD_digest_auth_calc_userdigest()
   7717  * @sa #MHD_digest_auth_calc_userhash(), #MHD_digest_auth_calc_userhash_hex()
   7718  * @ingroup authentication
   7719  */
   7720 MHD_EXTERN_ size_t
   7721 MHD_digest_get_hash_size (enum MHD_DigestAuthAlgo algo)
   7722 MHD_FN_CONST_;
   7723 
   7724 /**
   7725  * Digest algorithm identification, allow multiple selection.
   7726  *
   7727  * #MHD_DigestAuthAlgo always can be casted to #MHD_DigestAuthMultiAlgo, but
   7728  * not vice versa.
   7729  */
   7730 enum MHD_FIXED_ENUM_MHD_APP_SET_ MHD_DigestAuthMultiAlgo
   7731 {
   7732   /**
   7733    * Unknown or wrong algorithm type.
   7734    */
   7735   MHD_DIGEST_AUTH_MULT_ALGO_INVALID = MHD_DIGEST_AUTH_ALGO_INVALID
   7736   ,
   7737   /**
   7738    * The 'MD5' algorithm, non-session version.
   7739    */
   7740   MHD_DIGEST_AUTH_MULT_ALGO_MD5 = MHD_DIGEST_AUTH_ALGO_MD5
   7741   ,
   7742   /**
   7743    * The 'MD5-sess' algorithm.
   7744    * Not supported by MHD for authentication.
   7745    * Reserved value.
   7746    */
   7747   MHD_DIGEST_AUTH_MULT_ALGO_MD5_SESSION = MHD_DIGEST_AUTH_ALGO_MD5_SESSION
   7748   ,
   7749   /**
   7750    * The 'SHA-256' algorithm, non-session version.
   7751    */
   7752   MHD_DIGEST_AUTH_MULT_ALGO_SHA256 = MHD_DIGEST_AUTH_ALGO_SHA256
   7753   ,
   7754   /**
   7755    * The 'SHA-256-sess' algorithm.
   7756    * Not supported by MHD for authentication.
   7757    * Reserved value.
   7758    */
   7759   MHD_DIGEST_AUTH_MULT_ALGO_SHA256_SESSION =
   7760     MHD_DIGEST_AUTH_ALGO_SHA256_SESSION
   7761   ,
   7762   /**
   7763    * The 'SHA-512-256' (SHA-512/256) algorithm, non-session version.
   7764    */
   7765   MHD_DIGEST_AUTH_MULT_ALGO_SHA512_256 = MHD_DIGEST_AUTH_ALGO_SHA512_256
   7766   ,
   7767   /**
   7768    * The 'SHA-512-256-sess' (SHA-512/256 session) algorithm.
   7769    * Not supported by MHD for authentication.
   7770    * Reserved value.
   7771    */
   7772   MHD_DIGEST_AUTH_MULT_ALGO_SHA512_256_SESSION =
   7773     MHD_DIGEST_AUTH_ALGO_SHA512_256_SESSION
   7774   ,
   7775   /**
   7776    * SHA-256 or SHA-512/256 non-session algorithm, MHD will choose
   7777    * the preferred or the matching one.
   7778    */
   7779   MHD_DIGEST_AUTH_MULT_ALGO_SHA_ANY_NON_SESSION =
   7780     MHD_DIGEST_AUTH_ALGO_SHA256 | MHD_DIGEST_AUTH_ALGO_SHA512_256
   7781   ,
   7782   /**
   7783    * Any non-session algorithm, MHD will choose the preferred or
   7784    * the matching one.
   7785    */
   7786   MHD_DIGEST_AUTH_MULT_ALGO_ANY_NON_SESSION =
   7787     (0x3F) | MHD_DIGEST_AUTH_ALGO_NON_SESSION
   7788   ,
   7789   /**
   7790    * The SHA-256 or SHA-512/256 session algorithm.
   7791    * Not supported by MHD.
   7792    * Reserved value.
   7793    */
   7794   MHD_DIGEST_AUTH_MULT_ALGO_SHA_ANY_SESSION =
   7795     MHD_DIGEST_AUTH_ALGO_SHA256_SESSION
   7796     | MHD_DIGEST_AUTH_ALGO_SHA512_256_SESSION
   7797   ,
   7798   /**
   7799    * Any session algorithm.
   7800    * Not supported by MHD.
   7801    * Reserved value.
   7802    */
   7803   MHD_DIGEST_AUTH_MULT_ALGO_ANY_SESSION =
   7804     (0x3F) | MHD_DIGEST_AUTH_ALGO_SESSION
   7805   ,
   7806   /**
   7807    * The MD5 algorithm, session or non-session.
   7808    * Currently supported as non-session only.
   7809    */
   7810   MHD_DIGEST_AUTH_MULT_ALGO_MD5_ANY =
   7811     MHD_DIGEST_AUTH_MULT_ALGO_MD5 | MHD_DIGEST_AUTH_MULT_ALGO_MD5_SESSION
   7812   ,
   7813   /**
   7814    * The SHA-256 algorithm, session or non-session.
   7815    * Currently supported as non-session only.
   7816    */
   7817   MHD_DIGEST_AUTH_MULT_ALGO_SHA256_ANY =
   7818     MHD_DIGEST_AUTH_MULT_ALGO_SHA256
   7819     | MHD_DIGEST_AUTH_MULT_ALGO_SHA256_SESSION
   7820   ,
   7821   /**
   7822    * The SHA-512/256 algorithm, session or non-session.
   7823    * Currently supported as non-session only.
   7824    */
   7825   MHD_DIGEST_AUTH_MULT_ALGO_SHA512_256_ANY =
   7826     MHD_DIGEST_AUTH_MULT_ALGO_SHA512_256
   7827     | MHD_DIGEST_AUTH_MULT_ALGO_SHA512_256_SESSION
   7828   ,
   7829   /**
   7830    * The SHA-256 or SHA-512/256 algorithm, session or non-session.
   7831    * Currently supported as non-session only.
   7832    */
   7833   MHD_DIGEST_AUTH_MULT_ALGO_SHA_ANY_ANY =
   7834     MHD_DIGEST_AUTH_MULT_ALGO_SHA_ANY_NON_SESSION
   7835     | MHD_DIGEST_AUTH_MULT_ALGO_SHA_ANY_SESSION
   7836   ,
   7837   /**
   7838    * Any algorithm, MHD will choose the preferred or the matching one.
   7839    */
   7840   MHD_DIGEST_AUTH_MULT_ALGO_ANY =
   7841     (0x3F) | MHD_DIGEST_AUTH_ALGO_NON_SESSION | MHD_DIGEST_AUTH_ALGO_SESSION
   7842 };
   7843 
   7844 
   7845 /**
   7846  * Calculate "userhash", return it as binary data.
   7847  *
   7848  * The "userhash" is the hash of the string "username:realm".
   7849  *
   7850  * The "userhash" could be used to avoid sending username in cleartext in Digest
   7851  * Authorization client's header.
   7852  *
   7853  * Userhash is not designed to hide the username in local database or files,
   7854  * as username in cleartext is required for #MHD_digest_auth_check() function
   7855  * to check the response, but it can be used to hide username in HTTP headers.
   7856  *
   7857  * This function could be used when the new username is added to the username
   7858  * database to save the "userhash" alongside with the username (preferably) or
   7859  * when loading list of the usernames to generate the userhash for every loaded
   7860  * username (this will cause delays at the start with the long lists).
   7861  *
   7862  * Once "userhash" is generated it could be used to identify users by clients
   7863  * with "userhash" support.
   7864  * Avoid repetitive usage of this function for the same username/realm
   7865  * combination as it will cause excessive CPU load; save and reuse the result
   7866  * instead.
   7867  *
   7868  * @param algo the algorithm for userhash calculations
   7869  * @param username the username
   7870  * @param realm the realm
   7871  * @param[out] userhash_bin the output buffer for userhash as binary data;
   7872  *                          if this function succeeds, then this buffer has
   7873  *                          #MHD_digest_get_hash_size() bytes of userhash
   7874  *                          upon return
   7875  * @param bin_buf_size the size of the @a userhash_bin buffer, must be
   7876  *                     at least #MHD_digest_get_hash_size() bytes long
   7877  * @return #MHD_SC_OK on success,
   7878  *         #MHD_SC_OUT_BUFF_TOO_SMALL if @a bin_buf_size is too small,
   7879  *         #MHD_SC_HASH_FAILED if hashing failed,
   7880  *         #MHD_SC_AUTH_DIGEST_ALGO_NOT_SUPPORTED if requested @a algo is
   7881  *                                                unknown or unsupported.
   7882  * @sa #MHD_digest_auth_calc_userhash_hex()
   7883  * @ingroup authentication
   7884  */
   7885 MHD_EXTERN_ enum MHD_StatusCode
   7886 MHD_digest_auth_calc_userhash (enum MHD_DigestAuthAlgo algo,
   7887                                const char *MHD_RESTRICT username,
   7888                                const char *MHD_RESTRICT realm,
   7889                                size_t bin_buf_size,
   7890                                void *MHD_RESTRICT userhash_bin)
   7891 MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_CSTR_ (2)
   7892 MHD_FN_PAR_CSTR_ (3) MHD_FN_PAR_OUT_SIZE_ (5, 4);
   7893 
   7894 
   7895 /**
   7896  * Calculate "userhash", return it as hexadecimal string.
   7897  *
   7898  * The "userhash" is the hash of the string "username:realm".
   7899  *
   7900  * The "userhash" could be used to avoid sending username in cleartext in Digest
   7901  * Authorization client's header.
   7902  *
   7903  * Userhash is not designed to hide the username in local database or files,
   7904  * as username in cleartext is required for #MHD_digest_auth_check() function
   7905  * to check the response, but it can be used to hide username in HTTP headers.
   7906  *
   7907  * This function could be used when the new username is added to the username
   7908  * database to save the "userhash" alongside with the username (preferably) or
   7909  * when loading list of the usernames to generate the userhash for every loaded
   7910  * username (this will cause delays at the start with the long lists).
   7911  *
   7912  * Once "userhash" is generated it could be used to identify users by clients
   7913  * with "userhash" support.
   7914  * Avoid repetitive usage of this function for the same username/realm
   7915  * combination as it will cause excessive CPU load; save and reuse the result
   7916  * instead.
   7917  *
   7918  * @param algo the algorithm for userhash calculations
   7919  * @param username the username
   7920  * @param realm the realm
   7921  * @param hex_buf_size the size of the @a userhash_hex buffer, must be
   7922  *                     at least #MHD_digest_get_hash_size()*2+1 chars long
   7923  * @param[out] userhash_hex the output buffer for userhash as hex string;
   7924  *                          if this function succeeds, then this buffer has
   7925  *                          #MHD_digest_get_hash_size()*2 chars long
   7926  *                          userhash string plus one zero-termination char
   7927  * @return #MHD_SC_OK on success,
   7928  *         #MHD_SC_OUT_BUFF_TOO_SMALL if @a bin_buf_size is too small,
   7929  *         #MHD_SC_HASH_FAILED if hashing failed,
   7930  *         #MHD_SC_AUTH_DIGEST_ALGO_NOT_SUPPORTED if requested @a algo is
   7931  *                                                unknown or unsupported.
   7932  * @sa #MHD_digest_auth_calc_userhash()
   7933  * @ingroup authentication
   7934  */
   7935 MHD_EXTERN_ enum MHD_StatusCode
   7936 MHD_digest_auth_calc_userhash_hex (
   7937   enum MHD_DigestAuthAlgo algo,
   7938   const char *MHD_RESTRICT username,
   7939   const char *MHD_RESTRICT realm,
   7940   size_t hex_buf_size,
   7941   char *userhash_hex)
   7942 MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_CSTR_ (2)
   7943 MHD_FN_PAR_CSTR_ (3) MHD_FN_PAR_OUT_SIZE_ (5, 4);
   7944 
   7945 
   7946 /**
   7947  * The type of username used by client in Digest Authorization header
   7948  *
   7949  * Values are sorted so simplified checks could be used.
   7950  * For example:
   7951  * * (value <= MHD_DIGEST_AUTH_UNAME_TYPE_INVALID) is true if no valid username
   7952  *   is provided by the client (not used currently)
   7953  * * (value >= MHD_DIGEST_AUTH_UNAME_TYPE_USERHASH) is true if username is
   7954  *   provided in any form
   7955  * * (value >= MHD_DIGEST_AUTH_UNAME_TYPE_STANDARD) is true if username is
   7956  *   provided in clear text (no userhash matching is needed)
   7957  */
   7958 enum MHD_FIXED_ENUM_MHD_SET_ MHD_DigestAuthUsernameType
   7959 {
   7960   /**
   7961    * No username parameter is in Digest Authorization header.
   7962    * Not used currently. Value #MHD_SC_REQ_AUTH_DATA_BROKEN is returned
   7963    * by #MHD_request_get_info_dynamic_sz() if the request has no username.
   7964    */
   7965   MHD_DIGEST_AUTH_UNAME_TYPE_MISSING = 0
   7966   ,
   7967   /**
   7968    * The 'username' parameter is used to specify the username.
   7969    */
   7970   MHD_DIGEST_AUTH_UNAME_TYPE_STANDARD = (1u << 2)
   7971   ,
   7972   /**
   7973    * The username is specified by 'username*' parameter with
   7974    * the extended notation (see RFC 5987, section 3.2.1).
   7975    * The only difference between standard and extended types is
   7976    * the way how username value is encoded in the header.
   7977    */
   7978   MHD_DIGEST_AUTH_UNAME_TYPE_EXTENDED = (1u << 3)
   7979   ,
   7980   /**
   7981    * The username provided in form of 'userhash' as
   7982    * specified by RFC 7616, section 3.4.4.
   7983    * @sa #MHD_digest_auth_calc_userhash_hex(), #MHD_digest_auth_calc_userhash()
   7984    */
   7985   MHD_DIGEST_AUTH_UNAME_TYPE_USERHASH = (1u << 1)
   7986   ,
   7987   /**
   7988    * The invalid combination of username parameters are used by client.
   7989    * Either:
   7990    * + both 'username' and 'username*' are used
   7991    * + 'username*' is used with 'userhash=true'
   7992    * + 'username*' used with invalid extended notation
   7993    * + 'username' is not hexadecimal string, while 'userhash' set to 'true'
   7994    * Not used currently. Value #MHD_SC_REQ_AUTH_DATA_BROKEN is returned
   7995    * by #MHD_request_get_info_dynamic_sz() if the request has broken username.
   7996    */
   7997   MHD_DIGEST_AUTH_UNAME_TYPE_INVALID = (1u << 0)
   7998 };
   7999 
   8000 /**
   8001  * The QOP ('quality of protection') types.
   8002  */
   8003 enum MHD_FIXED_ENUM_MHD_APP_SET_ MHD_DigestAuthQOP
   8004 {
   8005   /**
   8006    * Invalid/unknown QOP.
   8007    * Used in struct MHD_AuthDigestInfo to indicate client value that
   8008    * cannot by identified.
   8009    */
   8010   MHD_DIGEST_AUTH_QOP_INVALID = 0
   8011   ,
   8012   /**
   8013    * No QOP parameter.
   8014    * As described in old RFC 2069 original specification.
   8015    * This mode is not allowed by latest RFCs and should be used only to
   8016    * communicate with clients that do not support more modern modes (with QOP
   8017    * parameter).
   8018    * This mode is less secure than other modes and inefficient.
   8019    */
   8020   MHD_DIGEST_AUTH_QOP_NONE = (1u << 0)
   8021   ,
   8022   /**
   8023    * The 'auth' QOP type.
   8024    */
   8025   MHD_DIGEST_AUTH_QOP_AUTH = (1u << 1)
   8026   ,
   8027   /**
   8028    * The 'auth-int' QOP type.
   8029    * Not supported by MHD for authentication.
   8030    */
   8031   MHD_DIGEST_AUTH_QOP_AUTH_INT = (1u << 2)
   8032 };
   8033 
   8034 /**
   8035  * The QOP ('quality of protection') types, multiple selection.
   8036  *
   8037  * #MHD_DigestAuthQOP always can be casted to #MHD_DigestAuthMultiQOP, but
   8038  * not vice versa.
   8039  */
   8040 enum MHD_FIXED_ENUM_MHD_APP_SET_ MHD_DigestAuthMultiQOP
   8041 {
   8042   /**
   8043    * Invalid/unknown QOP.
   8044    */
   8045   MHD_DIGEST_AUTH_MULT_QOP_INVALID = MHD_DIGEST_AUTH_QOP_INVALID
   8046   ,
   8047   /**
   8048    * No QOP parameter.
   8049    * As described in old RFC 2069 original specification.
   8050    * This mode is not allowed by latest RFCs and should be used only to
   8051    * communicate with clients that do not support more modern modes (with QOP
   8052    * parameter).
   8053    * This mode is less secure than other modes and inefficient.
   8054    */
   8055   MHD_DIGEST_AUTH_MULT_QOP_NONE = MHD_DIGEST_AUTH_QOP_NONE
   8056   ,
   8057   /**
   8058    * The 'auth' QOP type.
   8059    */
   8060   MHD_DIGEST_AUTH_MULT_QOP_AUTH = MHD_DIGEST_AUTH_QOP_AUTH
   8061   ,
   8062   /**
   8063    * The 'auth-int' QOP type.
   8064    * Not supported by MHD.
   8065    * Reserved value.
   8066    */
   8067   MHD_DIGEST_AUTH_MULT_QOP_AUTH_INT = MHD_DIGEST_AUTH_QOP_AUTH_INT
   8068   ,
   8069   /**
   8070    * The 'auth' QOP type OR the old RFC2069 (no QOP) type.
   8071    * In other words: any types except 'auth-int'.
   8072    * RFC2069-compatible mode is allowed, thus this value should be used only
   8073    * when it is really necessary.
   8074    */
   8075   MHD_DIGEST_AUTH_MULT_QOP_ANY_NON_INT =
   8076     MHD_DIGEST_AUTH_QOP_NONE | MHD_DIGEST_AUTH_QOP_AUTH
   8077   ,
   8078   /**
   8079    * Any 'auth' QOP type ('auth' or 'auth-int').
   8080    * Currently supported as 'auth' QOP type only.
   8081    */
   8082   MHD_DIGEST_AUTH_MULT_QOP_AUTH_ANY =
   8083     MHD_DIGEST_AUTH_QOP_AUTH | MHD_DIGEST_AUTH_QOP_AUTH_INT
   8084 };
   8085 
   8086 /**
   8087  * The type of 'nc' (nonce count) value provided in the request
   8088  */
   8089 enum MHD_FIXED_ENUM_MHD_SET_ MHD_DigestAuthNC
   8090 {
   8091   /**
   8092    * Readable hexdecimal non-zero number.
   8093    * The decoded value is placed in @a nc member of struct MHD_AuthDigestInfo
   8094    */
   8095   MHD_DIGEST_AUTH_NC_NUMBER = 1
   8096   ,
   8097   /**
   8098    * Readable zero number.
   8099    * Compliant clients should not use such values.
   8100    * Can be treated as invalid request.
   8101    */
   8102   MHD_DIGEST_AUTH_NC_ZERO = 2
   8103   ,
   8104   /**
   8105    * 'nc' value is not provided by the client.
   8106    * Unless old RFC 2069 mode is allowed, this should be treated as invalid
   8107    * request.
   8108    */
   8109   MHD_DIGEST_AUTH_NC_NONE = 3
   8110   ,
   8111   /**
   8112    * 'nc' value is too long to be decoded.
   8113    * Compliant clients should not use such values.
   8114    * Can be treated as invalid request.
   8115    */
   8116   MHD_DIGEST_AUTH_NC_TOO_LONG = 4
   8117   ,
   8118   /**
   8119    * 'nc' value is too large for uint32_t.
   8120    * Compliant clients should not use such values.
   8121    * Can be treated as request with a stale nonce or as invalid request.
   8122    */
   8123   MHD_DIGEST_AUTH_NC_TOO_LARGE = 5
   8124 };
   8125 
   8126 
   8127 /**
   8128  * Information from Digest Authorization client's header.
   8129  *
   8130  * @see #MHD_REQUEST_INFO_DYNAMIC_AUTH_DIGEST_INFO
   8131  */
   8132 struct MHD_AuthDigestInfo
   8133 {
   8134   /**
   8135    * The algorithm as defined by client.
   8136    * Set automatically to MD5 if not specified by client.
   8137    */
   8138   enum MHD_DigestAuthAlgo algo;
   8139 
   8140   /**
   8141    * The type of username used by client.
   8142    */
   8143   enum MHD_DigestAuthUsernameType uname_type;
   8144 
   8145   /**
   8146    * The username string.
   8147    * Used only if username type is standard or extended, always NULL otherwise.
   8148    * If extended notation is used, this string is pct-decoded string
   8149    * with charset and language tag removed (i.e. it is original username
   8150    * extracted from the extended notation).
   8151    * When userhash is used by the client, the string pointer is NULL and
   8152    * @a userhash_hex and @a userhash_bin are set.
   8153    */
   8154   struct MHD_StringNullable username;
   8155 
   8156   /**
   8157    * The userhash string.
   8158    * Valid only if username type is userhash.
   8159    * This is unqoted string without decoding of the hexadecimal
   8160    * digits (as provided by the client).
   8161    * @sa #MHD_digest_auth_calc_userhash_hex()
   8162    */
   8163   struct MHD_StringNullable userhash_hex;
   8164 
   8165   /**
   8166    * The userhash decoded to binary form.
   8167    * Used only if username type is userhash, always NULL otherwise.
   8168    * When not NULL, this points to binary sequence @a userhash_bin_size bytes
   8169    * long.
   8170    * The valid size should be #MHD_digest_get_hash_size() bytes.
   8171    * @warning This is a binary data, no zero termination.
   8172    * @warning To avoid buffer overruns, always check the size of the data before
   8173    *          use, because @a userhash_bin can point even to zero-sized
   8174    *          data.
   8175    * @sa #MHD_digest_auth_calc_userhash()
   8176    */
   8177   const uint8_t *userhash_bin;
   8178 
   8179   /**
   8180    * The size of the data pointed by @a userhash_bin.
   8181    * Always zero when @a userhash_bin is NULL.
   8182    */
   8183   size_t userhash_bin_size;
   8184 
   8185   /**
   8186    * The 'opaque' parameter value, as specified by client.
   8187    * If not specified by client then string pointer is NULL.
   8188    */
   8189   struct MHD_StringNullable opaque;
   8190 
   8191   /**
   8192    * The 'realm' parameter value, as specified by client.
   8193    * If not specified by client then string pointer is NULL.
   8194    */
   8195   struct MHD_StringNullable realm;
   8196 
   8197   /**
   8198    * The 'qop' parameter value.
   8199    */
   8200   enum MHD_DigestAuthQOP qop;
   8201 
   8202   /**
   8203    * The length of the 'cnonce' parameter value, including possible
   8204    * backslash-escape characters.
   8205    * 'cnonce' is used in hash calculation, which is CPU-intensive procedure.
   8206    * An application may want to reject too large cnonces to limit the CPU load.
   8207    * A few kilobytes is a reasonable limit, typically cnonce is just 32-160
   8208    * characters long.
   8209    */
   8210   size_t cnonce_len;
   8211 
   8212   /**
   8213    * The type of 'nc' (nonce count) value provided in the request.
   8214    */
   8215   enum MHD_DigestAuthNC nc_type;
   8216 
   8217   /**
   8218    * The nc (nonce count) parameter value.
   8219    * Can be used by application to limit the number of nonce re-uses. If @a nc
   8220    * is higher than application wants to allow, then "auth required" response
   8221    * with 'stale=true' could be used to force client to retry with the fresh
   8222    * 'nonce'.
   8223    * Set to zero when @a nc_type is not set to #MHD_DIGEST_AUTH_NC_NUMBER.
   8224    */
   8225   uint_fast32_t nc;
   8226 };
   8227 
   8228 /**
   8229  * The result of digest authentication of the client.
   8230  *
   8231  * All error values are zero or negative.
   8232  */
   8233 enum MHD_FIXED_ENUM_MHD_SET_ MHD_DigestAuthResult
   8234 {
   8235   /**
   8236    * Authentication OK.
   8237    */
   8238   MHD_DAUTH_OK = 1
   8239   ,
   8240   /**
   8241    * General error, like "out of memory".
   8242    * Authentication may be valid, but cannot be checked.
   8243    */
   8244   MHD_DAUTH_ERROR = 0
   8245   ,
   8246   /**
   8247    * No "Authorization" header for Digest Authentication.
   8248    */
   8249   MHD_DAUTH_HEADER_MISSING = -1
   8250   ,
   8251   /**
   8252    * Wrong format of the header.
   8253    * Also returned if required parameters in Authorization header are missing
   8254    * or broken (in invalid format).
   8255    */
   8256   MHD_DAUTH_HEADER_BROKEN = -9
   8257   ,
   8258   /**
   8259    * Unsupported algorithm.
   8260    */
   8261   MHD_DAUTH_UNSUPPORTED_ALGO = -10
   8262   ,
   8263   /**
   8264    * Unsupported 'qop'.
   8265    */
   8266   MHD_DAUTH_UNSUPPORTED_QOP = -11
   8267   ,
   8268   /**
   8269    * Incorrect userdigest size.
   8270    */
   8271   MHD_DAUTH_INVALID_USERDIGEST_SIZE = -15
   8272   ,
   8273   /**
   8274    * Wrong 'username'.
   8275    */
   8276   MHD_DAUTH_WRONG_USERNAME = -17
   8277   ,
   8278   /**
   8279    * Wrong 'realm'.
   8280    */
   8281   MHD_DAUTH_WRONG_REALM = -18
   8282   ,
   8283   /**
   8284    * Wrong 'URI' (or URI parameters).
   8285    */
   8286   MHD_DAUTH_WRONG_URI = -19
   8287   ,
   8288   /**
   8289    * Wrong 'qop'.
   8290    */
   8291   MHD_DAUTH_WRONG_QOP = -20
   8292   ,
   8293   /**
   8294    * Wrong 'algorithm'.
   8295    */
   8296   MHD_DAUTH_WRONG_ALGO = -21
   8297   ,
   8298   /**
   8299    * Too large (>64 KiB) Authorization parameter value.
   8300    */
   8301   MHD_DAUTH_TOO_LARGE = -22
   8302   ,
   8303   /* The different form of naming is intentionally used for the results below,
   8304    * as they are more important */
   8305 
   8306   /**
   8307    * The 'nonce' is too old. Suggest the client to retry with the same
   8308    * username and password to get the fresh 'nonce'.
   8309    * The validity of the 'nonce' may be not checked.
   8310    */
   8311   MHD_DAUTH_NONCE_STALE = -25
   8312   ,
   8313   /**
   8314    * The 'nonce' is wrong. May indicate an attack attempt.
   8315    */
   8316   MHD_DAUTH_NONCE_WRONG = -33
   8317   ,
   8318   /**
   8319    * The 'response' is wrong. May indicate a wrong password used or
   8320    * an attack attempt.
   8321    */
   8322   MHD_DAUTH_RESPONSE_WRONG = -34
   8323 };
   8324 
   8325 
   8326 /**
   8327  * Authenticates the authorization header sent by the client.
   8328  *
   8329  * If RFC2069 mode is allowed by setting bit #MHD_DIGEST_AUTH_QOP_NONE in
   8330  * @a mqop and the client uses this mode, then server generated nonces are
   8331  * used as one-time nonces because nonce-count is not supported in this old RFC.
   8332  * Communication in this mode is very inefficient, especially if the client
   8333  * requests several resources one-by-one as for every request a new nonce must
   8334  * be generated and client repeats all requests twice (first time to get a new
   8335  * nonce and second time to perform an authorised request).
   8336  *
   8337  * @param request the request
   8338  * @param realm the realm for authorization of the client
   8339  * @param username the username to be authenticated, must be in clear text
   8340  *                 even if userhash is used by the client
   8341  * @param password the password matching the @a username (and the @a realm)
   8342  * @param max_nc the maximum allowed nc (Nonce Count) value, if client's nc
   8343  *               exceeds the specified value then MHD_DAUTH_NONCE_STALE is
   8344  *               returned;
   8345  *               if zero is specified then daemon default value is used.
   8346  * @param mqop the QOP to use
   8347  * @param malgo digest algorithms allowed to use, fail if algorithm used
   8348  *               by the client is not allowed by this parameter
   8349  * @return #MHD_DAUTH_OK if authenticated,
   8350  *         the error code otherwise
   8351  * @ingroup authentication
   8352  */
   8353 MHD_EXTERN_ enum MHD_DigestAuthResult
   8354 MHD_digest_auth_check (struct MHD_Request *MHD_RESTRICT request,
   8355                        const char *MHD_RESTRICT realm,
   8356                        const char *MHD_RESTRICT username,
   8357                        const char *MHD_RESTRICT password,
   8358                        uint_fast32_t max_nc,
   8359                        enum MHD_DigestAuthMultiQOP mqop,
   8360                        enum MHD_DigestAuthMultiAlgo malgo)
   8361 MHD_FN_PAR_NONNULL_ALL_
   8362 MHD_FN_PAR_CSTR_ (2) MHD_FN_PAR_CSTR_ (3) MHD_FN_PAR_CSTR_ (4);
   8363 
   8364 
   8365 /**
   8366  * Calculate userdigest, return it as a binary data.
   8367  *
   8368  * The "userdigest" is the hash of the "username:realm:password" string.
   8369  *
   8370  * The "userdigest" can be used to avoid storing the password in clear text
   8371  * in database/files
   8372  *
   8373  * This function is designed to improve security of stored credentials,
   8374  * the "userdigest" does not improve security of the authentication process.
   8375  *
   8376  * The results can be used to store username & userdigest pairs instead of
   8377  * username & password pairs. To further improve security, application may
   8378  * store username & userhash & userdigest triplets.
   8379  *
   8380  * @param algo the digest algorithm
   8381  * @param username the username
   8382  * @param realm the realm
   8383  * @param password the password
   8384  * @param bin_buf_size the size of the @a userdigest_bin buffer, must be
   8385  *                     at least #MHD_digest_get_hash_size() bytes long
   8386  * @param[out] userdigest_bin the output buffer for userdigest;
   8387  *                            if this function succeeds, then this buffer has
   8388  *                            #MHD_digest_get_hash_size() bytes of
   8389  *                            userdigest upon return
   8390  * @return #MHD_SC_OK on success,
   8391  *         #MHD_SC_OUT_BUFF_TOO_SMALL if @a bin_buf_size is too small,
   8392  *         #MHD_SC_HASH_FAILED if hashing failed,
   8393  *         #MHD_SC_AUTH_DIGEST_ALGO_NOT_SUPPORTED if requested @a algo is
   8394  *                                                unknown or unsupported.
   8395  * @sa #MHD_digest_auth_check_digest()
   8396  * @ingroup authentication
   8397  */
   8398 MHD_EXTERN_ enum MHD_StatusCode
   8399 MHD_digest_auth_calc_userdigest (enum MHD_DigestAuthAlgo algo,
   8400                                  const char *MHD_RESTRICT username,
   8401                                  const char *MHD_RESTRICT realm,
   8402                                  const char *MHD_RESTRICT password,
   8403                                  size_t bin_buf_size,
   8404                                  void *MHD_RESTRICT userdigest_bin)
   8405 MHD_FN_PAR_NONNULL_ALL_
   8406 MHD_FN_PAR_CSTR_ (2)
   8407 MHD_FN_PAR_CSTR_ (3)
   8408 MHD_FN_PAR_CSTR_ (4)
   8409 MHD_FN_PAR_OUT_SIZE_ (6, 5);
   8410 
   8411 
   8412 /**
   8413  * Authenticates the authorization header sent by the client by using
   8414  * hash of "username:realm:password".
   8415  *
   8416  * If RFC2069 mode is allowed by setting bit #MHD_DIGEST_AUTH_QOP_NONE in
   8417  * @a mqop and the client uses this mode, then server generated nonces are
   8418  * used as one-time nonces because nonce-count is not supported in this old RFC.
   8419  * Communication in this mode is very inefficient, especially if the client
   8420  * requests several resources one-by-one as for every request a new nonce must
   8421  * be generated and client repeats all requests twice (first time to get a new
   8422  * nonce and second time to perform an authorised request).
   8423  *
   8424  * @param request the request
   8425  * @param realm the realm for authorization of the client
   8426  * @param username the username to be authenticated, must be in clear text
   8427  *                 even if userhash is used by the client
   8428  * @param userdigest_size the size of the @a userdigest in bytes, must match the
   8429  *                        hashing algorithm (see #MHD_MD5_DIGEST_SIZE,
   8430  *                        #MHD_SHA256_DIGEST_SIZE, #MHD_SHA512_256_DIGEST_SIZE,
   8431  *                        #MHD_digest_get_hash_size())
   8432  * @param userdigest the precalculated binary hash of the string
   8433  *                   "username:realm:password",
   8434  *                   see #MHD_digest_auth_calc_userdigest()
   8435  * @param max_nc the maximum allowed nc (Nonce Count) value, if client's nc
   8436  *               exceeds the specified value then MHD_DAUTH_NONCE_STALE is
   8437  *               returned;
   8438  *               if zero is specified then daemon default value is used.
   8439  * @param mqop the QOP to use
   8440  * @param malgo digest algorithms allowed to use, fail if algorithm used
   8441  *              by the client is not allowed by this parameter;
   8442  *              more than one base algorithms (MD5, SHA-256, SHA-512/256)
   8443  *              cannot be used at the same time for this function
   8444  *              as @a userdigest must match specified algorithm
   8445  * @return #MHD_DAUTH_OK if authenticated,
   8446  *         the error code otherwise
   8447  * @sa #MHD_digest_auth_calc_userdigest()
   8448  * @ingroup authentication
   8449  */
   8450 MHD_EXTERN_ enum MHD_DigestAuthResult
   8451 MHD_digest_auth_check_digest (struct MHD_Request *MHD_RESTRICT request,
   8452                               const char *MHD_RESTRICT realm,
   8453                               const char *MHD_RESTRICT username,
   8454                               size_t userdigest_size,
   8455                               const void *MHD_RESTRICT userdigest,
   8456                               uint_fast32_t max_nc,
   8457                               enum MHD_DigestAuthMultiQOP mqop,
   8458                               enum MHD_DigestAuthMultiAlgo malgo)
   8459 MHD_FN_PAR_NONNULL_ALL_
   8460 MHD_FN_PAR_CSTR_ (2)
   8461 MHD_FN_PAR_CSTR_ (3)
   8462 MHD_FN_PAR_IN_SIZE_ (5, 4);
   8463 
   8464 
   8465 /**
   8466  * Add Digest Authentication "challenge" to the response.
   8467  *
   8468  * The response must have #MHD_HTTP_STATUS_UNAUTHORIZED status code.
   8469  *
   8470  * If @a mqop allows both RFC 2069 (#MHD_DIGEST_AUTH_QOP_NONE) and other QOP
   8471  * values, then the "challenge" is formed like if MHD_DIGEST_AUTH_QOP_NONE bit
   8472  * was not set, because such "challenge" should be backward-compatible with
   8473  * RFC 2069.
   8474  *
   8475  * If @a mqop allows only MHD_DIGEST_AUTH_MULT_QOP_NONE, then the response is
   8476  * formed in strict accordance with RFC 2069 (no 'qop', no 'userhash', no
   8477  * 'charset'). For better compatibility with clients, it is recommended (but
   8478  * not required) to set @a domain to NULL in this mode.
   8479  *
   8480  * New nonces are generated each time when the resulting response is used.
   8481  *
   8482  * See RFC 7616, section 3.3 for details.
   8483  *
   8484  * @param response the response to update; should contain the "access denied"
   8485  *                 body;
   8486  *                 note: this function sets the "WWW Authenticate" header and
   8487  *                 the caller should not set this header;
   8488  *                 the response must have #MHD_HTTP_STATUS_UNAUTHORIZED status
   8489  *                 code;
   8490  *                 the NULL is tolerated (the result is
   8491  *                 #MHD_SC_RESP_POINTER_NULL)
   8492  * @param realm the realm presented to the client
   8493  * @param opaque the string for opaque value, can be NULL, but NULL is
   8494  *               not recommended for better compatibility with clients;
   8495  *               the recommended format is hex or Base64 encoded string
   8496  * @param domain the optional space-separated list of URIs for which the
   8497  *               same authorisation could be used, URIs can be in form
   8498  *               "path-absolute" (the path for the same host with initial slash)
   8499  *               or in form "absolute-URI" (the full path with protocol), in
   8500  *               any case client may assume that URI is in the same "protection
   8501  *               space" if it starts with any of values specified here;
   8502  *               could be NULL (clients typically assume that the same
   8503  *               credentials could be used for any URI on the same host);
   8504  *               this list provides information for the client only and does
   8505  *               not actually restrict anything on the server side
   8506  * @param indicate_stale if set to #MHD_YES then indication of stale nonce used
   8507  *                       in the client's request is indicated by adding
   8508  *                       'stale=true' to the authentication header, this
   8509  *                       instructs the client to retry immediately with the new
   8510  *                       nonce and the same credentials, without asking user
   8511  *                       for the new password
   8512  * @param mqop the QOP to use
   8513  * @param malgo digest algorithm to use; if several algorithms are allowed
   8514  *              then one challenge for each allowed algorithm is added
   8515  * @param userhash_support if set to #MHD_YES then support of userhash is
   8516  *                         indicated, allowing client to provide
   8517  *                         hash("username:realm") instead of the username in
   8518  *                         clear text;
   8519  *                         note that clients are allowed to provide the username
   8520  *                         in cleartext even if this parameter set to non-zero;
   8521  *                         when userhash is used, application must be ready to
   8522  *                         identify users by provided userhash value instead of
   8523  *                         username; see #MHD_digest_auth_calc_userhash() and
   8524  *                         #MHD_digest_auth_calc_userhash_hex()
   8525  * @param prefer_utf8 if not set to #MHD_NO, parameter 'charset=UTF-8' is
   8526  *                    added, indicating for the client that UTF-8 encoding for
   8527  *                    the username is preferred
   8528  * @return #MHD_SC_OK if succeed,
   8529  *         #MHD_SC_TOO_LATE if the response has been already "frozen" (used to
   8530  *         create an action),
   8531  *         #MHD_SC_RESP_HEADERS_CONFLICT if Digest Authentication "challenge"
   8532  *         has been added already,
   8533  *         #MHD_SC_RESP_POINTER_NULL if @a response is NULL,
   8534  *         #MHD_SC_RESP_HTTP_CODE_NOT_SUITABLE is response status code is wrong,
   8535  *         #MHD_SC_RESP_HEADER_VALUE_INVALID if @a realm, @a opaque or @a domain
   8536  *         have wrong characters or zero length (for @a realm),
   8537  *         #MHD_SC_RESP_HEADER_MEM_ALLOC_FAILED if memory allocation failed,
   8538  *         or other error code if failed
   8539  * @ingroup authentication
   8540  */
   8541 MHD_EXTERN_ enum MHD_StatusCode
   8542 MHD_response_add_auth_digest_challenge (
   8543   struct MHD_Response *MHD_RESTRICT response,
   8544   const char *MHD_RESTRICT realm,
   8545   const char *MHD_RESTRICT opaque,
   8546   const char *MHD_RESTRICT domain,
   8547   enum MHD_Bool indicate_stale,
   8548   enum MHD_DigestAuthMultiQOP mqop,
   8549   enum MHD_DigestAuthMultiAlgo malgo,
   8550   enum MHD_Bool userhash_support,
   8551   enum MHD_Bool prefer_utf8)
   8552 MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_CSTR_ (2)
   8553 MHD_FN_PAR_CSTR_ (3) MHD_FN_PAR_CSTR_ (4);
   8554 
   8555 
   8556 /* Application may define MHD_NO_STATIC_INLINE macro before including
   8557    libmicrohttpd headers to disable static inline functions in the headers. */
   8558 #ifndef MHD_NO_STATIC_INLINE
   8559 
   8560 /**
   8561  * Create action to reply with Digest Authentication "challenge".
   8562  *
   8563  * The @a response must have #MHD_HTTP_STATUS_UNAUTHORIZED status code.
   8564  *
   8565  * See RFC 7616, section 3.3 for details.
   8566  *
   8567  * @param request the request to create the action for
   8568  * @param realm the realm presented to the client
   8569  * @param opaque the string for opaque value, can be NULL, but NULL is
   8570  *               not recommended for better compatibility with clients;
   8571  *               the recommended format is hex or Base64 encoded string
   8572  * @param domain the optional space-separated list of URIs for which the
   8573  *               same authorisation could be used, URIs can be in form
   8574  *               "path-absolute" (the path for the same host with initial slash)
   8575  *               or in form "absolute-URI" (the full path with protocol), in
   8576  *               any case client may assume that URI is in the same "protection
   8577  *               space" if it starts with any of values specified here;
   8578  *               could be NULL (clients typically assume that the same
   8579  *               credentials could be used for any URI on the same host);
   8580  *               this list provides information for the client only and does
   8581  *               not actually restrict anything on the server side
   8582  * @param indicate_stale if set to #MHD_YES then indication of stale nonce used
   8583  *                       in the client's request is indicated by adding
   8584  *                       'stale=true' to the authentication header, this
   8585  *                       instructs the client to retry immediately with the new
   8586  *                       nonce and the same credentials, without asking user
   8587  *                       for the new password
   8588  * @param mqop the QOP to use
   8589  * @param malgo digest algorithm to use; if several algorithms are allowed
   8590  *              then one challenge for each allowed algorithm is added
   8591  * @param userhash_support if set to #MHD_YES then support of userhash is
   8592  *                         indicated, allowing client to provide
   8593  *                         hash("username:realm") instead of the username in
   8594  *                         clear text;
   8595  *                         note that clients are allowed to provide the username
   8596  *                         in cleartext even if this parameter set to non-zero;
   8597  *                         when userhash is used, application must be ready to
   8598  *                         identify users by provided userhash value instead of
   8599  *                         username; see #MHD_digest_auth_calc_userhash() and
   8600  *                         #MHD_digest_auth_calc_userhash_hex()
   8601  * @param prefer_utf8 if not set to #MHD_NO, parameter 'charset=UTF-8' is
   8602  *                    added, indicating for the client that UTF-8 encoding for
   8603  *                    the username is preferred
   8604  * @param response the response to update; should contain the "access denied"
   8605  *                 body;
   8606  *                 note: this function sets the "WWW Authenticate" header and
   8607  *                 the caller should not set this header;
   8608  *                 the response must have #MHD_HTTP_STATUS_UNAUTHORIZED status
   8609  *                 code;
   8610  *                 the NULL is tolerated (the result is
   8611  *                 #MHD_SC_RESP_POINTER_NULL)
   8612  * @param abort_if_failed if set to #MHD_NO the response will be used even if
   8613  *                        failed to add Basic Authentication "challenge",
   8614  *                        if not set to #MHD_NO the request will be aborted
   8615  *                        if the "challenge" could not be added.
   8616  * @return pointer to the action, the action must be consumed
   8617  *         otherwise response object may leak;
   8618  *         NULL if failed or if any action has been already created for
   8619  *         the @a request;
   8620  *         when failed the response object is consumed and need not
   8621  *         to be "destroyed"
   8622  * @ingroup authentication
   8623  */
   8624 MHD_STATIC_INLINE_
   8625 MHD_FN_PAR_NONNULL_ (1)
   8626 MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_CSTR_ (2)
   8627 const struct MHD_Action *
   8628 MHD_action_digest_auth_challenge (struct MHD_Request *MHD_RESTRICT request,
   8629                                   const char *MHD_RESTRICT realm,
   8630                                   const char *MHD_RESTRICT opaque,
   8631                                   const char *MHD_RESTRICT domain,
   8632                                   enum MHD_Bool indicate_stale,
   8633                                   enum MHD_DigestAuthMultiQOP mqop,
   8634                                   enum MHD_DigestAuthMultiAlgo malgo,
   8635                                   enum MHD_Bool userhash_support,
   8636                                   enum MHD_Bool prefer_utf8,
   8637                                   struct MHD_Response *MHD_RESTRICT response,
   8638                                   enum MHD_Bool abort_if_failed)
   8639 {
   8640   if ((MHD_SC_OK !=
   8641        MHD_response_add_auth_digest_challenge (response, realm, opaque, domain,
   8642                                                indicate_stale, mqop, malgo,
   8643                                                userhash_support, prefer_utf8))
   8644       && (MHD_NO != abort_if_failed))
   8645   {
   8646     MHD_response_destroy (response);
   8647     return MHD_action_abort_request (request);
   8648   }
   8649   return MHD_action_from_response (request, response);
   8650 }
   8651 
   8652 
   8653 MHD_STATIC_INLINE_END_
   8654 
   8655 /**
   8656  * Create action to reply with Digest Authentication "challenge".
   8657  *
   8658  * The @a r response must have #MHD_HTTP_STATUS_UNAUTHORIZED status code.
   8659  *
   8660  * If the @a r response object cannot be extended with the "challenge",
   8661  * the @a r response is used to reply without the "challenge".
   8662  *
   8663  * @param rq the request to create the action for
   8664  * @param l the realm presented to the client
   8665  * @param o the string for opaque value, can be NULL, but NULL is
   8666  *          not recommended for better compatibility with clients;
   8667  *          the recommended format is hex or Base64 encoded string
   8668  * @param d the optional space-separated list of URIs for which the
   8669  *          same authorisation could be used, URIs can be in form
   8670  *          "path-absolute" (the path for the same host with initial slash)
   8671  *          or in form "absolute-URI" (the full path with protocol), in
   8672  *          any case client may assume that URI is in the same "protection
   8673  *          space" if it starts with any of values specified here;
   8674  *          could be NULL (clients typically assume that the same
   8675  *          credentials could be used for any URI on the same host);
   8676  *          this list provides information for the client only and does
   8677  *          not actually restrict anything on the server side
   8678  * @param s if set to #MHD_YES then indication of stale nonce used
   8679  *          in the client's request is indicated by adding
   8680  *          'stale=true' to the authentication header, this
   8681  *          instructs the client to retry immediately with the new
   8682  *          nonce and the same credentials, without asking user
   8683  *          for the new password
   8684  * @param q the QOP to use
   8685  * @param a digest algorithm to use; if several algorithms are allowed
   8686  *          then one challenge for each allowed algorithm is added
   8687  * @param h if set to #MHD_YES then support of userhash is
   8688  *          indicated, allowing client to provide
   8689  *          hash("username:realm") instead of the username in
   8690  *          clear text;
   8691  *          note that clients are allowed to provide the username
   8692  *          in cleartext even if this parameter set to non-zero;
   8693  *          when userhash is used, application must be ready to
   8694  *          identify users by provided userhash value instead of
   8695  *          username; see #MHD_digest_auth_calc_userhash() and
   8696  *          #MHD_digest_auth_calc_userhash_hex()
   8697  * @param u if not set to #MHD_NO, parameter 'charset=UTF-8' is
   8698  *          added, indicating for the client that UTF-8 encoding for
   8699  *          the username is preferred
   8700  * @param r the response to update; should contain the "access denied"
   8701  *          body;
   8702  *          note: this function sets the "WWW Authenticate" header and
   8703  *          the caller should not set this header;
   8704  *          the response must have #MHD_HTTP_STATUS_UNAUTHORIZED status
   8705  *          code;
   8706  *          the NULL is tolerated (the result is
   8707  *          #MHD_SC_RESP_POINTER_NULL)
   8708  * @return pointer to the action, the action must be consumed
   8709  *         otherwise response object may leak;
   8710  *         NULL if failed or if any action has been already created for
   8711  *         the @a rq request;
   8712  *         when failed the response object is consumed and need not
   8713  *         to be "destroyed"
   8714  * @ingroup authentication
   8715  */
   8716 #  define MHD_action_digest_auth_challenge_p(rq, l, o, d, s, q, a, h, u, r) \
   8717           MHD_action_digest_auth_challenge ((rq),(l),(o),(d),(s),(q), \
   8718                                             (a),(h),(u),(r),MHD_NO)
   8719 
   8720 
   8721 /**
   8722  * Create action to reply with Digest Authentication "challenge".
   8723  *
   8724  * The @a r response must have #MHD_HTTP_STATUS_UNAUTHORIZED status code.
   8725  *
   8726  * If the @a r response object cannot be extended with the "challenge",
   8727  * the @a r response is aborted.
   8728  *
   8729  * @param rq the request to create the action for
   8730  * @param l the realm presented to the client
   8731  * @param o the string for opaque value, can be NULL, but NULL is
   8732  *          not recommended for better compatibility with clients;
   8733  *          the recommended format is hex or Base64 encoded string
   8734  * @param d the optional space-separated list of URIs for which the
   8735  *          same authorisation could be used, URIs can be in form
   8736  *          "path-absolute" (the path for the same host with initial slash)
   8737  *          or in form "absolute-URI" (the full path with protocol), in
   8738  *          any case client may assume that URI is in the same "protection
   8739  *          space" if it starts with any of values specified here;
   8740  *          could be NULL (clients typically assume that the same
   8741  *          credentials could be used for any URI on the same host);
   8742  *          this list provides information for the client only and does
   8743  *          not actually restrict anything on the server side
   8744  * @param s if set to #MHD_YES then indication of stale nonce used
   8745  *          in the client's request is indicated by adding
   8746  *          'stale=true' to the authentication header, this
   8747  *          instructs the client to retry immediately with the new
   8748  *          nonce and the same credentials, without asking user
   8749  *          for the new password
   8750  * @param q the QOP to use
   8751  * @param a digest algorithm to use; if several algorithms are allowed
   8752  *          then one challenge for each allowed algorithm is added
   8753  * @param h if set to #MHD_YES then support of userhash is
   8754  *          indicated, allowing client to provide
   8755  *          hash("username:realm") instead of the username in
   8756  *          clear text;
   8757  *          note that clients are allowed to provide the username
   8758  *          in cleartext even if this parameter set to non-zero;
   8759  *          when userhash is used, application must be ready to
   8760  *          identify users by provided userhash value instead of
   8761  *          username; see #MHD_digest_auth_calc_userhash() and
   8762  *          #MHD_digest_auth_calc_userhash_hex()
   8763  * @param u if not set to #MHD_NO, parameter 'charset=UTF-8' is
   8764  *          added, indicating for the client that UTF-8 encoding for
   8765  *          the username is preferred
   8766  * @param r the response to update; should contain the "access denied"
   8767  *          body;
   8768  *          note: this function sets the "WWW Authenticate" header and
   8769  *          the caller should not set this header;
   8770  *          the response must have #MHD_HTTP_STATUS_UNAUTHORIZED status
   8771  *          code;
   8772  *          the NULL is tolerated (the result is
   8773  *          #MHD_SC_RESP_POINTER_NULL)
   8774  * @return pointer to the action, the action must be consumed
   8775  *         otherwise response object may leak;
   8776  *         NULL if failed or if any action has been already created for
   8777  *         the @a rq request;
   8778  *         when failed the response object is consumed and need not
   8779  *         to be "destroyed"
   8780  * @ingroup authentication
   8781  */
   8782 #  define MHD_action_digest_auth_challenge_a(rq, l, o, d, s, q, a, h, u, r) \
   8783           MHD_action_digest_auth_challenge ((rq),(l),(o),(d),(s),(q), \
   8784                                             (a),(h),(u),(r),MHD_YES)
   8785 
   8786 #endif /* ! MHD_NO_STATIC_INLINE */
   8787 
   8788 
   8789 /**
   8790  * Add Basic Authentication "challenge" to the response.
   8791  *
   8792  * The response must have #MHD_HTTP_STATUS_UNAUTHORIZED status code.
   8793  *
   8794  * If access to any resource should be limited to specific users, authenticated
   8795  * by Basic Authentication mechanism, and the request for this resource does not
   8796  * have Basic Authentication information (see #MHD_AuthBasicCreds), then response
   8797  * with Basic Authentication "challenge" should be sent. This works as
   8798  * an indication that Basic Authentication should be used for the access.
   8799  *
   8800  * See RFC 7617, section 2 for details.
   8801  *
   8802  * @param response the reply to send; should contain the "access denied"
   8803  *                 body;
   8804  *                 note: this function sets the "WWW Authenticate" header and
   8805  *                 the caller should not set this header;
   8806  *                 the response must have #MHD_HTTP_STATUS_UNAUTHORIZED status
   8807  *                 code;
   8808  *                 the NULL is tolerated (the result is
   8809  *                 #MHD_SC_RESP_POINTER_NULL)
   8810  * @param realm the realm presented to the client
   8811  * @param prefer_utf8 if not set to #MHD_NO, parameter'charset="UTF-8"' will
   8812  *                    be added, indicating for client that UTF-8 encoding
   8813  *                    is preferred
   8814  * @return #MHD_SC_OK if succeed,
   8815  *         #MHD_SC_TOO_LATE if the response has been already "frozen" (used to
   8816  *         create an action),
   8817  *         #MHD_SC_RESP_HEADERS_CONFLICT if Basic Authentication "challenge"
   8818  *         has been added already,
   8819  *         #MHD_SC_RESP_POINTER_NULL if @a response is NULL,
   8820  *         #MHD_SC_RESP_HTTP_CODE_NOT_SUITABLE is response status code is wrong,
   8821  *         #MHD_SC_RESP_HEADER_VALUE_INVALID if realm is zero-length or has CR
   8822  *         or LF characters,
   8823  *         #MHD_SC_RESP_HEADER_MEM_ALLOC_FAILED if memory allocation failed,
   8824  *         or other error code if failed
   8825  * @ingroup authentication
   8826  */
   8827 MHD_EXTERN_ enum MHD_StatusCode
   8828 MHD_response_add_auth_basic_challenge (
   8829   struct MHD_Response *MHD_RESTRICT response,
   8830   const char *MHD_RESTRICT realm,
   8831   enum MHD_Bool prefer_utf8)
   8832 MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_CSTR_ (2);
   8833 
   8834 /* Application may define MHD_NO_STATIC_INLINE macro before including
   8835    libmicrohttpd headers to disable static inline functions in the headers. */
   8836 #ifndef MHD_NO_STATIC_INLINE
   8837 
   8838 /**
   8839  * Create action to reply with Basic Authentication "challenge".
   8840  *
   8841  * The @a response must have #MHD_HTTP_STATUS_UNAUTHORIZED status code.
   8842  *
   8843  * If access to any resource should be limited to specific users, authenticated
   8844  * by Basic Authentication mechanism, and the request for this resource does not
   8845  * have Basic Authentication information (see #MHD_AuthBasicCreds), then response
   8846  * with Basic Authentication "challenge" should be sent. This works as
   8847  * an indication that Basic Authentication should be used for the access.
   8848  *
   8849  * See RFC 7617, section 2 for details.
   8850  *
   8851  * @param request the request to create the action for
   8852  * @param realm the realm presented to the client
   8853  * @param prefer_utf8 if not set to #MHD_NO, parameter'charset="UTF-8"' will
   8854  *                    be added, indicating for client that UTF-8 encoding
   8855  *                    is preferred
   8856  * @param response the reply to send; should contain the "access denied"
   8857  *                 body;
   8858  *                 note: this function adds the "WWW Authenticate" header in
   8859  *                 the response and the caller should not set this header;
   8860  *                 the response must have #MHD_HTTP_STATUS_UNAUTHORIZED status
   8861  *                 code;
   8862  *                 the NULL is tolerated (the result is
   8863  *                 #MHD_action_abort_request())
   8864  * @param abort_if_failed if set to #MHD_NO the response will be used even if
   8865  *                        failed to add Basic Authentication "challenge",
   8866  *                        if not set to #MHD_NO the request will be aborted
   8867  *                        if the "challenge" could not be added.
   8868  * @return pointer to the action, the action must be consumed
   8869  *         otherwise response object may leak;
   8870  *         NULL if failed or if any action has been already created for
   8871  *         the @a request;
   8872  *         when failed the response object is consumed and need not
   8873  *         to be "destroyed"
   8874  * @ingroup authentication
   8875  */
   8876 MHD_STATIC_INLINE_
   8877 MHD_FN_PAR_NONNULL_ (1)
   8878 MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_CSTR_ (2)
   8879 const struct MHD_Action *
   8880 MHD_action_basic_auth_challenge (struct MHD_Request *MHD_RESTRICT request,
   8881                                  const char *MHD_RESTRICT realm,
   8882                                  enum MHD_Bool prefer_utf8,
   8883                                  struct MHD_Response *MHD_RESTRICT response,
   8884                                  enum MHD_Bool abort_if_failed)
   8885 {
   8886   if ((MHD_SC_OK !=
   8887        MHD_response_add_auth_basic_challenge (response, realm, prefer_utf8))
   8888       && (MHD_NO != abort_if_failed))
   8889   {
   8890     MHD_response_destroy (response);
   8891     return MHD_action_abort_request (request);
   8892   }
   8893   return MHD_action_from_response (request, response);
   8894 }
   8895 
   8896 
   8897 MHD_STATIC_INLINE_END_
   8898 
   8899 
   8900 /**
   8901  * Create action to reply with Basic Authentication "challenge".
   8902  *
   8903  * The @a r response must have #MHD_HTTP_STATUS_UNAUTHORIZED status code.
   8904  *
   8905  * If the @a r response object cannot be extended with the "challenge",
   8906  * the @a r response will be used to reply without the "challenge".
   8907  *
   8908  * @param rq the request to create the action for
   8909  * @param l the realm presented to the client
   8910  * @param u if not set to #MHD_NO, parameter'charset="UTF-8"' will
   8911  *          be added, indicating for client that UTF-8 encoding
   8912  *          is preferred
   8913  * @param r the reply to send; should contain the "access denied"
   8914  *          body;
   8915  *          note: this function adds the "WWW Authenticate" header in
   8916  *          the response and the caller should not set this header;
   8917  *          the response must have #MHD_HTTP_STATUS_UNAUTHORIZED status
   8918  *          code;
   8919  *          the NULL is tolerated (the result is
   8920  *          #MHD_action_abort_request())
   8921  * @return pointer to the action, the action must be consumed
   8922  *         otherwise response object may leak;
   8923  *         NULL if failed or if any action has been already created for
   8924  *         the @a rq request;
   8925  *         when failed the response object is consumed and need not
   8926  *         to be "destroyed"
   8927  * @ingroup authentication
   8928  */
   8929 #  define MHD_action_basic_auth_challenge_p(rq, l, u, r) \
   8930           MHD_action_basic_auth_challenge ((rq), (l), (u), (r), MHD_NO)
   8931 
   8932 /**
   8933  * Create action to reply with Basic Authentication "challenge".
   8934  *
   8935  * The @a r response must have #MHD_HTTP_STATUS_UNAUTHORIZED status code.
   8936  *
   8937  * If the @a r response object cannot be extended with the "challenge",
   8938  * the request will be aborted.
   8939  *
   8940  * @param rq the request to create the action for
   8941  * @param l the realm presented to the client
   8942  * @param u if not set to #MHD_NO, parameter'charset="UTF-8"' will
   8943  *          be added, indicating for client that UTF-8 encoding
   8944  *          is preferred
   8945  * @param r the reply to send; should contain the "access denied"
   8946  *          body;
   8947  *          note: this function adds the "WWW Authenticate" header in
   8948  *          the response and the caller should not set this header;
   8949  *          the response must have #MHD_HTTP_STATUS_UNAUTHORIZED status
   8950  *          code;
   8951  *          the NULL is tolerated (the result is
   8952  *          #MHD_action_abort_request())
   8953  * @return pointer to the action, the action must be consumed
   8954  *         otherwise response object may leak;
   8955  *         NULL if failed or if any action has been already created for
   8956  *         the @a rq request;
   8957  *         when failed the response object is consumed and need not
   8958  *         to be "destroyed"
   8959  * @ingroup authentication
   8960  */
   8961 #  define MHD_action_basic_auth_challenge_a(rq, l, u, r) \
   8962           MHD_action_basic_auth_challenge ((rq), (l), (u), (r), MHD_YES)
   8963 
   8964 #endif /* ! MHD_NO_STATIC_INLINE */
   8965 
   8966 
   8967 /**
   8968  * Information decoded from Basic Authentication client's header.
   8969  *
   8970  * @see #MHD_REQUEST_INFO_DYNAMIC_AUTH_BASIC_CREDS
   8971  */
   8972 struct MHD_AuthBasicCreds
   8973 {
   8974   /**
   8975    * The username
   8976    */
   8977   struct MHD_String username;
   8978 
   8979   /**
   8980    * The password, string pointer may be NULL if password is not encoded
   8981    * by the client.
   8982    */
   8983   struct MHD_StringNullable password;
   8984 };
   8985 
   8986 /* ********************** (f) Introspection ********************** */
   8987 
   8988 
   8989 /**
   8990  * Types of information about MHD, used by #MHD_lib_get_info_fixed_sz().
   8991  * This information is not changed at run-time.
   8992  */
   8993 enum MHD_FIXED_ENUM_APP_SET_ MHD_LibInfoFixed
   8994 {
   8995   /* * Basic MHD information * */
   8996 
   8997   /**
   8998    * Get the MHD version as a number.
   8999    * The result is placed in @a v_version_num_uint32 member.
   9000    */
   9001   MHD_LIB_INFO_FIXED_VERSION_NUM = 0
   9002   ,
   9003   /**
   9004    * Get the MHD version as a string.
   9005    * The result is placed in @a v_version_string member.
   9006    */
   9007   MHD_LIB_INFO_FIXED_VERSION_STRING = 1
   9008   ,
   9009 
   9010   /* * Basic MHD features, buid-time configurable * */
   9011   /* These features should be always available unless the library was
   9012    * not compiled specifically for some embedded project.
   9013    * Exceptions are marked explicitly in the description. */
   9014 
   9015   /**
   9016    * Get whether messages are supported. If supported then messages can be
   9017    * printed to stderr or to an external logger.
   9018    * The result is placed in @a v_support_log_messages_bool member.
   9019    */
   9020   MHD_LIB_INFO_FIXED_SUPPORT_LOG_MESSAGES = 11
   9021   ,
   9022   /**
   9023    * Get whether detailed automatic HTTP reply messages are supported.
   9024    * If supported then automatic responses have bodies with text explaining
   9025    * the error details.
   9026    * Automatic responses are sent by MHD automatically when client is violating
   9027    * HTTP specification, for example, the request header has whitespace in
   9028    * header name or request's "Content-Length" header has non-number value.
   9029    * The result is placed in @a v_support_auto_replies_bodies_bool member.
   9030    */
   9031   MHD_LIB_INFO_FIXED_SUPPORT_AUTO_REPLIES_BODIES = 12
   9032   ,
   9033   /**
   9034    * Get whether MHD was built with debug asserts disabled.
   9035    * These asserts enabled only on special debug builds.
   9036    * For debug builds the error log is always enabled.
   9037    * The result is placed in @a v_is_non_debug_bool member.
   9038    */
   9039   MHD_LIB_INFO_FIXED_IS_NON_DEBUG = 13
   9040   ,
   9041   /**
   9042    * Get whether MHD supports threads.
   9043    * The result is placed in @a v_support_threads_bool member.
   9044    */
   9045   MHD_LIB_INFO_FIXED_SUPPORT_THREADS = 14
   9046   ,
   9047   /**
   9048    * Get whether automatic parsing of HTTP Cookie header is supported.
   9049    * If disabled, no #MHD_VK_COOKIE will be generated by MHD.
   9050    * The result is placed in @a v_support_cookie_parser_bool member.
   9051    */
   9052   MHD_LIB_INFO_FIXED_SUPPORT_COOKIE_PARSER = 15
   9053   ,
   9054   /**
   9055    * Get whether postprocessor is supported. If supported then
   9056    * #MHD_action_post_processor() can be used.
   9057    * The result is placed in @a v_support_post_parser_bool member.
   9058    */
   9059   MHD_LIB_INFO_FIXED_SUPPORT_POST_PARSER = 16
   9060   ,
   9061   /**
   9062    * Get whether HTTP "Upgrade" is supported.
   9063    * If supported then #MHD_action_upgrade() can be used.
   9064    * The result is placed in @a v_support_upgrade_bool member.
   9065    */
   9066   MHD_LIB_INFO_FIXED_SUPPORT_UPGRADE = 17
   9067   ,
   9068   /**
   9069    * Get whether HTTP Basic authorization is supported. If supported
   9070    * then functions #MHD_action_basic_auth_required_response ()
   9071    * and #MHD_REQUEST_INFO_DYNAMIC_AUTH_BASIC_CREDS can be used.
   9072    * The result is placed in @a v_support_auth_basic_bool member.
   9073    */
   9074   MHD_LIB_INFO_FIXED_SUPPORT_AUTH_BASIC = 20
   9075   ,
   9076   /**
   9077    * Get whether HTTP Digest authorization is supported. If
   9078    * supported then options #MHD_D_O_RANDOM_ENTROPY,
   9079    * #MHD_D_O_DAUTH_MAP_SIZE and functions
   9080    * #MHD_action_digest_auth_required_response () and
   9081    * #MHD_digest_auth_check() can be used.
   9082    * The result is placed in @a v_support_auth_digest_bool member.
   9083    */
   9084   MHD_LIB_INFO_FIXED_SUPPORT_AUTH_DIGEST = 21
   9085   ,
   9086   /**
   9087    * Get whether the early version the Digest Authorization (RFC 2069) is
   9088    * supported (digest authorisation without QOP parameter).
   9089    * Currently it is always supported if Digest Auth module is built.
   9090    * The result is placed in @a v_support_digest_auth_rfc2069_bool member.
   9091    */
   9092   MHD_LIB_INFO_FIXED_SUPPORT_DIGEST_AUTH_RFC2069 = 22
   9093   ,
   9094   /**
   9095    * Get whether the MD5-based hashing algorithms are supported for Digest
   9096    * Authorization and the type of the implementation if supported.
   9097    * Currently it is always supported if Digest Auth module is built
   9098    * unless manually disabled in a custom build.
   9099    * The result is placed in @a v_type_digest_auth_md5_algo_type member.
   9100    */
   9101   MHD_LIB_INFO_FIXED_TYPE_DIGEST_AUTH_MD5 = 23
   9102   ,
   9103   /**
   9104    * Get whether the SHA-256-based hashing algorithms are supported for Digest
   9105    * Authorization and the type of the implementation if supported.
   9106    * Currently it is always supported if Digest Auth module is built
   9107    * unless manually disabled in a custom build.
   9108    * The result is placed in @a v_type_digest_auth_sha256_algo_type member.
   9109    */
   9110   MHD_LIB_INFO_FIXED_TYPE_DIGEST_AUTH_SHA256 = 24
   9111   ,
   9112   /**
   9113    * Get whether the SHA-512/256-based hashing algorithms are supported
   9114    * Authorization and the type of the implementation if supported.
   9115    * Currently it is always supported if Digest Auth module is built
   9116    * unless manually disabled in a custom build.
   9117    * The result is placed in @a v_type_digest_auth_sha512_256_algo_type member.
   9118    */
   9119   MHD_LIB_INFO_FIXED_TYPE_DIGEST_AUTH_SHA512_256 = 25
   9120   ,
   9121   /**
   9122    * Get whether QOP with value 'auth-int' (authentication with integrity
   9123    * protection) is supported for Digest Authorization.
   9124    * Currently it is always not supported.
   9125    * The result is placed in @a v_support_digest_auth_auth_int_bool member.
   9126    */
   9127   MHD_LIB_INFO_FIXED_SUPPORT_DIGEST_AUTH_AUTH_INT = 28
   9128   ,
   9129   /**
   9130    * Get whether 'session' algorithms (like 'MD5-sess') are supported for Digest
   9131    * Authorization.
   9132    * Currently it is always not supported.
   9133    * The result is placed in @a v_support_digest_auth_algo_session_bool member.
   9134    */
   9135   MHD_LIB_INFO_FIXED_SUPPORT_DIGEST_AUTH_ALGO_SESSION = 29
   9136   ,
   9137   /**
   9138    * Get whether 'userhash' is supported for Digest Authorization.
   9139    * Currently it is always supported if Digest Auth module is built.
   9140    * The result is placed in @a v_support_digest_auth_userhash_bool member.
   9141    */
   9142   MHD_LIB_INFO_FIXED_SUPPORT_DIGEST_AUTH_USERHASH = 30
   9143   ,
   9144 
   9145   /* * Platform-dependent features, some are configurable at build-time * */
   9146   /* These features depends on the platform, third-party libraries and
   9147    * the toolchain.
   9148    * Some of the features can be disabled or selected at build-time. */
   9149   /**
   9150    * Get sockets polling functions/techniques supported by this MHD build.
   9151    * Some functions can be disabled (like epoll) in kernel, this is not
   9152    * checked.
   9153    * The result is placed in @a v_types_sockets_polling member.
   9154    */
   9155   MHD_LIB_INFO_FIXED_TYPES_SOCKETS_POLLING = 60
   9156   ,
   9157   /**
   9158    * Get whether aggregate FD external polling is supported.
   9159    * The result is placed in @a v_support_aggregate_fd_bool member.
   9160    */
   9161   MHD_LIB_INFO_FIXED_SUPPORT_AGGREGATE_FD = 61
   9162   ,
   9163   /**
   9164    * Get whether IPv6 is supported on the platform and IPv6-only listen socket
   9165    * can be used.
   9166    * The result is placed in @a v_ipv6 member.
   9167    * @note The platform may have disabled IPv6 at run-time, it is not checked
   9168    *       by this information type.
   9169    */
   9170   MHD_LIB_INFO_FIXED_TYPE_IPV6 = 62
   9171   ,
   9172   /**
   9173    * Get whether TCP Fast Open is supported by MHD build.
   9174    * If supported then option #MHD_D_O_TCP_FASTOPEN can be used.
   9175    * The result is placed in @a v_support_tcp_fastopen_bool member.
   9176    */
   9177   MHD_LIB_INFO_FIXED_SUPPORT_TCP_FASTOPEN = 64
   9178   ,
   9179   /**
   9180    * Get whether MHD support automatic detection of bind port number.
   9181    * @sa #MHD_D_O_BIND_PORT
   9182    * The result is placed in @a v_has_autodetect_bind_port_bool member.
   9183    */
   9184   MHD_LIB_INFO_FIXED_HAS_AUTODETECT_BIND_PORT = 65
   9185   ,
   9186   /**
   9187    * Get whether MHD use system's sendfile() function to send
   9188    * file-FD based responses over non-TLS connections.
   9189    * The result is placed in @a v_has_sendfile_bool member.
   9190    */
   9191   MHD_LIB_INFO_FIXED_HAS_SENDFILE = 66
   9192   ,
   9193   /**
   9194    * Get whether MHD supports automatic SIGPIPE suppression within internal
   9195    * events loop (MHD's managed threads).
   9196    * If SIGPIPE suppression is not supported, application must handle
   9197    * SIGPIPE signal by itself whem using MHD with internal events loop.
   9198    * If the platform does not have SIGPIPE the result is #MHD_YES.
   9199    * The result is placed in @a v_has_autosuppress_sigpipe_int_bool member.
   9200    */
   9201   MHD_LIB_INFO_FIXED_HAS_AUTOSUPPRESS_SIGPIPE_INT = 80
   9202   ,
   9203   /**
   9204    * Get whether MHD supports automatic SIGPIPE suppression when used with
   9205    * extenal events loop (in application thread).
   9206    * If SIGPIPE suppression is not supported, application must handle
   9207    * SIGPIPE signal by itself whem using MHD with external events loop.
   9208    * If the platform does not have SIGPIPE the result is #MHD_YES.
   9209    * The result is placed in @a v_has_autosuppress_sigpipe_ext_bool member.
   9210    */
   9211   MHD_LIB_INFO_FIXED_HAS_AUTOSUPPRESS_SIGPIPE_EXT = 81
   9212   ,
   9213   /**
   9214    * Get whether MHD sets names on generated threads.
   9215    * The result is placed in @a v_has_thread_names_bool member.
   9216    */
   9217   MHD_LIB_INFO_FIXED_HAS_THREAD_NAMES = 82
   9218   ,
   9219   /**
   9220    * Get the type of supported inter-thread communication.
   9221    * The result is placed in @a v_type_itc member.
   9222    */
   9223   MHD_LIB_INFO_FIXED_TYPE_ITC = 83
   9224   ,
   9225   /**
   9226    * Get whether reading files beyond 2 GiB boundary is supported.
   9227    * If supported then #MHD_response_from_fd() can be used with sizes and
   9228    * offsets larger than 2 GiB. If not supported value of size+offset could be
   9229    * limited to 2 GiB.
   9230    * The result is placed in @a v_support_large_file_bool member.
   9231    */
   9232   MHD_LIB_INFO_FIXED_SUPPORT_LARGE_FILE = 84
   9233   ,
   9234 
   9235   /* * Platform-dependent features, some set on startup and some are
   9236    *   configurable at build-time * */
   9237   /* These features depends on the platform, third-party libraries availability
   9238    * and configuration. The features can be enabled/disabled during startup
   9239    * of the library depending on conditions.
   9240    * Some of the features can be disabled or selected at build-time. */
   9241   /**
   9242    * Get whether HTTPS and which types of TLS backend(s) supported by
   9243    * this build.
   9244    * The result is placed in @a v_tls_backends member.
   9245    */
   9246   MHD_LIB_INFO_FIXED_TLS_BACKENDS = 100
   9247   ,
   9248   /**
   9249   * Get whether password encrypted private key for HTTPS daemon is
   9250   * supported by TLS backends.
   9251   * If supported then option #MHD_D_OPTION_TLS_KEY_CERT can be used with
   9252   * non-NULL @a mem_pass.
   9253   * The result is placed in @a v_tls_key_password_backends member.
   9254   */
   9255   MHD_LIB_INFO_FIXED_TLS_KEY_PASSWORD_BACKENDS = 102
   9256   ,
   9257 
   9258   /* * Sentinel * */
   9259   /**
   9260    * The sentinel value.
   9261    * This value enforces specific underlying integer type for the enum.
   9262    * Do not use.
   9263    */
   9264   MHD_LIB_INFO_FIXED_SENTINEL = 65535
   9265 };
   9266 
   9267 /**
   9268  * The type of the data for digest algorithm implementations.
   9269  */
   9270 enum MHD_FIXED_ENUM_MHD_SET_ MHD_LibInfoFixedDigestAlgoType
   9271 {
   9272   /**
   9273    * The algorithm is not implemented or disabled at the build time.
   9274    */
   9275   MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_NOT_AVAILABLE = 0
   9276   ,
   9277   /**
   9278    * The algorithm is implemented by MHD internal code.
   9279    * MHD implementation of hashing can never fail.
   9280    */
   9281   MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_BUILT_IN = 1
   9282   ,
   9283   /**
   9284    * The algorithm is implemented by external code that never fails.
   9285    */
   9286   MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_EXTERNAL_NEVER_FAIL = 2
   9287   ,
   9288   /**
   9289    * The algorithm is implemented by external code that may hypothetically fail.
   9290    */
   9291   MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_EXTERNAL_MAY_FAIL = 3
   9292 };
   9293 
   9294 /**
   9295  * The types of the sockets polling functions/techniques supported
   9296  */
   9297 struct MHD_LibInfoFixedPollingFunc
   9298 {
   9299   /**
   9300    * select() function for sockets polling
   9301    */
   9302   enum MHD_Bool func_select;
   9303   /**
   9304    * poll() function for sockets polling
   9305    */
   9306   enum MHD_Bool func_poll;
   9307   /**
   9308    * epoll technique for sockets polling
   9309    */
   9310   enum MHD_Bool tech_epoll;
   9311   /**
   9312    * kqueue technique for sockets polling
   9313    */
   9314   enum MHD_Bool tech_kqueue;
   9315 };
   9316 
   9317 /**
   9318  * The types of IPv6 supported
   9319  */
   9320 enum MHD_FIXED_ENUM_MHD_SET_ MHD_LibInfoFixedIPv6Type
   9321 {
   9322   /**
   9323    * IPv6 is not supported by this MHD build
   9324    */
   9325   MHD_LIB_INFO_FIXED_IPV6_TYPE_NONE = 0
   9326   ,
   9327   /**
   9328    * IPv6 is supported only as "dual stack".
   9329    * IPv4 connections can be received by IPv6 listen socket.
   9330    */
   9331   MHD_LIB_INFO_FIXED_IPV6_TYPE_DUAL_ONLY = 1
   9332   ,
   9333   /**
   9334    * IPv6 can be used as IPv6-only (without getting IPv4 incoming connections).
   9335    * The platform may support "dual stack" too.
   9336    */
   9337   MHD_LIB_INFO_FIXED_IPV6_TYPE_IPV6_PURE = 2
   9338 };
   9339 
   9340 /**
   9341  * The types of inter-thread communication
   9342  * @note the enum can be extended in future versions with new values
   9343  */
   9344 enum MHD_FIXED_ENUM_MHD_SET_ MHD_LibInfoFixedITCType
   9345 {
   9346   /**
   9347    * No ITC used.
   9348    * This value is returned if MHD is built without threads support
   9349    */
   9350   MHD_LIB_INFO_FIXED_ITC_TYPE_NONE = 0
   9351   ,
   9352   /**
   9353    * The pair of sockets are used as inter-thread communication.
   9354    * The is the least efficient method of communication.
   9355    */
   9356   MHD_LIB_INFO_FIXED_ITC_TYPE_SOCKETPAIR = 1
   9357   ,
   9358   /**
   9359    * The pipe is used as inter-thread communication.
   9360    */
   9361   MHD_LIB_INFO_FIXED_ITC_TYPE_PIPE = 2
   9362   ,
   9363   /**
   9364    * The EventFD is used as inter-thread communication.
   9365    * This is the most efficient method of communication.
   9366    */
   9367   MHD_LIB_INFO_FIXED_ITC_TYPE_EVENTFD = 3
   9368 };
   9369 
   9370 
   9371 /**
   9372  * The types of the TLS (or TLS feature) backend supported/available/enabled
   9373  * @note the enum can be extended in future versions with new members
   9374  */
   9375 struct MHD_LibInfoTLSType
   9376 {
   9377   /**
   9378    * The TLS (or TLS feature) is supported/enabled.
   9379    * Set to #MHD_YES if any other member is #MHD_YES.
   9380    */
   9381   enum MHD_Bool tls_supported;
   9382   /**
   9383    * The GnuTLS backend is supported/available/enabled.
   9384    */
   9385   enum MHD_Bool backend_gnutls;
   9386   /**
   9387    * The OpenSSL backend is supported/available/enabled.
   9388    */
   9389   enum MHD_Bool backend_openssl;
   9390   /**
   9391    * The MbedTLS backend is supported/available/enabled.
   9392    */
   9393   enum MHD_Bool backend_mbedtls;
   9394 };
   9395 
   9396 /**
   9397  * The data provided by #MHD_lib_get_info_fixed_sz()
   9398  */
   9399 union MHD_LibInfoFixedData
   9400 {
   9401   /**
   9402    * The data for the #MHD_LIB_INFO_FIXED_VERSION_NUM query
   9403    */
   9404   uint_fast32_t v_version_num_uint32;
   9405   /**
   9406    * The data for the #MHD_LIB_INFO_FIXED_VERSION_STR query
   9407    */
   9408   struct MHD_String v_version_string;
   9409   /**
   9410    * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_LOG_MESSAGES query
   9411    */
   9412   enum MHD_Bool v_support_log_messages_bool;
   9413   /**
   9414    * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_AUTO_REPLIES_BODIES query
   9415    */
   9416   enum MHD_Bool v_support_auto_replies_bodies_bool;
   9417   /**
   9418    * The data for the #MHD_LIB_INFO_FIXED_IS_NON_DEBUG query
   9419    */
   9420   enum MHD_Bool v_is_non_debug_bool;
   9421   /**
   9422    * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_THREADS query
   9423    */
   9424   enum MHD_Bool v_support_threads_bool;
   9425   /**
   9426    * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_COOKIE_PARSER query
   9427    */
   9428   enum MHD_Bool v_support_cookie_parser_bool;
   9429   /**
   9430    * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_POST_PARSER query
   9431    */
   9432   enum MHD_Bool v_support_post_parser_bool;
   9433   /**
   9434    * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_UPGRADE query
   9435    */
   9436   enum MHD_Bool v_support_upgrade_bool;
   9437   /**
   9438    * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_AUTH_BASIC query
   9439    */
   9440   enum MHD_Bool v_support_auth_basic_bool;
   9441   /**
   9442    * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_AUTH_DIGEST query
   9443    */
   9444   enum MHD_Bool v_support_auth_digest_bool;
   9445   /**
   9446    * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_DIGEST_AUTH_RFC2069 query
   9447    */
   9448   enum MHD_Bool v_support_digest_auth_rfc2069_bool;
   9449   /**
   9450    * The data for the #MHD_LIB_INFO_FIXED_TYPE_DIGEST_AUTH_MD5 query
   9451    */
   9452   enum MHD_LibInfoFixedDigestAlgoType v_type_digest_auth_md5_algo_type;
   9453   /**
   9454    * The data for the #MHD_LIB_INFO_FIXED_TYPE_DIGEST_AUTH_SHA256 query
   9455    */
   9456   enum MHD_LibInfoFixedDigestAlgoType v_type_digest_auth_sha256_algo_type;
   9457   /**
   9458    * The data for the #MHD_LIB_INFO_FIXED_TYPE_DIGEST_AUTH_SHA512_256 query
   9459    */
   9460   enum MHD_LibInfoFixedDigestAlgoType v_type_digest_auth_sha512_256_algo_type;
   9461   /**
   9462    * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_DIGEST_AUTH_AUTH_INT query
   9463    */
   9464   enum MHD_Bool v_support_digest_auth_auth_int_bool;
   9465   /**
   9466    * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_DIGEST_AUTH_ALGO_SESSION query
   9467    */
   9468   enum MHD_Bool v_support_digest_auth_algo_session_bool;
   9469   /**
   9470    * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_DIGEST_AUTH_USERHASH query
   9471    */
   9472   enum MHD_Bool v_support_digest_auth_userhash_bool;
   9473   /**
   9474    * The data for the #MHD_LIB_INFO_FIXED_TYPES_SOCKETS_POLLING query
   9475    */
   9476   struct MHD_LibInfoFixedPollingFunc v_types_sockets_polling;
   9477   /**
   9478    * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_AGGREGATE_FD query
   9479    */
   9480   enum MHD_Bool v_support_aggregate_fd_bool;
   9481   /**
   9482    * The data for the #MHD_LIB_INFO_FIXED_TYPE_IPV6 query
   9483    */
   9484   enum MHD_LibInfoFixedIPv6Type v_ipv6;
   9485   /**
   9486    * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_TCP_FASTOPEN query
   9487    */
   9488   enum MHD_Bool v_support_tcp_fastopen_bool;
   9489   /**
   9490    * The data for the #MHD_LIB_INFO_FIXED_HAS_AUTODETECT_BIND_PORT query
   9491    */
   9492   enum MHD_Bool v_has_autodetect_bind_port_bool;
   9493   /**
   9494    * The data for the #MHD_LIB_INFO_FIXED_HAS_SENDFILE query
   9495    */
   9496   enum MHD_Bool v_has_sendfile_bool;
   9497   /**
   9498    * The data for the #MHD_LIB_INFO_FIXED_HAS_AUTOSUPPRESS_SIGPIPE_INT query
   9499    */
   9500   enum MHD_Bool v_has_autosuppress_sigpipe_int_bool;
   9501   /**
   9502    * The data for the #MHD_LIB_INFO_FIXED_HAS_AUTOSUPPRESS_SIGPIPE_EXT query
   9503    */
   9504   enum MHD_Bool v_has_autosuppress_sigpipe_ext_bool;
   9505   /**
   9506    * The data for the #MHD_LIB_INFO_FIXED_HAS_THREAD_NAMES query
   9507    */
   9508   enum MHD_Bool v_has_thread_names_bool;
   9509   /**
   9510    * The data for the #MHD_LIB_INFO_FIXED_TYPE_ITC query
   9511    */
   9512   enum MHD_LibInfoFixedITCType v_type_itc;
   9513   /**
   9514    * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_LARGE_FILE query
   9515    */
   9516   enum MHD_Bool v_support_large_file_bool;
   9517   /**
   9518    * The data for the #MHD_LIB_INFO_FIXED_TLS_BACKENDS query
   9519    */
   9520   struct MHD_LibInfoTLSType v_tls_backends;
   9521   /**
   9522    * The data for the #MHD_LIB_INFO_FIXED_TLS_KEY_PASSWORD_BACKENDS query
   9523    */
   9524   struct MHD_LibInfoTLSType v_tls_key_password_backends;
   9525 };
   9526 
   9527 /**
   9528  * Get fixed information about MHD that is not changed at run-time.
   9529  * The returned information can be cached by application as it will be not
   9530  * changed at run-time.
   9531  *
   9532  * For any valid @a info_type the only possible returned error value is
   9533  * #MHD_SC_INFO_GET_BUFF_TOO_SMALL. If the buffer is large enough and
   9534  * the requested type of information is valid, the function always succeeds
   9535  * and returns #MHD_SC_OK.
   9536  *
   9537  * The wrapper macro #MHD_lib_get_info_fixed() may be more convenient.
   9538  *
   9539  * @param info_type the type of requested information
   9540  * @param[out] output_buf the pointer to union to be set to the requested
   9541  *                        information
   9542  * @param output_buf_size the size of the memory area pointed by @a output_buf
   9543  *                        (provided by the caller for storing the requested
   9544  *                        information), in bytes
   9545  * @return #MHD_SC_OK if succeed,
   9546  *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown,
   9547  *         #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small
   9548  * @ingroup specialized
   9549  */
   9550 MHD_EXTERN_ enum MHD_StatusCode
   9551 MHD_lib_get_info_fixed_sz (enum MHD_LibInfoFixed info_type,
   9552                            union MHD_LibInfoFixedData *MHD_RESTRICT output_buf,
   9553                            size_t output_buf_size)
   9554 MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_OUT_ (2);
   9555 
   9556 /**
   9557  * Get fixed information about MHD that is not changed at run-time.
   9558  * The returned information can be cached by application as it will be not
   9559  * changed at run-time.
   9560  *
   9561  * @param info the type of requested information
   9562  * @param[out] output_buf the pointer to union to be set to the requested
   9563  *                        information
   9564  * @return #MHD_SC_OK if succeed,
   9565  *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown,
   9566  *         or other error code
   9567  * @ingroup specialized
   9568  */
   9569 #define MHD_lib_get_info_fixed(info, output_buf) \
   9570         MHD_lib_get_info_fixed_sz ((info),(output_buf),sizeof(*(output_buf)))
   9571 
   9572 /* Application may define MHD_NO_STATIC_INLINE macro before including
   9573    libmicrohttpd headers to disable static inline functions in the headers. */
   9574 #ifndef MHD_NO_STATIC_INLINE
   9575 
   9576 /*
   9577  * A helper below can be used in a simple check preventing use of downgraded
   9578  * library version.
   9579  * As new library version may introduce new functionality, and the application
   9580  * may detect some functionality available at application build-time, use of
   9581  * previous versions may lead to run-time failures.
   9582  * To prevent run-time failures, application may use a check like:
   9583 
   9584  if (MHD_lib_get_info_ver_num() < ((uint_fast32_t) MHD_VERSION))
   9585    handle_init_failure();
   9586 
   9587  */
   9588 /**
   9589  * Get the library version number.
   9590  * @return the library version number.
   9591  */
   9592 MHD_STATIC_INLINE_ MHD_FN_PURE_ uint_fast32_t
   9593 MHD_lib_get_info_ver_num (void)
   9594 {
   9595   union MHD_LibInfoFixedData data;
   9596   data.v_version_num_uint32 = 0; /* Not really necessary */
   9597   (void)MHD_lib_get_info_fixed (MHD_LIB_INFO_FIXED_VERSION_NUM, \
   9598                                 &data);  /* Never fail */
   9599   return data.v_version_num_uint32;
   9600 }
   9601 
   9602 
   9603 MHD_STATIC_INLINE_END_
   9604 
   9605 #endif /* ! MHD_NO_STATIC_INLINE */
   9606 
   9607 /**
   9608  * Types of information about MHD, used by #MHD_lib_get_info_dynamic_sz().
   9609  * This information may vary over time.
   9610  */
   9611 enum MHD_FIXED_ENUM_APP_SET_ MHD_LibInfoDynamic
   9612 {
   9613   /* * Basic MHD information * */
   9614 
   9615   /**
   9616    * Get whether MHD has been successfully fully initialised.
   9617    * MHD uses lazy initialisation: a minimal initialisation is performed at
   9618    * startup, complete initialisation is performed when any daemon is created
   9619    * (or when called some function which requires full initialisation).
   9620    * The result is #MHD_NO when the library has been not yet initialised
   9621    * completely since startup.
   9622    * The result is placed in @a v_inited_fully_once_bool member.
   9623    */
   9624   MHD_LIB_INFO_DYNAMIC_INITED_FULLY_ONCE = 0
   9625   ,
   9626   /**
   9627    * Get whether MHD is fully initialised.
   9628    * MHD uses lazy initialisation: a minimal initialisation is performed at
   9629    * startup, complete initialisation is perfromed when any daemon is created
   9630    * (or when called some function which requires full initialisation).
   9631    * The result is #MHD_YES if library is initialised state now (meaning
   9632    * that at least one daemon is created and not destroyed or some function
   9633    * required full initialisation is running).
   9634    * The result is placed in @a v_inited_fully_now_bool member.
   9635    */
   9636   MHD_LIB_INFO_DYNAMIC_INITED_FULLY_NOW = 1
   9637   ,
   9638 
   9639   /**
   9640    * Get whether HTTPS and which types of TLS backend(s) currently available.
   9641    * If any MHD daemons active (created and not destroyed, not necessary
   9642    * running) the result reflects the current backends availability.
   9643    * If no MHD daemon is active, then this function would try to temporarily
   9644    * enable backends to check for their availability.
   9645    * If global library initialisation failed, the function returns
   9646    * #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE error code.
   9647    * The result is placed in @a v_tls_backends member.
   9648    */
   9649   MHD_LIB_INFO_DYNAMIC_TYPE_TLS = 100
   9650   ,
   9651 
   9652   /* * Sentinel * */
   9653   /**
   9654    * The sentinel value.
   9655    * This value enforces specific underlying integer type for the enum.
   9656    * Do not use.
   9657    */
   9658   MHD_LIB_INFO_DYNAMIC_SENTINEL = 65535
   9659 };
   9660 
   9661 
   9662 /**
   9663  * The data provided by #MHD_lib_get_info_dynamic_sz().
   9664  * The resulting value may vary over time.
   9665  */
   9666 union MHD_LibInfoDynamicData
   9667 {
   9668   /**
   9669    * The data for the #MHD_LIB_INFO_DYNAMIC_INITED_FULLY_ONCE query
   9670    */
   9671   enum MHD_Bool v_inited_fully_once_bool;
   9672 
   9673   /**
   9674    * The data for the #MHD_LIB_INFO_DYNAMIC_INITED_FULLY_NOW query
   9675    */
   9676   enum MHD_Bool v_inited_fully_now_bool;
   9677 
   9678   /**
   9679    * The data for the #MHD_LIB_INFO_DYNAMIC_TYPE_TLS query
   9680    */
   9681   struct MHD_LibInfoTLSType v_tls_backends;
   9682 
   9683   /**
   9684    * Unused member.
   9685    * Help enforcing future-proof alignment of the union.
   9686    * Do not use.
   9687    */
   9688   void *reserved;
   9689 };
   9690 
   9691 /**
   9692  * Get dynamic information about MHD that may be changed at run-time.
   9693  * The wrapper macro #MHD_lib_get_info_dynamic() could be more convenient.
   9694  *
   9695  * @param info_type the type of requested information
   9696  * @param[out] output_buf the pointer to union to be set to the requested
   9697  *                        information
   9698  * @param output_buf_size the size of the memory area pointed by @a output_buf
   9699  *                        (provided by the caller for storing the requested
   9700  *                        information), in bytes
   9701  * @return #MHD_SC_OK if succeed,
   9702  *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown,
   9703  *         #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small,
   9704  *         or other error code
   9705  * @ingroup specialized
   9706  */
   9707 MHD_EXTERN_ enum MHD_StatusCode
   9708 MHD_lib_get_info_dynamic_sz (
   9709   enum MHD_LibInfoDynamic info_type,
   9710   union MHD_LibInfoDynamicData *MHD_RESTRICT output_buf,
   9711   size_t output_buf_size)
   9712 MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_OUT_ (2);
   9713 
   9714 /**
   9715  * Get dynamic information about MHD that may be changed at run-time.
   9716  *
   9717  * @param info the type of requested information
   9718  * @param[out] output_buf the pointer to union to be set to the requested
   9719  *                        information
   9720  * @return #MHD_SC_OK if succeed,
   9721  *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown,
   9722  *         or other error code
   9723  * @ingroup specialized
   9724  */
   9725 #define MHD_lib_get_info_dynamic(info, output_buf) \
   9726         MHD_lib_get_info_dynamic_sz ((info),(output_buf),sizeof(*(output_buf)))
   9727 
   9728 
   9729 /**
   9730  * Values of this enum are used to specify what information about a daemon is
   9731  * requested.
   9732  * These types of information do not change after the start of the daemon
   9733  * until the daemon is destroyed.
   9734  */
   9735 enum MHD_DaemonInfoFixedType
   9736 {
   9737 
   9738   /**
   9739    * Get the type of system call used for sockets polling.
   9740    * The value #MHD_SPS_AUTO is never set in the returned data.
   9741    * The function returns #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the daemon
   9742    * does not use internal sockets polling.
   9743    * The result is placed in @a v_poll_syscall member.
   9744    */
   9745   MHD_DAEMON_INFO_FIXED_POLL_SYSCALL = 41
   9746   ,
   9747   /**
   9748    * Get the file descriptor for the single FD that triggered when
   9749    * any MHD event happens.
   9750    * This FD can be watched as aggregate indicator for all MHD events.
   9751    * The provided socket must be used as 'read-only': only select() or similar
   9752    * functions should be used. Any modifications (changing socket attributes,
   9753    * calling accept(), closing it etc.) will lead to undefined behaviour.
   9754    * The function returns #MHD_SC_INFO_GET_TYPE_NOT_SUPP_BY_BUILD if the library
   9755    * does not support mode with agregate FD.
   9756    * The function returns #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the daemon
   9757    * is not configured to use this mode.
   9758    * The result is placed in @a v_aggreagate_fd member.
   9759    */
   9760   MHD_DAEMON_INFO_FIXED_AGGREAGATE_FD = 46
   9761   ,
   9762   /**
   9763    * Get the number of worker threads when used in MHD_WM_WORKER_THREADS mode.
   9764    * The function returns #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the daemon
   9765    * does not use worker threads mode.
   9766    * The result is placed in @a v_num_work_threads_uint member.
   9767    */
   9768   MHD_DAEMON_INFO_FIXED_NUM_WORK_THREADS = 47
   9769   ,
   9770   /**
   9771    * Get the port number of daemon's listen socket.
   9772    * Note: if port '0' (auto port) was specified for #MHD_D_OPTION_BIND_PORT(),
   9773    * returned value will be the real port number.
   9774    * The function returns #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the daemon
   9775    * does not have listening socket or if listening socket is non-IP.
   9776    * The function returns #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the port number
   9777    * detection failed or not supported by the platform.
   9778    * If the function succeed, the returned port number is never zero.
   9779    * The result is placed in @a v_bind_port_uint16 member.
   9780    */
   9781   MHD_DAEMON_INFO_FIXED_BIND_PORT = 80
   9782   ,
   9783   /**
   9784    * Get the file descriptor for the listening socket.
   9785    * The provided socket must be used as 'read-only': only select() or similar
   9786    * functions should be used. Any modifications (changing socket attributes,
   9787    * calling accept(), closing it etc.) will lead to undefined behaviour.
   9788    * The function returns #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the daemon
   9789    * does not have listening socket.
   9790    * The result is placed in @a v_listen_socket member.
   9791    */
   9792   MHD_DAEMON_INFO_FIXED_LISTEN_SOCKET = 82
   9793   ,
   9794   /**
   9795    * Get the TLS backend used by the daemon.
   9796    * The value #MHD_TLS_BACKEND_ANY is never set in the returned data.
   9797    * The value #MHD_TLS_BACKEND_NONE is set if the daemon does not use TLS.
   9798    * If MHD built without TLS support then #MHD_TLS_BACKEND_NONE is always set.
   9799    * The result is placed in @a v_tls_backend member.
   9800    */
   9801   MHD_DAEMON_INFO_FIXED_TLS_BACKEND = 120
   9802   ,
   9803   /**
   9804    * Get the default inactivity timeout for connections in milliseconds.
   9805    * The result is placed in @a v_default_timeout_milsec_uint32 member.
   9806    */
   9807   MHD_DAEMON_INFO_FIXED_DEFAULT_TIMEOUT_MILSEC = 160
   9808   ,
   9809   /**
   9810    * Get the limit of number of simutaneous network connections served by
   9811    * the daemon.
   9812    * The result is placed in @a v_global_connection_limit_uint member.
   9813    */
   9814   MHD_DAEMON_INFO_FIXED_GLOBAL_CONNECTION_LIMIT = 161
   9815   ,
   9816   /**
   9817    * Get the limit of number of simutaneous network connections served by
   9818    * the daemon for any single IP address.
   9819    * The result is placed in @a v_per_ip_limit_uint member.
   9820    */
   9821   MHD_DAEMON_INFO_FIXED_PER_IP_LIMIT = 162
   9822   ,
   9823   /**
   9824    * Get the setting for suppression of the 'Date:' header in replies.
   9825    * The result is placed in @a v_suppress_date_header_bool member.
   9826    */
   9827   MHD_DAEMON_INFO_FIXED_SUPPRESS_DATE_HEADER = 240
   9828   ,
   9829   /**
   9830    * Get the size of buffer unsed per connection.
   9831    * The result is placed in @a v_conn_memory_limit_sizet member.
   9832    */
   9833   MHD_DAEMON_INFO_FIXED_CONN_MEMORY_LIMIT = 280
   9834   ,
   9835   /**
   9836    * Get the limit of maximum FD value for the daemon.
   9837    * The daemon rejects (closes) any sockets with FD equal or higher
   9838    * the resulting number.
   9839    * The function returns #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the daemon
   9840    * is built for W32.
   9841    * The result is placed in @a v_fd_number_limit_uint member.
   9842    */
   9843   MHD_DAEMON_INFO_FIXED_FD_NUMBER_LIMIT = 283
   9844   ,
   9845 
   9846   /* * Sentinel * */
   9847   /**
   9848    * The sentinel value.
   9849    * This value enforces specific underlying integer type for the enum.
   9850    * Do not use.
   9851    */
   9852   MHD_DAEMON_INFO_FIXED_SENTINEL = 65535
   9853 
   9854 };
   9855 
   9856 
   9857 /**
   9858  * Information about an MHD daemon.
   9859  */
   9860 union MHD_DaemonInfoFixedData
   9861 {
   9862   /**
   9863    * The data for the #MHD_DAEMON_INFO_FIXED_POLL_SYSCALL query
   9864    */
   9865   enum MHD_SockPollSyscall v_poll_syscall;
   9866 
   9867   /**
   9868    * The data for the #MHD_DAEMON_INFO_FIXED_NUM_WORK_THREADS query
   9869    */
   9870   unsigned int v_num_work_threads_uint;
   9871 
   9872   /**
   9873    * The data for the #MHD_DAEMON_INFO_FIXED_BIND_PORT query
   9874    */
   9875   uint_least16_t v_bind_port_uint16;
   9876 
   9877   /**
   9878    * The data for the #MHD_DAEMON_INFO_FIXED_LISTEN_SOCKET query
   9879    */
   9880   MHD_Socket v_listen_socket;
   9881 
   9882   /**
   9883    * The data for the #MHD_DAEMON_INFO_FIXED_AGGREAGATE_FD query
   9884    */
   9885   int v_aggreagate_fd;
   9886 
   9887   /**
   9888    * The data for the #MHD_DAEMON_INFO_FIXED_TLS_BACKEND query
   9889    */
   9890   enum MHD_TlsBackend v_tls_backend;
   9891 
   9892   /**
   9893    * The data for the #MHD_DAEMON_INFO_FIXED_DEFAULT_TIMEOUT_MILSEC query
   9894    */
   9895   uint_fast32_t v_default_timeout_milsec_uint32;
   9896 
   9897   /**
   9898    * The data for the #MHD_DAEMON_INFO_FIXED_GLOBAL_CONNECTION_LIMIT query
   9899    */
   9900   unsigned int v_global_connection_limit_uint;
   9901 
   9902   /**
   9903    * The data for the #MHD_DAEMON_INFO_FIXED_PER_IP_LIMIT query
   9904    */
   9905   unsigned int v_per_ip_limit_uint;
   9906 
   9907   /**
   9908    * The data for the #MHD_DAEMON_INFO_FIXED_SUPPRESS_DATE_HEADER query
   9909    */
   9910   enum MHD_Bool v_suppress_date_header_bool;
   9911 
   9912   /**
   9913    * The data for the #MHD_DAEMON_INFO_FIXED_CONN_MEMORY_LIMIT query
   9914    */
   9915   size_t v_conn_memory_limit_sizet;
   9916 
   9917   /**
   9918    * The data for the #MHD_DAEMON_INFO_FIXED_FD_NUMBER_LIMIT query
   9919    */
   9920   MHD_Socket v_fd_number_limit_socket;
   9921 
   9922   /**
   9923    * Unused member.
   9924    * Help enforcing future-proof alignment of the union.
   9925    * Do not use.
   9926    */
   9927   void *reserved;
   9928 };
   9929 
   9930 
   9931 /**
   9932  * Obtain fixed information about the given daemon.
   9933  * This information is not changed at after start of the daemon until
   9934  * the daemon is destroyed.
   9935  * The wrapper macro #MHD_daemon_get_info_fixed() may be more convenient.
   9936  *
   9937  * @param daemon the daemon to get information about
   9938  * @param info_type the type of information requested
   9939  * @param[out] output_buf pointer to union where requested information will
   9940  *                        be stored
   9941  * @param output_buf_size the size of the memory area pointed by @a output_buf
   9942  *                        (provided by the caller for storing the requested
   9943  *                        information), in bytes
   9944  * @return #MHD_SC_OK if succeed,
   9945  *         #MHD_SC_TOO_EARLY if the daemon has not been started yet,
   9946  *         #MHD_SC_TOO_LATE if the daemon is being stopped or has failed,
   9947  *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown,
   9948  *         #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information
   9949  *                                              is not available for this
   9950  *                                              daemon due to the daemon
   9951  *                                              configuration/mode,
   9952  *         #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the requested information
   9953  *                                            should be available for
   9954  *                                            the daemon, but cannot be provided
   9955  *                                            due to some error or other
   9956  *                                            reasons,
   9957  *         #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small,
   9958  *         other error codes in case of other errors
   9959  * @ingroup specialized
   9960  */
   9961 MHD_EXTERN_ enum MHD_StatusCode
   9962 MHD_daemon_get_info_fixed_sz (
   9963   struct MHD_Daemon *MHD_RESTRICT daemon,
   9964   enum MHD_DaemonInfoFixedType info_type,
   9965   union MHD_DaemonInfoFixedData *MHD_RESTRICT output_buf,
   9966   size_t output_buf_size)
   9967 MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ (1)
   9968 MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3);
   9969 
   9970 /**
   9971  * Obtain fixed information about the given daemon.
   9972  * This types of information are not changed at after start of the daemon until
   9973  * the daemon is destroyed.
   9974  *
   9975  * @param daemon the daemon to get information about
   9976  * @param info_type the type of information requested
   9977  * @param[out] output_buf pointer to union where requested information will
   9978  *                          be stored
   9979  * @return #MHD_SC_OK if succeed,
   9980  *         #MHD_SC_TOO_EARLY if the daemon has not been started yet,
   9981  *         #MHD_SC_TOO_LATE if the daemon is being stopped or has failed,
   9982  *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown,
   9983  *         #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information
   9984  *                                              is not available for this
   9985  *                                              daemon due to the daemon
   9986  *                                              configuration/mode,
   9987  *         #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the requested information
   9988  *                                            should be available for
   9989  *                                            the daemon, but cannot be provided
   9990  *                                            due to some error or other
   9991  *                                            reasons,
   9992  *         other error codes in case of other errors
   9993  * @ingroup specialized
   9994  */
   9995 #define MHD_daemon_get_info_fixed(daemon, info_type, output_buf) \
   9996         MHD_daemon_get_info_fixed_sz ((daemon), (info_type), (output_buf), \
   9997                                       sizeof(*(output_buf)))
   9998 
   9999 
  10000 /**
  10001  * Values of this enum are used to specify what
  10002  * information about a daemon is desired.
  10003  * This types of information may be changed after the start of the daemon.
  10004  */
  10005 enum MHD_DaemonInfoDynamicType
  10006 {
  10007   /**
  10008    * The the maximum number of millisecond from the current moment until
  10009    * the mandatory call of the daemon data processing function (like
  10010    * #MHD_daemon_process_reg_events(), #MHD_daemon_process_blocking()).
  10011    * If resulting value is zero then daemon data processing function should be
  10012    * called as soon as possible as some data processing is already pending.
  10013    * The data processing function can also be called earlier as well.
  10014    * Available only for daemons stated in #MHD_WM_EXTERNAL_PERIODIC,
  10015    * #MHD_WM_EXTERNAL_EVENT_LOOP_CB_LEVEL, #MHD_WM_EXTERNAL_EVENT_LOOP_CB_EDGE
  10016    * or #MHD_WM_EXTERNAL_SINGLE_FD_WATCH modes.
  10017    * The function returns #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the daemon has
  10018    * internal handling of events (internal threads).
  10019    * The result is placed in @a v_max_time_to_wait_uint64 member.
  10020    */
  10021   MHD_DAEMON_INFO_DYNAMIC_MAX_TIME_TO_WAIT = 1
  10022   ,
  10023   /**
  10024    * Check whether the daemon has any connected network clients.
  10025    * The result is placed in @a v_has_connections_bool member.
  10026    */
  10027   MHD_DAEMON_INFO_DYNAMIC_HAS_CONNECTIONS = 20
  10028   ,
  10029   /* * Sentinel * */
  10030   /**
  10031    * The sentinel value.
  10032    * This value enforces specific underlying integer type for the enum.
  10033    * Do not use.
  10034    */
  10035   MHD_DAEMON_INFO_DYNAMIC_SENTINEL = 65535
  10036 };
  10037 
  10038 
  10039 /**
  10040  * Information about an MHD daemon.
  10041  */
  10042 union MHD_DaemonInfoDynamicData
  10043 {
  10044   /**
  10045    * The data for the #MHD_DAEMON_INFO_DYNAMIC_MAX_TIME_TO_WAIT query
  10046    */
  10047   uint_fast64_t v_max_time_to_wait_uint64;
  10048 
  10049   /**
  10050    * The data for the #MHD_DAEMON_INFO_DYNAMIC_HAS_CONNECTIONS query
  10051    */
  10052   enum MHD_Bool v_has_connections_bool;
  10053 
  10054   /**
  10055    * Unused member.
  10056    * Help enforcing future-proof alignment of the union.
  10057    * Do not use.
  10058    */
  10059   void *reserved;
  10060 };
  10061 
  10062 
  10063 /**
  10064  * Obtain dynamic information about the given daemon.
  10065  * This information may be changed after the start of the daemon.
  10066  * The wrapper macro #MHD_daemon_get_info_dynamic() could be more convenient.
  10067  *
  10068  * @param daemon the daemon to get information about
  10069  * @param info_type the type of information requested
  10070  * @param[out] output_buf the pointer to union to be set to the requested
  10071  *                        information
  10072  * @param output_buf_size the size of the memory area pointed by @a output_buf
  10073  *                        (provided by the caller for storing the requested
  10074  *                        information), in bytes
  10075  * @return #MHD_SC_OK if succeed,
  10076  *         #MHD_SC_TOO_EARLY if the daemon has not been started yet,
  10077  *         #MHD_SC_TOO_LATE if the daemon is being stopped or has failed,
  10078  *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown,
  10079  *         #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information
  10080  *                                              is not available for this
  10081  *                                              daemon due to the daemon
  10082  *                                              configuration/mode,
  10083  *         #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the requested information
  10084  *                                            should be available for
  10085  *                                            the daemon, but cannot be provided
  10086  *                                            due to some error or other
  10087  *                                            reasons,
  10088  *         #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small,
  10089  *         other error codes in case of other errors
  10090  * @ingroup specialized
  10091  */
  10092 MHD_EXTERN_ enum MHD_StatusCode
  10093 MHD_daemon_get_info_dynamic_sz (
  10094   struct MHD_Daemon *MHD_RESTRICT daemon,
  10095   enum MHD_DaemonInfoDynamicType info_type,
  10096   union MHD_DaemonInfoDynamicData *MHD_RESTRICT output_buf,
  10097   size_t output_buf_size)
  10098 MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ (1)
  10099 MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3);
  10100 
  10101 /**
  10102  * Obtain dynamic information about the given daemon.
  10103  * This types of information may be changed after the start of the daemon.
  10104  *
  10105  * @param daemon the daemon to get information about
  10106  * @param info_type the type of information requested
  10107  * @param[out] output_buf the pointer to union to be set to the requested
  10108  *                        information
  10109  * @return #MHD_SC_OK if succeed,
  10110  *         #MHD_SC_TOO_EARLY if the daemon has not been started yet,
  10111  *         #MHD_SC_TOO_LATE if the daemon is being stopped or has failed,
  10112  *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown,
  10113  *         #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information
  10114  *                                              is not available for this
  10115  *                                              daemon due to the daemon
  10116  *                                              configuration/mode,
  10117  *         #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the requested information
  10118  *                                            should be available for
  10119  *                                            the daemon, but cannot be provided
  10120  *                                            due to some error or other
  10121  *                                            reasons,
  10122  *         other error codes in case of other errors
  10123  * @ingroup specialized
  10124  */
  10125 #define MHD_daemon_get_info_dynamic(daemon, info_type, output_buf) \
  10126         MHD_daemon_get_info_dynamic_sz ((daemon), (info_type), (output_buf), \
  10127                                         sizeof(*(output_buf)))
  10128 
  10129 
  10130 /**
  10131  * Select which fixed information about connection is desired.
  10132  * This information is not changed during the lifetime of the connection.
  10133  */
  10134 enum MHD_ConnectionInfoFixedType
  10135 {
  10136   /**
  10137    * Get the network address of the client.
  10138    * If the connection does not have known remote address (was not provided
  10139    * by the system or by the application in case of externally added
  10140    * connection) then error code #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE is
  10141    * returned if connection is IP type or unknown type or error code
  10142    * #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if connection type is non-IP.
  10143    * The @a sa pointer is never NULL if the function succeed (#MHD_SC_OK
  10144    * returned).
  10145    * The result is placed in @a v_client_address_sa_info member.
  10146    * @ingroup request
  10147    */
  10148   MHD_CONNECTION_INFO_FIXED_CLIENT_ADDRESS = 1
  10149   ,
  10150   /**
  10151    * Get the file descriptor for the connection socket.
  10152    * The provided socket must be used as 'read-only': only select() or similar
  10153    * functions should be used. Any modifications (changing socket attributes,
  10154    * calling send() or recv(), closing it etc.) will lead to undefined
  10155    * behaviour.
  10156    * The result is placed in @a v_connection_socket member.
  10157    * @ingroup request
  10158    */
  10159   MHD_CONNECTION_INFO_FIXED_CONNECTION_SOCKET = 2
  10160   ,
  10161   /**
  10162    * Get the `struct MHD_Daemon *` responsible for managing this connection.
  10163    * The result is placed in @a v_daemon member.
  10164    * @ingroup request
  10165    */
  10166   MHD_CONNECTION_INFO_FIXED_DAEMON = 20
  10167   ,
  10168   /**
  10169    * Returns the pointer to a variable pointing to connection-specific
  10170    * application context data that was (possibly) set during
  10171    * a #MHD_NotifyConnectionCallback or provided via @a connection_cntx
  10172    * parameter of #MHD_daemon_add_connection().
  10173    * By using provided pointer application may get or set the pointer to
  10174    * any data specific for the particular connection.
  10175    * Note: resulting data is NOT the context pointer itself.
  10176    * The result is placed in @a v_app_context_ppvoid member.
  10177    * @ingroup request
  10178    */
  10179   MHD_CONNECTION_INFO_FIXED_APP_CONTEXT = 30
  10180   ,
  10181 
  10182   /* * Sentinel * */
  10183   /**
  10184    * The sentinel value.
  10185    * This value enforces specific underlying integer type for the enum.
  10186    * Do not use.
  10187    */
  10188   MHD_CONNECTION_INFO_FIXED_SENTINEL = 65535
  10189 };
  10190 
  10191 /**
  10192  * Socket address information data
  10193  */
  10194 struct MHD_ConnInfoFixedSockAddr
  10195 {
  10196   /**
  10197    * The size of the @a sa
  10198    */
  10199   size_t sa_size;
  10200 
  10201   /**
  10202    * Socket Address type
  10203    */
  10204   const struct sockaddr *sa;
  10205 };
  10206 
  10207 /**
  10208  * Information about a connection.
  10209  */
  10210 union MHD_ConnectionInfoFixedData
  10211 {
  10212 
  10213   /**
  10214    * The data for the #MHD_CONNECTION_INFO_FIXED_CLIENT_ADDRESS query
  10215    */
  10216   struct MHD_ConnInfoFixedSockAddr v_client_address_sa_info;
  10217 
  10218   /**
  10219    * The data for the #MHD_CONNECTION_INFO_FIXED_CONNECTION_SOCKET query
  10220    */
  10221   MHD_Socket v_connection_socket;
  10222 
  10223   /**
  10224    * The data for the #MHD_CONNECTION_INFO_FIXED_DAEMON query
  10225    */
  10226   struct MHD_Daemon *v_daemon;
  10227 
  10228   /**
  10229    * The data for the #MHD_CONNECTION_INFO_FIXED_APP_CONTEXT query
  10230    */
  10231   void **v_app_context_ppvoid;
  10232 };
  10233 
  10234 
  10235 /**
  10236  * Obtain fixed information about the given connection.
  10237  * This information is not changed for the lifetime of the connection.
  10238  * The wrapper macro #MHD_connection_get_info_fixed() may be more convenient.
  10239  *
  10240  * @param connection the connection to get information about
  10241  * @param info_type the type of information requested
  10242  * @param[out] output_buf the pointer to union to be set to the requested
  10243  *                        information
  10244  * @param output_buf_size the size of the memory area pointed by @a output_buf
  10245  *                        (provided by the caller for storing the requested
  10246  *                        information), in bytes
  10247  * @return #MHD_SC_OK if succeed,
  10248  *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown,
  10249  *         #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information
  10250  *                                              is not available for this
  10251  *                                              connection due to the connection
  10252  *                                              configuration/mode,
  10253  *         #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the requested information
  10254  *                                            should be available for
  10255  *                                            the connection, but cannot be
  10256  *                                            provided due to some error or
  10257  *                                            other reasons,
  10258  *         #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small,
  10259  *         other error codes in case of other errors
  10260  * @ingroup specialized
  10261  */
  10262 MHD_EXTERN_ enum MHD_StatusCode
  10263 MHD_connection_get_info_fixed_sz (
  10264   struct MHD_Connection *MHD_RESTRICT connection,
  10265   enum MHD_ConnectionInfoFixedType info_type,
  10266   union MHD_ConnectionInfoFixedData *MHD_RESTRICT output_buf,
  10267   size_t output_buf_size)
  10268 MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ (1)
  10269 MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3);
  10270 
  10271 
  10272 /**
  10273  * Obtain fixed information about the given connection.
  10274  * This information is not changed for the lifetime of the connection.
  10275  *
  10276  * @param connection the connection to get information about
  10277  * @param info_type the type of information requested
  10278  * @param[out] output_buf the pointer to union to be set to the requested
  10279  *                        information
  10280  * @return #MHD_SC_OK if succeed,
  10281  *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown,
  10282  *         #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information
  10283  *                                              is not available for this
  10284  *                                              connection due to the connection
  10285  *                                              configuration/mode,
  10286  *         #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the requested information
  10287  *                                            should be available for
  10288  *                                            the connection, but cannot be
  10289  *                                            provided due to some error or
  10290  *                                            other reasons,
  10291  *         other error codes in case of other errors
  10292  * @ingroup specialized
  10293  */
  10294 #define MHD_connection_get_info_fixed(connection, info_type, output_buf) \
  10295         MHD_connection_get_info_fixed_sz ((connection),(info_type), \
  10296                                           (output_buf), sizeof(*(output_buf)))
  10297 
  10298 
  10299 /**
  10300  * Select which dynamic information about connection is desired.
  10301  * This information may be changed during the lifetime of the connection.
  10302  */
  10303 enum MHD_ConnectionInfoDynamicType
  10304 {
  10305   /**
  10306    * Get current version of HTTP protocol used for connection.
  10307    * If connection is handling HTTP/1.x requests the function may return
  10308    * error code #MHD_SC_TOO_EARLY if the full request line has not been received
  10309    * yet for the current request.
  10310    * The result is placed in @a v_http_ver member.
  10311    * @ingroup request
  10312    */
  10313   MHD_CONNECTION_INFO_DYNAMIC_HTTP_VER = 1
  10314   ,
  10315   /**
  10316    * Get connection timeout value.
  10317    * This is the total number of milliseconds after which the idle
  10318    * connection is automatically disconnected.
  10319    * Note: the value set is NOT the number of milliseconds left before
  10320    * automatic disconnection.
  10321    * The result is placed in @a v_connection_timeout_uint32 member.
  10322    * @ingroup request
  10323    */
  10324   MHD_CONNECTION_INFO_DYNAMIC_CONNECTION_TIMEOUT_MILSEC = 10
  10325   ,
  10326   /**
  10327    * Check whether the connection is suspended.
  10328    * The result is placed in @a v_connection_suspended_bool member.
  10329    * @ingroup request
  10330    */
  10331   MHD_CONNECTION_INFO_DYNAMIC_CONNECTION_SUSPENDED = 11
  10332   ,
  10333   /**
  10334    * Get current version of TLS transport protocol used for connection
  10335    * If plain TCP connection is used then #MHD_TLS_VERSION_NO_TLS set in
  10336    * the data.
  10337    * It TLS handshake is not yet finished then error code #MHD_SC_TOO_EARLY is
  10338    * returned. If TLS has failed or being closed then #MHD_SC_TOO_LATE error
  10339    * code is returned.
  10340    * If TLS version cannot be detected for any reason then error code
  10341    * #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE is returned.
  10342    * The result is placed in @a v_tls_ver member.
  10343    * @ingroup request
  10344    */
  10345   MHD_CONNECTION_INFO_DYNAMIC_TLS_VER = 105
  10346   ,
  10347   /**
  10348    * Get the TLS backend session handle.
  10349    * If plain TCP connection is used then the function returns error code
  10350    * #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE.
  10351    * The resulting union has only one valid member.
  10352    * The result is placed in @a v_tls_session member.
  10353    * @ingroup request
  10354    */
  10355   MHD_CONNECTION_INFO_DYNAMIC_TLS_SESSION = 140
  10356   ,
  10357 
  10358   /* * Sentinel * */
  10359   /**
  10360    * The sentinel value.
  10361    * This value enforces specific underlying integer type for the enum.
  10362    * Do not use.
  10363    */
  10364   MHD_CONNECTION_INFO_DYNAMIC_SENTINEL = 65535
  10365 };
  10366 
  10367 
  10368 /**
  10369  * The versions of TLS protocol
  10370  */
  10371 enum MHD_FIXED_ENUM_MHD_SET_ MHD_TlsVersion
  10372 {
  10373 
  10374   /**
  10375    * No TLS / plain socket connection
  10376    */
  10377   MHD_TLS_VERSION_NO_TLS = 0
  10378   ,
  10379   /**
  10380    * Not supported/failed to negotiate/failed to handshake TLS
  10381    */
  10382   MHD_TLS_VERSION_BROKEN = 1
  10383   ,
  10384   /**
  10385    * TLS version 1.0
  10386    */
  10387   MHD_TLS_VERSION_1_0 = 2
  10388   ,
  10389   /**
  10390    * TLS version 1.1
  10391    */
  10392   MHD_TLS_VERSION_1_1 = 3
  10393   ,
  10394   /**
  10395    * TLS version 1.2
  10396    */
  10397   MHD_TLS_VERSION_1_2 = 4
  10398   ,
  10399   /**
  10400    * TLS version 1.3
  10401    */
  10402   MHD_TLS_VERSION_1_3 = 5
  10403   ,
  10404   /**
  10405    * Some unknown TLS version.
  10406    * The TLS version is supported by TLS backend, but unknown to MHD.
  10407    */
  10408   MHD_TLS_VERSION_UNKNOWN = 1999
  10409 };
  10410 
  10411 /**
  10412  * Connection TLS session information.
  10413  * Only one member is valid. Use #MHD_DAEMON_INFO_FIXED_TLS_TYPE to find out
  10414  * which member should be used.
  10415  */
  10416 union MHD_ConnInfoDynamicTlsSess
  10417 {
  10418   /* Include <gnutls/gnutls.h> before this header to get a better type safety */
  10419   /**
  10420    * GnuTLS session handle, of type "gnutls_session_t".
  10421    */
  10422 #if defined(GNUTLS_VERSION_MAJOR) && GNUTLS_VERSION_MAJOR >= 3
  10423   gnutls_session_t v_gnutls_session;
  10424 #else
  10425   void * /* gnutls_session_t */ v_gnutls_session;
  10426 #endif
  10427 
  10428   /* Include <openssl/types.h> or <openssl/crypto.h> before this header to get
  10429      a better type safety */
  10430   /**
  10431    * OpenSSL session handle, of type "SSL*".
  10432    */
  10433 #if defined(OPENSSL_TYPES_H) && OPENSSL_VERSION_MAJOR >= 3
  10434   SSL *v_openssl_session;
  10435 #else
  10436   void /* SSL */ *v_openssl_session;
  10437 #endif
  10438 
  10439   /* Include <mbedtls/ssl.h> before this header to get a better type safety */
  10440   /**
  10441    * MbedTLS session handle, of type "mbedtls_ssl_context*".
  10442    */
  10443 #if defined(MBEDTLS_SSL_H)
  10444   mbedtls_ssl_context *v_mbedtls_session;
  10445 #else
  10446   void /* mbedtls_ssl_context */ *v_mbedtls_session;
  10447 #endif
  10448 };
  10449 
  10450 /**
  10451  * Information about a connection.
  10452  */
  10453 union MHD_ConnectionInfoDynamicData
  10454 {
  10455   /**
  10456    * The data for the #MHD_CONNECTION_INFO_DYNAMIC_HTTP_VER query
  10457    */
  10458   enum MHD_HTTP_ProtocolVersion v_http_ver;
  10459 
  10460   /**
  10461    * The data for the #MHD_CONNECTION_INFO_DYNAMIC_CONNECTION_TIMEOUT_MILSEC
  10462    * query
  10463    */
  10464   uint_fast32_t v_connection_timeout_uint32;
  10465 
  10466   /**
  10467    * The data for the #MHD_CONNECTION_INFO_DYNAMIC_CONNECTION_SUSPENDED query
  10468    */
  10469   enum MHD_Bool v_connection_suspended_bool;
  10470 
  10471   /**
  10472    * The data for the #MHD_CONNECTION_INFO_DYNAMIC_CONNECTION_SUSPENDED query
  10473    */
  10474   enum MHD_TlsVersion v_tls_ver;
  10475 
  10476   /**
  10477    * Connection TLS session information.
  10478    * Only one member is valid. Use #MHD_DAEMON_INFO_FIXED_TLS_TYPE to find out
  10479    * which member should be used.
  10480    */
  10481   union MHD_ConnInfoDynamicTlsSess v_tls_session;
  10482 };
  10483 
  10484 /**
  10485  * Obtain dynamic information about the given connection.
  10486  * This information may be changed during the lifetime of the connection.
  10487  *
  10488  * The wrapper macro #MHD_connection_get_info_dynamic() may be more convenient.
  10489  *
  10490  * @param connection the connection to get information about
  10491  * @param info_type the type of information requested
  10492  * @param[out] output_buf the pointer to union to be set to the requested
  10493  *                        information
  10494  * @param output_buf_size the size of the memory area pointed by @a output_buf
  10495  *                        (provided by the caller for storing the requested
  10496  *                        information), in bytes
  10497  * @return #MHD_SC_OK if succeed,
  10498  *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown,
  10499  *         #MHD_SC_TOO_EARLY if the connection has not reached yet required
  10500  *                           state,
  10501  *         #MHD_SC_TOO_LATE if the connection is already in state where
  10502  *                          the requested information is not available,
  10503  *         #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information
  10504  *                                              is not available for this
  10505  *                                              connection due to the connection
  10506  *                                              configuration/mode,
  10507  *         #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small,
  10508  *         #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the requested information
  10509  *                                            should be available for
  10510  *                                            the connection, but cannot be
  10511  *                                            provided due to some error or
  10512  *                                            other reasons,
  10513  *         other error codes in case of other errors
  10514  * @ingroup specialized
  10515  */
  10516 MHD_EXTERN_ enum MHD_StatusCode
  10517 MHD_connection_get_info_dynamic_sz (
  10518   struct MHD_Connection *MHD_RESTRICT connection,
  10519   enum MHD_ConnectionInfoDynamicType info_type,
  10520   union MHD_ConnectionInfoDynamicData *MHD_RESTRICT output_buf,
  10521   size_t output_buf_size)
  10522 MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ (1)
  10523 MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3);
  10524 
  10525 
  10526 /**
  10527  * Obtain dynamic information about the given connection.
  10528  * This information may be changed during the lifetime of the connection.
  10529  *
  10530  * @param connection the connection to get information about
  10531  * @param info_type the type of information requested
  10532  * @param[out] output_buf the pointer to union to be set to the requested
  10533  *                        information
  10534  * @return #MHD_SC_OK if succeed,
  10535  *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown,
  10536  *         #MHD_SC_TOO_EARLY if the connection has not reached yet required
  10537  *                           state,
  10538  *         #MHD_SC_TOO_LATE if the connection is already in state where
  10539  *                          the requested information is not available,
  10540  *         #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information
  10541  *                                              is not available for this
  10542  *                                              connection due to the connection
  10543  *                                              configuration/mode,
  10544  *         #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the requested information
  10545  *                                            should be available for
  10546  *                                            the connection, but cannot be
  10547  *                                            provided due to some error or
  10548  *                                            other reasons,
  10549  *         other error codes in case of other errors
  10550  * @ingroup specialized
  10551  */
  10552 #define MHD_connection_get_info_dynamic(connection, info_type, output_buf) \
  10553         MHD_connection_get_info_dynamic_sz ((connection),(info_type), \
  10554                                             (output_buf),sizeof(*(output_buf)))
  10555 
  10556 
  10557 /**
  10558  * Select which fixed information about stream is desired.
  10559  * This information is not changed during the lifetime of the connection.
  10560  */
  10561 enum MHD_FIXED_ENUM_APP_SET_ MHD_StreamInfoFixedType
  10562 {
  10563   /**
  10564    * Get the `struct MHD_Daemon *` responsible for managing connection which
  10565    * is responsible for this stream.
  10566    * The result is placed in @a v_daemon member.
  10567    * @ingroup request
  10568    */
  10569   MHD_STREAM_INFO_FIXED_DAEMON = 20
  10570   ,
  10571   /**
  10572    * Get the `struct MHD_Connection *` responsible for managing this stream.
  10573    * The result is placed in @a v_connection member.
  10574    * @ingroup request
  10575    */
  10576   MHD_STREAM_INFO_FIXED_CONNECTION = 21
  10577   ,
  10578 
  10579   /* * Sentinel * */
  10580   /**
  10581    * The sentinel value.
  10582    * This value enforces specific underlying integer type for the enum.
  10583    * Do not use.
  10584    */
  10585   MHD_STREAM_INFO_FIXED_SENTINEL = 65535
  10586 };
  10587 
  10588 
  10589 /**
  10590  * Fixed information about a stream.
  10591  */
  10592 union MHD_StreamInfoFixedData
  10593 {
  10594   /**
  10595    * The data for the #MHD_STREAM_INFO_FIXED_DAEMON query
  10596    */
  10597   struct MHD_Daemon *v_daemon;
  10598   /**
  10599    * The data for the #MHD_STREAM_INFO_FIXED_CONNECTION query
  10600    */
  10601   struct MHD_Connection *v_connection;
  10602 };
  10603 
  10604 
  10605 /**
  10606  * Obtain fixed information about the given stream.
  10607  * This information is not changed for the lifetime of the stream.
  10608  *
  10609  * The wrapper macro #MHD_stream_get_info_fixed() may be more convenient.
  10610  *
  10611  * @param stream the stream to get information about
  10612  * @param info_type the type of information requested
  10613  * @param[out] output_buf the pointer to union to be set to the requested
  10614  *                        information
  10615  * @param output_buf_size the size of the memory area pointed by @a output_buf
  10616  *                        (provided by the caller for storing the requested
  10617  *                        information), in bytes
  10618  * @return #MHD_SC_OK if succeed,
  10619  *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown,
  10620  *         #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small,
  10621  *         other error codes in case of other errors
  10622  * @ingroup specialized
  10623  */
  10624 MHD_EXTERN_ enum MHD_StatusCode
  10625 MHD_stream_get_info_fixed_sz (
  10626   struct MHD_Stream *MHD_RESTRICT stream,
  10627   enum MHD_StreamInfoFixedType info_type,
  10628   union MHD_StreamInfoFixedData *MHD_RESTRICT output_buf,
  10629   size_t output_buf_size)
  10630 MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ (1)
  10631 MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3);
  10632 
  10633 
  10634 /**
  10635  * Obtain fixed information about the given stream.
  10636  * This information is not changed for the lifetime of the tream.
  10637  *
  10638  * @param stream the stream to get information about
  10639  * @param info_type the type of information requested
  10640  * @param[out] output_buf the pointer to union to be set to the requested
  10641  *                        information
  10642  * @return #MHD_SC_OK if succeed,
  10643  *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown,
  10644  *         other error codes in case of other errors
  10645  * @ingroup specialized
  10646  */
  10647 #define MHD_stream_get_info_fixed(stream, info_type, output_buf) \
  10648         MHD_stream_get_info_fixed_sz ((stream),(info_type),(output_buf), \
  10649                                       sizeof(*(output_buf)))
  10650 
  10651 
  10652 /**
  10653  * Select which fixed information about stream is desired.
  10654  * This information may be changed during the lifetime of the stream.
  10655  */
  10656 enum MHD_FIXED_ENUM_APP_SET_ MHD_StreamInfoDynamicType
  10657 {
  10658   /**
  10659    * Get the `struct MHD_Request *` for current request processed by the stream.
  10660    * If no request is being processed, the error code #MHD_SC_TOO_EARLY is
  10661    * returned.
  10662    * The result is placed in @a v_request member.
  10663    * @ingroup request
  10664    */
  10665   MHD_STREAM_INFO_DYNAMIC_REQUEST = 20
  10666   ,
  10667 
  10668   /* * Sentinel * */
  10669   /**
  10670    * The sentinel value.
  10671    * This value enforces specific underlying integer type for the enum.
  10672    * Do not use.
  10673    */
  10674   MHD_STREAM_INFO_DYNAMIC_SENTINEL = 65535
  10675 };
  10676 
  10677 
  10678 /**
  10679  * Dynamic information about stream.
  10680  * This information may be changed during the lifetime of the connection.
  10681  */
  10682 union MHD_StreamInfoDynamicData
  10683 {
  10684   /**
  10685    * The data for the #MHD_STREAM_INFO_DYNAMIC_REQUEST query
  10686    */
  10687   struct MHD_Request *v_request;
  10688 };
  10689 
  10690 /**
  10691  * Obtain dynamic information about the given stream.
  10692  * This information may be changed during the lifetime of the stream.
  10693  *
  10694  * The wrapper macro #MHD_stream_get_info_dynamic() may be more convenient.
  10695  *
  10696  * @param stream the stream to get information about
  10697  * @param info_type the type of information requested
  10698  * @param[out] output_buf the pointer to union to be set to the requested
  10699  *                        information
  10700  * @param output_buf_size the size of the memory area pointed by @a output_buf
  10701  *                        (provided by the caller for storing the requested
  10702  *                        information), in bytes
  10703  * @return #MHD_SC_OK if succeed,
  10704  *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown,
  10705  *         #MHD_SC_TOO_EARLY if the stream has not reached yet required state,
  10706  *         #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small,
  10707  *         other error codes in case of other errors
  10708  * @ingroup specialized
  10709  */
  10710 MHD_EXTERN_ enum MHD_StatusCode
  10711 MHD_stream_get_info_dynamic_sz (
  10712   struct MHD_Stream *MHD_RESTRICT stream,
  10713   enum MHD_StreamInfoDynamicType info_type,
  10714   union MHD_StreamInfoDynamicData *MHD_RESTRICT output_buf,
  10715   size_t output_buf_size)
  10716 MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ (1)
  10717 MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3);
  10718 
  10719 
  10720 /**
  10721  * Obtain dynamic information about the given stream.
  10722  * This information may be changed during the lifetime of the stream.
  10723  *
  10724  * @param stream the stream to get information about
  10725  * @param info_type the type of information requested
  10726  * @param[out] output_buf the pointer to union to be set to the requested
  10727  *                        information
  10728  * @return #MHD_SC_OK if succeed,
  10729  *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown,
  10730  *         #MHD_SC_TOO_EARLY if the stream has not reached yet required state,
  10731  *         other error codes in case of other errors
  10732  * @ingroup specialized
  10733  */
  10734 #define MHD_stream_get_info_dynamic(stream, info_type, output_buf) \
  10735         MHD_stream_get_info_dynamic_sz ((stream),(info_type),(output_buf), \
  10736                                         sizeof(*(output_buf)))
  10737 
  10738 
  10739 /**
  10740  * Select which fixed information about request is desired.
  10741  * This information is not changed during the lifetime of the request.
  10742  */
  10743 enum MHD_FIXED_ENUM_APP_SET_ MHD_RequestInfoFixedType
  10744 {
  10745   /**
  10746    * Get the version of HTTP protocol used for the request.
  10747    * If request line has not been fully received yet then #MHD_SC_TOO_EARLY
  10748    * error code is returned.
  10749    * The result is placed in @a v_http_ver member.
  10750    * @ingroup request
  10751    */
  10752   MHD_REQUEST_INFO_FIXED_HTTP_VER = 1
  10753   ,
  10754   /**
  10755    * Get the HTTP method used for the request (as a enum).
  10756    * The result is placed in @a v_http_method member.
  10757    * @sa #MHD_REQUEST_INFO_DYNAMIC_HTTP_METHOD_STR
  10758    * @ingroup request
  10759    */
  10760   MHD_REQUEST_INFO_FIXED_HTTP_METHOD = 2
  10761   ,
  10762   /**
  10763    * Return MHD daemon to which the request belongs to.
  10764    * The result is placed in @a v_daemon member.
  10765    */
  10766   MHD_REQUEST_INFO_FIXED_DAEMON = 20
  10767   ,
  10768   /**
  10769    * Return which connection is associated with the stream which is associated
  10770    * with the request.
  10771    * The result is placed in @a v_connection member.
  10772    */
  10773   MHD_REQUEST_INFO_FIXED_CONNECTION = 21
  10774   ,
  10775   /**
  10776    * Return which stream the request is associated with.
  10777    * The result is placed in @a v_stream member.
  10778    */
  10779   MHD_REQUEST_INFO_FIXED_STREAM = 22
  10780   ,
  10781   /**
  10782    * Returns the pointer to a variable pointing to request-specific
  10783    * application context data. The same data is provided for
  10784    * #MHD_EarlyUriLogCallback and #MHD_RequestTerminationCallback.
  10785    * By using provided pointer application may get or set the pointer to
  10786    * any data specific for the particular request.
  10787    * Note: resulting data is NOT the context pointer itself.
  10788    * The result is placed in @a v_app_context_ppvoid member.
  10789    * @ingroup request
  10790    */
  10791   MHD_REQUEST_INFO_FIXED_APP_CONTEXT = 30
  10792   ,
  10793 
  10794   /* * Sentinel * */
  10795   /**
  10796    * The sentinel value.
  10797    * This value enforces specific underlying integer type for the enum.
  10798    * Do not use.
  10799    */
  10800   MHD_REQUEST_INFO_FIXED_SENTINEL = 65535
  10801 };
  10802 
  10803 
  10804 /**
  10805  * Fixed information about a request.
  10806  */
  10807 union MHD_RequestInfoFixedData
  10808 {
  10809 
  10810   /**
  10811    * The data for the #MHD_REQUEST_INFO_FIXED_HTTP_VER query
  10812    */
  10813   enum MHD_HTTP_ProtocolVersion v_http_ver;
  10814 
  10815   /**
  10816    * The data for the #MHD_REQUEST_INFO_FIXED_HTTP_METHOD query
  10817    */
  10818   enum MHD_HTTP_Method v_http_method;
  10819 
  10820   /**
  10821    * The data for the #MHD_REQUEST_INFO_FIXED_DAEMON query
  10822    */
  10823   struct MHD_Daemon *v_daemon;
  10824 
  10825   /**
  10826    * The data for the #MHD_REQUEST_INFO_FIXED_CONNECTION query
  10827    */
  10828   struct MHD_Connection *v_connection;
  10829 
  10830   /**
  10831    * The data for the #MHD_REQUEST_INFO_FIXED_STREAM query
  10832    */
  10833   struct MHD_Stream *v_stream;
  10834 
  10835   /**
  10836    * The data for the #MHD_REQUEST_INFO_FIXED_APP_CONTEXT query
  10837    */
  10838   void **v_app_context_ppvoid;
  10839 };
  10840 
  10841 /**
  10842  * Obtain fixed information about the given request.
  10843  * This information is not changed for the lifetime of the request.
  10844  *
  10845  * The wrapper macro #MHD_request_get_info_fixed() may be more convenient.
  10846  *
  10847  * @param request the request to get information about
  10848  * @param info_type the type of information requested
  10849  * @param[out] output_buf the pointer to union to be set to the requested
  10850  *                        information
  10851  * @param output_buf_size the size of the memory area pointed by @a output_buf
  10852  *                        (provided by the caller for storing the requested
  10853  *                        information), in bytes
  10854  * @return #MHD_SC_OK if succeed,
  10855  *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown,
  10856  *         #MHD_SC_TOO_EARLY if the request processing has not reached yet
  10857  *                           the required state,
  10858  *         #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small,
  10859  *         other error codes in case of other errors
  10860  * @ingroup specialized
  10861  */
  10862 MHD_EXTERN_ enum MHD_StatusCode
  10863 MHD_request_get_info_fixed_sz (
  10864   struct MHD_Request *MHD_RESTRICT request,
  10865   enum MHD_RequestInfoFixedType info_type,
  10866   union MHD_RequestInfoFixedData *MHD_RESTRICT output_buf,
  10867   size_t output_buf_size)
  10868 MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ (1)
  10869 MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3);
  10870 
  10871 
  10872 /**
  10873  * Obtain fixed information about the given request.
  10874  * This information is not changed for the lifetime of the request.
  10875  *
  10876  * @param request the request to get information about
  10877  * @param info_type the type of information requested
  10878  * @param[out] output_buf the pointer to union to be set to the requested
  10879  *                        information
  10880  * @return #MHD_SC_OK if succeed,
  10881  *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown,
  10882  *         #MHD_SC_TOO_EARLY if the request processing has not reached yet
  10883  *                           the required state,
  10884  *         other error codes in case of other errors
  10885  * @ingroup specialized
  10886  */
  10887 #define MHD_request_get_info_fixed(request, info_type, output_buf) \
  10888         MHD_request_get_info_fixed_sz ((request), (info_type), (output_buf), \
  10889                                        sizeof(*(output_buf)))
  10890 
  10891 
  10892 /**
  10893  * Select which dynamic information about request is desired.
  10894  * This information may be changed during the lifetime of the request.
  10895  * Any returned string pointers are valid only until a response is provided.
  10896  */
  10897 enum MHD_FIXED_ENUM_APP_SET_ MHD_RequestInfoDynamicType
  10898 {
  10899   /**
  10900    * Get the HTTP method used for the request (as a MHD_String).
  10901    * The resulting string pointer in valid only until a response is provided.
  10902    * The result is placed in @a v_http_method_string member.
  10903    * @sa #MHD_REQUEST_INFO_FIXED_HTTP_METHOD
  10904    * @ingroup request
  10905    */
  10906   MHD_REQUEST_INFO_DYNAMIC_HTTP_METHOD_STRING = 1
  10907   ,
  10908   /**
  10909    * Get the URI used for the request (as a MHD_String), excluding
  10910    * the parameter part (anything after '?').
  10911    * The resulting string pointer in valid only until a response is provided.
  10912    * The result is placed in @a v_uri_string member.
  10913    * @ingroup request
  10914    */
  10915   MHD_REQUEST_INFO_DYNAMIC_URI = 2
  10916   ,
  10917   /**
  10918    * Get the number of URI parameters (the decoded part of the original
  10919    * URI string after '?'). Sometimes it is called "GET parameters".
  10920    * The result is placed in @a v_number_uri_params_sizet member.
  10921    * @ingroup request
  10922    */
  10923   MHD_REQUEST_INFO_DYNAMIC_NUMBER_URI_PARAMS = 3
  10924   ,
  10925   /**
  10926    * Get the number of cookies in the request.
  10927    * The result is placed in @a v_number_cookies_sizet member.
  10928    * If cookies parsing is disabled in MHD build then the function returns
  10929    * error code #MHD_SC_FEATURE_DISABLED.
  10930    * If cookies parsing is disabled this daemon then the function returns
  10931    * error code #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE.
  10932    * @ingroup request
  10933    */
  10934   MHD_REQUEST_INFO_DYNAMIC_NUMBER_COOKIES = 4
  10935   ,
  10936   /**
  10937    * Return length of the client's HTTP request header.
  10938    * This is a total raw size of the header (after TLS decipher if any)
  10939    * The result is placed in @a v_header_size_sizet member.
  10940    * @ingroup request
  10941    */
  10942   MHD_REQUEST_INFO_DYNAMIC_HEADER_SIZE = 5
  10943   ,
  10944   /**
  10945    * Get the number of decoded POST entries in the request.
  10946    * The result is placed in @a v_number_post_params_sizet member.
  10947    * @ingroup request
  10948    */
  10949   MHD_REQUEST_INFO_DYNAMIC_NUMBER_POST_PARAMS = 6
  10950   ,
  10951   /**
  10952    * Get whether the upload content is present in the request.
  10953    * The result is #MHD_YES if any upload content is present, even
  10954    * if the upload content size is zero.
  10955    * The result is placed in @a v_upload_present_bool member.
  10956    * @ingroup request
  10957    */
  10958   MHD_REQUEST_INFO_DYNAMIC_UPLOAD_PRESENT = 10
  10959   ,
  10960   /**
  10961    * Get whether the chunked upload content is present in the request.
  10962    * The result is #MHD_YES if chunked upload content is present.
  10963    * The result is placed in @a v_upload_chunked_bool member.
  10964    * @ingroup request
  10965    */
  10966   MHD_REQUEST_INFO_DYNAMIC_UPLOAD_CHUNKED = 11
  10967   ,
  10968   /**
  10969    * Get the total content upload size.
  10970    * Resulted in zero if no content upload or upload content size is zero,
  10971    * #MHD_SIZE_UNKNOWN if size is not known (chunked upload).
  10972    * The result is placed in @a v_upload_size_total_uint64 member.
  10973    * @ingroup request
  10974    */
  10975   MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_TOTAL = 12
  10976   ,
  10977   /**
  10978    * Get the total size of the content upload already received from the client.
  10979    * This is the total size received, could be not yet fully processed by the
  10980    * application.
  10981    * The result is placed in @a v_upload_size_recieved_uint64 member.
  10982    * @ingroup request
  10983    */
  10984   MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_RECIEVED = 13
  10985   ,
  10986   /**
  10987    * Get the total size of the content upload left to be received from
  10988    * the client.
  10989    * Resulted in #MHD_SIZE_UNKNOWN if total size is not known (chunked upload).
  10990    * The result is placed in @a v_upload_size_to_recieve_uint64 member.
  10991    * @ingroup request
  10992    */
  10993   MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_TO_RECIEVE = 14
  10994   ,
  10995   /**
  10996    * Get the total size of the content upload already processed (upload callback
  10997    * called and completed (if any)).
  10998    * If the value is requested from #MHD_UploadCallback, then result does NOT
  10999    * include the current data being processed by the callback.
  11000    * The result is placed in @a v_upload_size_processed_uint64 member.
  11001    * @ingroup request
  11002    */
  11003   MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_PROCESSED = 15
  11004   ,
  11005   /**
  11006    * Get the total size of the content upload left to be processed.
  11007    * The resulting value includes the size of the data not yet received from
  11008    * the client.
  11009    * If the value is requested from #MHD_UploadCallback, then result includes
  11010    * the current data being processed by the callback.
  11011    * Resulted in #MHD_SIZE_UNKNOWN if total size is not known (chunked upload).
  11012    * The result is placed in @a v_upload_size_to_process_uint64 member.
  11013    * @ingroup request
  11014    */
  11015   MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_TO_PROCESS = 16
  11016   ,
  11017   /**
  11018    * Returns pointer to information about digest auth in client request.
  11019    * The resulting pointer is NULL if no digest auth header is set by
  11020    * the client or the format of the digest auth header is broken.
  11021    * Pointers in the returned structure (if any) are valid until response
  11022    * is provided for the request.
  11023    * The result is placed in @a v_auth_digest_info member.
  11024    */
  11025   MHD_REQUEST_INFO_DYNAMIC_AUTH_DIGEST_INFO = 42
  11026   ,
  11027   /**
  11028    * Returns information about Basic Authentication credentials in the request.
  11029    * Pointers in the returned structure (if any) are valid until any MHD_Action
  11030    * or MHD_UploadAction is provided. If the data is needed beyond this point,
  11031    * it should be copied.
  11032    * If #MHD_request_get_info_dynamic_sz() returns #MHD_SC_OK then
  11033    * @a v_auth_basic_creds is NOT NULL and at least the username data
  11034    * is provided.
  11035    * The result is placed in @a v_auth_basic_creds member.
  11036    */
  11037   MHD_REQUEST_INFO_DYNAMIC_AUTH_BASIC_CREDS = 51
  11038   ,
  11039   /* * Sentinel * */
  11040   /**
  11041    * The sentinel value.
  11042    * This value enforces specific underlying integer type for the enum.
  11043    * Do not use.
  11044    */
  11045   MHD_REQUEST_INFO_DYNAMIC_SENTINEL = 65535
  11046 };
  11047 
  11048 
  11049 /**
  11050  * Dynamic information about a request.
  11051  */
  11052 union MHD_RequestInfoDynamicData
  11053 {
  11054 
  11055   /**
  11056    * The data for the #MHD_REQUEST_INFO_DYNAMIC_HTTP_METHOD_STRING query
  11057    */
  11058   struct MHD_String v_http_method_string;
  11059 
  11060   /**
  11061    * The data for the #MHD_REQUEST_INFO_DYNAMIC_URI query
  11062    */
  11063   struct MHD_String v_uri_string;
  11064 
  11065   /**
  11066    * The data for the #MHD_REQUEST_INFO_DYNAMIC_NUMBER_URI_PARAMS query
  11067    */
  11068   size_t v_number_uri_params_sizet;
  11069 
  11070   /**
  11071    * The data for the #MHD_REQUEST_INFO_DYNAMIC_NUMBER_COOKIES query
  11072    */
  11073   size_t v_number_cookies_sizet;
  11074 
  11075   /**
  11076    * The data for the #MHD_REQUEST_INFO_DYNAMIC_HEADER_SIZE query
  11077    */
  11078   size_t v_header_size_sizet;
  11079 
  11080   /**
  11081    * The data for the #MHD_REQUEST_INFO_DYNAMIC_NUMBER_POST_PARAMS query
  11082    */
  11083   size_t v_number_post_params_sizet;
  11084 
  11085   /**
  11086    * The data for the #MHD_REQUEST_INFO_DYNAMIC_UPLOAD_PRESENT query
  11087    */
  11088   enum MHD_Bool v_upload_present_bool;
  11089 
  11090   /**
  11091    * The data for the #MHD_REQUEST_INFO_DYNAMIC_UPLOAD_CHUNKED query
  11092    */
  11093   enum MHD_Bool v_upload_chunked_bool;
  11094 
  11095   /**
  11096    * The data for the #MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_TOTAL query
  11097    */
  11098   uint_fast64_t v_upload_size_total_uint64;
  11099 
  11100   /**
  11101    * The data for the #MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_RECIEVED query
  11102    */
  11103   uint_fast64_t v_upload_size_recieved_uint64;
  11104 
  11105   /**
  11106    * The data for the #MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_TO_RECIEVE query
  11107    */
  11108   uint_fast64_t v_upload_size_to_recieve_uint64;
  11109 
  11110   /**
  11111    * The data for the #MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_PROCESSED query
  11112    */
  11113   uint_fast64_t v_upload_size_processed_uint64;
  11114 
  11115   /**
  11116    * The data for the #MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_TO_PROCESS query
  11117    */
  11118   uint_fast64_t v_upload_size_to_process_uint64;
  11119 
  11120   /**
  11121    * The data for the #MHD_REQUEST_INFO_DYNAMIC_AUTH_DIGEST_INFO query
  11122    */
  11123   const struct MHD_AuthDigestInfo *v_auth_digest_info;
  11124 
  11125   /**
  11126    * The data for the #MHD_REQUEST_INFO_DYNAMIC_AUTH_BASIC_CREDS query
  11127    */
  11128   const struct MHD_AuthBasicCreds *v_auth_basic_creds;
  11129 };
  11130 
  11131 
  11132 /**
  11133  * Obtain dynamic information about the given request.
  11134  * This information may be changed during the lifetime of the request.
  11135  * Most of the data provided is available only when the request line or complete
  11136  * request headers are processed and not available if responding has been
  11137  * started.
  11138  *
  11139  * The wrapper macro #MHD_request_get_info_dynamic() may be more convenient.
  11140  *
  11141  * Any pointers in the returned data are valid until any MHD_Action or
  11142  * MHD_UploadAction is provided. If the data is needed beyond this point,
  11143  * it should be copied.
  11144  *
  11145  * @param request the request to get information about
  11146  * @param info_type the type of information requested
  11147  * @param[out] output_buf the pointer to union to be set to the requested
  11148  *                        information
  11149  * @param output_buf_size the size of the memory area pointed by @a output_buf
  11150  *                        (provided by the caller for storing the requested
  11151  *                        information), in bytes
  11152  * @return #MHD_SC_OK if succeed,
  11153  *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if requested information type is
  11154  *                                       not recognized by MHD,
  11155  *         #MHD_SC_TOO_LATE if request is already being closed or the response
  11156  *                          is being sent
  11157  *         #MHD_SC_TOO_EARLY if requested data is not yet ready (for example,
  11158  *                           headers are not yet received),
  11159  *         #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information is
  11160  *                                              not available for this request
  11161  *                                              due to used configuration/mode,
  11162  *         #MHD_SC_FEATURE_DISABLED if requested functionality is not supported
  11163  *                                  by this MHD build,
  11164  *         #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small,
  11165  *         #MHD_SC_AUTH_ABSENT if request does not have particular Auth data,
  11166  *         #MHD_SC_CONNECTION_POOL_NO_MEM_AUTH_DATA if connection memory pool
  11167  *                                                  has no space to put decoded
  11168  *                                                  authentication data,
  11169  *         #MHD_SC_REQ_AUTH_DATA_BROKEN if the format of authentication data is
  11170  *                                      incorrect or broken,
  11171  *         other error codes in case of other errors
  11172  * @ingroup specialized
  11173  */
  11174 MHD_EXTERN_ enum MHD_StatusCode
  11175 MHD_request_get_info_dynamic_sz (
  11176   struct MHD_Request *MHD_RESTRICT request,
  11177   enum MHD_RequestInfoDynamicType info_type,
  11178   union MHD_RequestInfoDynamicData *MHD_RESTRICT output_buf,
  11179   size_t output_buf_size)
  11180 MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ (1)
  11181 MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3);
  11182 
  11183 
  11184 /**
  11185  * Obtain dynamic information about the given request.
  11186  * This information may be changed during the lifetime of the request.
  11187  * Most of the data provided is available only when the request line or complete
  11188  * request headers are processed and not available if responding has been
  11189  * started.
  11190  *
  11191  * Any pointers in the returned data are valid until any MHD_Action or
  11192  * MHD_UploadAction is provided. If the data is needed beyond this point,
  11193  * it should be copied.
  11194  *
  11195  * @param request the request to get information about
  11196  * @param info_type the type of information requested
  11197  * @param[out] output_buf the pointer to union to be set to the requested
  11198  *                        information
  11199  * @return #MHD_SC_OK if succeed,
  11200  *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if requested information type is
  11201  *                                       not recognized by MHD,
  11202  *         #MHD_SC_TOO_LATE if request is already being closed or the response
  11203  *                          is being sent
  11204  *         #MHD_SC_TOO_EARLY if requested data is not yet ready (for example,
  11205  *                           headers are not yet received),
  11206  *         #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information is
  11207  *                                              not available for this request
  11208  *                                              due to used configuration/mode,
  11209  *         #MHD_SC_FEATURE_DISABLED if requested functionality is not supported
  11210  *                                  by this MHD build,
  11211  *         #MHD_SC_AUTH_ABSENT if request does not have particular Auth data,
  11212  *         #MHD_SC_CONNECTION_POOL_NO_MEM_AUTH_DATA if connection memory pool
  11213  *                                                  has no space to put decoded
  11214  *                                                  authentication data,
  11215  *         #MHD_SC_REQ_AUTH_DATA_BROKEN if the format of authentication data is
  11216  *                                      incorrect or broken,
  11217  *         other error codes in case of other errors
  11218  * @ingroup specialized
  11219  */
  11220 #define MHD_request_get_info_dynamic(request, info_type, output_buf) \
  11221         MHD_request_get_info_dynamic_sz ((request), (info_type), \
  11222                                          (output_buf), \
  11223                                          sizeof(*(output_buf)))
  11224 
  11225 /**
  11226  * Callback for serious error condition. The default action is to print
  11227  * an error message and `abort()`.
  11228  * The callback should not return.
  11229  * Some parameters could be empty strings (the strings with zero-termination at
  11230  * zero position) if MHD built without log messages (only for embedded
  11231  * projects).
  11232  *
  11233  * @param cls user specified value
  11234  * @param file where the error occurred, could be empty
  11235  * @param func the name of the function, where the error occurred, may be empty
  11236  * @param line where the error occurred
  11237  * @param message the error details, could be empty
  11238  * @ingroup logging
  11239  */
  11240 typedef void
  11241 (*MHD_PanicCallback)(void *cls,
  11242                      const char *file,
  11243                      const char *func,
  11244                      unsigned int line,
  11245                      const char *message);
  11246 
  11247 
  11248 /**
  11249  * Sets the global error handler to a different implementation.
  11250  * The @a cb will only be called in the case of typically fatal, serious
  11251  * internal consistency issues.
  11252  * These issues should only arise in the case of serious memory corruption or
  11253  * similar problems with the architecture.
  11254  * The @a cb should not return.
  11255  *
  11256  * The default implementation that is used if no panic function is set
  11257  * simply prints an error message and calls `abort()`.  Alternative
  11258  * implementations might call `exit()` or other similar functions.
  11259  *
  11260  * @param cb new error handler, NULL to reset to default handler
  11261  * @param cls passed to @a cb
  11262  * @ingroup logging
  11263  */
  11264 MHD_EXTERN_ void
  11265 MHD_lib_set_panic_func (MHD_PanicCallback cb,
  11266                         void *cls);
  11267 
  11268 #define MHD_lib_set_panic_func_default() \
  11269         MHD_lib_set_panic_func (MHD_STATIC_CAST_ (MHD_PanicCallback,NULL),NULL)
  11270 MHD_C_DECLARATIONS_FINISH_HERE_
  11271 
  11272 #endif /* ! MICROHTTPD2_H */