conn_get_info.c (7152B)
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) 2025 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/conn_get_info.c 41 * @brief The implementation of MHD_connection_get_info_*() functions 42 * @author Karlson2k (Evgeny Grin) 43 */ 44 45 #include "mhd_sys_options.h" 46 47 #include "mhd_assert.h" 48 #include "mhd_unreachable.h" 49 50 #include "mhd_connection.h" 51 52 #include "daemon_funcs.h" 53 #ifdef MHD_SUPPORT_HTTPS 54 # include "mhd_tls_funcs.h" 55 # include "mhd_tls_ver_stct.h" 56 #endif 57 58 #include "mhd_public_api.h" 59 60 MHD_EXTERN_ MHD_FN_MUST_CHECK_RESULT_ 61 MHD_FN_PAR_NONNULL_ (1) 62 MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3) enum MHD_StatusCode 63 MHD_connection_get_info_fixed_sz ( 64 struct MHD_Connection *MHD_RESTRICT connection, 65 enum MHD_ConnectionInfoFixedType info_type, 66 union MHD_ConnectionInfoFixedData *MHD_RESTRICT output_buf, 67 size_t output_buf_size) 68 { 69 switch (info_type) 70 { 71 case MHD_CONNECTION_INFO_FIXED_CLIENT_ADDRESS: 72 if (NULL == connection->sk.addr.data) 73 { 74 if (mhd_T_IS_NOT_YES (connection->sk.props.is_nonip)) 75 return MHD_SC_INFO_GET_TYPE_UNOBTAINABLE; 76 else 77 return MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE; 78 } 79 mhd_assert (0 != connection->sk.addr.size); 80 if (sizeof(output_buf->v_client_address_sa_info) > output_buf_size) 81 return MHD_SC_INFO_GET_BUFF_TOO_SMALL; 82 output_buf->v_client_address_sa_info.sa_size = connection->sk.addr.size; 83 output_buf->v_client_address_sa_info.sa = 84 (const struct sockaddr*) connection->sk.addr.data; 85 return MHD_SC_OK; 86 case MHD_CONNECTION_INFO_FIXED_CONNECTION_SOCKET: 87 if (sizeof(output_buf->v_connection_socket) > output_buf_size) 88 return MHD_SC_INFO_GET_BUFF_TOO_SMALL; 89 mhd_assert (MHD_INVALID_SOCKET != connection->sk.fd); 90 output_buf->v_connection_socket = connection->sk.fd; 91 return MHD_SC_OK; 92 case MHD_CONNECTION_INFO_FIXED_DAEMON: 93 if (sizeof(output_buf->v_daemon) > output_buf_size) 94 return MHD_SC_INFO_GET_BUFF_TOO_SMALL; 95 output_buf->v_daemon = mhd_daemon_get_master_daemon (connection->daemon); 96 return MHD_SC_OK; 97 case MHD_CONNECTION_INFO_FIXED_APP_CONTEXT: 98 if (sizeof(output_buf->v_app_context_ppvoid) > output_buf_size) 99 return MHD_SC_INFO_GET_BUFF_TOO_SMALL; 100 output_buf->v_app_context_ppvoid = &(connection->socket_context); 101 return MHD_SC_OK; 102 103 case MHD_CONNECTION_INFO_FIXED_SENTINEL: 104 default: 105 break; 106 } 107 return MHD_SC_INFO_GET_TYPE_UNKNOWN; 108 } 109 110 111 MHD_EXTERN_ MHD_FN_MUST_CHECK_RESULT_ 112 MHD_FN_PAR_NONNULL_ (1) 113 MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3) enum MHD_StatusCode 114 MHD_connection_get_info_dynamic_sz ( 115 struct MHD_Connection *MHD_RESTRICT connection, 116 enum MHD_ConnectionInfoDynamicType info_type, 117 union MHD_ConnectionInfoDynamicData *MHD_RESTRICT output_buf, 118 size_t output_buf_size) 119 { 120 switch (info_type) 121 { 122 case MHD_CONNECTION_INFO_DYNAMIC_HTTP_VER: 123 if (mhd_HTTP_STAGE_REQ_LINE_RECEIVED > connection->stage) 124 return MHD_SC_TOO_EARLY; 125 if (sizeof(output_buf->v_http_ver) > output_buf_size) 126 return MHD_SC_INFO_GET_BUFF_TOO_SMALL; 127 output_buf->v_http_ver = connection->rq.http_ver; 128 return MHD_SC_OK; 129 case MHD_CONNECTION_INFO_DYNAMIC_CONNECTION_TIMEOUT: 130 if (sizeof(output_buf->v_connection_timeout_uint) <= output_buf_size) 131 { 132 const uint_fast64_t tmout_ms = connection->connection_timeout_ms; 133 const unsigned int tmout = (unsigned int) (tmout_ms / 1000); 134 mhd_assert ((1000 * ((uint_fast64_t) tmout)) == tmout_ms); 135 output_buf->v_connection_timeout_uint = tmout; 136 return MHD_SC_OK; 137 } 138 return MHD_SC_INFO_GET_BUFF_TOO_SMALL; 139 case MHD_CONNECTION_INFO_DYNAMIC_CONNECTION_SUSPENDED: 140 if (sizeof(output_buf->v_connection_suspended_bool) > output_buf_size) 141 return MHD_SC_INFO_GET_BUFF_TOO_SMALL; 142 output_buf->v_connection_suspended_bool = 143 connection->suspended ? MHD_YES : MHD_NO; 144 return MHD_SC_OK; 145 case MHD_CONNECTION_INFO_DYNAMIC_TLS_VER: 146 #ifdef MHD_SUPPORT_HTTPS 147 if ((mhd_CONN_STATE_TCP_CONNECTED != connection->conn_state) && 148 (mhd_CONN_STATE_TLS_CONNECTED != connection->conn_state)) 149 { 150 if (mhd_CONN_FLAG_CLOSING > connection->conn_state) 151 return MHD_SC_TOO_EARLY; 152 else 153 return MHD_SC_TOO_LATE; 154 } 155 #endif 156 if (sizeof(output_buf->v_tls_ver) > output_buf_size) 157 return MHD_SC_INFO_GET_BUFF_TOO_SMALL; 158 if (! mhd_C_HAS_TLS (connection)) 159 output_buf->v_tls_ver = MHD_TLS_VERSION_NO_TLS; 160 else 161 { 162 #ifdef MHD_SUPPORT_HTTPS 163 struct mhd_StctTlsVersion stct_tls_ver; 164 if (! mhd_tls_conn_get_tls_ver (connection->tls, \ 165 &stct_tls_ver)) 166 return MHD_SC_INFO_GET_TYPE_UNOBTAINABLE; 167 output_buf->v_tls_ver = stct_tls_ver.tls_ver; 168 #else /* ! MHD_SUPPORT_HTTPS */ 169 mhd_UNREACHABLE (); 170 #endif /* ! MHD_SUPPORT_HTTPS */ 171 } 172 return MHD_SC_OK; 173 case MHD_CONNECTION_INFO_DYNAMIC_TLS_SESSION: 174 if (! mhd_C_HAS_TLS (connection)) 175 return MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE; 176 if (sizeof(output_buf->v_tls_session) > output_buf_size) 177 return MHD_SC_INFO_GET_BUFF_TOO_SMALL; 178 #ifndef MHD_SUPPORT_HTTPS 179 mhd_UNREACHABLE (); 180 return MHD_SC_INTERNAL_ERROR; 181 #else /* MHD_SUPPORT_HTTPS */ 182 mhd_tls_conn_get_tls_sess (connection->tls, &(output_buf->v_tls_session)); 183 #endif /* MHD_SUPPORT_HTTPS */ 184 break; 185 case MHD_CONNECTION_INFO_DYNAMIC_SENTINEL: 186 default: 187 break; 188 } 189 return MHD_SC_INFO_GET_TYPE_UNKNOWN; 190 }