]>
git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/minicurl.cc
4 * Copyright (c) 2018-2019 powerdns.com bv
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 #include "minicurl.hh"
26 #include <curl/curl.h>
31 d_curl
= curl_easy_init();
36 // NEEDS TO CLEAN HOSTLIST
37 curl_easy_cleanup(d_curl
);
40 size_t MiniCurl::write_callback(char *ptr
, size_t size
, size_t nmemb
, void *userdata
)
42 MiniCurl
* us
= (MiniCurl
*)userdata
;
43 us
->d_data
.append(ptr
, size
*nmemb
);
47 static string
extractHostFromURL(const std::string
& url
)
49 auto pos
= url
.find("://");
50 if(pos
== string::npos
)
51 throw runtime_error("Can't find host part of '"+url
+"'");
53 auto endpos
= url
.find('/', pos
);
54 if(endpos
== string::npos
)
55 return url
.substr(pos
);
57 return url
.substr(pos
, endpos
-pos
);
60 void MiniCurl::setupURL(const std::string
& str
, const ComboAddress
* rem
, const ComboAddress
* src
)
63 struct curl_slist
*hostlist
= nullptr; // THIS SHOULD BE FREED
65 // url = http://hostname.enzo/url
66 string host4
=extractHostFromURL(str
);
67 // doest the host contain port indication
68 std::size_t found
= host4
.find(':');
69 vector
<uint16_t> ports
{80, 443};
70 if (found
!= std::string::npos
) {
71 int port
= std::stoi(host4
.substr(found
+ 1));
72 if (port
<= 0 || port
> 65535)
73 throw std::overflow_error("Invalid port number");
74 ports
= {(uint16_t)port
};
75 host4
= host4
.substr(0, found
);
78 for (const auto& port
: ports
) {
79 string hcode
= boost::str(boost::format("%s:%u:%s") % host4
% port
% rem
->toString());
80 hostlist
= curl_slist_append(hostlist
, hcode
.c_str());
83 curl_easy_setopt(d_curl
, CURLOPT_RESOLVE
, hostlist
);
86 curl_easy_setopt(d_curl
, CURLOPT_INTERFACE
, src
->toString().c_str());
88 curl_easy_setopt(d_curl
, CURLOPT_FOLLOWLOCATION
, true);
89 /* only allow HTTP, TFTP and SFTP */
90 curl_easy_setopt(d_curl
, CURLOPT_PROTOCOLS
, CURLPROTO_HTTP
| CURLPROTO_HTTPS
);
91 curl_easy_setopt(d_curl
, CURLOPT_SSL_VERIFYPEER
, false);
92 curl_easy_setopt(d_curl
, CURLOPT_SSL_VERIFYHOST
, false);
93 curl_easy_setopt(d_curl
, CURLOPT_FAILONERROR
, true);
94 curl_easy_setopt(d_curl
, CURLOPT_URL
, str
.c_str());
95 curl_easy_setopt(d_curl
, CURLOPT_WRITEFUNCTION
, write_callback
);
96 curl_easy_setopt(d_curl
, CURLOPT_WRITEDATA
, this);
97 curl_easy_setopt(d_curl
, CURLOPT_TIMEOUT
, 2L);
101 std::string
MiniCurl::getURL(const std::string
& str
, const ComboAddress
* rem
, const ComboAddress
* src
)
103 setupURL(str
, rem
, src
);
104 auto res
= curl_easy_perform(d_curl
);
106 curl_easy_getinfo(d_curl
, CURLINFO_RESPONSE_CODE
, &http_code
);
108 if(res
!= CURLE_OK
|| http_code
!= 200) {
109 throw std::runtime_error("Unable to retrieve URL ("+std::to_string(http_code
)+"): "+string(curl_easy_strerror(res
)));
111 std::string ret
=d_data
;
116 std::string
MiniCurl::postURL(const std::string
& str
, const std::string
& postdata
)
119 curl_easy_setopt(d_curl
, CURLOPT_POSTFIELDS
, postdata
.c_str());
121 auto res
= curl_easy_perform(d_curl
);
123 throw std::runtime_error("Unable to post URL");
125 std::string ret
=d_data
;