/src/mhd2/src/mhd2/response_funcs.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/response_funcs.c |
41 | | * @brief The definition of the internal response helper functions |
42 | | * @author Karlson2k (Evgeny Grin) |
43 | | */ |
44 | | |
45 | | #include "mhd_sys_options.h" |
46 | | |
47 | | #include "sys_malloc.h" |
48 | | |
49 | | #include "mhd_assert.h" |
50 | | #include "sys_null_macro.h" |
51 | | #include "mhd_response.h" |
52 | | #include "response_funcs.h" |
53 | | #include "mhd_locks.h" |
54 | | #include "response_options.h" |
55 | | |
56 | | #include "mhd_atomic_counter.h" |
57 | | |
58 | | |
59 | | MHD_INTERNAL |
60 | | MHD_FN_PAR_NONNULL_ALL_ bool |
61 | | response_make_reusable (struct MHD_Response *restrict r) |
62 | 0 | { |
63 | 0 | mhd_assert (! r->reuse.reusable); |
64 | 0 | mhd_assert (! r->frozen); |
65 | 0 | mhd_assert (NULL != r->settings); |
66 | |
|
67 | 0 | if (mhd_mutex_init (&(r->reuse.settings_lock))) |
68 | 0 | { |
69 | 0 | if (mhd_atomic_counter_init (&(r->reuse.counter), 1)) |
70 | 0 | { |
71 | 0 | r->reuse.reusable = true; |
72 | 0 | return true; |
73 | 0 | } |
74 | 0 | (void) mhd_mutex_destroy (&(r->reuse.settings_lock)); |
75 | 0 | } |
76 | 0 | return false; |
77 | 0 | } |
78 | | |
79 | | |
80 | | MHD_INTERNAL |
81 | | MHD_FN_PAR_NONNULL_ALL_ void |
82 | | mhd_response_deinit_reusable (struct MHD_Response *restrict r) |
83 | 0 | { |
84 | 0 | mhd_assert (r->reuse.reusable); |
85 | 0 | mhd_assert (0 == mhd_atomic_counter_get (&(r->reuse.counter))); |
86 | |
|
87 | 0 | mhd_atomic_counter_deinit (&(r->reuse.counter)); |
88 | 0 | mhd_mutex_destroy_chk (&(r->reuse.settings_lock)); |
89 | 0 | } |
90 | | |
91 | | |
92 | | static MHD_FN_PAR_NONNULL_ALL_ void |
93 | | response_set_properties (struct MHD_Response *restrict r) |
94 | 0 | { |
95 | 0 | struct ResponseOptions *restrict const s = r->settings; |
96 | 0 | mhd_assert (NULL != s); |
97 | |
|
98 | 0 | r->cfg.head_only = s->head_only_response; |
99 | 0 | if (s->http_1_0_compatible_strict) |
100 | 0 | { |
101 | 0 | r->cfg.close_forced = true; |
102 | 0 | r->cfg.chunked = false; |
103 | 0 | r->cfg.mode_1_0 = s->http_1_0_server; |
104 | 0 | } |
105 | 0 | else if (s->http_1_0_server) |
106 | 0 | { |
107 | 0 | r->cfg.close_forced = s->conn_close || (MHD_SIZE_UNKNOWN == r->cntn_size); |
108 | 0 | r->cfg.chunked = false; |
109 | 0 | r->cfg.mode_1_0 = true; |
110 | 0 | } |
111 | 0 | else |
112 | 0 | { |
113 | 0 | r->cfg.close_forced = s->conn_close; |
114 | 0 | r->cfg.chunked = s->chunked_enc || (MHD_SIZE_UNKNOWN == r->cntn_size); |
115 | 0 | r->cfg.mode_1_0 = false; |
116 | 0 | } |
117 | |
|
118 | 0 | r->cfg.cnt_len_by_app = s->insanity_header_content_length; // TODO: set only if "content-lengh" header is used |
119 | | |
120 | | // TODO: calculate size of the headers and the "Connection:" header |
121 | |
|
122 | 0 | r->frozen = true; |
123 | |
|
124 | 0 | r->settings = NULL; |
125 | 0 | free (s); |
126 | 0 | } |
127 | | |
128 | | |
129 | | MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ void |
130 | | mhd_response_check_frozen_freeze (struct MHD_Response *restrict response) |
131 | 0 | { |
132 | 0 | bool need_unlock; |
133 | 0 | if (response->frozen) |
134 | 0 | return; |
135 | | |
136 | 0 | if (response->reuse.reusable) |
137 | 0 | { |
138 | 0 | mhd_mutex_lock_chk (&(response->reuse.settings_lock)); |
139 | 0 | need_unlock = true; |
140 | 0 | } |
141 | 0 | else |
142 | 0 | need_unlock = false; |
143 | |
|
144 | 0 | if (! response->frozen)/* Re-check under the lock */ |
145 | 0 | { |
146 | 0 | mhd_assert ((! response->reuse.reusable) || \ |
147 | 0 | (1 == mhd_atomic_counter_get (&(response->reuse.counter)))); |
148 | 0 | response_set_properties (response); |
149 | 0 | } |
150 | |
|
151 | 0 | if (need_unlock) |
152 | 0 | mhd_mutex_unlock_chk (&(response->reuse.settings_lock)); |
153 | 0 | } |