libmicrohttpd2

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

request_get_info.c (14987B)


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