Ark Server API (ASE) - Wiki
Loading...
Searching...
No Matches
Requests.cpp
Go to the documentation of this file.
1#pragma once
2#define WIN32_LEAN_AND_MEAN
3
4#include <Requests.h>
5
6#include "../IBaseApi.h"
7
8#include <sstream>
9
10#include <mutex>
11
12#include <Poco/Net/HTTPSClientSession.h>
13#include <Poco/Net/HTTPRequest.h>
14#include <Poco/Net/HTTPResponse.h>
15#include <Poco/StreamCopier.h>
16#include <Poco/Path.h>
17#include <Poco/URI.h>
18#include <Poco/Exception.h>
19#include <Poco/UTF8String.h>
20#include <Poco/NullStream.h>
21#include <Poco/Net/SSLManager.h>
22#include <Poco/Net/InvalidCertificateHandler.h>
23#include <Poco/Net/RejectCertificateHandler.h>
24
25namespace API
26{
28 {
29 public:
30 void WriteRequest(std::function<void(bool, std::string)> callback, bool success, std::string result);
31
32 Poco::Net::HTTPRequest ConstructRequest(const std::string& url, Poco::Net::HTTPClientSession*& session,
33 const std::vector<std::string>& headers, const std::string& request_type);
34
35 std::string GetResponse(Poco::Net::HTTPClientSession* session, Poco::Net::HTTPResponse& response);
36
37 void Update();
38 private:
40 {
41 std::function<void(bool, std::string)> callback;
42 bool success;
43 std::string result;
44 };
45
48 };
49
51 : pimpl{ std::make_unique<impl>() }
52 {
55 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");
57
58 game_api->GetCommands()->AddOnTickCallback("RequestsUpdate", std::bind(&impl::Update, this->pimpl.get()));
59 }
60
62 {
65 }
66
68 {
69 static Requests instance;
70 return instance;
71 }
72
73 void Requests::impl::WriteRequest(std::function<void(bool, std::string)> callback, bool success, std::string result)
74 {
75 std::lock_guard<std::mutex> Guard(RequestMutex_);
76 RequestsVec_.push_back({ callback, success, result });
77 }
78
80 const std::vector<std::string>& headers, const std::string& request_type)
81 {
82 Poco::URI uri(url);
83
84 const std::string& path(uri.getPathAndQuery());
85
86 if (uri.getScheme() == "https")
88 else
89 session = new Poco::Net::HTTPClientSession(uri.getHost(), uri.getPort());
90
92
93 if (!headers.empty())
94 {
95 for (const auto& header : headers)
96 {
97 const std::string& key = header.substr(0, header.find(":"));
98 const std::string& data = header.substr(header.find(":") + 1);
99
100 request.add(key, data);
101 }
102 }
103
104 return request;
105 }
106
108 {
109 std::string result = "";
110
111 std::istream& rs = session->receiveResponse(response);
112
114 {
115 std::ostringstream oss;
116 Poco::StreamCopier::copyStream(rs, oss);
117 result = oss.str();
118 }
119 else
120 {
123 result = std::to_string(response.getStatus()) + " " + response.getReason();
124 }
125
126 return result;
127 }
128
129 bool Requests::CreateGetRequest(const std::string& url, const std::function<void(bool, std::string)>& callback,
130 std::vector<std::string> headers)
131 {
132 std::thread([this, url, callback, headers]
133 {
134 std::string Result = "";
136 Poco::Net::HTTPClientSession* session = nullptr;
137
138 try
139 {
141
142 session->sendRequest(request);
143 Result = pimpl->GetResponse(session, response);
144 }
145 catch (const Poco::Exception& exc)
146 {
148 }
149
150 const bool success = (int)response.getStatus() >= 200
151 && (int)response.getStatus() < 300;
152
153 pimpl->WriteRequest(callback, success, Result);
154 delete session;
155 session = nullptr;
156 }
157 ).detach();
158
159 return true;
160 }
161
162 bool Requests::CreatePostRequest(const std::string& url, const std::function<void(bool, std::string)>& callback,
163 const std::string& post_data, std::vector<std::string> headers)
164 {
165 std::thread([this, url, callback, post_data, headers]
166 {
167 std::string Result = "";
169 Poco::Net::HTTPClientSession* session = nullptr;
170
171 try
172 {
174
175 request.setContentType("application/x-www-form-urlencoded");
176 request.setContentLength(post_data.length());
177
178 std::ostream& OutputStream = session->sendRequest(request);
179 OutputStream << post_data;
180
181 Result = pimpl->GetResponse(session, response);
182 }
183 catch (const Poco::Exception& exc)
184 {
186 }
187
188 const bool success = (int)response.getStatus() >= 200
189 && (int)response.getStatus() < 300;
190
191 pimpl->WriteRequest(callback, success, Result);
192 delete session;
193 session = nullptr;
194 }
195 ).detach();
196
197 return true;
198 }
199
200 bool Requests::CreatePostRequest(const std::string& url, const std::function<void(bool, std::string)>& callback,
201 const std::string& post_data, const std::string& content_type, std::vector<std::string> headers)
202 {
203 std::thread([this, url, callback, post_data, content_type, headers]
204 {
205 std::string Result = "";
207 Poco::Net::HTTPClientSession* session = nullptr;
208
209 try
210 {
212
213 request.setContentType(content_type);
214 request.setContentLength(post_data.length());
215
216 std::ostream& OutputStream = session->sendRequest(request);
217 OutputStream << post_data;
218
219 Result = pimpl->GetResponse(session, response);
220 }
221 catch (const Poco::Exception& exc)
222 {
224 }
225
226 const bool success = (int)response.getStatus() >= 200
227 && (int)response.getStatus() < 300;
228
229 pimpl->WriteRequest(callback, success, Result);
230 delete session;
231 session = nullptr;
232 }
233 ).detach();
234
235 return true;
236 }
237
238 bool Requests::CreatePostRequest(const std::string& url, const std::function<void(bool, std::string)>& callback,
239 const std::vector<std::string>& post_ids,
240 const std::vector<std::string>& post_data, std::vector<std::string> headers)
241 {
242 if (post_ids.size() != post_data.size())
243 return false;
244
245 std::thread([this, url, callback, post_ids, post_data, headers]
246 {
247 std::string Result = "";
249 Poco::Net::HTTPClientSession* session = nullptr;
250
251 try
252 {
254
255 std::string body;
256
257 for (size_t i = 0; i < post_ids.size(); ++i)
258 {
259 const std::string& id = post_ids[i];
260 const std::string& data = post_data[i];
261
262 body += fmt::format("{}={}&", Poco::UTF8::escape(id), Poco::UTF8::escape(data));
263 }
264
265 body.pop_back(); // Remove last '&'
266
267 request.setContentType("application/x-www-form-urlencoded");
268 request.setContentLength(body.size());
269
270 std::ostream& OutputStream = session->sendRequest(request);
271 OutputStream << body;
272
273 Result = pimpl->GetResponse(session, response);
274 }
275 catch (const Poco::Exception& exc)
276 {
278 }
279
280 const bool success = (int)response.getStatus() >= 200
281 && (int)response.getStatus() < 300;
282
283 pimpl->WriteRequest(callback, success, Result);
284 delete session;
285 session = nullptr;
286 }
287 ).detach();
288
289 return true;
290 }
291
292 bool Requests::CreateDeleteRequest(const std::string& url, const std::function<void(bool, std::string)>& callback,
293 std::vector<std::string> headers)
294 {
295 std::thread([this, url, callback, headers]
296 {
297 std::string Result = "";
299 Poco::Net::HTTPClientSession* session = nullptr;
300
301 try
302 {
304
305 session->sendRequest(request);
306 Result = pimpl->GetResponse(session, response);
307 }
308 catch (const Poco::Exception& exc)
309 {
311 }
312
313 const bool success = (int)response.getStatus() >= 200
314 && (int)response.getStatus() < 300;
315
316 pimpl->WriteRequest(callback, success, Result);
317 delete session;
318 session = nullptr;
319 }
320 ).detach();
321
322 return true;
323 }
324
326 {
327 if (RequestsVec_.empty())
328 return;
329
330 RequestMutex_.lock();
331 std::vector<RequestData> requests_temp = std::move(RequestsVec_);
332 RequestMutex_.unlock();
333
334 for (const auto& request : requests_temp) { request.callback(request.success, request.result); }
335 }
336} // namespace API
virtual std::unique_ptr< ArkApi::ICommands > & GetCommands()=0
std::mutex RequestMutex_
Definition Requests.cpp:47
void WriteRequest(std::function< void(bool, std::string)> callback, bool success, std::string result)
Definition Requests.cpp:73
std::string GetResponse(Poco::Net::HTTPClientSession *session, Poco::Net::HTTPResponse &response)
Definition Requests.cpp:107
Poco::Net::HTTPRequest ConstructRequest(const std::string &url, Poco::Net::HTTPClientSession *&session, const std::vector< std::string > &headers, const std::string &request_type)
Definition Requests.cpp:79
std::vector< RequestData > RequestsVec_
Definition Requests.cpp:46
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.
Definition Requests.cpp:129
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...
Definition Requests.cpp:238
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...
Definition Requests.cpp:292
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...
Definition Requests.cpp:162
static ARK_API Requests & Get()
Definition Requests.cpp:67
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...
Definition Requests.cpp:200
std::unique_ptr< impl > pimpl
Definition Requests.h:84
virtual void AddOnTickCallback(const FString &id, const std::function< void(float)> &callback)=0
Added function will be called every frame.
virtual bool RemoveOnTickCallback(const FString &id)=0
Removes a on-tick callback.
Definition Logger.h:9
static std::shared_ptr< spdlog::logger > & GetLog()
Definition Logger.h:22
std::string displayText() const
Returns the exception code if defined.
virtual std::istream & receiveResponse(HTTPResponse &response)
virtual std::ostream & sendRequest(HTTPRequest &request)
Returns the connection timeout for HTTP connections.
static const std::string HTTP_1_1
void setContentLength(std::streamsize length)
Returns the HTTP version for this message.
HTTPRequest(const std::string &method, const std::string &uri, const std::string &version)
Creates a HTTP/1.0 request with the given method and URI.
static const std::string HTTP_GET
static const std::string HTTP_DELETE
static const std::string HTTP_POST
const std::string & getReason() const
Sets the HTTP reason phrase.
HTTPResponse(HTTPStatus status)
HTTPStatus getStatus() const
HTTPSClientSession(const std::string &host, Poco::UInt16 port=HTTPS_PORT)
RejectCertificateHandler(bool handleErrorsOnServerSide)
void initializeClient(PrivateKeyPassphraseHandlerPtr ptrPassphraseHandler, InvalidCertificateHandlerPtr ptrHandler, Context::Ptr ptrContext)
static SSLManager & instance()
This stream discards all characters written to it.
Definition NullStream.h:77
static std::streamsize copyStream(std::istream &istr, std::ostream &ostr, std::size_t bufferSize=8192)
const std::string & getHost() const
Sets the user-info part of the URI.
Definition URI.h:385
const std::string & getScheme() const
Definition URI.h:373
URI(const std::string &uri)
Creates an empty URI.
unsigned short getPort() const
Sets the host part of the URI.
std::string getPathAndQuery() const
Returns the encoded path, query and fragment parts of the URI.
void error(const T &)
Definition IBaseApi.h:9
std::unique_ptr< IBaseApi > game_api
Definition IBaseApi.h:25
void NetSSL_API initializeSSL()
void NetSSL_API uninitializeSSL()
Definition format.h:408
Definition json.hpp:4518
std::function< void(bool, std::string)> callback
Definition Requests.cpp:41
static std::string escape(const std::string &s, bool strictJSON=false)