libmicrohttpd2

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

mhd_response.h (8863B)


      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 Evgeny Grin (Karlson2k)
      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 src/mhd2/mhd_response.h
     41  * @brief  The definition of the MHD_Response type and related structures
     42  * @author Karlson2k (Evgeny Grin)
     43  */
     44 
     45 #ifndef MHD_RESPONSE_H
     46 #define MHD_RESPONSE_H 1
     47 
     48 #include "mhd_sys_options.h"
     49 
     50 #include "sys_bool_type.h"
     51 #include "sys_base_types.h"
     52 
     53 #include "mhd_public_api.h"
     54 
     55 #include "mhd_dlinked_list.h"
     56 #include "mhd_str_types.h"
     57 #ifdef MHD_SUPPORT_AUTH_DIGEST
     58 #  include "mhd_auth_digest_hdr.h"
     59 #endif
     60 
     61 #include "mhd_iovec.h"
     62 
     63 #ifdef MHD_SUPPORT_THREADS
     64 #  include "mhd_locks.h"
     65 #endif
     66 
     67 #include "mhd_atomic_counter.h"
     68 
     69 #ifdef MHD_SUPPORT_HTTP2
     70 #  include "h2/h2_resp_data.h"
     71 #endif
     72 
     73 
     74 struct ResponseOptions; /* forward declaration */
     75 
     76 struct mhd_ResponseHeader; /* forward declaration */
     77 
     78 mhd_DLINKEDL_LINKS_DEF (mhd_ResponseHeader);
     79 
     80 /**
     81  * Response header / field
     82  */
     83 struct mhd_ResponseHeader
     84 {
     85   /**
     86    * The name of the header / field
     87    */
     88   struct MHD_String name;
     89 
     90   /**
     91    * The value of the header / field
     92    */
     93   struct MHD_String value;
     94 
     95 #ifdef MHD_SUPPORT_HTTP2
     96   /**
     97    * HTTP/2-specific header / field data
     98    */
     99   struct mhd_H2ResponseHeader h2;
    100 #endif /* MHD_SUPPORT_HTTP2 */
    101 
    102   /**
    103    * The links to other headers
    104    */
    105   mhd_DLNKDL_LINKS (mhd_ResponseHeader,headers);
    106 };
    107 
    108 /**
    109  * The type of content
    110  */
    111 enum mhd_ResponseContentDataType
    112 {
    113   mhd_RESPONSE_CONTENT_DATA_INVALID = 0
    114   ,
    115   mhd_RESPONSE_CONTENT_DATA_BUFFER
    116   ,
    117   mhd_RESPONSE_CONTENT_DATA_IOVEC
    118   ,
    119   mhd_RESPONSE_CONTENT_DATA_FILE
    120   ,
    121   mhd_RESPONSE_CONTENT_DATA_CALLBACK
    122 };
    123 
    124 /**
    125  * I/O vector response data
    126  */
    127 struct mhd_ResponseIoVec
    128 {
    129   /**
    130    * The copy of array of iovec elements.
    131    * Must be freed!
    132    */
    133   mhd_iovec *iov;
    134 
    135   /**
    136    * The number of elements in the @a iov array
    137    */
    138   size_t cnt;
    139 };
    140 
    141 /**
    142  * The file data for the the response
    143  */
    144 struct mhd_ResponseFD
    145 {
    146   /**
    147    * The file description of the response
    148    */
    149   int fd;
    150 
    151   /**
    152    * The offset in the file of the response content
    153    */
    154   uint_fast64_t offset;
    155 
    156   /**
    157    * Indicate that @a fd is a pipe
    158    */
    159   bool is_pipe;
    160 
    161 #ifdef mhd_USE_SENDFILE
    162   /**
    163    * Use 'sendfile()' function for the @a FD
    164    * Initially 'true' (except for pipes) but can be flipped to 'false' if
    165    * sendfile() cannot handle this file.
    166    */
    167   volatile bool use_sf;
    168 #endif
    169 };
    170 
    171 /**
    172  * Dynamic response data
    173  */
    174 struct mhd_ResponseDynamic
    175 {
    176   /**
    177    * The callback for the content data
    178    */
    179   MHD_DynamicContentCreator cb;
    180   /**
    181    * The closure for the @a cb
    182    */
    183   void *cls;
    184 };
    185 
    186 /**
    187  * The response content data
    188  */
    189 union mhd_ResponseContent
    190 {
    191   /**
    192    * The fixed unmodifiable data.
    193    * 'unsigned char' pointer is used to simplify individual ranges addressing.
    194    */
    195   const unsigned char *restrict buf;
    196 
    197   /**
    198    * The I/O vector data
    199    */
    200   struct mhd_ResponseIoVec iovec;
    201 
    202   /**
    203    * The file data for the the response
    204    */
    205   struct mhd_ResponseFD file;
    206 
    207   /**
    208    * Dynamic response data
    209    */
    210   struct mhd_ResponseDynamic dyn;
    211 };
    212 
    213 /**
    214  * The data of the free/cleanup callback
    215  */
    216 struct mhd_FreeCbData
    217 {
    218   /**
    219    * The Free/Cleanup callback
    220    */
    221   MHD_FreeCallback cb;
    222 
    223   /**
    224    * The closure for the @a cb
    225    */
    226   void *cls;
    227 };
    228 
    229 
    230 struct mhd_ResponseReuseData
    231 {
    232   /**
    233    * Indicate that response could be used more than one time
    234    */
    235   volatile bool reusable;
    236 
    237   /**
    238    * The number of active uses of the response.
    239    * Used only when @a reusable is 'true'.
    240    * When number reached zero, the response is destroyed.
    241    */
    242   struct mhd_AtomicCounter counter;
    243 
    244 #ifdef MHD_SUPPORT_THREADS
    245   /**
    246    * The mutex for @a settings access.
    247    * Used only when @a reusable is 'true'.
    248    */
    249   mhd_mutex settings_lock;
    250 #endif /* MHD_SUPPORT_THREADS */
    251 };
    252 
    253 struct mhd_ResponseConfiguration
    254 {
    255   /**
    256    * Response have undefined content
    257    * Must be used only when response content (even zero-size) is not allowed.
    258    */
    259   bool head_only;
    260 
    261   /**
    262    * If set to 'true' then the chunked encoding must be used (if allowed
    263    * by HTTP version).
    264    * If 'false' then chunked encoding must not be used.
    265    */
    266   bool chunked;
    267 
    268   /**
    269    * If 'true', "Connection: close" header must be always used
    270    */
    271   bool close_forced;
    272 
    273   /**
    274    * Use "HTTP/1.0" in the reply header
    275    * @a chunked is 'false' if this flag set.
    276    * @a close_forced is 'true' is this flag set.
    277    */
    278   bool mode_1_0;
    279 
    280   /**
    281    * The (possible incorrect) content length is provided by application
    282    */
    283   bool cnt_len_by_app;
    284 
    285   /**
    286    * Response has "Date:" header
    287    */
    288   bool has_hdr_date; // TODO: set the member
    289 
    290   /**
    291    * Response has "Connection:" header
    292    */
    293   bool has_hdr_conn; // TODO: set the member
    294 
    295   /**
    296    * Response is internal-only error response
    297    */
    298   bool int_err_resp;
    299 
    300 #ifdef MHD_SUPPORT_AUTH_BASIC
    301   /**
    302    * Response has Basic Auth "challenge" header
    303    */
    304   bool has_bauth;
    305 #endif /* MHD_SUPPORT_AUTH_BASIC */
    306 };
    307 
    308 /**
    309  * Special data for internal error responses
    310  */
    311 struct mhd_ResponseInternalErrData
    312 {
    313   /**
    314    * The length of the @a spec_hdr
    315    */
    316   size_t spec_hdr_len;
    317   /**
    318    * The special header string.
    319    * The final CRLF is not included.
    320    * Must be deallocated if not NULL.
    321    */
    322   char *spec_hdr;
    323 };
    324 
    325 #ifndef NDEBUG
    326 struct mhd_ResponseDebug
    327 {
    328   bool is_internal;
    329 };
    330 #endif
    331 
    332 mhd_DLINKEDL_LIST_DEF (mhd_ResponseHeader);
    333 
    334 // TODO: Group members in structs
    335 
    336 struct MHD_Response
    337 {
    338   /**
    339    * The response HTTP status code
    340    */
    341   enum MHD_HTTP_StatusCode sc;
    342 
    343   /**
    344    * The size of the response.
    345    * #MHD_SIZE_UNKNOWN if size is undefined
    346    */
    347   uint_fast64_t cntn_size;
    348 
    349   /**
    350    * The type of the content data
    351    */
    352   enum mhd_ResponseContentDataType cntn_dtype;
    353 
    354   /**
    355    * The data of the content of the response
    356    */
    357   union mhd_ResponseContent cntn;
    358 
    359   /**
    360    * The data of the free/cleanup callback
    361    */
    362   struct mhd_FreeCbData free;
    363 
    364   /**
    365    * Configuration data of the response
    366    */
    367   struct mhd_ResponseConfiguration cfg;
    368 
    369   /**
    370    * If response is "frozen" then response data cannot be changed.
    371    * The use counter for re-usable responses is the exception and can be
    372    * changed when "frozen".
    373    */
    374   volatile bool frozen;
    375 
    376   /**
    377    * The re-use parameters
    378    */
    379   struct mhd_ResponseReuseData reuse;
    380 
    381   /**
    382    * The settings, before the response is @a frozen
    383    */
    384   struct ResponseOptions *restrict settings;
    385 
    386   /**
    387    * The double linked list of the response headers
    388    */
    389   mhd_DLNKDL_LIST (mhd_ResponseHeader,headers);
    390 
    391 #ifdef MHD_SUPPORT_AUTH_DIGEST
    392   /**
    393    * The double linked list of the Digest Auth response headers
    394    */
    395   mhd_DLNKDL_LIST (mhd_RespAuthDigestHeader,auth_d_hdrs);
    396 #endif
    397 
    398   /**
    399    * Special data for internal error responses
    400    */
    401   struct mhd_ResponseInternalErrData special_resp;
    402 
    403   /**
    404    * Should be always 'false' for the response lifetime
    405    */
    406   bool was_destroyed;
    407 
    408 #ifndef NDEBUG
    409   struct mhd_ResponseDebug dbg;
    410 #endif
    411 };
    412 
    413 /*
    414  * Check whether the response has Digest Auth headers
    415  */
    416 #ifdef MHD_SUPPORT_AUTH_DIGEST
    417 #define mhd_RESP_HAS_AUTH_DIGEST(resp) \
    418         (NULL != mhd_DLINKEDL_GET_FIRST (resp, auth_d_hdrs))
    419 #else
    420 #define mhd_RESP_HAS_AUTH_DIGEST(resp) (((void) (resp)), ! ! 0)
    421 #endif
    422 
    423 #endif /* ! MHD_RESPONSE_H */