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