]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/minicurl.cc
Merge branch 'master' into luarec
[thirdparty/pdns.git] / pdns / minicurl.cc
1 #include "minicurl.hh"
2 #include <curl/curl.h>
3 #include <stdexcept>
4
5 MiniCurl::MiniCurl()
6 {
7 d_curl = curl_easy_init();
8 }
9
10 MiniCurl::~MiniCurl()
11 {
12 curl_easy_cleanup(d_curl);
13 }
14
15 size_t MiniCurl::write_callback(char *ptr, size_t size, size_t nmemb, void *userdata)
16 {
17 MiniCurl* us = (MiniCurl*)userdata;
18 us->d_data.append(ptr, size*nmemb);
19 return size*nmemb;
20 }
21
22 static string extractHostFromURL(const std::string& url)
23 {
24 auto pos = url.find("://");
25 if(pos == string::npos)
26 throw runtime_error("Can't find host part of '"+url+"'");
27 pos += 3;
28 auto endpos = url.find('/', pos);
29 if(endpos == string::npos)
30 return url.substr(pos);
31
32 return url.substr(pos, endpos-pos);
33 }
34
35 void MiniCurl::setupURL(const std::string& str, const ComboAddress* rem, const ComboAddress* src)
36 {
37 if(rem) {
38 struct curl_slist *hostlist = NULL;
39
40 // url = http://hostname.enzo/url
41
42 string host4=extractHostFromURL(str);
43 string hcode=(host4+":80:"+rem->toString());
44 //cout<<"Setting hardcoded IP: "<<hcode<<endl;
45 hostlist = curl_slist_append(NULL, hcode.c_str());
46 hcode=(host4+":443:"+rem->toString());
47 // cout<<"Setting hardcoded IP: "<<hcode<<endl;;
48 hostlist = curl_slist_append(hostlist, hcode.c_str());
49
50 curl_easy_setopt(d_curl, CURLOPT_RESOLVE, hostlist);
51 }
52 if(src) {
53 curl_easy_setopt(d_curl, CURLOPT_INTERFACE, src->toString().c_str());
54 }
55 curl_easy_setopt(d_curl, CURLOPT_FOLLOWLOCATION, true);
56 /* only allow HTTP, TFTP and SFTP */
57 curl_easy_setopt(d_curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
58 curl_easy_setopt(d_curl, CURLOPT_SSL_VERIFYPEER, false);
59 curl_easy_setopt(d_curl, CURLOPT_SSL_VERIFYHOST, false);
60 curl_easy_setopt(d_curl, CURLOPT_FAILONERROR, true);
61 curl_easy_setopt(d_curl, CURLOPT_URL, str.c_str());
62 curl_easy_setopt(d_curl, CURLOPT_WRITEFUNCTION, write_callback);
63 curl_easy_setopt(d_curl, CURLOPT_WRITEDATA, this);
64 curl_easy_setopt(d_curl, CURLOPT_TIMEOUT, 2L);
65
66 d_data.clear();
67 }
68 std::string MiniCurl::getURL(const std::string& str, const ComboAddress* rem, const ComboAddress* src)
69 {
70 setupURL(str, rem, src);
71 auto res = curl_easy_perform(d_curl);
72 long http_code = 0;
73 curl_easy_getinfo(d_curl, CURLINFO_RESPONSE_CODE, &http_code);
74
75 if(res != CURLE_OK || http_code != 200) {
76 throw std::runtime_error("Unable to retrieve URL ("+std::to_string(http_code)+"): "+string(curl_easy_strerror(res)));
77 }
78 std::string ret=d_data;
79 d_data.clear();
80 return ret;
81 }
82
83 std::string MiniCurl::postURL(const std::string& str, const std::string& postdata)
84 {
85 setupURL(str);
86 curl_easy_setopt(d_curl, CURLOPT_POSTFIELDS, postdata.c_str());
87
88 auto res = curl_easy_perform(d_curl);
89 if(res != CURLE_OK)
90 throw std::runtime_error("Unable to post URL");
91
92 std::string ret=d_data;
93
94 d_data.clear();
95 return ret;
96 }