Kurlyk
Loading...
Searching...
No Matches
utils.hpp
Go to the documentation of this file.
1#pragma once
2#ifndef _KURLYK_HTTP_UTILS_HPP_INCLUDED
3#define _KURLYK_HTTP_UTILS_HPP_INCLUDED
4
7
8namespace kurlyk {
9
14 long create_rate_limit(long requests_per_period, long period_ms) {
15 return HttpRequestManager::get_instance().create_rate_limit(requests_per_period, period_ms);
16 }
17
21 long create_rate_limit_rpm(long requests_per_minute) {
22 long period_ms = 60000; // 1 minute in milliseconds
23 return HttpRequestManager::get_instance().create_rate_limit(requests_per_minute, period_ms);
24 }
25
29 long create_rate_limit_rps(long requests_per_second) {
30 long period_ms = 1000; // 1 second in milliseconds
31 return HttpRequestManager::get_instance().create_rate_limit(requests_per_second, period_ms);
32 }
33
37 bool remove_limit(long limit_id) {
39 }
40
46
50 void cancel_request_by_id(uint64_t request_id, std::function<void()> callback) {
51 HttpRequestManager::get_instance().cancel_request_by_id(request_id, std::move(callback));
53 }
54
58 std::future<void> cancel_request_by_id(uint64_t request_id) {
59 auto promise = std::make_shared<std::promise<void>>();
60 auto future = promise->get_future();
62 try {
63 promise->set_value();
64 } catch (const std::future_error& e) {
65 if (e.code() == std::make_error_condition(std::future_errc::promise_already_satisfied)) {
66 KURLYK_HANDLE_ERROR(e, "Promise already satisfied in HttpClient::request callback");
67 } else {
68 KURLYK_HANDLE_ERROR(e, "Future error in HttpClient::request callback");
69 }
70 } catch (const std::exception& e) {
71 KURLYK_HANDLE_ERROR(e, "Unhandled exception in HttpClient::request callback");
72 } catch (...) {
73 // Unknown fatal error in request callback
74 }
75 });
77 return future;
78 }
79
85 std::unique_ptr<HttpRequest> request_ptr,
86 HttpResponseCallback callback) {
87 const bool status = HttpRequestManager::get_instance().add_request(std::move(request_ptr), std::move(callback));
89 return status;
90 }
91
95 std::future<HttpResponsePtr> http_request(
96 std::unique_ptr<HttpRequest> request_ptr) {
97
98 auto promise = std::make_shared<std::promise<HttpResponsePtr>>();
99 auto future = promise->get_future();
100
101 HttpResponseCallback callback = [promise](HttpResponsePtr response) {
102 if (!response || !response->ready) return;
103 try {
104 promise->set_value(std::move(response));
105 } catch (const std::future_error& e) {
106 if (e.code() == std::make_error_condition(std::future_errc::promise_already_satisfied)) {
107 KURLYK_HANDLE_ERROR(e, "Promise already satisfied in HttpClient::request callback");
108 } else {
109 KURLYK_HANDLE_ERROR(e, "Future error in HttpClient::request callback");
110 }
111 } catch (const std::exception& e) {
112 KURLYK_HANDLE_ERROR(e, "Unhandled exception in HttpClient::request callback");
113 } catch (...) {
114 // Unknown fatal error in request callback
115 }
116 };
117
118 const bool status = HttpRequestManager::get_instance().add_request(std::move(request_ptr), std::move(callback));
119 if (!status) {
120 try {
121 promise->set_exception(std::make_exception_ptr(
122 std::runtime_error(
123 "Failed to add request to RequestManager")));
124 } catch (...) {}
125 }
127
128 return future;
129 }
130
139 uint64_t http_request(
140 const std::string &method,
141 const std::string &url,
142 const QueryParams &query,
143 const Headers &headers,
144 const std::string &content,
145 HttpResponseCallback callback) {
146# if __cplusplus >= 201402L
147 auto request_ptr = std::make_unique<HttpRequest>();
148# else
149 auto request_ptr = std::unique_ptr<HttpRequest>(new HttpRequest());
150# endif
151
152 const uint64_t request_id = HttpRequestManager::get_instance().generate_request_id();
153 request_ptr->request_id = request_id;
154 request_ptr->set_url(url, query);
155 request_ptr->method = method;
156 request_ptr->headers = headers;
157 request_ptr->content = content;
158 if (http_request(std::move(request_ptr), std::move(callback))) return request_id;
159 return 0;
160 }
161
169 std::pair<uint64_t, std::future<HttpResponsePtr>> http_request(
170 const std::string &method,
171 const std::string &url,
172 const QueryParams &query,
173 const Headers &headers,
174 const std::string &content) {
175
176# if __cplusplus >= 201402L
177 auto request_ptr = std::make_unique<HttpRequest>();
178# else
179 auto request_ptr = std::unique_ptr<HttpRequest>(new HttpRequest());
180# endif
181
182 const uint64_t request_id = HttpRequestManager::get_instance().generate_request_id();
183 request_ptr->request_id = request_id;
184 request_ptr->set_url(url, query);
185 request_ptr->method = method;
186 request_ptr->headers = headers;
187 request_ptr->content = content;
188
189 auto promise = std::make_shared<std::promise<HttpResponsePtr>>();
190 auto future = promise->get_future();
191
192 HttpResponseCallback callback = [promise](HttpResponsePtr response) {
193 if (!response || !response->ready) return;
194 try {
195 promise->set_value(std::move(response));
196 } catch (const std::future_error& e) {
197 if (e.code() == std::make_error_condition(std::future_errc::promise_already_satisfied)) {
198 KURLYK_HANDLE_ERROR(e, "Promise already satisfied in HttpClient::request callback");
199 } else {
200 KURLYK_HANDLE_ERROR(e, "Future error in HttpClient::request callback");
201 }
202 } catch (const std::exception& e) {
203 KURLYK_HANDLE_ERROR(e, "Unhandled exception in HttpClient::request callback");
204 } catch (...) {
205 // Unknown fatal error in request callback
206 }
207 };
208
209 if (!http_request(std::move(request_ptr), std::move(callback))) {
210 try {
211 promise->set_exception(std::make_exception_ptr(
212 std::runtime_error(
213 "Failed to add request to HttpRequestManager")));
214 } catch (...) {}
215 }
216
217 return {request_id, std::move(future)};
218 }
219
229 uint64_t http_request(
230 const std::string &method,
231 const std::string &host,
232 const std::string &path,
233 const QueryParams &query,
234 const Headers &headers,
235 const std::string &content,
236 HttpResponseCallback callback) {
237
238# if __cplusplus >= 201402L
239 auto request_ptr = std::make_unique<HttpRequest>();
240# else
241 auto request_ptr = std::unique_ptr<HttpRequest>(new HttpRequest());
242# endif
243
244 const uint64_t request_id = HttpRequestManager::get_instance().generate_request_id();
245 request_ptr->request_id = request_id;
246 request_ptr->set_url(host, path, query);
247 request_ptr->method = method;
248 request_ptr->headers = headers;
249 request_ptr->content = content;
250 if (http_request(std::move(request_ptr), std::move(callback))) return request_id;
251 return 0;
252 }
253
260 uint64_t http_get(
261 const std::string &url,
262 const QueryParams& query,
263 const Headers& headers,
264 HttpResponseCallback callback) {
265 return http_request("GET", url, query, headers, std::string(), std::move(callback));
266 }
267
273 std::pair<uint64_t, std::future<HttpResponsePtr>> http_get(
274 const std::string& url,
275 const QueryParams& query,
276 const Headers& headers) {
277
278# if __cplusplus >= 201402L
279 auto request_ptr = std::make_unique<HttpRequest>();
280# else
281 auto request_ptr = std::unique_ptr<HttpRequest>(new HttpRequest());
282# endif
283
284 const uint64_t request_id = HttpRequestManager::get_instance().generate_request_id();
285 request_ptr->request_id = request_id;
286 request_ptr->set_url(url, query);
287 request_ptr->method = "GET";
288 request_ptr->headers = headers;
289
290 auto promise = std::make_shared<std::promise<HttpResponsePtr>>();
291 auto future = promise->get_future();
292
293 HttpResponseCallback callback = [promise](HttpResponsePtr response) {
294 if (!response || !response->ready) return;
295 try {
296 promise->set_value(std::move(response));
297 } catch (const std::future_error& e) {
298 if (e.code() == std::make_error_condition(std::future_errc::promise_already_satisfied)) {
299 KURLYK_HANDLE_ERROR(e, "Promise already satisfied in HttpClient::request callback");
300 } else {
301 KURLYK_HANDLE_ERROR(e, "Future error in HttpClient::request callback");
302 }
303 } catch (const std::exception& e) {
304 KURLYK_HANDLE_ERROR(e, "Unhandled exception in HttpClient::request callback");
305 } catch (...) {
306 // Unknown fatal error in request callback
307 }
308 };
309
310 if (!http_request(std::move(request_ptr), std::move(callback))) {
311 try {
312 promise->set_exception(std::make_exception_ptr(
313 std::runtime_error(
314 "Failed to add request to HttpRequestManager")));
315 } catch (...) {}
316 }
317
318 return {request_id, std::move(future)};
319 }
320
328 uint64_t http_post(
329 const std::string &url,
330 const QueryParams& query,
331 const Headers& headers,
332 const std::string& content,
333 HttpResponseCallback callback) {
334 return http_request("POST", url, query, headers, content, std::move(callback));
335 }
336
343 std::pair<uint64_t, std::future<HttpResponsePtr>> http_post(
344 const std::string& url,
345 const QueryParams& query,
346 const Headers& headers,
347 const std::string& content) {
348
349# if __cplusplus >= 201402L
350 auto request_ptr = std::make_unique<HttpRequest>();
351# else
352 auto request_ptr = std::unique_ptr<HttpRequest>(new HttpRequest());
353# endif
354
355 const uint64_t request_id = HttpRequestManager::get_instance().generate_request_id();
356 request_ptr->request_id = request_id;
357 request_ptr->set_url(url, query);
358 request_ptr->method = "POST";
359 request_ptr->headers = headers;
360 request_ptr->content = content;
361
362 auto promise = std::make_shared<std::promise<HttpResponsePtr>>();
363 auto future = promise->get_future();
364
365 HttpResponseCallback callback = [promise](HttpResponsePtr response) {
366 if (!response || !response->ready) return;
367 try {
368 promise->set_value(std::move(response));
369 } catch (const std::future_error& e) {
370 if (e.code() == std::make_error_condition(std::future_errc::promise_already_satisfied)) {
371 KURLYK_HANDLE_ERROR(e, "Promise already satisfied in HttpClient::request callback");
372 } else {
373 KURLYK_HANDLE_ERROR(e, "Future error in HttpClient::request callback");
374 }
375 } catch (const std::exception& e) {
376 KURLYK_HANDLE_ERROR(e, "Unhandled exception in HttpClient::request callback");
377 } catch (...) {
378 // Unknown fatal error in request callback
379 }
380 };
381
382 if (!http_request(std::move(request_ptr), std::move(callback))) {
383 try {
384 promise->set_exception(std::make_exception_ptr(
385 std::runtime_error(
386 "Failed to add request to HttpRequestManager")));
387 } catch (...) {}
388 }
389
390 return {request_id, std::move(future)};
391 }
392
393} // namespace kurlyk
394
395#endif // _KURLYK_HTTP_UTILS_HPP_INCLUDED
#define KURLYK_HANDLE_ERROR(e, msg)
const bool add_request(std::unique_ptr< HttpRequest > request_ptr, HttpResponseCallback callback)
Adds a new HTTP request to the manager.
const long create_rate_limit(long requests_per_period, long period_ms)
Creates a rate limit with specified parameters.
void cancel_request_by_id(uint64_t request_id, std::function< void()> callback)
Cancels a request by its unique identifier.
static HttpRequestManager & get_instance()
Get the singleton instance of HttpRequestManager.
bool remove_limit(long limit_id)
Removes an existing rate limit with the specified identifier.
uint64_t generate_request_id()
Generates a new unique request ID.
Represents an HTTP request.
void notify()
Notifies the worker to begin processing requests or tasks.
static NetworkWorker & get_instance()
Get the singleton instance of NetworkWorker.
Primary namespace for the Kurlyk library, encompassing initialization, request management,...
std::function< void(HttpResponsePtr response)> HttpResponseCallback
Type definition for the callback function used to handle HTTP responses.
std::unique_ptr< HttpResponse > HttpResponsePtr
A unique pointer to an HttpResponse object for memory management.
bool http_request(std::unique_ptr< HttpRequest > request_ptr, HttpResponseCallback callback)
Sends an HTTP request with callback.
Definition utils.hpp:84
long create_rate_limit_rpm(long requests_per_minute)
Creates a rate limit based on Requests Per Minute (RPM).
Definition utils.hpp:21
utils::CaseInsensitiveMultimap Headers
Alias for HTTP headers, providing a case-insensitive unordered multimap.
uint64_t generate_request_id()
Generates a new unique request ID.
Definition utils.hpp:43
long create_rate_limit_rps(long requests_per_second)
Creates a rate limit based on Requests Per Second (RPS).
Definition utils.hpp:29
uint64_t http_get(const std::string &url, const QueryParams &query, const Headers &headers, HttpResponseCallback callback)
Sends an asynchronous HTTP GET request with a callback.
Definition utils.hpp:260
bool remove_limit(long limit_id)
Removes an existing rate limit with the specified identifier.
Definition utils.hpp:37
utils::CaseInsensitiveMultimap QueryParams
Alias for query parameters in HTTP requests, stored case-insensitively.
long create_rate_limit(long requests_per_period, long period_ms)
Creates a rate limit with specified parameters.
Definition utils.hpp:14
void cancel_request_by_id(uint64_t request_id, std::function< void()> callback)
Cancels a request by its unique identifier.
Definition utils.hpp:50
uint64_t http_post(const std::string &url, const QueryParams &query, const Headers &headers, const std::string &content, HttpResponseCallback callback)
Sends an asynchronous HTTP POST request with a callback.
Definition utils.hpp:328