libmicrohttpd2

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

libtest.h (27550B)


      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) 2024 Christian Grothoff
      5 
      6   GNU libmicrohttpd is free software; you can redistribute it and/or
      7   modify it under the terms of the GNU Lesser General Public
      8   License as published by the Free Software Foundation; either
      9   version 2.1 of the License, or (at your option) any later version.
     10 
     11   GNU libmicrohttpd is distributed in the hope that it will be useful,
     12   but WITHOUT ANY WARRANTY; without even the implied warranty of
     13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14   Lesser General Public License for more details.
     15 
     16   Alternatively, you can redistribute GNU libmicrohttpd and/or
     17   modify it under the terms of the GNU General Public License as
     18   published by the Free Software Foundation; either version 2 of
     19   the License, or (at your option) any later version, together
     20   with the eCos exception, as follows:
     21 
     22     As a special exception, if other files instantiate templates or
     23     use macros or inline functions from this file, or you compile this
     24     file and link it with other works to produce a work based on this
     25     file, this file does not by itself cause the resulting work to be
     26     covered by the GNU General Public License. However the source code
     27     for this file must still be made available in accordance with
     28     section (3) of the GNU General Public License v2.
     29 
     30     This exception does not invalidate any other reasons why a work
     31     based on this file might be covered by the GNU General Public
     32     License.
     33 
     34   You should have received copies of the GNU Lesser General Public
     35   License and the GNU General Public License along with this library;
     36   if not, see <https://www.gnu.org/licenses/>.
     37 */
     38 
     39 /**
     40  * @file libtest.h
     41  * @brief testing harness with clients against server
     42  * @author Christian Grothoff
     43  */
     44 #ifndef LIBTEST_H
     45 #define LIBTEST_H
     46 
     47 #include "mhd_sys_options.h"
     48 #include <stdio.h>
     49 #include <stdlib.h>
     50 #include <string.h>
     51 #ifdef HAVE_STDBOOL_H
     52 #  include <stdbool.h>
     53 #endif
     54 #include "microhttpd2.h"
     55 
     56 
     57 /**
     58  * A phase defines some server and client-side
     59  * behaviors to execute.
     60  */
     61 struct MHDT_Phase;
     62 
     63 
     64 /**
     65  * Information about the current phase.
     66  */
     67 struct MHDT_PhaseContext
     68 {
     69   /**
     70    * Base URL of the server
     71    */
     72   const char *base_url;
     73 
     74   /**
     75    * Data structure to keep around during the request because
     76    * Curl.
     77    */
     78   struct curl_slist *hosts;
     79 
     80   /**
     81    * Specific client we are running.
     82    */
     83   unsigned int client_id;
     84 
     85   /**
     86    * More details about the phase we are running.
     87    */
     88   struct MHDT_Phase *phase;
     89 
     90 };
     91 
     92 
     93 /**
     94  * Function called to run some client logic against
     95  * the server.
     96  *
     97  * @param cls closure
     98  * @param pc context for the client
     99  * @return error message, NULL on success
    100  */
    101 typedef const char *
    102 (*MHDT_ClientLogic)(const void *cls,
    103                     struct MHDT_PhaseContext *pc);
    104 
    105 
    106 struct MHDT_Phase
    107 {
    108 
    109   /**
    110    * Name of the phase, for debugging/logging.
    111    */
    112   const char *label;
    113 
    114   /**
    115    * Logic for the MHD server for this phase.
    116    */
    117   MHD_RequestCallback server_cb;
    118 
    119   /**
    120    * Closure for @e server_cb.
    121    */
    122   void *server_cb_cls;
    123 
    124   /**
    125    * Logic for the CURL client for this phase.
    126    */
    127   MHDT_ClientLogic client_cb;
    128 
    129   /**
    130    * Closure for @e client_cb.
    131    */
    132   const void *client_cb_cls;
    133 
    134   /**
    135    * How long is the phase allowed to run at most before
    136    * timing out. 0 for no timeout.
    137    */
    138   uint_fast32_t timeout_ms;
    139 
    140   /**
    141    * How many clients should be run in parallel.
    142    * 0 to run just one client.
    143    */
    144   unsigned int num_clients;
    145 
    146   /**
    147    * Set to true if clients should setup the connection to use TLS.
    148    */
    149   bool use_tls;
    150 
    151   /**
    152    * Set to true if clients should check server cert.
    153    */
    154   bool check_server_cert;
    155 
    156   /**
    157    * HTTP version to use. 0 = any (negotiated),
    158    * 1 = HTTP/1.x, 2 = HTTP/2, 3 = HTTP/3.
    159    */
    160   unsigned int http_version;
    161 
    162   /**
    163    * Client certificate to present to the server, NULL for none.
    164    */
    165   const char *client_cert;
    166 
    167   /**
    168    * Client private key to use, NULL for none.
    169    */
    170   const char *client_priv;
    171 
    172   /**
    173    * Server certificate to present to the client, NULL for default.
    174    */
    175   const char *server_cert;
    176 
    177   /**
    178    * Server private key to use, NULL for default.
    179    */
    180   const char *server_priv;
    181 };
    182 
    183 
    184 /**
    185  * Load PEM file from data/ folder and return data in it.
    186  *
    187  * @param name name of PEM file to load
    188  * @return NULL on error
    189  */
    190 char *
    191 MHDT_load_pem (const char *name);
    192 
    193 
    194 /**
    195  * Fill the buffer with the text-like data and zero-terminate it.
    196  *
    197  * The generated data is position-dependent, therefore any shift, repetition
    198  * or loss of the transferred data is detected by the content check.
    199  * The data has spaces, so it could be split to "words" by the chunked
    200  * response callback.
    201  *
    202  * @param[out] buf the buffer to fill
    203  * @param buf_size the size of the @a buf buffer, including the space for
    204  *                 the terminating zero; must be non-zero
    205  */
    206 void
    207 MHDT_fill_text_data (char *buf,
    208                      size_t buf_size);
    209 
    210 
    211 /**
    212  * Run request against the root URL of the
    213  * hostname given in @a cls.
    214  *
    215  * @param cls closure with hostname to use
    216  * @param pc context for the client
    217  * @return error message, NULL on success
    218  */
    219 const char *
    220 MHDT_client_get_host (const void *cls,
    221                       struct MHDT_PhaseContext *pc);
    222 
    223 
    224 /**
    225  * Run request against the base URL and expect the
    226  * string in @a cls to be returned
    227  *
    228  * @param cls closure with text string to be returned
    229  * @param pc context for the client
    230  * @return error message, NULL on success
    231  */
    232 const char *
    233 MHDT_client_get_root (const void *cls,
    234                       struct MHDT_PhaseContext *pc);
    235 
    236 
    237 /**
    238  * Run request against the base URL with the
    239  * query arguments from @a cls appended to it.
    240  * Expect the server to return a 200 OK response.
    241  *
    242  * @param cls closure with query parameters to append
    243  *  to the base URL of the server
    244  * @param pc context for the client
    245  * @return error message, NULL on success
    246  */
    247 const char *
    248 MHDT_client_get_with_query (const void *cls,
    249                             struct MHDT_PhaseContext *pc);
    250 
    251 
    252 /**
    253  * Run request against the base URL with the
    254  * custom header from @a cls set.
    255  * Expect the server to return a 204 No content response.
    256  *
    257  * @param cls closure with custom header to set
    258  * @param pc context for the client
    259  * @return error message, NULL on success
    260  */
    261 const char *
    262 MHDT_client_set_header (const void *cls,
    263                         struct MHDT_PhaseContext *pc);
    264 
    265 
    266 /**
    267  * Run request against the base URL and expect the header from @a cls to be
    268  * set in the 204 No content response.
    269  *
    270  * @param cls closure with custom header to set,
    271  *      must be of the format "$KEY:$VALUE"
    272  *      without space before the "$VALUE".
    273  * @param pc context for the client
    274  * @return error message, NULL on success
    275  */
    276 const char *
    277 MHDT_client_expect_header (const void *cls,
    278                            struct MHDT_PhaseContext *pc);
    279 
    280 
    281 /**
    282  * Run simple upload against the base URL and expect a
    283  * 204 No Content response.
    284  *
    285  * @param cls 0-terminated string with data to PUT
    286  * @param pc context for the client
    287  * @return error message, NULL on success
    288  */
    289 const char *
    290 MHDT_client_put_data (const void *cls,
    291                       struct MHDT_PhaseContext *pc);
    292 
    293 
    294 /**
    295  * Run chunked upload against the base URL and expect a
    296  * 204 No Content response.
    297  *
    298  * @param cls 0-terminated string with data to PUT
    299  * @param pc context for the client
    300  * @return error message, NULL on success
    301  */
    302 const char *
    303 MHDT_client_chunk_data (const void *cls,
    304                         struct MHDT_PhaseContext *pc);
    305 
    306 
    307 /**
    308  * Information about a result we expect from the PP.
    309  */
    310 struct MHDT_PostWant
    311 {
    312   /**
    313    * key for the result
    314    */
    315   const char *key;
    316 
    317   /**
    318    * Value for the result.
    319    */
    320   const char *value;
    321 
    322   /**
    323    * Filename attribute for the result, NULL for none.
    324    */
    325   const char *filename;
    326 
    327   /**
    328    * Content type attribute for the result, NULL for none.
    329    */
    330   const char *content_type;
    331 
    332   /**
    333    * Number of bytes in @a value, 0 if value is 0-terminated.
    334    */
    335   size_t value_size;
    336 
    337   /**
    338    * Internal book-keeping for @e incremental processing.
    339    */
    340   size_t value_off;
    341 
    342   /**
    343    * True if @e value may be transmitted incrementally.
    344    */
    345   bool incremental;
    346 
    347   /**
    348    * Set to true if a matching record was returned.
    349    */
    350   bool satisfied;
    351 
    352 };
    353 
    354 
    355 /**
    356  * Arguments and state for the #MHDT_server_reply_check_post and
    357  * #MHDT_client_do_post() functions.
    358  */
    359 struct MHDT_PostInstructions
    360 {
    361   /**
    362    * Encoding to use when decoding.
    363    */
    364   enum MHD_HTTP_PostEncoding enc;
    365 
    366   /**
    367    * Data to be POSTed to the server.
    368    */
    369   const char *postdata;
    370 
    371   /**
    372    * HTTP header to set POST content encoding, use
    373    * NULL if you want to set @e request_hdr directly.
    374    */
    375   const char *postheader;
    376 
    377   /**
    378    * NULL-terminated array of expected POST data for
    379    * the server.
    380    */
    381   struct MHDT_PostWant *wants;
    382 
    383   /**
    384    * Number of bytes in @e postdata, use 0 for
    385    * 0-terminated @e postdata.
    386    */
    387   size_t postdata_size;
    388 
    389   /**
    390    * size to use for the buffer.
    391    */
    392   size_t buffer_size;
    393 
    394   /**
    395    * Size above which we switch to stream processing.
    396    */
    397   size_t auto_stream_size;
    398 };
    399 
    400 
    401 /**
    402  * Perform POST request suitable for testing the post processor and expect a
    403  * 204 No Content response.
    404  *
    405  * Note that @a cls cannot be used by multiple commands
    406  * simultaneously, so do not use this in concurrent
    407  * tests aliasing @a cls.
    408  *
    409  * @param cls information what to post of type `struct MHDT_PostInstructions`
    410  * @param pc context for the client
    411  * @return error message, NULL on success
    412  */
    413 const char *
    414 MHDT_client_do_post (
    415   const void *cls,
    416   struct MHDT_PhaseContext *pc);
    417 
    418 
    419 /**
    420  * Perform GET request and send some HTTP basic authentication header
    421  * to authorize the request.
    422  *
    423  * @param cls a string with "$USERNAME:$PASSWORD"
    424  * @param pc context for the client
    425  * @return error message, NULL on success
    426  */
    427 const char *
    428 MHDT_client_send_basic_auth (
    429   const void *cls,
    430   struct MHDT_PhaseContext *pc);
    431 
    432 
    433 /**
    434  * Perform GET request and send some HTTP basic authentication header
    435  * to authorize the request. Expect authentication to fail.
    436  *
    437  * @param cls a string with "$USERNAME:$PASSWORD"
    438  * @param pc context for the client
    439  * @return error message, NULL on success
    440  */
    441 const char *
    442 MHDT_client_fail_basic_auth (
    443   const void *cls,
    444   struct MHDT_PhaseContext *pc);
    445 
    446 
    447 /**
    448  * Perform GET request and send some HTTP digest authentication header
    449  * to authorize the request.
    450  *
    451  * @param cls a string with "$USERNAME:$PASSWORD"
    452  * @param pc context for the client
    453  * @return error message, NULL on success
    454  */
    455 const char *
    456 MHDT_client_send_digest_auth (
    457   const void *cls,
    458   struct MHDT_PhaseContext *pc);
    459 
    460 
    461 /**
    462  * Perform GET request and send some HTTP digest authentication header
    463  * to authorize the request. Expect authentication to fail.
    464  *
    465  * @param cls a string with "$USERNAME:$PASSWORD"
    466  * @param pc context for the client
    467  * @return error message, NULL on success
    468  */
    469 const char *
    470 MHDT_client_fail_digest_auth (
    471   const void *cls,
    472   struct MHDT_PhaseContext *pc);
    473 
    474 
    475 /**
    476  * Returns the text from @a cls as the response to any
    477  * request.
    478  *
    479  * @param cls argument given together with the function
    480  *        pointer when the handler was registered with MHD
    481  * @param request the request object
    482  * @param path the requested uri (without arguments after "?")
    483  * @param method the HTTP method used (#MHD_HTTP_METHOD_GET,
    484  *        #MHD_HTTP_METHOD_PUT, etc.)
    485  * @param upload_size the size of the message upload content payload,
    486  *                    #MHD_SIZE_UNKNOWN for chunked uploads (if the
    487  *                    final chunk has not been processed yet)
    488  * @return action how to proceed, NULL
    489  *         if the request must be aborted due to a serious
    490  *         error while handling the request (implies closure
    491  *         of underling data stream, for HTTP/1.1 it means
    492  *         socket closure).
    493  */
    494 const struct MHD_Action *
    495 MHDT_server_reply_text (
    496   void *cls,
    497   struct MHD_Request *MHD_RESTRICT request,
    498   const struct MHD_String *MHD_RESTRICT path,
    499   enum MHD_HTTP_Method method,
    500   uint_fast64_t upload_size);
    501 
    502 
    503 /**
    504  * Returns the text from @a cls as the response to any
    505  * request, but using chunks by returning @a cls
    506  * word-wise (breaking into chunks at spaces).
    507  *
    508  * @param cls argument given together with the function
    509  *        pointer when the handler was registered with MHD
    510  * @param request the request object
    511  * @param path the requested uri (without arguments after "?")
    512  * @param method the HTTP method used (#MHD_HTTP_METHOD_GET,
    513  *        #MHD_HTTP_METHOD_PUT, etc.)
    514  * @param upload_size the size of the message upload content payload,
    515  *                    #MHD_SIZE_UNKNOWN for chunked uploads (if the
    516  *                    final chunk has not been processed yet)
    517  * @return action how to proceed, NULL
    518  *         if the request must be aborted due to a serious
    519  *         error while handling the request (implies closure
    520  *         of underling data stream, for HTTP/1.1 it means
    521  *         socket closure).
    522  */
    523 const struct MHD_Action *
    524 MHDT_server_reply_chunked_text (
    525   void *cls,
    526   struct MHD_Request *MHD_RESTRICT request,
    527   const struct MHD_String *MHD_RESTRICT path,
    528   enum MHD_HTTP_Method method,
    529   uint_fast64_t upload_size);
    530 
    531 
    532 /**
    533  * Returns writes text from @a cls to a temporary file
    534  * and then uses the file descriptor to serve the
    535  * content to the client.
    536  *
    537  * @param cls argument given together with the function
    538  *        pointer when the handler was registered with MHD
    539  * @param request the request object
    540  * @param path the requested uri (without arguments after "?")
    541  * @param method the HTTP method used (#MHD_HTTP_METHOD_GET,
    542  *        #MHD_HTTP_METHOD_PUT, etc.)
    543  * @param upload_size the size of the message upload content payload,
    544  *                    #MHD_SIZE_UNKNOWN for chunked uploads (if the
    545  *                    final chunk has not been processed yet)
    546  * @return action how to proceed, NULL
    547  *         if the request must be aborted due to a serious
    548  *         error while handling the request (implies closure
    549  *         of underling data stream, for HTTP/1.1 it means
    550  *         socket closure).
    551  */
    552 const struct MHD_Action *
    553 MHDT_server_reply_file (
    554   void *cls,
    555   struct MHD_Request *MHD_RESTRICT request,
    556   const struct MHD_String *MHD_RESTRICT path,
    557   enum MHD_HTTP_Method method,
    558   uint_fast64_t upload_size);
    559 
    560 
    561 /**
    562  * Writes text from @a cls to a temporary file and then uses the file
    563  * descriptor to serve the content to the client without indicating the size
    564  * of the content.
    565  *
    566  * The reply is sent by chunked encoding (HTTP/1.1) or is terminated by
    567  * the end of the stream (HTTP/2), the size of the content is detected by
    568  * the end of the file.
    569  *
    570  * @param cls argument given together with the function
    571  *        pointer when the handler was registered with MHD
    572  * @param request the request object
    573  * @param path the requested uri (without arguments after "?")
    574  * @param method the HTTP method used (#MHD_HTTP_METHOD_GET,
    575  *        #MHD_HTTP_METHOD_PUT, etc.)
    576  * @param upload_size the size of the message upload content payload,
    577  *                    #MHD_SIZE_UNKNOWN for chunked uploads (if the
    578  *                    final chunk has not been processed yet)
    579  * @return action how to proceed, NULL
    580  *         if the request must be aborted due to a serious
    581  *         error while handling the request (implies closure
    582  *         of underling data stream, for HTTP/1.1 it means
    583  *         socket closure).
    584  */
    585 const struct MHD_Action *
    586 MHDT_server_reply_file_unknown_size (
    587   void *cls,
    588   struct MHD_Request *MHD_RESTRICT request,
    589   const struct MHD_String *MHD_RESTRICT path,
    590   enum MHD_HTTP_Method method,
    591   uint_fast64_t upload_size);
    592 
    593 
    594 /**
    595  * Returns an emtpy response with a custom header
    596  * set from @a cls and the #MHD_HTTP_STATUS_NO_CONTENT.
    597  *
    598  * @param cls header in the format "$NAME:$VALUE"
    599  *        without a space before "$VALUE".
    600  * @param request the request object
    601  * @param path the requested uri (without arguments after "?")
    602  * @param method the HTTP method used (#MHD_HTTP_METHOD_GET,
    603  *        #MHD_HTTP_METHOD_PUT, etc.)
    604  * @param upload_size the size of the message upload content payload,
    605  *                    #MHD_SIZE_UNKNOWN for chunked uploads (if the
    606  *                    final chunk has not been processed yet)
    607  * @return action how to proceed, NULL
    608  *         if the request must be aborted due to a serious
    609  *         error while handling the request (implies closure
    610  *         of underling data stream, for HTTP/1.1 it means
    611  *         socket closure).
    612  */
    613 const struct MHD_Action *
    614 MHDT_server_reply_with_header (
    615   void *cls,
    616   struct MHD_Request *MHD_RESTRICT request,
    617   const struct MHD_String *MHD_RESTRICT path,
    618   enum MHD_HTTP_Method method,
    619   uint_fast64_t upload_size);
    620 
    621 
    622 /**
    623  * Checks that the request query arguments match the
    624  * arguments given in @a cls.
    625  * request.
    626  *
    627  * @param cls string with expected arguments separated by '&' and '='. URI encoding is NOT supported.
    628  * @param request the request object
    629  * @param path the requested uri (without arguments after "?")
    630  * @param method the HTTP method used (#MHD_HTTP_METHOD_GET,
    631  *        #MHD_HTTP_METHOD_PUT, etc.)
    632  * @param upload_size the size of the message upload content payload,
    633  *                    #MHD_SIZE_UNKNOWN for chunked uploads (if the
    634  *                    final chunk has not been processed yet)
    635  * @return action how to proceed, NULL
    636  *         if the request must be aborted due to a serious
    637  *         error while handling the request (implies closure
    638  *         of underling data stream, for HTTP/1.1 it means
    639  *         socket closure).
    640  */
    641 const struct MHD_Action *
    642 MHDT_server_reply_check_query (
    643   void *cls,
    644   struct MHD_Request *MHD_RESTRICT request,
    645   const struct MHD_String *MHD_RESTRICT path,
    646   enum MHD_HTTP_Method method,
    647   uint_fast64_t upload_size);
    648 
    649 
    650 /**
    651  * Checks that the client request includes the given
    652  * custom header.  If so, returns #MHD_HTTP_STATUS_NO_CONTENT.
    653  *
    654  * @param cls expected header with "$NAME:$VALUE" format.
    655  * @param request the request object
    656  * @param path the requested uri (without arguments after "?")
    657  * @param method the HTTP method used (#MHD_HTTP_METHOD_GET,
    658  *        #MHD_HTTP_METHOD_PUT, etc.)
    659  * @param upload_size the size of the message upload content payload,
    660  *                    #MHD_SIZE_UNKNOWN for chunked uploads (if the
    661  *                    final chunk has not been processed yet)
    662  * @return action how to proceed, NULL
    663  *         if the request must be aborted due to a serious
    664  *         error while handling the request (implies closure
    665  *         of underling data stream, for HTTP/1.1 it means
    666  *         socket closure).
    667  */
    668 const struct MHD_Action *
    669 MHDT_server_reply_check_header (
    670   void *cls,
    671   struct MHD_Request *MHD_RESTRICT request,
    672   const struct MHD_String *MHD_RESTRICT path,
    673   enum MHD_HTTP_Method method,
    674   uint_fast64_t upload_size);
    675 
    676 
    677 /**
    678  * Checks that the client request includes the given
    679  * upload.  If so, returns #MHD_HTTP_STATUS_NO_CONTENT.
    680  *
    681  * @param cls expected upload data as a 0-terminated string.
    682  * @param request the request object
    683  * @param path the requested uri (without arguments after "?")
    684  * @param method the HTTP method used (#MHD_HTTP_METHOD_GET,
    685  *        #MHD_HTTP_METHOD_PUT, etc.)
    686  * @param upload_size the size of the message upload content payload,
    687  *                    #MHD_SIZE_UNKNOWN for chunked uploads (if the
    688  *                    final chunk has not been processed yet)
    689  * @return action how to proceed, NULL
    690  *         if the request must be aborted due to a serious
    691  *         error while handling the request (implies closure
    692  *         of underling data stream, for HTTP/1.1 it means
    693  *         socket closure).
    694  */
    695 const struct MHD_Action *
    696 MHDT_server_reply_check_upload (
    697   void *cls,
    698   struct MHD_Request *MHD_RESTRICT request,
    699   const struct MHD_String *MHD_RESTRICT path,
    700   enum MHD_HTTP_Method method,
    701   uint_fast64_t upload_size);
    702 
    703 
    704 /**
    705  * Checks that the client request against the expected
    706  * POST data.  If so, returns #MHD_HTTP_STATUS_NO_CONTENT.
    707  *
    708  * Note that @a cls cannot be used by multiple commands
    709  * simultaneously, so do not use this in concurrent
    710  * tests aliasing @a cls.
    711  *
    712  * @param cls a `struct MHD_PostInstructions`
    713  * @param request the request object
    714  * @param path the requested uri (without arguments after "?")
    715  * @param method the HTTP method used (#MHD_HTTP_METHOD_GET,
    716  *        #MHD_HTTP_METHOD_PUT, etc.)
    717  * @param upload_size the size of the message upload content payload,
    718  *                    #MHD_SIZE_UNKNOWN for chunked uploads (if the
    719  *                    final chunk has not been processed yet)
    720  * @return action how to proceed, NULL
    721  *         if the request must be aborted due to a serious
    722  *         error while handling the request (implies closure
    723  *         of underling data stream, for HTTP/1.1 it means
    724  *         socket closure).
    725  */
    726 const struct MHD_Action *
    727 MHDT_server_reply_check_post (
    728   void *cls,
    729   struct MHD_Request *MHD_RESTRICT request,
    730   const struct MHD_String *MHD_RESTRICT path,
    731   enum MHD_HTTP_Method method,
    732   uint_fast64_t upload_size);
    733 
    734 
    735 /**
    736  * Checks that the client request includes the given
    737  * username and password in HTTP basic authetnication.
    738  * If so, returns #MHD_HTTP_STATUS_NO_CONTENT, otherwise
    739  * an #MHD_HTTP_STATUS_UNAUTHORIZED.
    740  *
    741  * @param cls expected upload data as a 0-terminated string.
    742  * @param request the request object
    743  * @param path the requested uri (without arguments after "?")
    744  * @param method the HTTP method used (#MHD_HTTP_METHOD_GET,
    745  *        #MHD_HTTP_METHOD_PUT, etc.)
    746  * @param upload_size the size of the message upload content payload,
    747  *                    #MHD_SIZE_UNKNOWN for chunked uploads (if the
    748  *                    final chunk has not been processed yet)
    749  * @return action how to proceed, NULL
    750  *         if the request must be aborted due to a serious
    751  *         error while handling the request (implies closure
    752  *         of underling data stream, for HTTP/1.1 it means
    753  *         socket closure).
    754  */
    755 const struct MHD_Action *
    756 MHDT_server_reply_check_basic_auth (
    757   void *cls,
    758   struct MHD_Request *MHD_RESTRICT request,
    759   const struct MHD_String *MHD_RESTRICT path,
    760   enum MHD_HTTP_Method method,
    761   uint_fast64_t upload_size);
    762 
    763 
    764 /**
    765  * Checks that the client request includes the given
    766  * username and password in HTTP digest authetnication.
    767  * If so, returns #MHD_HTTP_STATUS_NO_CONTENT, otherwise
    768  * an #MHD_HTTP_STATUS_UNAUTHORIZED.
    769  *
    770  * @param cls expected upload data as a 0-terminated string.
    771  * @param request the request object
    772  * @param path the requested uri (without arguments after "?")
    773  * @param method the HTTP method used (#MHD_HTTP_METHOD_GET,
    774  *        #MHD_HTTP_METHOD_PUT, etc.)
    775  * @param upload_size the size of the message upload content payload,
    776  *                    #MHD_SIZE_UNKNOWN for chunked uploads (if the
    777  *                    final chunk has not been processed yet)
    778  * @return action how to proceed, NULL
    779  *         if the request must be aborted due to a serious
    780  *         error while handling the request (implies closure
    781  *         of underling data stream, for HTTP/1.1 it means
    782  *         socket closure).
    783  */
    784 const struct MHD_Action *
    785 MHDT_server_reply_check_digest_auth (
    786   void *cls,
    787   struct MHD_Request *MHD_RESTRICT request,
    788   const struct MHD_String *MHD_RESTRICT path,
    789   enum MHD_HTTP_Method method,
    790   uint_fast64_t upload_size);
    791 
    792 
    793 /**
    794  * Initialize options for an MHD daemon for a test.
    795  *
    796  * @param cls closure
    797  * @param[in,out] d daemon to initialize
    798  * @return error message, NULL on success
    799  */
    800 typedef const char *
    801 (*MHDT_ServerSetup)(const void *cls,
    802                     struct MHD_Daemon *d);
    803 
    804 
    805 /**
    806  * Initialize MHD daemon without any special
    807  * options, binding to any free port.
    808  *
    809  * @param cls closure
    810  * @param[in,out] d daemon to initialize
    811  * @return error message, NULL on success
    812  */
    813 const char *
    814 MHDT_server_setup_minimal (const void *cls,
    815                            struct MHD_Daemon *d);
    816 
    817 
    818 /**
    819  * Initialize MHD daemon for an external event loop.
    820  * Must be used together with #MHDT_server_run_external().
    821  *
    822  * @param cls closure (use NULL)
    823  * @param[in,out] d daemon to initialize
    824  * @return error message, NULL on success
    825  */
    826 const char *
    827 MHDT_server_setup_external (const void *cls,
    828                             struct MHD_Daemon *d);
    829 
    830 
    831 /**
    832  * Initialize MHD daemon with TLS support, binding to any free port.
    833  *
    834  * @param cls closure
    835  * @param[in,out] d daemon to initialize
    836  * @return error message, NULL on success
    837  */
    838 const char *
    839 MHDT_server_setup_tls (const void *cls,
    840                        struct MHD_Daemon *d);
    841 
    842 
    843 /**
    844  * Initialize MHD daemon with TLS support using GnuTLS, binding to any free
    845  * port.
    846  *
    847  * @param cls closure
    848  * @param[in,out] d daemon to initialize
    849  * @return error message, NULL on success
    850  */
    851 const char *
    852 MHDT_server_setup_gnutls (const void *cls,
    853                           struct MHD_Daemon *d);
    854 
    855 
    856 /**
    857  * Initialize MHD daemon with TLS support using OpenSSL, binding to any free
    858  * port.
    859  *
    860  * @param cls closure
    861  * @param[in,out] d daemon to initialize
    862  * @return error message, NULL on success
    863  */
    864 const char *
    865 MHDT_server_setup_openssl (const void *cls,
    866                            struct MHD_Daemon *d);
    867 
    868 
    869 /**
    870  * Function that runs an MHD daemon until
    871  * a read() against @a finsig succeeds.
    872  *
    873  * @param cls closure
    874  * @param finsig fd to read from to detect termination request
    875  * @param[in,out] d daemon to run
    876  */
    877 typedef void
    878 (*MHDT_ServerRunner)(void *cls,
    879                      int finsig,
    880                      struct MHD_Daemon *d);
    881 
    882 
    883 /**
    884  * Function that starts an MHD daemon with the
    885  * simple #MHD_daemon_start() method until
    886  * a read() against @a finsig succeeds.
    887  *
    888  * @param cls closure, pass a NULL-terminated (!)
    889  *   array of `struct MHD_DaemonOptionAndValue` with the
    890  *   the threading mode to use
    891  * @param finsig fd to read from to detect termination request
    892  * @param[in,out] d daemon to run
    893  */
    894 void
    895 MHDT_server_run_minimal (void *cls,
    896                          int finsig,
    897                          struct MHD_Daemon *d);
    898 
    899 
    900 /**
    901  * Function that runs an MHD daemon in blocking mode until
    902  * a read() against @a finsig succeeds.
    903  *
    904  * @param cls closure
    905  * @param finsig fd to read from to detect termination request
    906  * @param[in,out] d daemon to run
    907  */
    908 void
    909 MHDT_server_run_blocking (void *cls,
    910                           int finsig,
    911                           struct MHD_Daemon *d);
    912 
    913 
    914 /**
    915  * Function that runs an MHD daemon with an external event loop until
    916  * a read() against @a finsig succeeds.
    917  *
    918  * @param cls closure
    919  * @param finsig fd to read from to detect termination request
    920  * @param[in,out] d daemon to run
    921  */
    922 void
    923 MHDT_server_run_external (void *cls,
    924                           int finsig,
    925                           struct MHD_Daemon *d);
    926 
    927 
    928 /**
    929  * Run test suite with @a phases for a daemon initialized
    930  * using @a ss_cb on the local machine.
    931  *
    932  * @param ss_cb setup logic for the daemon
    933  * @param ss_cb_cls closure for @a ss_cb
    934  * @param run_cb runs the daemon
    935  * @param run_cb_cls closure for @a run_cb
    936  * @param phases test phases to run in child processes
    937  * @return 0 on success, 77 if test was skipped,
    938  *         error code otherwise
    939  */
    940 int
    941 MHDT_test (MHDT_ServerSetup ss_cb,
    942            void *ss_cb_cls,
    943            MHDT_ServerRunner run_cb,
    944            void *run_cb_cls,
    945            struct MHDT_Phase *phases);
    946 
    947 #endif