paivana-httpd_helper.c (4755B)
1 /* 2 This file is part of GNUnet. 3 Copyright (C) 2026 Taler Systems SA 4 5 Paivana is free software; you can redistribute it and/or 6 modify it under the terms of the GNU General Public License 7 as published by the Free Software Foundation; either version 8 3, or (at your option) any later version. 9 10 Paivana is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty 12 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 13 the GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public 16 License along with Paivana; see the file COPYING. If not, 17 write to the Free Software Foundation, Inc., 51 Franklin 18 Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 */ 20 21 /** 22 * @author Christian Grothoff 23 * @file paivana-httpd_helper.c 24 * @brief helper functions 25 */ 26 #include "paivana-httpd.h" 27 #include "paivana-httpd_helper.h" 28 #include <taler/taler_mhd_lib.h> 29 30 bool 31 PAIVANA_HTTPD_get_client_address (struct MHD_Connection *connection, 32 void **ca, 33 size_t *ca_len) 34 { 35 const union MHD_ConnectionInfo *ci; 36 const struct sockaddr *sa; 37 const void *ip; 38 size_t ip_len; 39 40 *ca = NULL; 41 *ca_len = 0; 42 if (PH_respect_forwarded_headers) 43 { 44 const char *xff; 45 46 xff = MHD_lookup_connection_value (connection, 47 MHD_HEADER_KIND, 48 "X-Forwarded-For"); 49 if (NULL != xff) 50 { 51 const char *start = xff; 52 const char *end; 53 size_t len; 54 55 /* Use first part before ',', getting rid of whitespace 56 at start or end of the substring. */ 57 while ( (' ' == *start) || 58 ('\t' == *start) ) 59 start++; 60 end = strchr (start, 61 ','); 62 len = (NULL != end) 63 ? (size_t) (end - start) 64 : strlen (start); 65 while ( (len > 0) && 66 ( (' ' == start[len - 1]) || 67 ('\t' == start[len - 1]) ) ) 68 len--; 69 if (0 == len) 70 { 71 GNUNET_break_op (0); 72 return false; 73 } 74 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 75 "Client address is based on X-Forwarded-For: `%.*s'\n", 76 (int) len, 77 start); 78 *ca = GNUNET_strndup (start, 79 len); 80 *ca_len = len; 81 return true; 82 } 83 /* No header present: fall through to the socket address. */ 84 } 85 ci = MHD_get_connection_info (connection, 86 MHD_CONNECTION_INFO_CLIENT_ADDRESS); 87 GNUNET_assert (NULL != ci); 88 sa = ci->client_addr; 89 switch (sa->sa_family) 90 { 91 case AF_INET: 92 ip_len = sizeof (struct in_addr); 93 ip = &((const struct sockaddr_in *) sa)->sin_addr; 94 break; 95 case AF_INET6: 96 ip_len = sizeof (struct in6_addr); 97 ip = &((const struct sockaddr_in6 *) sa)->sin6_addr; 98 break; 99 default: 100 GNUNET_break (0); 101 return false; 102 } 103 *ca = GNUNET_memdup (ip, 104 ip_len); 105 *ca_len = ip_len; 106 return true; 107 } 108 109 110 bool 111 PAIVANA_HTTPD_get_base_url (struct MHD_Connection *connection, 112 struct GNUNET_Buffer *buf) 113 { 114 const char *host; 115 const char *forwarded_host; 116 const char *forwarded_port; 117 118 GNUNET_buffer_clear (buf); 119 if (NULL != PH_base_url) 120 { 121 GNUNET_buffer_write_str (buf, 122 PH_base_url); 123 return true; 124 } 125 if (GNUNET_YES == 126 TALER_mhd_is_https (connection)) 127 GNUNET_buffer_write_str (buf, 128 "https://"); 129 else 130 GNUNET_buffer_write_str (buf, 131 "http://"); 132 host = MHD_lookup_connection_value (connection, 133 MHD_HEADER_KIND, 134 MHD_HTTP_HEADER_HOST); 135 forwarded_host = MHD_lookup_connection_value (connection, 136 MHD_HEADER_KIND, 137 "X-Forwarded-Host"); 138 if (NULL != forwarded_host) 139 { 140 GNUNET_buffer_write_str (buf, 141 forwarded_host); 142 } 143 else 144 { 145 if (NULL == host) 146 { 147 GNUNET_break (0); 148 return false; 149 } 150 GNUNET_buffer_write_str (buf, 151 host); 152 } 153 forwarded_port = MHD_lookup_connection_value (connection, 154 MHD_HEADER_KIND, 155 "X-Forwarded-Port"); 156 if (NULL != forwarded_port) 157 { 158 GNUNET_buffer_write_str (buf, 159 ":"); 160 GNUNET_buffer_write_str (buf, 161 forwarded_port); 162 } 163 return true; 164 }