libmicrohttpd2

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

request_get_info.c (15101B)


      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/request_get_info.c
     41  * @brief  The implementation of MHD_request_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_cntnr_ptr.h"
     53 
     54 #include "mhd_request.h"
     55 #include "mhd_connection.h"
     56 
     57 #include "daemon_funcs.h"
     58 
     59 #ifdef MHD_SUPPORT_AUTH_BASIC
     60 #  include "auth_basic.h"
     61 #endif
     62 #ifdef MHD_SUPPORT_AUTH_DIGEST
     63 #  include "auth_digest.h"
     64 #endif
     65 
     66 #ifdef MHD_SUPPORT_COOKIES
     67 #  include "mhd_daemon.h"
     68 #endif
     69 
     70 #include "mhd_public_api.h"
     71 
     72 MHD_EXTERN_ MHD_FN_MUST_CHECK_RESULT_
     73 MHD_FN_PAR_NONNULL_ (1)
     74 MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3) enum MHD_StatusCode
     75 MHD_request_get_info_fixed_sz (
     76   struct MHD_Request *MHD_RESTRICT request,
     77   enum MHD_RequestInfoFixedType info_type,
     78   union MHD_RequestInfoFixedData *MHD_RESTRICT output_buf,
     79   size_t output_buf_size)
     80 {
     81   switch (info_type)
     82   {
     83   case MHD_REQUEST_INFO_FIXED_HTTP_VER:
     84     if (mhd_HTTP_STAGE_REQ_LINE_RECEIVED >
     85         mhd_CNTNR_PTR (request, \
     86                        struct MHD_Connection, \
     87                        rq)->stage)
     88       return MHD_SC_TOO_EARLY;
     89     if (sizeof(output_buf->v_http_ver) > output_buf_size)
     90       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
     91     output_buf->v_http_ver = request->http_ver;
     92     return MHD_SC_OK;
     93   case MHD_REQUEST_INFO_FIXED_HTTP_METHOD:
     94     if (mhd_HTTP_METHOD_NO_METHOD == request->http_mthd)
     95       return MHD_SC_TOO_EARLY;
     96     if (sizeof(output_buf->v_http_method) > output_buf_size)
     97       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
     98     output_buf->v_http_method = (enum MHD_HTTP_Method)request->http_mthd;
     99     return MHD_SC_OK;
    100   case MHD_REQUEST_INFO_FIXED_DAEMON:
    101     if (sizeof(output_buf->v_daemon) > output_buf_size)
    102       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    103     output_buf->v_daemon =
    104       mhd_daemon_get_master_daemon (mhd_CNTNR_PTR (request, \
    105                                                    struct MHD_Connection, \
    106                                                    rq)->daemon);
    107     return MHD_SC_OK;
    108   case MHD_REQUEST_INFO_FIXED_CONNECTION:
    109     if (sizeof(output_buf->v_connection) > output_buf_size)
    110       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    111     output_buf->v_connection =
    112       mhd_CNTNR_PTR (request, \
    113                      struct MHD_Connection, \
    114                      rq);
    115     return MHD_SC_OK;
    116   case MHD_REQUEST_INFO_FIXED_STREAM:
    117     if (sizeof(output_buf->v_stream) > output_buf_size)
    118       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    119     output_buf->v_stream =
    120       &(mhd_CNTNR_PTR (request, \
    121                        struct MHD_Connection, \
    122                        rq)->h1_stream);
    123     return MHD_SC_OK;
    124   case MHD_REQUEST_INFO_FIXED_APP_CONTEXT:
    125     if (sizeof(output_buf->v_app_context_ppvoid) > output_buf_size)
    126       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    127     output_buf->v_app_context_ppvoid = &(request->app_context);
    128     return MHD_SC_OK;
    129 
    130   case MHD_REQUEST_INFO_FIXED_SENTINEL:
    131   default:
    132     break;
    133   }
    134 
    135   return MHD_SC_INFO_GET_TYPE_UNKNOWN;
    136 }
    137 
    138 
    139 MHD_EXTERN_
    140 MHD_FN_PAR_NONNULL_ (1)
    141 MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3) enum MHD_StatusCode
    142 MHD_request_get_info_dynamic_sz (
    143   struct MHD_Request *MHD_RESTRICT request,
    144   enum MHD_RequestInfoDynamicType info_type,
    145   union MHD_RequestInfoDynamicData *MHD_RESTRICT output_buf,
    146   size_t output_buf_size)
    147 {
    148   switch (info_type)
    149   {
    150   case MHD_REQUEST_INFO_DYNAMIC_HTTP_METHOD_STRING:
    151     if (mhd_HTTP_STAGE_REQ_RECV_FINISHED >
    152         mhd_CNTNR_PTR (request, \
    153                        struct MHD_Connection, \
    154                        rq)->stage)
    155       return MHD_SC_TOO_LATE;
    156     if (0 == request->method.len)
    157       return MHD_SC_TOO_EARLY;
    158     if (sizeof(output_buf->v_http_method_string) > output_buf_size)
    159       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    160     output_buf->v_http_method_string = request->method;
    161     return MHD_SC_OK;
    162   case MHD_REQUEST_INFO_DYNAMIC_URI:
    163     if (mhd_HTTP_STAGE_REQ_LINE_RECEIVED >
    164         mhd_CNTNR_PTR (request, \
    165                        struct MHD_Connection, \
    166                        rq)->stage)
    167       return MHD_SC_TOO_EARLY;
    168     if (mhd_HTTP_STAGE_REQ_RECV_FINISHED <
    169         mhd_CNTNR_PTR (request, \
    170                        struct MHD_Connection, \
    171                        rq)->stage)
    172       return MHD_SC_TOO_LATE;
    173     if (sizeof(output_buf->v_uri_string) > output_buf_size)
    174       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    175     output_buf->v_uri_string.cstr = request->url;
    176     output_buf->v_uri_string.len = request->url_len;
    177     return MHD_SC_OK;
    178   case MHD_REQUEST_INFO_DYNAMIC_NUMBER_URI_PARAMS:
    179     if (mhd_HTTP_STAGE_REQ_LINE_RECEIVED >
    180         mhd_CNTNR_PTR (request, \
    181                        struct MHD_Connection, \
    182                        rq)->stage)
    183       return MHD_SC_TOO_EARLY;
    184     if (mhd_HTTP_STAGE_REQ_RECV_FINISHED <
    185         mhd_CNTNR_PTR (request, \
    186                        struct MHD_Connection, \
    187                        rq)->stage)
    188       return MHD_SC_TOO_LATE;
    189     if (sizeof(output_buf->v_number_uri_params_sizet) > output_buf_size)
    190       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    191     output_buf->v_number_uri_params_sizet =
    192       MHD_request_get_values_cb (request,
    193                                  MHD_VK_URI_QUERY_PARAM,
    194                                  (MHD_NameValueIterator)NULL,
    195                                  NULL);
    196     return MHD_SC_OK;
    197   case MHD_REQUEST_INFO_DYNAMIC_NUMBER_COOKIES:
    198 #ifdef MHD_SUPPORT_COOKIES
    199     if (mhd_CNTNR_PTR (request, \
    200                        struct MHD_Connection, \
    201                        rq)->daemon->req_cfg.disable_cookies)
    202       return MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE;
    203     if (mhd_HTTP_STAGE_HEADERS_PROCESSED >
    204         mhd_CNTNR_PTR (request, \
    205                        struct MHD_Connection, \
    206                        rq)->stage)
    207       return MHD_SC_TOO_EARLY;
    208     if (mhd_HTTP_STAGE_REQ_RECV_FINISHED >
    209         mhd_CNTNR_PTR (request, \
    210                        struct MHD_Connection, \
    211                        rq)->stage)
    212       return MHD_SC_TOO_LATE;
    213     if (sizeof(output_buf->v_number_cookies_sizet) > output_buf_size)
    214       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    215     output_buf->v_number_cookies_sizet =
    216       MHD_request_get_values_cb (request,
    217                                  MHD_VK_COOKIE,
    218                                  (MHD_NameValueIterator)NULL,
    219                                  NULL);
    220     return MHD_SC_OK;
    221 #else
    222     return MHD_SC_FEATURE_DISABLED;
    223 #endif
    224     break;
    225   case MHD_REQUEST_INFO_DYNAMIC_HEADER_SIZE:
    226     if (mhd_HTTP_STAGE_HEADERS_PROCESSED >
    227         mhd_CNTNR_PTR (request, \
    228                        struct MHD_Connection, \
    229                        rq)->stage)
    230       return MHD_SC_TOO_EARLY;
    231     if (mhd_HTTP_STAGE_REQ_RECV_FINISHED <
    232         mhd_CNTNR_PTR (request, \
    233                        struct MHD_Connection, \
    234                        rq)->stage)
    235       return MHD_SC_TOO_LATE;
    236     if (sizeof(output_buf->v_header_size_sizet) > output_buf_size)
    237       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    238     output_buf->v_header_size_sizet = request->header_size;
    239     return MHD_SC_OK;
    240   case MHD_REQUEST_INFO_DYNAMIC_NUMBER_POST_PARAMS:
    241 #ifdef MHD_SUPPORT_POST_PARSER
    242     if (mhd_HTTP_STAGE_HEADERS_PROCESSED >
    243         mhd_CNTNR_PTR (request, \
    244                        struct MHD_Connection, \
    245                        rq)->stage)
    246       return MHD_SC_TOO_EARLY;
    247     if (mhd_HTTP_STAGE_REQ_RECV_FINISHED <
    248         mhd_CNTNR_PTR (request, \
    249                        struct MHD_Connection, \
    250                        rq)->stage)
    251       return MHD_SC_TOO_LATE;
    252     if (sizeof(output_buf->v_number_post_params_sizet) > output_buf_size)
    253       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    254     output_buf->v_number_post_params_sizet =
    255       MHD_request_get_values_cb (request,
    256                                  MHD_VK_POSTDATA,
    257                                  (MHD_NameValueIterator)NULL,
    258                                  NULL);
    259     return MHD_SC_OK;
    260 #else
    261     return MHD_SC_FEATURE_DISABLED;
    262 #endif
    263     break;
    264   case MHD_REQUEST_INFO_DYNAMIC_UPLOAD_PRESENT:
    265     if (mhd_HTTP_STAGE_HEADERS_PROCESSED >
    266         mhd_CNTNR_PTR (request, \
    267                        struct MHD_Connection, \
    268                        rq)->stage)
    269       return MHD_SC_TOO_EARLY;
    270     if (sizeof(output_buf->v_upload_present_bool) > output_buf_size)
    271       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    272     output_buf->v_upload_present_bool =
    273       request->cntn.cntn_present ? MHD_YES : MHD_NO;
    274     return MHD_SC_OK;
    275   case MHD_REQUEST_INFO_DYNAMIC_UPLOAD_CHUNKED:
    276     if (mhd_HTTP_STAGE_HEADERS_PROCESSED >
    277         mhd_CNTNR_PTR (request, \
    278                        struct MHD_Connection, \
    279                        rq)->stage)
    280       return MHD_SC_TOO_EARLY;
    281     if (sizeof(output_buf->v_upload_chunked_bool) > output_buf_size)
    282       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    283     output_buf->v_upload_chunked_bool =
    284       (MHD_SIZE_UNKNOWN == request->cntn.cntn_size) ? MHD_YES : MHD_NO;
    285     return MHD_SC_OK;
    286   case MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_TOTAL:
    287     if (mhd_HTTP_STAGE_HEADERS_PROCESSED >
    288         mhd_CNTNR_PTR (request, \
    289                        struct MHD_Connection, \
    290                        rq)->stage)
    291       return MHD_SC_TOO_EARLY;
    292     if (sizeof(output_buf->v_upload_size_total_uint64) > output_buf_size)
    293       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    294     output_buf->v_upload_size_total_uint64 = request->cntn.cntn_size;
    295     return MHD_SC_OK;
    296   case MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_RECIEVED:
    297     if (mhd_HTTP_STAGE_HEADERS_PROCESSED >
    298         mhd_CNTNR_PTR (request, \
    299                        struct MHD_Connection, \
    300                        rq)->stage)
    301       return MHD_SC_TOO_EARLY;
    302     if (sizeof(output_buf->v_upload_size_recieved_uint64) > output_buf_size)
    303       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    304     output_buf->v_upload_size_recieved_uint64 = request->cntn.recv_size;
    305     return MHD_SC_OK;
    306   case MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_TO_RECIEVE:
    307     if (mhd_HTTP_STAGE_HEADERS_PROCESSED >
    308         mhd_CNTNR_PTR (request, \
    309                        struct MHD_Connection, \
    310                        rq)->stage)
    311       return MHD_SC_TOO_EARLY;
    312     if (sizeof(output_buf->v_upload_size_to_recieve_uint64) > output_buf_size)
    313       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    314     output_buf->v_upload_size_to_recieve_uint64 =
    315       (MHD_SIZE_UNKNOWN == request->cntn.cntn_size) ?
    316       MHD_SIZE_UNKNOWN : (request->cntn.cntn_size - request->cntn.recv_size);
    317     return MHD_SC_OK;
    318   case MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_PROCESSED:
    319     if (mhd_HTTP_STAGE_HEADERS_PROCESSED >
    320         mhd_CNTNR_PTR (request, \
    321                        struct MHD_Connection, \
    322                        rq)->stage)
    323       return MHD_SC_TOO_EARLY;
    324     if (sizeof(output_buf->v_upload_size_processed_uint64) > output_buf_size)
    325       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    326     output_buf->v_upload_size_processed_uint64 = request->cntn.proc_size;
    327     return MHD_SC_OK;
    328   case MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_TO_PROCESS:
    329     if (mhd_HTTP_STAGE_HEADERS_PROCESSED >
    330         mhd_CNTNR_PTR (request, \
    331                        struct MHD_Connection, \
    332                        rq)->stage)
    333       return MHD_SC_TOO_EARLY;
    334     if (sizeof(output_buf->v_upload_size_to_process_uint64) > output_buf_size)
    335       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    336     output_buf->v_upload_size_to_process_uint64 =
    337       (MHD_SIZE_UNKNOWN == request->cntn.cntn_size) ?
    338       MHD_SIZE_UNKNOWN : (request->cntn.cntn_size - request->cntn.proc_size);
    339     return MHD_SC_OK;
    340   case MHD_REQUEST_INFO_DYNAMIC_AUTH_DIGEST_INFO:
    341     if (mhd_HTTP_STAGE_HEADERS_PROCESSED >
    342         mhd_CNTNR_PTR (request, \
    343                        struct MHD_Connection, \
    344                        rq)->stage)
    345       return MHD_SC_TOO_EARLY;
    346     if (mhd_HTTP_STAGE_REQ_RECV_FINISHED <
    347         mhd_CNTNR_PTR (request, \
    348                        struct MHD_Connection, \
    349                        rq)->stage)
    350       return MHD_SC_TOO_LATE;
    351 #ifdef MHD_SUPPORT_AUTH_DIGEST
    352     if (sizeof(output_buf->v_auth_basic_creds) > output_buf_size)
    353       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    354     return mhd_request_get_auth_digest_info (request,
    355                                              &(output_buf->
    356                                                v_auth_digest_info));
    357 #else  /* ! MHD_SUPPORT_AUTH_DIGEST */
    358     return MHD_SC_FEATURE_DISABLED;
    359 #endif /* ! MHD_SUPPORT_AUTH_DIGEST */
    360     break;
    361   case MHD_REQUEST_INFO_DYNAMIC_AUTH_BASIC_CREDS:
    362     if (mhd_HTTP_STAGE_HEADERS_PROCESSED >
    363         mhd_CNTNR_PTR (request, \
    364                        struct MHD_Connection, \
    365                        rq)->stage)
    366       return MHD_SC_TOO_EARLY;
    367     if (mhd_HTTP_STAGE_REQ_RECV_FINISHED <
    368         mhd_CNTNR_PTR (request, \
    369                        struct MHD_Connection, \
    370                        rq)->stage)
    371       return MHD_SC_TOO_LATE;
    372 #ifdef MHD_SUPPORT_AUTH_BASIC
    373     if (sizeof(output_buf->v_auth_basic_creds) > output_buf_size)
    374       return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
    375     return mhd_request_get_auth_basic_creds (request,
    376                                              &(output_buf->
    377                                                v_auth_basic_creds));
    378 #else  /* MHD_SUPPORT_AUTH_BASIC */
    379     return MHD_SC_FEATURE_DISABLED;
    380 #endif /* MHD_SUPPORT_AUTH_BASIC */
    381     break;
    382 
    383   case MHD_REQUEST_INFO_DYNAMIC_SENTINEL:
    384   default:
    385     break;
    386   }
    387 
    388   return MHD_SC_INFO_GET_TYPE_UNKNOWN;
    389 }