libmicrohttpd2

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

lib_get_info.c (20739B)


      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-2026 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/lib_get_info.c
     41  * @brief  The implementation of MHD_lib_get_info_*() functions
     42  * @author Karlson2k (Evgeny Grin)
     43  */
     44 
     45 #include "mhd_sys_options.h"
     46 
     47 #include "sys_bool_type.h"
     48 #include "sys_base_types.h"
     49 
     50 #include "mhd_assert.h"
     51 
     52 #include "mhd_str_types.h"
     53 #include "mhd_str_macros.h"
     54 
     55 #include <string.h>
     56 
     57 #include "sys_sockets_headers.h"
     58 #include "sys_ip_headers.h"
     59 
     60 #ifdef MHD_SUPPORT_THREADS
     61 #  include "mhd_threads.h"
     62 #endif
     63 
     64 #include "mhd_itc.h"
     65 
     66 #ifndef VERSION
     67 #  include "mhd_str.h"
     68 #endif
     69 
     70 #ifdef MHD_SUPPORT_HTTPS
     71 #  include "mhd_tls_choice.h"
     72 /* Include all supported TLS backends headers */
     73 #  if defined(MHD_SUPPORT_GNUTLS)
     74 #    include "tls_gnu_funcs.h"
     75 #  endif
     76 #  if defined(MHD_SUPPORT_OPENSSL)
     77 #    include "tls_open_funcs.h"
     78 #  endif
     79 #  if defined(MHD_SUPPORT_MBEDTLS)
     80 #    include "tls_mbed_funcs.h"
     81 #  endif
     82 #endif
     83 
     84 #ifdef MHD_SUPPORT_MD5
     85 #  include "mhd_md5.h"
     86 #endif
     87 #ifdef MHD_SUPPORT_SHA256
     88 #  include "mhd_sha256.h"
     89 #endif
     90 #ifdef MHD_SUPPORT_SHA512_256
     91 #  include "mhd_sha512_256.h"
     92 #endif
     93 
     94 #include "mhd_lib_init.h"
     95 
     96 #ifdef HAVE_SYS_TYPES_H
     97 #  include <sys/types.h>
     98 #endif
     99 
    100 #include "mhd_public_api.h"
    101 
    102 
    103 MHD_EXTERN_
    104 MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_OUT_ (2) enum MHD_StatusCode
    105 MHD_lib_get_info_fixed_sz (enum MHD_LibInfoFixed info_type,
    106                            union MHD_LibInfoFixedData *MHD_RESTRICT output_buf,
    107                            size_t output_buf_size)
    108 {
    109   if (0 != output_buf_size)
    110     memset (output_buf, 0, output_buf_size); /* For forward-compatibility */
    111 
    112   switch (info_type)
    113   {
    114 
    115   /* * Basic MHD information * */
    116 
    117   case MHD_LIB_INFO_FIXED_VERSION_NUM:
    118     if (sizeof(output_buf->v_version_num_uint32) > output_buf_size)
    119       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    120 #if ! MHD_VERSION
    121 #error MHD_VERSION is not defined
    122 #endif
    123     output_buf->v_version_num_uint32 = (uint_fast32_t) MHD_VERSION;
    124     return MHD_SC_OK;
    125   case MHD_LIB_INFO_FIXED_VERSION_STRING:
    126     if (sizeof(output_buf->v_version_string) <= output_buf_size)
    127     {
    128 #ifdef VERSION
    129       static const struct MHD_String ver_str =
    130         mhd_MSTR_INIT (VERSION);
    131       output_buf->v_version_string = ver_str;
    132       return MHD_SC_OK;
    133 #else  /* ! VERSION */
    134       static char str_buf[10] =    /* Larger than needed */
    135       {0, 1, 1, 1, 1, 1, 1, 1, 1, 1};
    136       static size_t str_len = 0;
    137       if ((0 == str_len) ||
    138           (0 != str_buf[str_len]))
    139       {
    140         const uint_fast32_t ver_num = MHD_VERSION;
    141         size_t pos = 0;
    142 
    143         mhd_assert (0 == str_buf[0]);
    144 
    145         pos += mhd_uint32_to_strx ((ver_num >> 24) & 0xFFu,
    146                                    str_buf + pos,
    147                                    sizeof(str_buf) - 1 - pos);
    148         mhd_assert (1 <= pos);
    149         mhd_assert (2 >= pos);
    150 
    151         str_buf[pos++] = '.';
    152 
    153         pos += mhd_uint32_to_strx ((ver_num >> 16) & 0xFFu,
    154                                    str_buf + pos,
    155                                    sizeof(str_buf) - 1 - pos);
    156         mhd_assert (3 <= pos);
    157         mhd_assert (5 >= pos);
    158 
    159         str_buf[pos++] = '.';
    160 
    161         pos += mhd_uint32_to_strx ((ver_num >> 8) & 0xFFu,
    162                                    str_buf + pos,
    163                                    sizeof(str_buf) - 1 - pos);
    164         mhd_assert (5 <= pos);
    165         mhd_assert (8 >= pos);
    166         mhd_assert (sizeof(str_buf) > pos);
    167 
    168         str_buf[pos] = 0;
    169         str_len = pos;
    170       }
    171       output_buf->v_version_string.cstr = str_buf;
    172       output_buf->v_version_string.len = str_len;
    173       return MHD_SC_OK;
    174 #endif /* ! VERSION */
    175     }
    176     return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    177 
    178   /* * Basic MHD features, buid-time configurable * */
    179 
    180   case MHD_LIB_INFO_FIXED_SUPPORT_LOG_MESSAGES:
    181     if (sizeof(output_buf->v_support_log_messages_bool) > output_buf_size)
    182       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    183 #ifdef MHD_SUPPORT_LOG_FUNCTIONALITY
    184     output_buf->v_support_log_messages_bool = MHD_YES;
    185 #else
    186     output_buf->v_support_log_messages_bool = MHD_NO;
    187 #endif
    188     return MHD_SC_OK;
    189   case MHD_LIB_INFO_FIXED_SUPPORT_AUTO_REPLIES_BODIES:
    190     if (sizeof(output_buf->v_support_auto_replies_bodies_bool) >
    191         output_buf_size)
    192       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    193 #ifdef MHD_ENABLE_AUTO_MESSAGES_BODIES
    194     output_buf->v_support_auto_replies_bodies_bool = MHD_YES;
    195 #else
    196     output_buf->v_support_auto_replies_bodies_bool = MHD_NO;
    197 #endif
    198     return MHD_SC_OK;
    199   case MHD_LIB_INFO_FIXED_IS_NON_DEBUG:
    200     if (sizeof(output_buf->v_is_non_debug_bool) > output_buf_size)
    201       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    202 #ifdef NDEBUG
    203     output_buf->v_is_non_debug_bool = MHD_YES;
    204 #else
    205     output_buf->v_is_non_debug_bool = MHD_NO;
    206 #endif
    207     return MHD_SC_OK;
    208   case MHD_LIB_INFO_FIXED_SUPPORT_THREADS:
    209     if (sizeof(output_buf->v_support_threads_bool) > output_buf_size)
    210       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    211 #ifdef MHD_SUPPORT_THREADS
    212     output_buf->v_support_threads_bool = MHD_YES;
    213 #else
    214     output_buf->v_support_threads_bool = MHD_NO;
    215 #endif
    216     return MHD_SC_OK;
    217   case MHD_LIB_INFO_FIXED_SUPPORT_COOKIE_PARSER:
    218     if (sizeof(output_buf->v_support_cookie_parser_bool) > output_buf_size)
    219       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    220 #ifdef MHD_SUPPORT_COOKIES
    221     output_buf->v_support_cookie_parser_bool = MHD_YES;
    222 #else
    223     output_buf->v_support_cookie_parser_bool = MHD_NO;
    224 #endif
    225     return MHD_SC_OK;
    226   case MHD_LIB_INFO_FIXED_SUPPORT_POST_PARSER:
    227     if (sizeof(output_buf->v_support_post_parser_bool) > output_buf_size)
    228       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    229 #ifdef MHD_SUPPORT_POST_PARSER
    230     output_buf->v_support_post_parser_bool = MHD_YES;
    231 #else
    232     output_buf->v_support_post_parser_bool = MHD_NO;
    233 #endif
    234     return MHD_SC_OK;
    235   case MHD_LIB_INFO_FIXED_SUPPORT_UPGRADE:
    236     if (sizeof(output_buf->v_support_upgrade_bool) > output_buf_size)
    237       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    238 #ifdef MHD_SUPPORT_UPGRADE
    239     output_buf->v_support_upgrade_bool = MHD_YES;
    240 #else
    241     output_buf->v_support_upgrade_bool = MHD_NO;
    242 #endif
    243     return MHD_SC_OK;
    244   case MHD_LIB_INFO_FIXED_SUPPORT_AUTH_BASIC:
    245     if (sizeof(output_buf->v_support_auth_basic_bool) > output_buf_size)
    246       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    247 #ifdef MHD_SUPPORT_AUTH_BASIC
    248     output_buf->v_support_auth_basic_bool = MHD_YES;
    249 #else
    250     output_buf->v_support_auth_basic_bool = MHD_NO;
    251 #endif
    252     return MHD_SC_OK;
    253   case MHD_LIB_INFO_FIXED_SUPPORT_AUTH_DIGEST:
    254   case MHD_LIB_INFO_FIXED_SUPPORT_DIGEST_AUTH_RFC2069:
    255   case MHD_LIB_INFO_FIXED_SUPPORT_DIGEST_AUTH_USERHASH:
    256     /* Simplified code: values of 'v_support_auth_digest_bool',
    257        'v_support_digest_auth_rfc2069_bool' and
    258        'v_support_digest_auth_userhash_bool' are always the same.
    259        To minimise the code size, use only the first member. The application
    260        gets correct resulting values for all members. */
    261     if (sizeof(output_buf->v_support_auth_digest_bool) > output_buf_size)
    262       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    263 #ifdef MHD_SUPPORT_AUTH_DIGEST
    264     output_buf->v_support_auth_digest_bool = MHD_YES;
    265 #else
    266     output_buf->v_support_auth_digest_bool = MHD_NO;
    267 #endif
    268     return MHD_SC_OK;
    269   case MHD_LIB_INFO_FIXED_TYPE_DIGEST_AUTH_MD5:
    270     if (sizeof(output_buf->v_type_digest_auth_md5_algo_type) > output_buf_size)
    271       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    272 #if ! defined(MHD_SUPPORT_MD5)
    273     output_buf->v_type_digest_auth_md5_algo_type =
    274       MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_NOT_AVAILABLE;
    275 #elif ! defined(MHD_MD5_EXTR)
    276     output_buf->v_type_digest_auth_md5_algo_type =
    277       MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_BUILT_IN;
    278 #elif ! defined(mhd_MD5_HAS_EXT_ERROR)
    279     output_buf->v_type_digest_auth_md5_algo_type =
    280       MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_EXTERNAL_NEVER_FAIL;
    281 #else
    282     output_buf->v_type_digest_auth_md5_algo_type =
    283       MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_EXTERNAL_MAY_FAIL;
    284 #endif
    285     return MHD_SC_OK;
    286   case MHD_LIB_INFO_FIXED_TYPE_DIGEST_AUTH_SHA256:
    287     if (sizeof(output_buf->v_type_digest_auth_sha256_algo_type) >
    288         output_buf_size)
    289       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    290 #if ! defined(MHD_SUPPORT_SHA256)
    291     output_buf->v_type_digest_auth_sha256_algo_type =
    292       MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_NOT_AVAILABLE;
    293 #elif ! defined(MHD_SHA256_EXTR)
    294     output_buf->v_type_digest_auth_sha256_algo_type =
    295       MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_BUILT_IN;
    296 #elif ! defined(mhd_SHA256_HAS_EXT_ERROR)
    297     output_buf->v_type_digest_auth_sha256_algo_type =
    298       MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_EXTERNAL_NEVER_FAIL;
    299 #else
    300     output_buf->v_type_digest_auth_sha256_algo_type =
    301       MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_EXTERNAL_MAY_FAIL;
    302 #endif
    303     return MHD_SC_OK;
    304   case MHD_LIB_INFO_FIXED_TYPE_DIGEST_AUTH_SHA512_256:
    305     if (sizeof(output_buf->v_type_digest_auth_sha512_256_algo_type) >
    306         output_buf_size)
    307       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    308 #if ! defined(MHD_SUPPORT_SHA512_256)
    309     output_buf->v_type_digest_auth_sha512_256_algo_type =
    310       MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_NOT_AVAILABLE;
    311 #elif ! defined(MHD_SHA512_256_EXTR)
    312     output_buf->v_type_digest_auth_sha512_256_algo_type =
    313       MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_BUILT_IN;
    314 #elif ! defined(mhd_SHA512_256_HAS_EXT_ERROR)
    315     output_buf->v_type_digest_auth_sha512_256_algo_type =
    316       MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_EXTERNAL_NEVER_FAIL;
    317 #else
    318     output_buf->v_type_digest_auth_sha512_256_algo_type =
    319       MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_EXTERNAL_MAY_FAIL;
    320 #endif
    321     return MHD_SC_OK;
    322   case MHD_LIB_INFO_FIXED_SUPPORT_DIGEST_AUTH_AUTH_INT:
    323   case MHD_LIB_INFO_FIXED_SUPPORT_DIGEST_AUTH_ALGO_SESSION:
    324     /* Simplified code: values of 'v_support_digest_auth_auth_int_bool' and
    325        'v_support_digest_auth_algo_session_bool' are always the same.
    326        To minimise the code size, use only the first member. The application
    327        gets correct resulting values for all members. */
    328     if (sizeof(output_buf->v_support_digest_auth_auth_int_bool) >
    329         output_buf_size)
    330       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    331     output_buf->v_support_digest_auth_auth_int_bool = MHD_NO;
    332     return MHD_SC_OK;
    333 
    334   /* * Platform-dependent features, some are configurable at build-time * */
    335 
    336   case MHD_LIB_INFO_FIXED_TYPES_SOCKETS_POLLING:
    337     if (sizeof(output_buf->v_types_sockets_polling) > output_buf_size)
    338       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    339 #ifdef MHD_SUPPORT_SELECT
    340     output_buf->v_types_sockets_polling.func_select = MHD_YES;
    341 #else
    342     output_buf->v_types_sockets_polling.func_select = MHD_NO;
    343 #endif
    344 #ifdef MHD_SUPPORT_POLL
    345     output_buf->v_types_sockets_polling.func_poll = MHD_YES;
    346 #else
    347     output_buf->v_types_sockets_polling.func_poll = MHD_NO;
    348 #endif
    349 #ifdef MHD_SUPPORT_EPOLL
    350     output_buf->v_types_sockets_polling.tech_epoll = MHD_YES;
    351 #else
    352     output_buf->v_types_sockets_polling.tech_epoll = MHD_NO;
    353 #endif
    354 #ifdef MHD_SUPPORT_KQUEUE
    355     output_buf->v_types_sockets_polling.tech_kqueue = MHD_YES;
    356 #else
    357     output_buf->v_types_sockets_polling.tech_kqueue = MHD_NO;
    358 #endif
    359     return MHD_SC_OK;
    360   case MHD_LIB_INFO_FIXED_SUPPORT_AGGREGATE_FD:
    361     if (sizeof(output_buf->v_support_aggregate_fd_bool) > output_buf_size)
    362       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    363 #ifdef MHD_SUPPORT_EPOLL
    364     output_buf->v_support_aggregate_fd_bool = MHD_YES;
    365 #else
    366     output_buf->v_support_aggregate_fd_bool = MHD_NO;
    367 #endif
    368     return MHD_SC_OK;
    369   case MHD_LIB_INFO_FIXED_TYPE_IPV6:
    370     if (sizeof(output_buf->v_ipv6) > output_buf_size)
    371       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    372 #if ! defined(HAVE_INET6)
    373     output_buf->v_ipv6 = MHD_LIB_INFO_FIXED_IPV6_TYPE_NONE;
    374 #elif ! defined(HAVE_DCLR_IPV6_V6ONLY)
    375     output_buf->v_ipv6 = MHD_LIB_INFO_FIXED_IPV6_TYPE_DUAL_ONLY;
    376 #else
    377     output_buf->v_ipv6 = MHD_LIB_INFO_FIXED_IPV6_TYPE_IPV6_PURE;
    378 #endif
    379     return MHD_SC_OK;
    380   case MHD_LIB_INFO_FIXED_SUPPORT_TCP_FASTOPEN:
    381     if (sizeof(output_buf->v_support_tcp_fastopen_bool) > output_buf_size)
    382       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    383 #ifdef HAVE_DCLR_TCP_FASTOPEN
    384     output_buf->v_support_tcp_fastopen_bool = MHD_YES;
    385 #else
    386     output_buf->v_support_tcp_fastopen_bool = MHD_NO;
    387 #endif
    388     return MHD_SC_OK;
    389   case MHD_LIB_INFO_FIXED_HAS_AUTODETECT_BIND_PORT:
    390     if (sizeof(output_buf->v_has_autodetect_bind_port_bool) > output_buf_size)
    391       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    392 #ifdef MHD_USE_GETSOCKNAME
    393     output_buf->v_has_autodetect_bind_port_bool = MHD_YES;
    394 #else
    395     output_buf->v_has_autodetect_bind_port_bool = MHD_NO;
    396 #endif
    397     return MHD_SC_OK;
    398   case MHD_LIB_INFO_FIXED_HAS_SENDFILE:
    399     if (sizeof(output_buf->v_has_sendfile_bool) > output_buf_size)
    400       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    401 #ifdef mhd_USE_SENDFILE
    402     output_buf->v_has_sendfile_bool = MHD_YES;
    403 #else
    404     output_buf->v_has_sendfile_bool = MHD_NO;
    405 #endif
    406     return MHD_SC_OK;
    407   case MHD_LIB_INFO_FIXED_HAS_AUTOSUPPRESS_SIGPIPE_INT:
    408     if (sizeof(output_buf->v_has_autosuppress_sigpipe_int_bool) >
    409         output_buf_size)
    410       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    411 #if ! defined (mhd_SEND_SPIPE_SUPPRESS_NEEDED)
    412     output_buf->v_has_autosuppress_sigpipe_int_bool = MHD_YES;
    413 #elif defined (mhd_SEND_SPIPE_SUPPRESS_POSSIBLE) \
    414     || defined(mhd_HAVE_MHD_THREAD_BLOCK_SIGPIPE)
    415     output_buf->v_has_autosuppress_sigpipe_int_bool = MHD_YES;
    416 #else
    417     output_buf->v_has_autosuppress_sigpipe_int_bool = MHD_NO;
    418 #endif
    419     return MHD_SC_OK;
    420   case MHD_LIB_INFO_FIXED_HAS_AUTOSUPPRESS_SIGPIPE_EXT:
    421     if (sizeof(output_buf->v_has_autosuppress_sigpipe_ext_bool) >
    422         output_buf_size)
    423       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    424 #if ! defined (mhd_SEND_SPIPE_SUPPRESS_NEEDED)
    425     output_buf->v_has_autosuppress_sigpipe_ext_bool = MHD_YES;
    426 #elif defined (mhd_SEND_SPIPE_SUPPRESS_POSSIBLE)
    427     output_buf->v_has_autosuppress_sigpipe_ext_bool = MHD_YES;
    428 #else
    429     output_buf->v_has_autosuppress_sigpipe_ext_bool = MHD_NO;
    430 #endif
    431     return MHD_SC_OK;
    432   case MHD_LIB_INFO_FIXED_HAS_THREAD_NAMES:
    433     if (sizeof(output_buf->v_has_thread_names_bool) > output_buf_size)
    434       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    435 #ifdef mhd_USE_THREAD_NAME
    436     output_buf->v_has_thread_names_bool = MHD_YES;
    437 #else
    438     output_buf->v_has_thread_names_bool = MHD_NO;
    439 #endif
    440     return MHD_SC_OK;
    441   case MHD_LIB_INFO_FIXED_TYPE_ITC:
    442     if (sizeof(output_buf->v_type_itc) > output_buf_size)
    443       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    444 #if ! defined(MHD_SUPPORT_THREADS)
    445     output_buf->v_type_itc = MHD_LIB_INFO_FIXED_ITC_TYPE_NONE;
    446 #elif defined(MHD_ITC_SOCKETPAIR_)
    447     output_buf->v_type_itc = MHD_LIB_INFO_FIXED_ITC_TYPE_SOCKETPAIR;
    448 #elif defined(MHD_ITC_PIPE_)
    449     output_buf->v_type_itc = MHD_LIB_INFO_FIXED_ITC_TYPE_PIPE;
    450 #elif defined(MHD_ITC_EVENTFD_)
    451     output_buf->v_type_itc = MHD_LIB_INFO_FIXED_ITC_TYPE_EVENTFD;
    452 #else
    453 #error The type of ITC is not defined
    454 #endif
    455     return MHD_SC_OK;
    456   case MHD_LIB_INFO_FIXED_SUPPORT_LARGE_FILE:
    457     if (sizeof(output_buf->v_support_large_file_bool) > output_buf_size)
    458       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    459 #if ! defined(HAVE_PREAD) && defined(lseek64)
    460     output_buf->v_support_large_file_bool = MHD_YES;
    461 #elif defined(HAVE_PREAD64)
    462     output_buf->v_support_large_file_bool = MHD_YES;
    463 #elif defined(mhd_W32_NATIVE)
    464     output_buf->v_support_large_file_bool = MHD_YES;
    465 #else
    466     output_buf->v_support_large_file_bool =
    467       (0x7FFFFFFFFFFFFFFF == ((off_t) 0x7FFFFFFFFFFFFFFF)) ? MHD_YES : MHD_NO;
    468 #endif
    469     return MHD_SC_OK;
    470   case MHD_LIB_INFO_FIXED_TLS_BACKENDS:
    471   case MHD_LIB_INFO_FIXED_TLS_KEY_PASSWORD_BACKENDS: /* Both backends have support */
    472     /* Simplified code: values of 'v_tls_backends' and
    473        'v_tls_key_password_backends' are always the same.
    474        To minimise the code size, use only the first member. The application
    475        gets correct resulting values for all members. */
    476     if (sizeof(output_buf->v_tls_backends) <= output_buf_size)
    477     {
    478 #ifndef MHD_SUPPORT_HTTPS
    479       output_buf->v_tls_backends.tls_supported = MHD_NO;
    480       output_buf->v_tls_backends.backend_gnutls = MHD_NO;
    481       output_buf->v_tls_backends.backend_openssl = MHD_NO;
    482 #else
    483       output_buf->v_tls_backends.tls_supported = MHD_YES;
    484 #  ifdef MHD_SUPPORT_GNUTLS
    485       output_buf->v_tls_backends.backend_gnutls = MHD_YES;
    486 #  else  /* ! MHD_SUPPORT_GNUTLS */
    487       output_buf->v_tls_backends.backend_gnutls = MHD_NO;
    488 #  endif /* ! MHD_SUPPORT_GNUTLS */
    489 #  ifdef MHD_SUPPORT_OPENSSL
    490       output_buf->v_tls_backends.backend_openssl = MHD_YES;
    491 #  else  /* ! MHD_SUPPORT_OPENSSL */
    492       output_buf->v_tls_backends.backend_openssl = MHD_NO;
    493 #  endif /* ! MHD_SUPPORT_OPENSSL */
    494 #endif
    495       return MHD_SC_OK;
    496     }
    497     return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    498     break;
    499   case MHD_LIB_INFO_FIXED_SENTINEL:
    500   default:
    501     break;
    502   }
    503   return MHD_SC_INFO_GET_TYPE_UNKNOWN;
    504 }
    505 
    506 
    507 MHD_EXTERN_ MHD_FN_MUST_CHECK_RESULT_
    508 MHD_FN_PAR_NONNULL_ (2)
    509 MHD_FN_PAR_OUT_ (2) enum MHD_StatusCode
    510 MHD_lib_get_info_dynamic_sz (
    511   enum MHD_LibInfoDynamic info_type,
    512   union MHD_LibInfoDynamicData *MHD_RESTRICT output_buf,
    513   size_t output_buf_size)
    514 {
    515   if (0 != output_buf_size)
    516     memset (output_buf, 0, output_buf_size); /* For forward-compatibility */
    517 
    518   switch (info_type)
    519   {
    520   case MHD_LIB_INFO_DYNAMIC_INITED_FULLY_ONCE:
    521     if (sizeof(output_buf->v_inited_fully_once_bool) > output_buf_size)
    522       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    523     output_buf->v_inited_fully_once_bool =
    524       mhd_lib_is_fully_initialised_once () ? MHD_YES : MHD_NO;
    525     return MHD_SC_OK;
    526   case MHD_LIB_INFO_DYNAMIC_INITED_FULLY_NOW:
    527     if (sizeof(output_buf->v_inited_fully_now_bool) > output_buf_size)
    528       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    529     output_buf->v_inited_fully_now_bool =
    530       mhd_lib_is_fully_initialised_now () ? MHD_YES : MHD_NO;
    531     return MHD_SC_OK;
    532   case MHD_LIB_INFO_DYNAMIC_TYPE_TLS:
    533     if (sizeof(output_buf->v_tls_backends) <= output_buf_size)
    534     {
    535 #ifndef MHD_SUPPORT_HTTPS
    536       output_buf->v_tls_backends.tls_supported = MHD_NO;
    537       output_buf->v_tls_backends.backend_gnutls = MHD_NO;
    538       output_buf->v_tls_backends.backend_openssl = MHD_NO;
    539       output_buf->v_tls_backends.backend_mbedtls = MHD_NO;
    540 #else
    541       bool gnutls_avail;
    542       bool openssl_avail;
    543       bool mdedtls_avail;
    544 
    545       if (! mhd_lib_init_global_if_needed ())
    546         return MHD_SC_INFO_GET_TYPE_UNOBTAINABLE;
    547 
    548       gnutls_avail = mhd_tls_gnu_is_inited_fine ();
    549       openssl_avail = mhd_tls_open_is_inited_fine ();
    550       mdedtls_avail = mhd_tls_mbed_is_inited_fine ();
    551 
    552       output_buf->v_tls_backends.tls_supported =
    553         (gnutls_avail || openssl_avail) ? MHD_YES : MHD_NO;
    554       output_buf->v_tls_backends.backend_gnutls =
    555         gnutls_avail ? MHD_YES : MHD_NO;
    556       output_buf->v_tls_backends.backend_openssl =
    557         openssl_avail ? MHD_YES : MHD_NO;
    558       output_buf->v_tls_backends.backend_mbedtls =
    559         mdedtls_avail ? MHD_YES : MHD_NO;
    560 
    561       mhd_lib_deinit_global_if_needed ();
    562 #endif
    563       return MHD_SC_OK;
    564     }
    565     return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    566   case MHD_LIB_INFO_DYNAMIC_SENTINEL:
    567   default:
    568     break;
    569   }
    570   return MHD_SC_INFO_GET_TYPE_UNKNOWN;
    571 }