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 }