response_destroy.c (4432B)
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_destroy.c 41 * @brief The declarations of internal functions for response deletion 42 * @author Karlson2k (Evgeny Grin) 43 */ 44 45 #include "mhd_sys_options.h" 46 #include "response_destroy.h" 47 #include "mhd_response.h" 48 49 #include "mhd_assert.h" 50 #include "mhd_panic.h" 51 #include "mhd_atomic_counter.h" 52 53 #include "sys_malloc.h" 54 55 #include "mhd_public_api.h" 56 57 #include "response_add_header.h" 58 #include "response_funcs.h" 59 #include "response_from.h" 60 61 #ifdef MHD_SUPPORT_AUTH_DIGEST 62 # include "response_auth_digest.h" 63 #endif 64 65 #define mhd_RESPONSE_DESTOYED "Attempt to use destroyed response, " \ 66 "re-use non-reusable response or wrong MHD_Response pointer" 67 68 /** 69 * Perform full response de-initialisation, with cleaning-up / freeing 70 * all content data and headers. 71 * The response settings (if any) must be already freed. 72 * @param r the response to free 73 */ 74 static MHD_FN_PAR_NONNULL_ (1) void 75 response_full_deinit (struct MHD_Response *restrict r) 76 { 77 #ifdef MHD_SUPPORT_AUTH_DIGEST 78 mhd_response_remove_auth_digest_headers (r); 79 #endif 80 mhd_response_remove_all_headers (r); 81 if (NULL != r->special_resp.spec_hdr) 82 free (r->special_resp.spec_hdr); 83 if (r->reuse.reusable) 84 mhd_response_deinit_reusable (r); 85 mhd_response_deinit_content_data (r); 86 87 r->was_destroyed = true; 88 free (r); 89 } 90 91 92 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ void 93 mhd_response_dec_use_count (struct MHD_Response *restrict r) 94 { 95 mhd_assert (r->frozen); 96 if (r->was_destroyed) 97 MHD_PANIC (mhd_RESPONSE_DESTOYED); 98 99 if (r->reuse.reusable) 100 { 101 if (1 != mhd_atomic_counter_get_dec (&(r->reuse.counter))) 102 return; /* The response is still used somewhere */ 103 } 104 105 response_full_deinit (r); 106 } 107 108 109 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ void 110 mhd_response_inc_use_count (struct MHD_Response *restrict r) 111 { 112 mhd_assert (r->frozen); 113 if (r->was_destroyed) 114 MHD_PANIC (mhd_RESPONSE_DESTOYED); 115 116 if (! r->reuse.reusable) 117 return; 118 119 mhd_atomic_counter_inc (&(r->reuse.counter)); 120 } 121 122 123 MHD_EXTERN_ 124 MHD_FN_PAR_NONNULL_ (1) void 125 MHD_response_destroy (struct MHD_Response *response) 126 { 127 if (response->was_destroyed) 128 MHD_PANIC (mhd_RESPONSE_DESTOYED); 129 130 if (! response->frozen) 131 { 132 /* This response has been never used for actions */ 133 mhd_assert (NULL != response->settings); 134 free (response->settings); 135 #ifndef NDEBUG 136 /* Decrement counter to avoid triggering assert in deinit function */ 137 if (response->reuse.reusable) 138 mhd_assert (1 == mhd_atomic_counter_get_dec (&(response->reuse.counter))); 139 #endif 140 response_full_deinit (response); 141 return; 142 } 143 144 mhd_response_dec_use_count (response); 145 }