libmicrohttpd2

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

microhttpd2.h (396038B)


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