LCOV - code coverage report
Current view: top level - curl - curl.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 30 36 83.3 %
Date: 2025-06-05 21:03:14 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /*
       2             :   This file is part of TALER
       3             :   Copyright (C) 2019-2024 Taler Systems SA
       4             : 
       5             :   TALER is free software; you can redistribute it and/or modify it
       6             :   under the terms of the GNU General Public License as published
       7             :   by the Free Software Foundation; either version 3, or (at your
       8             :   option) any later version.
       9             : 
      10             :   TALER is distributed in the hope that it will be useful, but
      11             :   WITHOUT ANY WARRANTY; without even the implied warranty of
      12             :   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13             :   GNU General Public License for more details.
      14             : 
      15             :   You should have received a copy of the GNU General Public
      16             :   License along with TALER; see the file COPYING.  If not, see
      17             :   <http://www.gnu.org/licenses/>
      18             : */
      19             : /**
      20             :  * @file curl/curl.c
      21             :  * @brief Helper routines for interactions with libcurl
      22             :  * @author Christian Grothoff
      23             :  */
      24             : #include "platform.h"
      25             : #include "taler_curl_lib.h"
      26             : 
      27             : 
      28             : #if TALER_CURL_COMPRESS_BODIES
      29             : #include <zlib.h>
      30             : #endif
      31             : 
      32             : 
      33             : void
      34        4716 : TALER_curl_set_secure_redirect_policy (CURL *eh,
      35             :                                        const char *url)
      36             : {
      37        4716 :   GNUNET_assert (CURLE_OK ==
      38             :                  curl_easy_setopt (eh,
      39             :                                    CURLOPT_FOLLOWLOCATION,
      40             :                                    1L));
      41        4716 :   GNUNET_assert ( (0 == strncasecmp (url,
      42             :                                      "https://",
      43             :                                      strlen ("https://"))) ||
      44             :                   (0 == strncasecmp (url,
      45             :                                      "http://",
      46             :                                      strlen ("http://"))) );
      47             : #ifdef CURLOPT_REDIR_PROTOCOLS_STR
      48             :   if (0 == strncasecmp (url,
      49             :                         "https://",
      50             :                         strlen ("https://")))
      51             :     GNUNET_assert (CURLE_OK ==
      52             :                    curl_easy_setopt (eh,
      53             :                                      CURLOPT_REDIR_PROTOCOLS_STR,
      54             :                                      "https"));
      55             :   else
      56             :     GNUNET_assert (CURLE_OK ==
      57             :                    curl_easy_setopt (eh,
      58             :                                      CURLOPT_REDIR_PROTOCOLS_STR,
      59             :                                      "http,https"));
      60             : #else
      61             : #ifdef CURLOPT_REDIR_PROTOCOLS
      62             :   if (0 == strncasecmp (url,
      63             :                         "https://",
      64             :                         strlen ("https://")))
      65             :     GNUNET_assert (CURLE_OK ==
      66             :                    curl_easy_setopt (eh,
      67             :                                      CURLOPT_REDIR_PROTOCOLS,
      68             :                                      CURLPROTO_HTTPS));
      69             :   else
      70             :     GNUNET_assert (CURLE_OK ==
      71             :                    curl_easy_setopt (eh,
      72             :                                      CURLOPT_REDIR_PROTOCOLS,
      73             :                                      CURLPROTO_HTTP | CURLPROTO_HTTPS));
      74             : #endif
      75             : #endif
      76             :   /* limit MAXREDIRS to 5 as a simple security measure against
      77             :      a potential infinite loop caused by a malicious target */
      78        4716 :   GNUNET_assert (CURLE_OK ==
      79             :                  curl_easy_setopt (eh,
      80             :                                    CURLOPT_MAXREDIRS,
      81             :                                    5L));
      82        4716 : }
      83             : 
      84             : 
      85             : enum GNUNET_GenericReturnValue
      86        4673 : TALER_curl_easy_post (struct TALER_CURL_PostContext *ctx,
      87             :                       CURL *eh,
      88             :                       const json_t *body)
      89             : {
      90             :   char *str;
      91             :   size_t slen;
      92             : 
      93        4673 :   str = json_dumps (body,
      94             :                     JSON_COMPACT);
      95        4673 :   if (NULL == str)
      96             :   {
      97           0 :     GNUNET_break (0);
      98           0 :     return GNUNET_SYSERR;
      99             :   }
     100        4673 :   slen = strlen (str);
     101        4673 :   if (TALER_CURL_COMPRESS_BODIES &&
     102        4673 :       (! ctx->disable_compression) )
     103             :   {
     104             :     Bytef *cbuf;
     105             :     uLongf cbuf_size;
     106             :     int ret;
     107             : 
     108        4673 :     cbuf_size = compressBound (slen);
     109        4673 :     cbuf = GNUNET_malloc (cbuf_size);
     110        4673 :     ret = compress (cbuf,
     111             :                     &cbuf_size,
     112             :                     (const Bytef *) str,
     113             :                     slen);
     114        4673 :     if (Z_OK != ret)
     115             :     {
     116             :       /* compression failed!? */
     117           0 :       GNUNET_break (0);
     118           0 :       GNUNET_free (cbuf);
     119           0 :       return GNUNET_SYSERR;
     120             :     }
     121        4673 :     free (str);
     122        4673 :     slen = (size_t) cbuf_size;
     123        4673 :     ctx->json_enc = (char *) cbuf;
     124        4673 :     GNUNET_assert (
     125             :       NULL !=
     126             :       (ctx->headers = curl_slist_append (
     127             :          ctx->headers,
     128             :          "Content-Encoding: deflate")));
     129             :   }
     130             :   else
     131             :   {
     132           0 :     ctx->json_enc = str;
     133             :   }
     134        4673 :   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
     135             :               "Uploading JSON of %d bytes (%s)\n",
     136             :               (int) slen,
     137             :               (TALER_CURL_COMPRESS_BODIES &&
     138             :                (! ctx->disable_compression) )
     139             :               ? "compressed"
     140             :               : "uncompressed");
     141        4673 :   GNUNET_assert (
     142             :     NULL !=
     143             :     (ctx->headers = curl_slist_append (
     144             :        ctx->headers,
     145             :        "Content-Type: application/json")));
     146             : 
     147        4673 :   GNUNET_assert (CURLE_OK ==
     148             :                  curl_easy_setopt (eh,
     149             :                                    CURLOPT_POSTFIELDS,
     150             :                                    ctx->json_enc));
     151        4673 :   GNUNET_assert (CURLE_OK ==
     152             :                  curl_easy_setopt (eh,
     153             :                                    CURLOPT_POSTFIELDSIZE,
     154             :                                    (long) slen));
     155        4673 :   return GNUNET_OK;
     156             : }
     157             : 
     158             : 
     159             : void
     160        4703 : TALER_curl_easy_post_finished (struct TALER_CURL_PostContext *ctx)
     161             : {
     162        4703 :   curl_slist_free_all (ctx->headers);
     163        4703 :   ctx->headers = NULL;
     164        4703 :   GNUNET_free (ctx->json_enc);
     165        4703 :   ctx->json_enc = NULL;
     166        4703 : }

Generated by: LCOV version 1.16