Skip to content

Commit 742e99f

Browse files
committed
Minor refactor to cURL backend.
* Fix error in cURL backend * Add Windows support
1 parent 519c8ca commit 742e99f

File tree

2 files changed

+66
-22
lines changed

2 files changed

+66
-22
lines changed

src/generic/CurlClient.cpp

+65-22
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,80 @@
1+
#ifdef _WIN32
2+
#define NOMINMAX
3+
#define WIN32_LEAN_AND_MEAN
4+
#endif
5+
16
#include "CurlClient.h"
27

38
#ifdef HTTPS_BACKEND_CURL
49

510
#include <algorithm>
6-
#include <dlfcn.h>
711
#include <stdexcept>
812
#include <sstream>
913
#include <vector>
1014

15+
// Dynamic library loader
16+
#ifdef _WIN32
17+
#include <windows.h>
18+
#else
19+
#include <dlfcn.h>
20+
#endif
21+
1122
typedef struct StringReader
1223
{
1324
const std::string *str;
1425
size_t pos;
1526
} StringReader;
1627

17-
template<typename T> bool loadSymbol(void *handle, const char *name, T &out)
28+
template <class T>
29+
static inline bool loadSymbol(T &var, void *handle, const char *name)
1830
{
19-
out = (T) dlsym(handle, name);
20-
return out != nullptr;
31+
#ifdef _WIN32
32+
var = (T) GetProcAddress((HMODULE) handle, name);
33+
#else
34+
var = (T) dlsym(handle, name);
35+
#endif
36+
return var != nullptr;
2137
}
2238

2339
CurlClient::Curl::Curl()
24-
: loaded(false)
40+
: handle(nullptr)
41+
, loaded(false)
42+
, global_cleanup(nullptr)
43+
, easy_init(nullptr)
44+
, easy_cleanup(nullptr)
45+
, easy_setopt(nullptr)
46+
, easy_perform(nullptr)
47+
, easy_getinfo(nullptr)
48+
, slist_append(nullptr)
49+
, slist_free_all(nullptr)
2550
{
26-
void *handle = dlopen("libcurl.so", RTLD_LAZY);
51+
#ifdef _WIN32
52+
handle = (void *) LoadLibraryA("libcurl.dll");
53+
#else
54+
handle = dlopen("libcurl.so.4", RTLD_LAZY);
55+
#endif
2756
if (!handle)
2857
return;
2958

3059
// Load symbols
31-
void(*global_init)(long) = nullptr;
32-
if (!loadSymbol(handle, "curl_global_init", global_init))
60+
decltype(&curl_global_init) global_init = nullptr;
61+
if (!loadSymbol(global_init, handle, "curl_global_init"))
3362
return;
34-
if (!loadSymbol(handle, "curl_global_cleanup", global_cleanup))
63+
if (!loadSymbol(global_cleanup, handle, "curl_global_cleanup"))
3564
return;
36-
if (!loadSymbol(handle, "curl_easy_init", easy_init))
65+
if (!loadSymbol(easy_init, handle, "curl_easy_init"))
3766
return;
38-
if (!loadSymbol(handle, "curl_easy_cleanup", easy_cleanup))
67+
if (!loadSymbol(easy_cleanup, handle, "curl_easy_cleanup"))
3968
return;
40-
if (!loadSymbol(handle, "curl_easy_setopt", easy_setopt))
69+
if (!loadSymbol(easy_setopt, handle, "curl_easy_setopt"))
4170
return;
42-
if (!loadSymbol(handle, "curl_easy_perform", easy_perform))
71+
if (!loadSymbol(easy_perform, handle, "curl_easy_perform"))
4372
return;
44-
if (!loadSymbol(handle, "curl_easy_getinfo", easy_getinfo))
73+
if (!loadSymbol(easy_getinfo, handle, "curl_easy_getinfo"))
4574
return;
46-
if (!loadSymbol(handle, "curl_slist_append", slist_append))
75+
if (!loadSymbol(slist_append, handle, "curl_slist_append"))
4776
return;
48-
if (!loadSymbol(handle, "curl_slist_free_all", slist_free_all))
77+
if (!loadSymbol(slist_free_all, handle, "curl_slist_free_all"))
4978
return;
5079

5180
global_init(CURL_GLOBAL_DEFAULT);
@@ -56,6 +85,13 @@ CurlClient::Curl::~Curl()
5685
{
5786
if (loaded)
5887
global_cleanup();
88+
89+
if (handle)
90+
#ifdef _WIN32
91+
FreeLibrary((HMODULE) handle);
92+
#else
93+
dlclose(handle);
94+
#endif
5995
}
6096

6197
static char toUppercase(char c)
@@ -69,12 +105,13 @@ static size_t stringReader(char *ptr, size_t size, size_t nmemb, StringReader *r
69105
const char *data = reader->str->data();
70106
size_t len = reader->str->length();
71107
size_t maxCount = (len - reader->pos) / size;
72-
size_t desiredBytes = std::min(maxCount, nmemb) * size;
108+
size_t desiredCount = std::min(maxCount, nmemb);
109+
size_t desiredBytes = desiredCount * size;
73110

74111
std::copy(data + reader->pos, data + desiredBytes, ptr);
75112
reader->pos += desiredBytes;
76113

77-
return desiredBytes;
114+
return desiredCount;
78115
}
79116

80117
static size_t stringstreamWriter(char *ptr, size_t size, size_t nmemb, std::stringstream *ss)
@@ -109,6 +146,9 @@ HTTPSClient::Reply CurlClient::request(const HTTPSClient::Request &req)
109146
Reply reply;
110147
reply.responseCode = 0;
111148

149+
// Use sensible default header for later
150+
HTTPSClient::header_map newHeaders = req.headers;
151+
112152
CURL *handle = curl.easy_init();
113153
if (!handle)
114154
throw std::runtime_error("Could not create curl request");
@@ -117,13 +157,13 @@ HTTPSClient::Reply CurlClient::request(const HTTPSClient::Request &req)
117157
curl.easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1L);
118158

119159
std::string method = req.method;
120-
if (method == "")
121-
method = "GET";
160+
if (method.empty())
161+
method = req.postdata.size() > 0 ? "POST" : "GET";
122162
else
123163
std::transform(method.begin(), method.end(), method.begin(), toUppercase);
124164
curl.easy_setopt(handle, CURLOPT_CUSTOMREQUEST, method.c_str());
125165

126-
StringReader reader;
166+
StringReader reader {};
127167

128168
if (req.postdata.size() > 0 && (method != "GET" && method != "HEAD"))
129169
{
@@ -133,11 +173,14 @@ HTTPSClient::Reply CurlClient::request(const HTTPSClient::Request &req)
133173
curl.easy_setopt(handle, CURLOPT_READFUNCTION, stringReader);
134174
curl.easy_setopt(handle, CURLOPT_READDATA, &reader);
135175
curl.easy_setopt(handle, CURLOPT_INFILESIZE_LARGE, (curl_off_t) req.postdata.length());
176+
177+
if (newHeaders.count("Content-Type") == 0)
178+
newHeaders["Content-Type"] = "application/x-www-form-urlencoded";
136179
}
137180

138181
// Curl doesn't copy memory, keep the strings around
139182
std::vector<std::string> lines;
140-
for (auto &header : req.headers)
183+
for (auto &header : newHeaders)
141184
{
142185
std::stringstream line;
143186
line << header.first << ": " << header.second;

src/generic/CurlClient.h

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class CurlClient : public HTTPSClient
1919
{
2020
Curl();
2121
~Curl();
22+
void *handle;
2223
bool loaded;
2324

2425
decltype(&curl_global_cleanup) global_cleanup;

0 commit comments

Comments
 (0)