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
9
10namespace kurlyk {
11
16 inline long create_rate_limit(long requests_per_period, long period_ms) {
17 return HttpRequestManager::get_instance().create_rate_limit(requests_per_period, period_ms);
18 }
19
23 inline long create_rate_limit_rpm(long requests_per_minute) {
24 long period_ms = 60000; // 1 minute in milliseconds
25 return HttpRequestManager::get_instance().create_rate_limit(requests_per_minute, period_ms);
26 }
27
31 inline long create_rate_limit_rps(long requests_per_second) {
32 long period_ms = 1000; // 1 second in milliseconds
33 return HttpRequestManager::get_instance().create_rate_limit(requests_per_second, period_ms);
34 }
35
39 inline bool remove_limit(long limit_id) {
41 }
42
48
54
60
64 inline void cancel_request_by_id(uint64_t request_id, std::function<void()> callback) {
65 HttpRequestManager::get_instance().cancel_request_by_id(request_id, std::move(callback));
67 }
68
72 inline std::future<void> cancel_request_by_id(uint64_t request_id) {
73 auto promise = std::make_shared<std::promise<void>>();
74 auto future = promise->get_future();
76 try {
77 promise->set_value();
78 } catch (const std::future_error& e) {
79 if (e.code() == std::make_error_condition(std::future_errc::promise_already_satisfied)) {
80 KURLYK_HANDLE_ERROR(e, "Promise already satisfied in HttpClient::request callback");
81 } else {
82 KURLYK_HANDLE_ERROR(e, "Future error in HttpClient::request callback");
83 }
84 } catch (const std::exception& e) {
85 KURLYK_HANDLE_ERROR(e, "Unhandled exception in HttpClient::request callback");
86 } catch (...) {
87 // Unknown fatal error in request callback
88 }
89 });
91 return future;
92 }
93
98# if __cplusplus >= 201402L
99 auto response = std::make_unique<HttpResponse>();
100# else
101 auto response = std::unique_ptr<HttpResponse>(new HttpResponse());
102# endif
103 response->ready = true;
104 response->status_code = 0;
105 response->error_code = submit_result.error_code;
106 response->error_message = submit_result.error_code.message();
107 return response;
108 }
109
113 inline void safe_set_response(
114 std::shared_ptr<std::promise<HttpResponsePtr>> promise,
115 HttpResponsePtr response) {
116 if (!response || !response->ready) return;
117 try {
118 promise->set_value(std::move(response));
119 } catch (const std::future_error& e) {
120 if (e.code() == std::make_error_condition(std::future_errc::promise_already_satisfied)) {
121 KURLYK_HANDLE_ERROR(e, "Promise already satisfied in HttpClient::request callback");
122 } else {
123 KURLYK_HANDLE_ERROR(e, "Future error in HttpClient::request callback");
124 }
125 } catch (const std::exception& e) {
126 KURLYK_HANDLE_ERROR(e, "Unhandled exception in HttpClient::request callback");
127 } catch (...) {
128 // Unknown fatal error in request callback
129 }
130 }
131
137 std::unique_ptr<HttpRequest> request_ptr,
138 HttpResponseCallback callback) {
140 std::move(request_ptr), std::move(callback));
141 if (submit_result) {
143 }
144 return submit_result;
145 }
146
151 inline bool http_request(
152 std::unique_ptr<HttpRequest> request_ptr,
153 HttpResponseCallback callback) {
154 return submit_http_request(std::move(request_ptr), std::move(callback)).accepted;
155 }
156
160 inline std::future<HttpResponsePtr> http_request(
161 std::unique_ptr<HttpRequest> request_ptr) {
162
163 auto promise = std::make_shared<std::promise<HttpResponsePtr>>();
164 auto future = promise->get_future();
165
166 HttpResponseCallback callback = [promise](HttpResponsePtr response) {
167 safe_set_response(promise, std::move(response));
168 };
169
170 const SubmitResult submit_result = submit_http_request(std::move(request_ptr), std::move(callback));
171 if (!submit_result) {
172 safe_set_response(promise, make_submit_error_response(submit_result));
173 }
174
175 return future;
176 }
177
186 inline uint64_t http_request(
187 const std::string &method,
188 const std::string &url,
189 const QueryParams &query,
190 const Headers &headers,
191 const std::string &content,
192 HttpResponseCallback callback) {
193# if __cplusplus >= 201402L
194 auto request_ptr = std::make_unique<HttpRequest>();
195# else
196 auto request_ptr = std::unique_ptr<HttpRequest>(new HttpRequest());
197# endif
198
199 const uint64_t request_id = HttpRequestManager::get_instance().generate_request_id();
200 request_ptr->request_id = request_id;
201 request_ptr->set_url(url, query);
202 request_ptr->method = method;
203 request_ptr->headers = headers;
204 request_ptr->content = content;
205 if (http_request(std::move(request_ptr), std::move(callback))) return request_id;
206 return 0;
207 }
208
218 inline uint64_t http_request(
219 const std::string &method,
220 const std::string &url,
221 const QueryParams &query,
222 const Headers &headers,
223 const std::string &content,
224 bool streaming,
225 HttpResponseCallback callback) {
226# if __cplusplus >= 201402L
227 auto request_ptr = std::make_unique<HttpRequest>();
228# else
229 auto request_ptr = std::unique_ptr<HttpRequest>(new HttpRequest());
230# endif
231
232 const uint64_t request_id = HttpRequestManager::get_instance().generate_request_id();
233 request_ptr->request_id = request_id;
234 request_ptr->set_url(url, query);
235 request_ptr->method = method;
236 request_ptr->headers = headers;
237 request_ptr->content = content;
238 request_ptr->streaming = streaming;
239 if (http_request(std::move(request_ptr), std::move(callback))) return request_id;
240 return 0;
241 }
242
250 inline std::pair<uint64_t, std::future<HttpResponsePtr>> http_request(
251 const std::string &method,
252 const std::string &url,
253 const QueryParams &query,
254 const Headers &headers,
255 const std::string &content) {
256
257# if __cplusplus >= 201402L
258 auto request_ptr = std::make_unique<HttpRequest>();
259# else
260 auto request_ptr = std::unique_ptr<HttpRequest>(new HttpRequest());
261# endif
262
263 const uint64_t request_id = HttpRequestManager::get_instance().generate_request_id();
264 request_ptr->request_id = request_id;
265 request_ptr->set_url(url, query);
266 request_ptr->method = method;
267 request_ptr->headers = headers;
268 request_ptr->content = content;
269
270 auto promise = std::make_shared<std::promise<HttpResponsePtr>>();
271 auto future = promise->get_future();
272
273 HttpResponseCallback callback = [promise](HttpResponsePtr response) {
274 safe_set_response(promise, std::move(response));
275 };
276
277 const SubmitResult submit_result = submit_http_request(std::move(request_ptr), std::move(callback));
278 if (!submit_result) {
279 safe_set_response(promise, make_submit_error_response(submit_result));
280 }
281
282 return {request_id, std::move(future)};
283 }
284
294 inline uint64_t http_request(
295 const std::string &method,
296 const std::string &host,
297 const std::string &path,
298 const QueryParams &query,
299 const Headers &headers,
300 const std::string &content,
301 HttpResponseCallback callback) {
302
303# if __cplusplus >= 201402L
304 auto request_ptr = std::make_unique<HttpRequest>();
305# else
306 auto request_ptr = std::unique_ptr<HttpRequest>(new HttpRequest());
307# endif
308
309 const uint64_t request_id = HttpRequestManager::get_instance().generate_request_id();
310 request_ptr->request_id = request_id;
311 request_ptr->set_url(host, path, query);
312 request_ptr->method = method;
313 request_ptr->headers = headers;
314 request_ptr->content = content;
315 if (http_request(std::move(request_ptr), std::move(callback))) return request_id;
316 return 0;
317 }
318
329 inline uint64_t http_request(
330 const std::string &method,
331 const std::string &host,
332 const std::string &path,
333 const QueryParams &query,
334 const Headers &headers,
335 const std::string &content,
336 bool streaming,
337 HttpResponseCallback callback) {
338
339# if __cplusplus >= 201402L
340 auto request_ptr = std::make_unique<HttpRequest>();
341# else
342 auto request_ptr = std::unique_ptr<HttpRequest>(new HttpRequest());
343# endif
344
345 const uint64_t request_id = HttpRequestManager::get_instance().generate_request_id();
346 request_ptr->request_id = request_id;
347 request_ptr->set_url(host, path, query);
348 request_ptr->method = method;
349 request_ptr->headers = headers;
350 request_ptr->content = content;
351 request_ptr->streaming = streaming;
352 if (http_request(std::move(request_ptr), std::move(callback))) return request_id;
353 return 0;
354 }
355
362 inline uint64_t http_get(
363 const std::string &url,
364 const QueryParams& query,
365 const Headers& headers,
366 HttpResponseCallback callback) {
367 return http_request("GET", url, query, headers, std::string(), std::move(callback));
368 }
369
377 inline uint64_t http_get(
378 const std::string &url,
379 const QueryParams& query,
380 const Headers& headers,
381 bool streaming,
382 HttpResponseCallback callback) {
383 return http_request("GET", url, query, headers, std::string(), streaming, std::move(callback));
384 }
385
391 inline std::pair<uint64_t, std::future<HttpResponsePtr>> http_get(
392 const std::string& url,
393 const QueryParams& query,
394 const Headers& headers) {
395
396# if __cplusplus >= 201402L
397 auto request_ptr = std::make_unique<HttpRequest>();
398# else
399 auto request_ptr = std::unique_ptr<HttpRequest>(new HttpRequest());
400# endif
401
402 const uint64_t request_id = HttpRequestManager::get_instance().generate_request_id();
403 request_ptr->request_id = request_id;
404 request_ptr->set_url(url, query);
405 request_ptr->method = "GET";
406 request_ptr->headers = headers;
407
408 auto promise = std::make_shared<std::promise<HttpResponsePtr>>();
409 auto future = promise->get_future();
410
411 HttpResponseCallback callback = [promise](HttpResponsePtr response) {
412 safe_set_response(promise, std::move(response));
413 };
414
415 const SubmitResult submit_result = submit_http_request(std::move(request_ptr), std::move(callback));
416 if (!submit_result) {
417 safe_set_response(promise, make_submit_error_response(submit_result));
418 }
419
420 return {request_id, std::move(future)};
421 }
422
430 inline uint64_t http_post(
431 const std::string &url,
432 const QueryParams& query,
433 const Headers& headers,
434 const std::string& content,
435 HttpResponseCallback callback) {
436 return http_request("POST", url, query, headers, content, std::move(callback));
437 }
438
447 inline uint64_t http_post(
448 const std::string &url,
449 const QueryParams& query,
450 const Headers& headers,
451 const std::string& content,
452 bool streaming,
453 HttpResponseCallback callback) {
454 return http_request("POST", url, query, headers, content, streaming, std::move(callback));
455 }
456
463 inline std::pair<uint64_t, std::future<HttpResponsePtr>> http_post(
464 const std::string& url,
465 const QueryParams& query,
466 const Headers& headers,
467 const std::string& content) {
468
469# if __cplusplus >= 201402L
470 auto request_ptr = std::make_unique<HttpRequest>();
471# else
472 auto request_ptr = std::unique_ptr<HttpRequest>(new HttpRequest());
473# endif
474
475 const uint64_t request_id = HttpRequestManager::get_instance().generate_request_id();
476 request_ptr->request_id = request_id;
477 request_ptr->set_url(url, query);
478 request_ptr->method = "POST";
479 request_ptr->headers = headers;
480 request_ptr->content = content;
481
482 auto promise = std::make_shared<std::promise<HttpResponsePtr>>();
483 auto future = promise->get_future();
484
485 HttpResponseCallback callback = [promise](HttpResponsePtr response) {
486 safe_set_response(promise, std::move(response));
487 };
488
489 const SubmitResult submit_result = submit_http_request(std::move(request_ptr), std::move(callback));
490 if (!submit_result) {
491 safe_set_response(promise, make_submit_error_response(submit_result));
492 }
493
494 return {request_id, std::move(future)};
495 }
496
497} // namespace kurlyk
498
499#endif // _KURLYK_HTTP_UTILS_HPP_INCLUDED
#define KURLYK_HANDLE_ERROR(e, msg)
std::size_t max_pending_requests() const
Returns the current maximum pending request count.
void set_max_pending_requests(std::size_t max_pending_requests)
Sets the maximum number of pending requests accepted into the global queue.
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.
SubmitResult submit_request(std::unique_ptr< HttpRequest > request_ptr, HttpResponseCallback callback)
Attempts to enqueue a new HTTP request and reports the admission result.
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.
Represents the response received from an HTTP request, including headers, content,...
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::size_t max_pending_requests()
Returns the current global pending queue limit.
Definition utils.hpp:57
std::function< void(HttpResponsePtr response)> HttpResponseCallback
Type definition for the callback function used to handle HTTP responses.
void set_max_pending_requests(std::size_t max_pending_requests)
Sets the maximum number of requests accepted into the global pending queue.
Definition utils.hpp:51
void safe_set_response(std::shared_ptr< std::promise< HttpResponsePtr > > promise, HttpResponsePtr response)
Safely sets an HTTP response on the provided promise.
Definition utils.hpp:113
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:151
long create_rate_limit_rpm(long requests_per_minute)
Creates a rate limit based on Requests Per Minute (RPM).
Definition utils.hpp:23
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:45
long create_rate_limit_rps(long requests_per_second)
Creates a rate limit based on Requests Per Second (RPS).
Definition utils.hpp:31
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:362
bool remove_limit(long limit_id)
Removes an existing rate limit with the specified identifier.
Definition utils.hpp:39
SubmitResult submit_http_request(std::unique_ptr< HttpRequest > request_ptr, HttpResponseCallback callback)
Attempts to submit an HTTP request and reports the admission result.
Definition utils.hpp:136
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:16
void cancel_request_by_id(uint64_t request_id, std::function< void()> callback)
Cancels a request by its unique identifier.
Definition utils.hpp:64
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:430
HttpResponsePtr make_submit_error_response(const SubmitResult &submit_result)
Creates a ready HTTP response describing a synchronous submission rejection.
Definition utils.hpp:97
Represents the synchronous result of trying to enqueue or submit work.
bool accepted
Indicates whether the work item was accepted for processing.
std::error_code error_code
Describes the rejection reason when accepted is false.