paivana

HTTP paywall reverse proxy
Log | Files | Refs | Submodules | README | LICENSE

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 }