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 "taler/taler_curl_lib.h"
25 :
26 :
27 : #if TALER_CURL_COMPRESS_BODIES
28 : #include <zlib.h>
29 : #endif
30 :
31 :
32 : void
33 924 : TALER_curl_set_secure_redirect_policy (CURL *eh,
34 : const char *url)
35 : {
36 924 : GNUNET_assert (CURLE_OK ==
37 : curl_easy_setopt (eh,
38 : CURLOPT_FOLLOWLOCATION,
39 : 1L));
40 924 : GNUNET_assert ( (0 == strncasecmp (url,
41 : "https://",
42 : strlen ("https://"))) ||
43 : (0 == strncasecmp (url,
44 : "http://",
45 : strlen ("http://"))) );
46 : #ifdef CURLOPT_REDIR_PROTOCOLS_STR
47 : if (0 == strncasecmp (url,
48 : "https://",
49 : strlen ("https://")))
50 : GNUNET_assert (CURLE_OK ==
51 : curl_easy_setopt (eh,
52 : CURLOPT_REDIR_PROTOCOLS_STR,
53 : "https"));
54 : else
55 : GNUNET_assert (CURLE_OK ==
56 : curl_easy_setopt (eh,
57 : CURLOPT_REDIR_PROTOCOLS_STR,
58 : "http,https"));
59 : #else
60 : #ifdef CURLOPT_REDIR_PROTOCOLS
61 : if (0 == strncasecmp (url,
62 : "https://",
63 : strlen ("https://")))
64 : GNUNET_assert (CURLE_OK ==
65 : curl_easy_setopt (eh,
66 : CURLOPT_REDIR_PROTOCOLS,
67 : CURLPROTO_HTTPS));
68 : else
69 : GNUNET_assert (CURLE_OK ==
70 : curl_easy_setopt (eh,
71 : CURLOPT_REDIR_PROTOCOLS,
72 : CURLPROTO_HTTP | CURLPROTO_HTTPS));
73 : #endif
74 : #endif
75 : /* limit MAXREDIRS to 5 as a simple security measure against
76 : a potential infinite loop caused by a malicious target */
77 924 : GNUNET_assert (CURLE_OK ==
78 : curl_easy_setopt (eh,
79 : CURLOPT_MAXREDIRS,
80 : 5L));
81 924 : }
82 :
83 :
84 : enum GNUNET_GenericReturnValue
85 877 : TALER_curl_easy_post (struct TALER_CURL_PostContext *ctx,
86 : CURL *eh,
87 : const json_t *body)
88 : {
89 : char *str;
90 : size_t slen;
91 :
92 877 : str = json_dumps (body,
93 : JSON_COMPACT);
94 877 : if (NULL == str)
95 : {
96 0 : GNUNET_break (0);
97 0 : return GNUNET_SYSERR;
98 : }
99 877 : slen = strlen (str);
100 877 : if (TALER_CURL_COMPRESS_BODIES &&
101 877 : (! ctx->disable_compression) )
102 : {
103 : Bytef *cbuf;
104 : uLongf cbuf_size;
105 : int ret;
106 :
107 877 : cbuf_size = compressBound (slen);
108 877 : cbuf = GNUNET_malloc (cbuf_size);
109 877 : ret = compress (cbuf,
110 : &cbuf_size,
111 : (const Bytef *) str,
112 : slen);
113 877 : if (Z_OK != ret)
114 : {
115 : /* compression failed!? */
116 0 : GNUNET_break (0);
117 0 : GNUNET_free (cbuf);
118 0 : return GNUNET_SYSERR;
119 : }
120 877 : free (str);
121 877 : slen = (size_t) cbuf_size;
122 877 : ctx->json_enc = (char *) cbuf;
123 877 : GNUNET_assert (
124 : NULL !=
125 : (ctx->headers = curl_slist_append (
126 : ctx->headers,
127 : "Content-Encoding: deflate")));
128 : }
129 : else
130 : {
131 0 : ctx->json_enc = str;
132 : }
133 877 : GNUNET_log (GNUNET_ERROR_TYPE_INFO,
134 : "Uploading JSON of %d bytes (%s)\n",
135 : (int) slen,
136 : (TALER_CURL_COMPRESS_BODIES &&
137 : (! ctx->disable_compression) )
138 : ? "compressed"
139 : : "uncompressed");
140 877 : GNUNET_assert (
141 : NULL !=
142 : (ctx->headers = curl_slist_append (
143 : ctx->headers,
144 : "Content-Type: application/json")));
145 :
146 877 : GNUNET_assert (CURLE_OK ==
147 : curl_easy_setopt (eh,
148 : CURLOPT_POSTFIELDS,
149 : ctx->json_enc));
150 877 : GNUNET_assert (CURLE_OK ==
151 : curl_easy_setopt (eh,
152 : CURLOPT_POSTFIELDSIZE,
153 : (long) slen));
154 877 : return GNUNET_OK;
155 : }
156 :
157 :
158 : void
159 887 : TALER_curl_easy_post_finished (struct TALER_CURL_PostContext *ctx)
160 : {
161 887 : curl_slist_free_all (ctx->headers);
162 887 : ctx->headers = NULL;
163 887 : GNUNET_free (ctx->json_enc);
164 887 : ctx->json_enc = NULL;
165 887 : }
|