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