Skip to content

Commit d042495

Browse files
committed
Don't link with cURL and OpenSSL libraries.
1 parent 464aca2 commit d042495

3 files changed

Lines changed: 90 additions & 38 deletions

File tree

src/CMakeLists.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,15 +113,15 @@ target_link_libraries (https https-common)
113113
if (USE_CURL_BACKEND)
114114
set(HTTPS_BACKEND_CURL ON)
115115
find_package (CURL REQUIRED)
116-
include_directories (${CURL_INCLUDE_DIR})
117-
target_link_libraries (https https-curl ${CURL_LIBRARIES})
116+
include_directories (${CURL_INCLUDE_DIRS})
117+
target_link_libraries (https https-curl)
118118
endif ()
119119

120120
if (USE_OPENSSL_BACKEND)
121121
set(HTTPS_BACKEND_OPENSSL ON)
122122
find_package (OpenSSL REQUIRED)
123123
include_directories (${OPENSSL_INCLUDE_DIR})
124-
target_link_libraries (https https-openssl ${OPENSSL_LIBRARIES})
124+
target_link_libraries (https https-openssl)
125125
endif ()
126126

127127
if (USE_SCHANNEL_BACKEND)

src/generic/CurlClient.cpp

Lines changed: 77 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,48 +2,91 @@
22

33
#ifdef HTTPS_BACKEND_CURL
44

5+
#include <algorithm>
56
#include <dlfcn.h>
67
#include <stdexcept>
78
#include <sstream>
89
#include <vector>
910

11+
typedef struct StringReader
12+
{
13+
const std::string *str;
14+
size_t pos;
15+
} StringReader;
16+
17+
template<typename T> bool loadSymbol(void *handle, const char *name, T &out)
18+
{
19+
out = (T) dlsym(handle, name);
20+
return out != nullptr;
21+
}
22+
1023
CurlClient::Curl::Curl()
24+
: loaded(false)
1125
{
1226
void *handle = dlopen("libcurl.so", RTLD_LAZY);
1327
if (!handle)
14-
{
15-
loaded = false;
1628
return;
17-
}
1829

19-
void (*global_init)() = (void(*)()) dlsym(handle, "curl_global_init");
20-
easy_init = (CURL*(*)()) dlsym(handle, "curl_easy_init");
21-
easy_cleanup = (void(*)(CURL*)) dlsym(handle, "curl_easy_cleanup");
22-
easy_setopt = (CURLcode(*)(CURL*,CURLoption,...)) dlsym(handle, "curl_easy_setopt");
23-
easy_perform = (CURLcode(*)(CURL*)) dlsym(handle, "curl_easy_perform");
24-
easy_getinfo = (CURLcode(*)(CURL*,CURLINFO,...)) dlsym(handle, "curl_easy_getinfo");
25-
slist_append = (curl_slist*(*)(curl_slist*,const char*)) dlsym(handle, "curl_slist_append");
26-
slist_free_all = (void(*)(curl_slist*)) dlsym(handle, "curl_slist_free_all");
30+
// Load symbols
31+
void(*global_init)(long) = nullptr;
32+
if (!loadSymbol(handle, "curl_global_init", global_init))
33+
return;
34+
if (!loadSymbol(handle, "curl_global_cleanup", global_cleanup))
35+
return;
36+
if (!loadSymbol(handle, "curl_easy_init", easy_init))
37+
return;
38+
if (!loadSymbol(handle, "curl_easy_cleanup", easy_cleanup))
39+
return;
40+
if (!loadSymbol(handle, "curl_easy_setopt", easy_setopt))
41+
return;
42+
if (!loadSymbol(handle, "curl_easy_perform", easy_perform))
43+
return;
44+
if (!loadSymbol(handle, "curl_easy_getinfo", easy_getinfo))
45+
return;
46+
if (!loadSymbol(handle, "curl_slist_append", slist_append))
47+
return;
48+
if (!loadSymbol(handle, "curl_slist_free_all", slist_free_all))
49+
return;
2750

28-
loaded = (global_init && easy_init && easy_cleanup && easy_setopt && easy_perform && easy_getinfo && slist_append && slist_free_all);
51+
global_init(CURL_GLOBAL_DEFAULT);
52+
loaded = true;
53+
}
2954

30-
if (!loaded)
31-
return;
55+
CurlClient::Curl::~Curl()
56+
{
57+
if (loaded)
58+
global_cleanup();
59+
}
3260

33-
global_init();
61+
static char toUppercase(char c)
62+
{
63+
int ch = (unsigned char) c;
64+
return toupper(ch);
3465
}
3566

36-
static size_t stringstreamWriter(char *ptr, size_t size, size_t nmemb, void *userdata)
67+
static size_t stringReader(char *ptr, size_t size, size_t nmemb, StringReader *reader)
68+
{
69+
const char *data = reader->str->data();
70+
size_t len = reader->str->length();
71+
size_t maxCount = (len - reader->pos) / size;
72+
size_t desiredBytes = std::min(maxCount, nmemb) * size;
73+
74+
std::copy(data + reader->pos, data + desiredBytes, ptr);
75+
reader->pos += desiredBytes;
76+
77+
return desiredBytes;
78+
}
79+
80+
static size_t stringstreamWriter(char *ptr, size_t size, size_t nmemb, std::stringstream *ss)
3781
{
38-
std::stringstream *ss = (std::stringstream*) userdata;
3982
size_t count = size*nmemb;
4083
ss->write(ptr, count);
4184
return count;
4285
}
4386

44-
static size_t headerWriter(char *ptr, size_t size, size_t nmemb, void *userdata)
87+
static size_t headerWriter(char *ptr, size_t size, size_t nmemb, std::map<std::string,std::string> *userdata)
4588
{
46-
std::map<std::string, std::string> &headers = *((std::map<std::string,std::string>*) userdata);
89+
std::map<std::string, std::string> &headers = *userdata;
4790
size_t count = size*nmemb;
4891
std::string line(ptr, count);
4992
size_t split = line.find(':');
@@ -64,7 +107,7 @@ bool CurlClient::valid() const
64107
HTTPSClient::Reply CurlClient::request(const HTTPSClient::Request &req)
65108
{
66109
Reply reply;
67-
reply.responseCode = 400;
110+
reply.responseCode = 0;
68111

69112
CURL *handle = curl.easy_init();
70113
if (!handle)
@@ -73,17 +116,23 @@ HTTPSClient::Reply CurlClient::request(const HTTPSClient::Request &req)
73116
curl.easy_setopt(handle, CURLOPT_URL, req.url.c_str());
74117
curl.easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1L);
75118

76-
if (req.method == "PUT")
77-
curl.easy_setopt(handle, CURLOPT_PUT, 1L);
78-
else if (req.method == "POST")
79-
curl.easy_setopt(handle, CURLOPT_POST, 1L);
119+
std::string method = req.method;
120+
if (method == "")
121+
method = "GET";
80122
else
81-
curl.easy_setopt(handle, CURLOPT_CUSTOMREQUEST, req.method.c_str());
123+
std::transform(method.begin(), method.end(), method.begin(), toUppercase);
124+
curl.easy_setopt(handle, CURLOPT_CUSTOMREQUEST, method.c_str());
125+
126+
StringReader reader;
82127

83-
if (req.postdata.size() > 0 && (req.method != "GET" && req.method != "HEAD"))
128+
if (req.postdata.size() > 0 && (method != "GET" && method != "HEAD"))
84129
{
85-
curl.easy_setopt(handle, CURLOPT_POSTFIELDS, req.postdata.c_str());
86-
curl.easy_setopt(handle, CURLOPT_POSTFIELDSIZE, req.postdata.size());
130+
reader.str = &req.postdata;
131+
reader.pos = 0;
132+
curl.easy_setopt(handle, CURLOPT_UPLOAD, 1L);
133+
curl.easy_setopt(handle, CURLOPT_READFUNCTION, stringReader);
134+
curl.easy_setopt(handle, CURLOPT_READDATA, &reader);
135+
curl.easy_setopt(handle, CURLOPT_INFILESIZE_LARGE, (curl_off_t) req.postdata.length());
87136
}
88137

89138
// Curl doesn't copy memory, keep the strings around

src/generic/CurlClient.h

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,19 @@ class CurlClient : public HTTPSClient
1818
static struct Curl
1919
{
2020
Curl();
21+
~Curl();
2122
bool loaded;
2223

23-
CURL *(*easy_init)();
24-
void (*easy_cleanup)(CURL *handle);
25-
CURLcode (*easy_setopt)(CURL *handle, CURLoption option, ...);
26-
CURLcode (*easy_perform)(CURL *easy_handle);
27-
CURLcode (*easy_getinfo)(CURL *curl, CURLINFO info, ...);
24+
decltype(&curl_global_cleanup) global_cleanup;
2825

29-
curl_slist *(*slist_append)(curl_slist *list, const char *string);
30-
void (*slist_free_all)(curl_slist *list);
26+
decltype(&curl_easy_init) easy_init;
27+
decltype(&curl_easy_cleanup) easy_cleanup;
28+
decltype(&curl_easy_setopt) easy_setopt;
29+
decltype(&curl_easy_perform) easy_perform;
30+
decltype(&curl_easy_getinfo) easy_getinfo;
31+
32+
decltype(&curl_slist_append) slist_append;
33+
decltype(&curl_slist_free_all) slist_free_all;
3134
} curl;
3235
};
3336

0 commit comments

Comments
 (0)