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 }