2#define WIN32_LEAN_AND_MEAN
4#pragma warning(disable: 4191
)
7#include "../IBaseApi.h"
14#include "Poco/StreamCopier.h"
16#include "Poco/Exception.h"
17#include "Poco/SharedPtr.h"
18#include "Poco/Net/SSLManager.h"
19#include <Poco/Net/InvalidCertificateHandler.h>
20#include <Poco/Net/RejectCertificateHandler.h>
21#include "Poco/Net/HTTPSClientSession.h"
22#include "Poco/Net/HTTPRequest.h"
23#include "Poco/Net/HTTPResponse.h"
25#include <Poco/UTF8String.h>
26#include <Poco/NullStream.h>
27#include "Poco/Net/Context.h"
28#include "Poco/Net/PrivateKeyPassphraseHandler.h"
29#include "Poco/Net/HTTPSClientSession.h"
30#include "Poco/Net/HTTPRequest.h"
31#include "Poco/Net/HTTPResponse.h"
43 std::string
GetResponse(Poco::Net::HTTPClientSession* session, Poco::Net::HTTPResponse& response);
62 Poco::Net::initializeSSL();
63 Poco::SharedPtr<Poco::Net::InvalidCertificateHandler> ptrCert =
new Poco::Net::RejectCertificateHandler(
false);
65 Poco::Net::Context::Ptr ptrContext =
new Poco::Net::Context(Poco::Net::Context::TLS_CLIENT_USE,
"",
"",
"", Poco::Net::Context::VERIFY_NONE, 9,
false,
"ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
67 Poco::Net::SSLManager::instance().initializeClient(0, ptrCert, ptrContext);
69 game_api->GetCommands()->AddOnTickCallback(
"RequestsUpdate", std::bind(&impl::Update,
this->pimpl.get()));
74 Poco::Net::uninitializeSSL();
75 game_api->GetCommands()->RemoveOnTickCallback(
"RequestsUpdate");
87 RequestsVec_.push_back({ callback, success, result });
95 const std::string& path(uri.getPathAndQuery());
97 if (uri.getScheme() ==
"https")
98 session =
new Poco::Net::HTTPSClientSession(uri.getHost(), uri.getPort());
100 session =
new Poco::Net::HTTPClientSession(uri.getHost(), uri.getPort());
102 Poco::Net::HTTPRequest request(request_type, path, Poco::Net::HTTPMessage::HTTP_1_1);
104 if (!headers.empty())
106 for (
const auto& header : headers)
108 const std::string& key = header.substr(0, header.find(
":"));
109 const std::string& data = header.substr(header.find(
":") + 1);
111 request.add(key, data);
120 std::string result =
"";
122 std::istream& rs = session->receiveResponse(response);
124 if (response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK)
126 std::ostringstream oss;
127 Poco::StreamCopier::copyStream(rs, oss);
132 Poco::NullOutputStream null;
133 Poco::StreamCopier::copyStream(rs, null);
134 result = std::to_string(response.getStatus()) +
" " + response.getReason();
141 std::vector<std::string> headers)
143 std::thread([
this, url, callback, headers]
145 std::string Result =
"";
146 Poco::Net::HTTPResponse response(Poco::Net::HTTPResponse::HTTP_BAD_REQUEST);
147 Poco::Net::HTTPClientSession* session =
nullptr;
151 Poco::Net::HTTPRequest&& request = pimpl->ConstructRequest(url, session, headers, Poco::Net::HTTPRequest::HTTP_GET);
153 session->sendRequest(request);
154 Result = pimpl->GetResponse(session, response);
156 catch (
const Poco::Exception& exc)
158 Log::GetLog()->error(exc.displayText());
161 const bool success = (
int)response.getStatus() >= 200
162 && (
int)response.getStatus() < 300;
164 pimpl->WriteRequest(callback, success, Result);
174 const std::string& post_data, std::vector<std::string> headers)
176 std::thread([
this, url, callback, post_data, headers]
178 std::string Result =
"";
179 Poco::Net::HTTPResponse response(Poco::Net::HTTPResponse::HTTP_BAD_REQUEST);
180 Poco::Net::HTTPClientSession* session =
nullptr;
184 Poco::Net::HTTPRequest&& request = pimpl->ConstructRequest(url, session, headers, Poco::Net::HTTPRequest::HTTP_POST);
186 request.setContentType(
"application/x-www-form-urlencoded");
187 request.setContentLength(post_data.length());
189 std::ostream& OutputStream = session->sendRequest(request);
190 OutputStream << post_data;
192 Result = pimpl->GetResponse(session, response);
194 catch (
const Poco::Exception& exc)
196 Log::GetLog()->error(exc.displayText());
199 const bool success = (
int)response.getStatus() >= 200
200 && (
int)response.getStatus() < 300;
202 pimpl->WriteRequest(callback, success, Result);
212 const std::string& post_data,
const std::string& content_type, std::vector<std::string> headers)
214 std::thread([
this, url, callback, post_data, content_type, headers]
216 std::string Result =
"";
217 Poco::Net::HTTPResponse response(Poco::Net::HTTPResponse::HTTP_BAD_REQUEST);
218 Poco::Net::HTTPClientSession* session =
nullptr;
222 Poco::Net::HTTPRequest&& request = pimpl->ConstructRequest(url, session, headers, Poco::Net::HTTPRequest::HTTP_POST);
224 request.setContentType(content_type);
225 request.setContentLength(post_data.length());
227 std::ostream& OutputStream = session->sendRequest(request);
228 OutputStream << post_data;
230 Result = pimpl->GetResponse(session, response);
232 catch (
const Poco::Exception& exc)
234 Log::GetLog()->error(exc.displayText());
237 const bool success = (
int)response.getStatus() >= 200
238 && (
int)response.getStatus() < 300;
240 pimpl->WriteRequest(callback, success, Result);
250 const std::vector<std::string>& post_ids,
251 const std::vector<std::string>& post_data, std::vector<std::string> headers)
253 if (post_ids.size() != post_data.size())
256 std::thread([
this, url, callback, post_ids, post_data, headers]
258 std::string Result =
"";
259 Poco::Net::HTTPResponse response(Poco::Net::HTTPResponse::HTTP_BAD_REQUEST);
260 Poco::Net::HTTPClientSession* session =
nullptr;
264 Poco::Net::HTTPRequest&& request = pimpl->ConstructRequest(url, session, headers, Poco::Net::HTTPRequest::HTTP_POST);
268 for (size_t i = 0; i < post_ids.size(); ++i)
270 const std::string& id = post_ids[i];
271 const std::string& data = post_data[i];
273 body += fmt::format(
"{}={}&", Poco::UTF8::escape(id), Poco::UTF8::escape(data));
278 request.setContentType(
"application/x-www-form-urlencoded");
279 request.setContentLength(body.size());
281 std::ostream& OutputStream = session->sendRequest(request);
282 OutputStream << body;
284 Result = pimpl->GetResponse(session, response);
286 catch (
const Poco::Exception& exc)
288 Log::GetLog()->error(exc.displayText());
291 const bool success = (
int)response.getStatus() >= 200
292 && (
int)response.getStatus() < 300;
294 pimpl->WriteRequest(callback, success, Result);
304 std::vector<std::string> headers)
306 std::thread([
this, url, callback, headers]
308 std::string Result =
"";
309 Poco::Net::HTTPResponse response(Poco::Net::HTTPResponse::HTTP_BAD_REQUEST);
310 Poco::Net::HTTPClientSession* session =
nullptr;
314 Poco::Net::HTTPRequest&& request = pimpl->ConstructRequest(url, session, headers, Poco::Net::HTTPRequest::HTTP_DELETE);
316 session->sendRequest(request);
317 Result = pimpl->GetResponse(session, response);
319 catch (
const Poco::Exception& exc)
321 Log::GetLog()->error(exc.displayText());
324 const bool success = (
int)response.getStatus() >= 200
325 && (
int)response.getStatus() < 300;
327 pimpl->WriteRequest(callback, success, Result);
336 bool Requests::DownloadFile(
const std::string& url,
const std::string& localPath, std::vector<std::string> headers)
338 Poco::Net::HTTPResponse response(Poco::Net::HTTPResponse::HTTP_BAD_REQUEST);
339 Poco::Net::HTTPClientSession* session =
nullptr;
343 Poco::Net::initializeSSL();
344 Poco::SharedPtr<Poco::Net::InvalidCertificateHandler> ptrCert =
new Poco::Net::RejectCertificateHandler(
false);
346 Poco::Net::Context::Ptr ptrContext =
new Poco::Net::Context(Poco::Net::Context::TLS_CLIENT_USE,
"",
"",
"", Poco::Net::Context::VERIFY_NONE, 9,
false,
"ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
348 Poco::Net::SSLManager::instance().initializeClient(0, ptrCert, ptrContext);
352 const std::string& path(uri.getPathAndQuery());
354 if (uri.getScheme() ==
"https")
355 session =
new Poco::Net::HTTPSClientSession(uri.getHost(), uri.getPort());
357 session =
new Poco::Net::HTTPClientSession(uri.getHost(), uri.getPort());
359 Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, path, Poco::Net::HTTPMessage::HTTP_1_1);
361 session->sendRequest(request);
362 std::istream& rs = session->receiveResponse(response);
363 if (response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK)
365 std::ofstream outFile(localPath, std::ios::binary);
368 Log::GetLog()->error(
"Writing the file '{}' failed", localPath);
374 Poco::StreamCopier::copyStream(rs, outFile);
378 Log::GetLog()->error(
"Requested file '{}' failed with error: '{}'", url, response.getReason());
379 Poco::NullOutputStream null;
380 Poco::StreamCopier::copyStream(rs, null);
386 catch (
const Poco::Exception& exc)
388 Log::GetLog()->error(exc.displayText());
402 if (RequestsVec_.empty())
406 std::vector<RequestData> requests_temp = std::move(RequestsVec_);
409 for (
const auto& request : requests_temp) { request.callback(request.success, request.result); }
void WriteRequest(std::function< void(bool, std::string)> callback, bool success, std::string result)
std::string GetResponse(Poco::Net::HTTPClientSession *session, Poco::Net::HTTPResponse &response)
Poco::Net::HTTPRequest ConstructRequest(const std::string &url, Poco::Net::HTTPClientSession *&session, const std::vector< std::string > &headers, const std::string &request_type)
std::vector< RequestData > RequestsVec_
ARK_API bool CreateGetRequest(const std::string &url, const std::function< void(bool, std::string)> &callback, std::vector< std::string > headers={})
Creates an async GET Request that runs in another thread but calls the callback from the main thread.
ARK_API bool CreatePostRequest(const std::string &url, const std::function< void(bool, std::string)> &callback, const std::vector< std::string > &post_ids, const std::vector< std::string > &post_data, std::vector< std::string > headers={})
Creates an async POST Request that runs in another thread but calls the callback from the main thread...
ARK_API bool CreateDeleteRequest(const std::string &url, const std::function< void(bool, std::string)> &callback, std::vector< std::string > headers={})
Creates an async DELETE Request that runs in another thread but calls the callback from the main thre...
ARK_API bool CreatePostRequest(const std::string &url, const std::function< void(bool, std::string)> &callback, const std::string &post_data, std::vector< std::string > headers={})
Creates an async POST Request with application/x-www-form-urlencoded content type that runs in anothe...
static ARK_API Requests & Get()
ARK_API bool CreatePostRequest(const std::string &url, const std::function< void(bool, std::string)> &callback, const std::string &post_data, const std::string &content_type, std::vector< std::string > headers={})
Creates an async POST Request that runs in another thread but calls the callback from the main thread...
std::function< void(bool, std::string)> callback