1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2021 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2019 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include <nel/web/http_client_curl.h>
23 #include <nel/misc/debug.h>
24 #include <nel/web/curl_certificates.h>
27 using namespace NLMISC
;
28 using namespace NLWEB
;
34 #define _Curl (CURL *)_CurlStruct
40 size_t CCurlHttpClient::writeDataFromCurl(void *buffer
, size_t size
, size_t nmemb
, void *pHttpClient
)
42 CCurlHttpClient
* httpClient
= static_cast<CCurlHttpClient
*>(pHttpClient
);
43 httpClient
->pushReceivedData((uint8
*)buffer
, (uint
)(size
*nmemb
));
47 // ***************************************************************************
48 bool CCurlHttpClient::connect(const std::string
&/* server */)
50 curl_version_info_data
*vdata
= curl_version_info(CURLVERSION_NOW
);
51 nldebug("Libcurl v%s", vdata
->version
);
52 if ((vdata
->features
& CURL_VERSION_SSL
) == 0)
53 nlwarning("SSL not supported");
55 curl_global_init(CURL_GLOBAL_ALL
);
56 _CurlStruct
= curl_easy_init();
59 curl_global_cleanup();
66 // ***************************************************************************
67 bool CCurlHttpClient::authenticate(const std::string
&user
, const std::string
&password
)
69 _Auth
= user
+ ":" + password
;
73 static const std::string CAFilename
= "cacert.pem"; // https://curl.haxx.se/docs/caextract.html
75 // ***************************************************************************
76 bool CCurlHttpClient::verifyServer(bool verify
)
78 curl_easy_setopt(_Curl
, CURLOPT_SSL_VERIFYHOST
, verify
? 2 : 0);
79 curl_easy_setopt(_Curl
, CURLOPT_SSL_VERIFYPEER
, verify
? 1 : 0);
81 // specify custom CA certs
82 CCurlCertificates::addCertificateFile(CAFilename
);
84 // if supported, use custom SSL context function to load certificates
85 CCurlCertificates::useCertificates(_Curl
);
90 // ***************************************************************************
91 bool CCurlHttpClient::sendRequest(const std::string
& methodWB
, const std::string
&url
, const std::string
&cookieName
, const std::string
&cookieValue
, const std::string
& postParams
, bool verbose
)
94 curl_easy_setopt(_Curl
, CURLOPT_VERBOSE
, 1);
97 curl_easy_setopt(_Curl
, CURLOPT_URL
, url
.c_str());
98 if (url
.length() > 8 && (url
[4] == 's' || url
[4] == 'S')) // 01234 https
100 curl_easy_setopt(_Curl
, CURLOPT_SSL_VERIFYPEER
, 1L);
101 curl_easy_setopt(_Curl
, CURLOPT_SSL_VERIFYHOST
, 2L);
107 curl_easy_setopt(_Curl
, CURLOPT_HTTPAUTH
, CURLAUTH_BASIC
); // TODO: CURLAUTH_ANY
108 curl_easy_setopt(_Curl
, CURLOPT_USERPWD
, _Auth
.c_str());
112 if ((methodWB
== "POST") && (!postParams
.empty()))
114 curl_easy_setopt(_Curl
, CURLOPT_POSTFIELDS
, postParams
.c_str());
117 if (!cookieName
.empty())
118 curl_easy_setopt(_Curl
, CURLOPT_COOKIE
, string(cookieName
+"="+cookieValue
).c_str());
120 // Include the header in the response
121 curl_easy_setopt(_Curl
, CURLOPT_HEADER
, 1);
123 // Register the receive callback
124 curl_easy_setopt(_Curl
, CURLOPT_WRITEFUNCTION
, CCurlHttpClient::writeDataFromCurl
);
125 curl_easy_setopt(_Curl
, CURLOPT_WRITEDATA
, this);
127 if (!m_ErrorBuf
.size())
128 m_ErrorBuf
.resize(CURL_ERROR_SIZE
+ 1);
129 m_ErrorBuf
[0] = '\0';
130 curl_easy_setopt(_Curl
, CURLOPT_ERRORBUFFER
, &m_ErrorBuf
[0]);
133 CURLcode res
= curl_easy_perform(_Curl
);
137 nlwarning(&m_ErrorBuf
[0]);
143 curl_easy_getinfo(_Curl
, CURLINFO_RESPONSE_CODE
, &r
);
146 nldebug("%u", (uint
)r
);
152 void CCurlHttpClient::pushReceivedData(uint8
*buffer
, uint size
)
154 _ReceiveBuffer
.insert(_ReceiveBuffer
.end(), buffer
, buffer
+size
);
157 // ***************************************************************************
158 bool CCurlHttpClient::sendGet(const string
&url
, const string
& params
, bool verbose
)
160 return sendRequest("GET", url
+ (params
.empty() ? "" : ("?" + params
)), string(), string(), string(), verbose
);
163 // ***************************************************************************
164 bool CCurlHttpClient::sendGetWithCookie(const string
&url
, const string
&name
, const string
&value
, const string
& params
, bool verbose
)
166 return sendRequest("GET", url
+ (params
.empty() ? "" : ("?" + params
)), name
, value
, string(), verbose
);
169 // ***************************************************************************
170 bool CCurlHttpClient::sendPost(const string
&url
, const string
& params
, bool verbose
)
172 return sendRequest("POST", url
, string(), string(), params
, verbose
);
175 // ***************************************************************************
176 bool CCurlHttpClient::sendPostWithCookie(const string
&url
, const string
&name
, const string
&value
, const string
& params
, bool verbose
)
178 return sendRequest("POST", url
, name
, value
, params
, verbose
);
181 // ***************************************************************************
182 bool CCurlHttpClient::receive(string
&res
, bool verbose
)
186 nldebug("Receiving %u bytes", (uint
)_ReceiveBuffer
.size());
190 if (!_ReceiveBuffer
.empty())
191 res
.assign((const char*)&(*(_ReceiveBuffer
.begin())), _ReceiveBuffer
.size());
192 _ReceiveBuffer
.clear();
196 // ***************************************************************************
197 void CCurlHttpClient::disconnect()
201 curl_easy_cleanup(_Curl
);
203 curl_global_cleanup();
207 CCurlHttpClient CurlHttpClient
;