Kurlyk
Loading...
Searching...
No Matches
HttpClient.hpp
Go to the documentation of this file.
1#pragma once
2#ifndef _KURLYK_HTTP_CLIENT_HPP_INCLUDED
3#define _KURLYK_HTTP_CLIENT_HPP_INCLUDED
4
7
8#if KURLYK_AUTH_SUPPORT
10#endif
11
12namespace kurlyk {
13
17 class HttpClient {
18 public:
19
25
28 HttpClient(const std::string& host) :
29 m_host(host) {
32 }
33
34 HttpClient(const HttpClient&) = delete;
35 HttpClient& operator=(const HttpClient&) = delete;
38
47
53 auto& worker = core::NetworkWorker::get_instance();
54 auto& manager = HttpRequestManager::get_instance();
55 const uint64_t group_id = m_request.group_id;
56 if (worker.is_worker_thread()) {
57 // On the worker thread: execute cancellation inline to avoid self-deadlock.
58 manager.cancel_requests_by_group_id(group_id, nullptr);
59 worker.process();
60 return;
61 }
62 auto promise = std::make_shared<std::promise<void>>();
63 auto future = promise->get_future();
64 manager.cancel_requests_by_group_id(group_id, [promise](){
65 try {
66 promise->set_value();
67 } catch (const std::future_error& e) {
68 if (e.code() == std::make_error_condition(std::future_errc::promise_already_satisfied)) {
69 KURLYK_HANDLE_ERROR(e, "Promise already satisfied in HttpClient::request callback");
70 } else {
71 KURLYK_HANDLE_ERROR(e, "Future error in HttpClient::request callback");
72 }
73 } catch (const std::exception& e) {
74 KURLYK_HANDLE_ERROR(e, "Unhandled exception in HttpClient::request callback");
75 } catch (...) {
76 // Unknown fatal error in request callback
77 }
78 });
79 worker.notify();
80 try {
81 future.get();
82 } catch (const std::exception& e) {
83 KURLYK_HANDLE_ERROR(e, "cancel_requests() future.get() failed");
84 }
85 }
86
92 auto& worker = core::NetworkWorker::get_instance();
93 if (worker.is_worker_thread()) {
94 throw std::logic_error("HttpClient::wait_requests() must not be called from the network worker thread");
95 }
96 auto future = make_wait_requests_future();
97 worker.notify();
98 try {
99 future.get();
100 } catch (const std::exception& e) {
101 KURLYK_HANDLE_ERROR(e, "wait_requests() future.get() failed");
102 }
103 }
104
111 bool wait_requests_for(std::chrono::milliseconds timeout) {
112 auto& worker = core::NetworkWorker::get_instance();
113 if (worker.is_worker_thread()) {
114 return false;
115 }
116 auto future = make_wait_requests_future();
117 worker.notify();
118 if (future.wait_for(timeout) == std::future_status::timeout) {
119 return false;
120 }
121 try {
122 future.get();
123 } catch (const std::exception& e) {
124 KURLYK_HANDLE_ERROR(e, "wait_requests_for() future.get() failed");
125 return false;
126 }
127 return true;
128 }
129
138 std::lock_guard<std::mutex> lock(m_submit_mutex);
140 }
141
144 std::size_t max_in_flight() const {
145 std::lock_guard<std::mutex> lock(m_submit_mutex);
146 return m_max_in_flight;
147 }
148
152 std::size_t in_flight_requests() const {
154 }
155
159 auto& instance = HttpRequestManager::get_instance();
160
161 switch (type) {
164 instance.remove_limit(m_request.general_rate_limit);
165 }
166 m_request.general_rate_limit.reset();
168 break;
169
172 instance.remove_limit(m_request.specific_rate_limit);
173 }
174 m_request.specific_rate_limit.reset();
176 break;
177 }
178 }
179
182 void set_host(const std::string& host) {
183 m_host = host;
184 }
185
188 void set_headers(const kurlyk::Headers& headers) {
189 m_request.headers = headers;
190 }
191
192#if KURLYK_AUTH_SUPPORT
200 void set_auth_provider(std::shared_ptr<http::auth::IAuthProvider> provider) {
201 m_auth_provider = provider;
202 }
203
205 void clear_auth_provider() {
206 m_auth_provider.reset();
207 }
208
210 bool has_auth_provider() const {
211 return m_auth_provider != nullptr;
212 }
213
215 std::shared_ptr<http::auth::IAuthProvider> auth_provider() const {
216 return m_auth_provider;
217 }
218#endif
219
225 long limit_id,
229 }
230
238 const HttpRateLimitHandlePtr& limit,
240 if (!limit) {
241 return false;
242 }
243
244 clear_rate_limit(type);
245
246 switch (type) {
248 m_request.general_rate_limit = limit;
249 break;
250
252 m_request.specific_rate_limit = limit;
253 break;
254 }
255 return true;
256 }
257
264 long limit_id,
266 return assign_rate_limit_id(limit_id, type);
267 }
268
274 const HttpRateLimitHandlePtr& limit,
276 return assign_rate_limit_handle(limit, type);
277 }
278
286 long requests_per_period,
287 long period_ms,
289 bool sequential = false) {
290 auto& instance = HttpRequestManager::get_instance();
291
292 clear_rate_limit(type);
293
294 switch (type) {
296 m_request.general_rate_limit =
297 instance.create_rate_limit(requests_per_period, period_ms, sequential);
299 break;
300
302 m_request.specific_rate_limit =
303 instance.create_rate_limit(requests_per_period, period_ms, sequential);
305 break;
306 }
307 }
308
315 long requests_per_minute,
317 bool sequential = false) {
318 long period_ms = 60000; // 1 minute in milliseconds
319 set_rate_limit(requests_per_minute, period_ms, type, sequential);
320 }
321
328 long requests_per_second,
330 bool sequential = false) {
331 long period_ms = 1000; // 1 second in milliseconds
332 set_rate_limit(requests_per_second, period_ms, type, sequential);
333 }
334
338 void set_rate_limit_key(const std::string& key) {
339 m_request.general_rate_limit_key = key;
340 m_request.specific_rate_limit_key = key;
341 }
342
346 void set_general_rate_limit_key(const std::string& key) {
347 m_request.general_rate_limit_key = key;
348 }
349
353 void set_specific_rate_limit_key(const std::string& key) {
354 m_request.specific_rate_limit_key = key;
355 }
356
361 const std::string& general_key,
362 const std::string& specific_key) {
363 m_request.general_rate_limit_key = general_key;
364 m_request.specific_rate_limit_key = specific_key;
365 }
366
373 bool identity = false,
374 bool deflate = false,
375 bool gzip = false,
376 bool brotli = false) {
377 m_request.set_accept_encoding(identity, deflate, gzip, brotli);
378 }
379
382 void set_accept_encoding(const std::string& value) {
383 m_request.accept_encoding = value;
384 }
385
388 void set_accept_language(const std::string& value) {
389 set_header("Accept-Language", value);
390 }
391
394 void set_content_type(const std::string& value) {
395 set_header("Content-Type", value);
396 }
397
400 void set_origin(const std::string& value) {
401 set_header("Origin", value);
402 }
403
406 void set_referer(const std::string& value) {
407 set_header("Referer", value);
408 }
409
412 void set_dnt(const bool value) {
413 m_request.headers.erase("dnt");
414 if (value) m_request.headers.emplace("dnt", "1");
415 }
416
419 void set_follow_location(bool value) {
420 m_request.follow_location = value;
421 }
422
425 void set_auto_referer(bool value) {
426 m_request.auto_referer = value;
427 }
428
431 void set_proxy_tunnel(bool value) {
432 m_request.proxy_tunnel = value;
433 }
434
438 void set_head_only(bool value) {
439 m_request.head_only = value;
440 }
441
444 void set_streaming(bool streaming) {
445 m_request.streaming = streaming;
446 }
447
453 const std::string& ip,
454 int port,
456 m_request.set_proxy(ip, port, type);
457 }
458
466 const std::string& ip,
467 const int port,
468 const std::string& username,
469 const std::string& password,
471 m_request.set_proxy(ip, port, username, password, type);
472 }
473
478 const std::string& username,
479 const std::string& password) {
480 m_request.set_proxy_auth(username, password);
481 }
482
485 void set_proxy_server(const std::string& server) {
486 m_request.set_proxy_server(server);
487 }
488
491 void set_proxy_auth(const std::string& auth) {
492 m_request.set_proxy_auth(auth);
493 }
494
498 m_request.set_proxy_type(type);
499 }
500
504 void set_retry_attempts(long retry_attempts, long retry_delay_ms) {
505 m_request.set_retry_attempts(retry_attempts, retry_delay_ms);
506 }
507
510 void add_valid_status(long status) {
511 m_request.add_valid_status(status);
512 }
513
516 void set_valid_statuses(const std::set<long>& statuses) {
517 m_request.set_valid_statuses(statuses);
518 }
519
522 m_request.clear_valid_statuses();
523 }
524
527 void set_user_agent(const std::string& user_agent) {
528 m_request.set_user_agent(user_agent);
529 }
530
533 void set_cookie(const std::string& cookie) {
534 m_request.set_cookie(cookie);
535 }
536
539 void set_cert_file(const std::string& cert_file) {
540 m_request.set_cert_file(cert_file);
541 }
542
545 void set_ca_file(const std::string& ca_file) {
546 m_request.set_ca_file(ca_file);
547 }
548
551 void set_timeout(long timeout) {
552 m_request.set_timeout(timeout);
553 }
554
557 void set_connect_timeout(long connect_timeout) {
558 m_request.set_connect_timeout(connect_timeout);
559 }
560
563 void set_verbose(bool verbose) {
564 m_request.verbose = verbose;
565 }
566
569 void set_debug_header(bool debug_header) {
570 m_request.debug_header = debug_header;
571 }
572
575 void set_max_redirects(long max_redirects) {
576 m_request.max_redirects = max_redirects;
577 }
578
586 std::unique_ptr<HttpRequest> request_ptr,
587 HttpResponseCallback callback) {
588 SubmitResult submit_result;
589 {
590 std::lock_guard<std::mutex> lock(m_submit_mutex);
591
592 if (m_max_in_flight != 0 &&
593 HttpRequestManager::get_instance().group_request_count(m_request.group_id) >= m_max_in_flight) {
595 }
596
598 std::move(request_ptr), std::move(callback));
599 }
600
601 if (submit_result) {
603 }
604 return submit_result;
605 }
606
616 const std::string &method,
617 const std::string& path,
618 const QueryParams &query,
619 const Headers &headers,
620 const std::string &content,
621 HttpResponseCallback callback) {
622 return request(make_request(method, path, query, headers, content), std::move(callback));
623 }
624
636 const std::string &method,
637 const std::string& path,
638 const QueryParams &query,
639 const Headers &headers,
640 const std::string &content,
641 long specific_rate_limit_id,
642 HttpResponseCallback callback) {
643 return request(
644 method,
645 path,
646 query,
647 headers,
648 content,
649 HttpRequestManager::get_instance().get_rate_limit(specific_rate_limit_id),
650 std::move(callback));
651 }
652
663 const std::string &method,
664 const std::string& path,
665 const QueryParams &query,
666 const Headers &headers,
667 const std::string &content,
668 const HttpRateLimitHandlePtr& specific_rate_limit,
669 HttpResponseCallback callback) {
670 auto request_ptr = make_request(method, path, query, headers, content);
671 request_ptr->specific_rate_limit = specific_rate_limit;
672 return request(std::move(request_ptr), std::move(callback));
673 }
674
681 bool get(
682 const std::string& path,
683 const QueryParams& query,
684 const Headers& headers,
685 HttpResponseCallback callback) {
686 return request("GET", path, query, headers, std::string(), std::move(callback));
687 }
688
696 bool post(
697 const std::string& path,
698 const QueryParams& query,
699 const Headers& headers,
700 const std::string& content,
701 HttpResponseCallback callback) {
702 return request("POST", path, query, headers, content, std::move(callback));
703 }
704
713 bool get(
714 const std::string& path,
715 const QueryParams& query,
716 const Headers& headers,
717 long specific_rate_limit_id,
718 HttpResponseCallback callback) {
719 return request("GET", path, query, headers, std::string(), specific_rate_limit_id, std::move(callback));
720 }
721
729 bool get(
730 const std::string& path,
731 const QueryParams& query,
732 const Headers& headers,
733 const HttpRateLimitHandlePtr& specific_rate_limit,
734 HttpResponseCallback callback) {
735 return request("GET", path, query, headers, std::string(), specific_rate_limit, std::move(callback));
736 }
737
747 bool post(
748 const std::string& path,
749 const QueryParams& query,
750 const Headers& headers,
751 const std::string& content,
752 long specific_rate_limit_id,
753 HttpResponseCallback callback) {
754 return request("POST", path, query, headers, content, specific_rate_limit_id, std::move(callback));
755 }
756
765 bool post(
766 const std::string& path,
767 const QueryParams& query,
768 const Headers& headers,
769 const std::string& content,
770 const HttpRateLimitHandlePtr& specific_rate_limit,
771 HttpResponseCallback callback) {
772 return request("POST", path, query, headers, content, specific_rate_limit, std::move(callback));
773 }
774
782 std::future<HttpResponsePtr> request(
783 const std::string& method,
784 const std::string& path,
785 const QueryParams& query,
786 const Headers& headers,
787 const std::string& content) {
788 return submit_future_request(make_request(method, path, query, headers, content));
789 }
790
800 std::future<HttpResponsePtr> request(
801 const std::string& method,
802 const std::string& path,
803 const QueryParams& query,
804 const Headers& headers,
805 const std::string& content,
806 long specific_rate_limit_id) {
807 return request(
808 method,
809 path,
810 query,
811 headers,
812 content,
813 HttpRequestManager::get_instance().get_rate_limit(specific_rate_limit_id));
814 }
815
824 std::future<HttpResponsePtr> request(
825 const std::string& method,
826 const std::string& path,
827 const QueryParams& query,
828 const Headers& headers,
829 const std::string& content,
830 const HttpRateLimitHandlePtr& specific_rate_limit) {
831 auto request_ptr = make_request(method, path, query, headers, content);
832 request_ptr->specific_rate_limit = specific_rate_limit;
833 return submit_future_request(std::move(request_ptr));
834 }
835
841 std::future<HttpResponsePtr> get(
842 const std::string& path,
843 const QueryParams& query,
844 const Headers& headers) {
845 return request("GET", path, query, headers, std::string());
846 }
847
854 std::future<HttpResponsePtr> post(
855 const std::string& path,
856 const QueryParams& query,
857 const Headers& headers,
858 const std::string& content) {
859 return request("POST", path, query, headers, content);
860 }
861
869 std::future<HttpResponsePtr> get(
870 const std::string& path,
871 const QueryParams& query,
872 const Headers& headers,
873 long specific_rate_limit_id) {
874 return request("GET", path, query, headers, std::string(), specific_rate_limit_id);
875 }
876
885 std::future<HttpResponsePtr> post(
886 const std::string& path,
887 const QueryParams& query,
888 const Headers& headers,
889 const std::string& content,
890 long specific_rate_limit_id) {
891 return request("POST", path, query, headers, content, specific_rate_limit_id);
892 }
893
900 std::future<HttpResponsePtr> get(
901 const std::string& path,
902 const QueryParams& query,
903 const Headers& headers,
904 const HttpRateLimitHandlePtr& specific_rate_limit) {
905 return request("GET", path, query, headers, std::string(), specific_rate_limit);
906 }
907
915 std::future<HttpResponsePtr> post(
916 const std::string& path,
917 const QueryParams& query,
918 const Headers& headers,
919 const std::string& content,
920 const HttpRateLimitHandlePtr& specific_rate_limit) {
921 return request("POST", path, query, headers, content, specific_rate_limit);
922 }
923
924 private:
926 std::string m_host;
929 mutable std::mutex m_submit_mutex;
930 std::size_t m_max_in_flight = 0;
931# if KURLYK_AUTH_SUPPORT
932 std::shared_ptr<http::auth::IAuthProvider> m_auth_provider;
933# endif
934
940 std::unique_ptr<HttpRequest> request_ptr,
941 HttpResponseCallback callback) {
942 return submit_request(std::move(request_ptr), std::move(callback)).accepted;
943 }
944
945 void set_header(const std::string& name, const std::string& value) {
946 m_request.headers.erase(name);
947 m_request.headers.emplace(name, value);
948 }
949
950 std::unique_ptr<HttpRequest> make_request(
951 const std::string& method,
952 const std::string& path,
953 const QueryParams& query,
954 const Headers& headers,
955 const std::string& content) const {
956# if __cplusplus >= 201402L
957 auto request_ptr = std::make_unique<HttpRequest>(m_request);
958# else
959 auto request_ptr = std::unique_ptr<HttpRequest>(new HttpRequest(m_request));
960# endif
961
962 request_ptr->request_id = HttpRequestManager::get_instance().generate_request_id();
963 request_ptr->method = method;
964 request_ptr->set_url(m_host, path, query);
965 request_ptr->headers.insert(headers.begin(), headers.end());
966 request_ptr->content = content;
967# if KURLYK_AUTH_SUPPORT
968 if (m_auth_provider) {
969 m_auth_provider->authorize(*request_ptr);
970 }
971# endif
972 return request_ptr;
973 }
974
975 std::future<HttpResponsePtr> submit_future_request(std::unique_ptr<HttpRequest> request_ptr) {
976 auto promise = std::make_shared<std::promise<HttpResponsePtr>>();
977 auto future = promise->get_future();
978
979 HttpResponseCallback callback = [promise](HttpResponsePtr response) {
980 safe_set_response(promise, std::move(response));
981 };
982
983 safe_submit_request(promise, std::move(request_ptr), std::move(callback));
984 return future;
985 }
986
989 std::future<void> make_wait_requests_future() {
990 auto promise = std::make_shared<std::promise<void>>();
991 auto future = promise->get_future();
992
994 m_request.group_id,
995 [promise]() {
996 try {
997 promise->set_value();
998 } catch (const std::future_error& e) {
999 if (e.code() == std::make_error_condition(std::future_errc::promise_already_satisfied)) {
1000 KURLYK_HANDLE_ERROR(e, "Promise already satisfied in HttpClient::wait_requests callback");
1001 } else {
1002 KURLYK_HANDLE_ERROR(e, "Future error in HttpClient::wait_requests callback");
1003 }
1004 } catch (const std::exception& e) {
1005 KURLYK_HANDLE_ERROR(e, "Unhandled exception in HttpClient::wait_requests callback");
1006 } catch (...) {
1007 // Unknown fatal error in wait callback
1008 }
1009 });
1010
1011 return future;
1012 }
1013
1018 std::shared_ptr<std::promise<HttpResponsePtr>> promise,
1019 HttpResponsePtr response) {
1020 if (!response || !response->ready) return;
1021 try {
1022 promise->set_value(std::move(response));
1023 } catch (const std::future_error& e) {
1024 if (e.code() == std::make_error_condition(std::future_errc::promise_already_satisfied)) {
1025 KURLYK_HANDLE_ERROR(e, "Promise already satisfied in HttpClient::request callback");
1026 } else {
1027 KURLYK_HANDLE_ERROR(e, "Future error in HttpClient::request callback");
1028 }
1029 } catch (const std::exception& e) {
1030 KURLYK_HANDLE_ERROR(e, "Unhandled exception in HttpClient::request callback");
1031 } catch (...) {
1032 // Unknown fatal error in request callback
1033 }
1034 }
1035
1040# if __cplusplus >= 201402L
1041 auto response = std::make_unique<HttpResponse>();
1042# else
1043 auto response = std::unique_ptr<HttpResponse>(new HttpResponse());
1044# endif
1045 response->ready = true;
1046 response->status_code = 0;
1047 response->error_code = submit_result.error_code;
1048 response->error_message = submit_result.error_code.message();
1049 return response;
1050 }
1051
1057 std::shared_ptr<std::promise<HttpResponsePtr>> promise,
1058 std::unique_ptr<HttpRequest> request_ptr,
1059 HttpResponseCallback callback) {
1060 try {
1061 const SubmitResult submit_result = submit_request(std::move(request_ptr), std::move(callback));
1062 if (!submit_result) {
1063 safe_set_response(promise, make_submit_error_response(submit_result));
1064 }
1065 } catch (const std::exception& e) {
1066 KURLYK_HANDLE_ERROR(e, "Exception while submitting request");
1067 try {
1068 promise->set_exception(std::current_exception());
1069 } catch (...) {} // fallback
1070 } catch (...) {
1071 // Unknown fatal error while submitting request
1072 try {
1073 promise->set_exception(std::current_exception());
1074 } catch (...) {} // fallback
1075 }
1076 }
1077
1079 static void ensure_initialized() {
1080 static std::once_flag once;
1081 std::call_once(once, []() {
1084 });
1085 }
1086
1087 }; // HttpClient
1088
1089}; // namespace kurlyk
1090
1091#endif // _KURLYK_HTTP_CLIENT_HPP_INCLUDED
Defines the IAuthProvider interface for HTTP authentication strategies.
#define KURLYK_HANDLE_ERROR(e, msg)
bool get(const std::string &path, const QueryParams &query, const Headers &headers, long specific_rate_limit_id, HttpResponseCallback callback)
Sends a GET request with a temporary specific rate limit found by ID.
bool request(std::unique_ptr< HttpRequest > request_ptr, HttpResponseCallback callback)
Adds the request to the request manager and notifies the worker to process it.
void set_proxy_auth(const std::string &auth)
Sets the proxy authentication credentials.
std::unique_ptr< HttpRequest > make_request(const std::string &method, const std::string &path, const QueryParams &query, const Headers &headers, const std::string &content) const
bool m_owns_general_rate_limit
Flag indicating if the client owns the general rate limit.
~HttpClient()
Destroys the client, cancels requests associated with this client, and releases owned rate limits.
void wait_requests()
Waits until all requests associated with this client group finish.
void set_rate_limit(long requests_per_period, long period_ms, RateLimitType type=RateLimitType::RL_GENERAL, bool sequential=false)
Creates and assigns an owned rate limit for future requests.
HttpRequest m_request
Request defaults shared by requests created by this client.
bool wait_requests_for(std::chrono::milliseconds timeout)
Waits until all requests associated with this client group finish or timeout expires.
std::size_t max_in_flight() const
Returns this client's configured admission cap.
void set_valid_statuses(const std::set< long > &statuses)
Replaces all valid HTTP status codes for the request.
void set_head_only(bool value)
Configures whether to send only the HTTP headers (HEAD request).
void set_verbose(bool verbose)
Enables or disables verbose output.
void set_accept_language(const std::string &value)
Sets the Accept-Language header value.
std::future< HttpResponsePtr > request(const std::string &method, const std::string &path, const QueryParams &query, const Headers &headers, const std::string &content, long specific_rate_limit_id)
Sends an HTTP request with a temporary specific rate limit found by ID and returns a future with the ...
std::string m_host
The base host URL for the HTTP client.
void set_max_redirects(long max_redirects)
Sets the maximum number of redirects for the client.
std::future< HttpResponsePtr > post(const std::string &path, const QueryParams &query, const Headers &headers, const std::string &content, long specific_rate_limit_id)
Sends an asynchronous POST request with a temporary specific rate limit found by ID.
void set_content_type(const std::string &value)
Sets the Content-Type header value.
bool post(const std::string &path, const QueryParams &query, const Headers &headers, const std::string &content, HttpResponseCallback callback)
Sends a POST request.
bool request(const std::string &method, const std::string &path, const QueryParams &query, const Headers &headers, const std::string &content, HttpResponseCallback callback)
Sends an HTTP request with the specified method, path, and parameters.
HttpClient(const HttpClient &)=delete
void add_valid_status(long status)
Adds a valid HTTP status code to the request.
std::future< HttpResponsePtr > get(const std::string &path, const QueryParams &query, const Headers &headers, const HttpRateLimitHandlePtr &specific_rate_limit)
Sends an asynchronous GET request with a temporary specific rate limit.
std::future< HttpResponsePtr > request(const std::string &method, const std::string &path, const QueryParams &query, const Headers &headers, const std::string &content, const HttpRateLimitHandlePtr &specific_rate_limit)
Sends an HTTP request with a temporary specific rate limit and returns a future with the response.
HttpClient()
Default constructor for HttpClient.
void set_streaming(bool streaming)
Enables or disables intermediate callbacks for response body chunks.
void set_ca_file(const std::string &ca_file)
Sets the path to the CA certificate file.
void clear_valid_statuses()
Clears the set of valid HTTP status codes for the request.
SubmitResult submit_request(std::unique_ptr< HttpRequest > request_ptr, HttpResponseCallback callback)
Attempts to submit a prepared request to the global HTTP manager.
std::future< HttpResponsePtr > post(const std::string &path, const QueryParams &query, const Headers &headers, const std::string &content, const HttpRateLimitHandlePtr &specific_rate_limit)
Sends an asynchronous POST request with a temporary specific rate limit.
std::future< HttpResponsePtr > request(const std::string &method, const std::string &path, const QueryParams &query, const Headers &headers, const std::string &content)
Sends an HTTP request with a specified method, path, and parameters, and returns a future with the re...
void set_proxy(const std::string &ip, int port, ProxyType type=ProxyType::PROXY_HTTP)
Sets the proxy server address.
bool set_rate_limit_handle(const HttpRateLimitHandlePtr &limit, RateLimitType type=RateLimitType::RL_GENERAL)
Sets an existing rate-limit handle for future requests.
void safe_submit_request(std::shared_ptr< std::promise< HttpResponsePtr > > promise, std::unique_ptr< HttpRequest > request_ptr, HttpResponseCallback callback)
Submits a request and propagates any failure to the provided promise.
bool get(const std::string &path, const QueryParams &query, const Headers &headers, const HttpRateLimitHandlePtr &specific_rate_limit, HttpResponseCallback callback)
Sends a GET request with a temporary specific rate limit.
void set_cert_file(const std::string &cert_file)
Sets the client certificate file path.
static void safe_set_response(std::shared_ptr< std::promise< HttpResponsePtr > > promise, HttpResponsePtr response)
Safely sets the response value on the given promise.
void set_auto_referer(bool value)
Configures whether to automatically set the Referer header on redirects.
void set_connect_timeout(long connect_timeout)
Sets the connection timeout duration.
void set_retry_attempts(long retry_attempts, long retry_delay_ms)
Sets retry attempts and delay between retries for HTTP requests.
void set_rate_limit_rps(long requests_per_second, RateLimitType type=RateLimitType::RL_GENERAL, bool sequential=false)
Sets the rate limit based on requests per second (RPS).
void set_timeout(long timeout)
Sets the timeout duration for HTTP requests.
void set_proxy_server(const std::string &server)
Sets the proxy server address.
std::future< HttpResponsePtr > get(const std::string &path, const QueryParams &query, const Headers &headers)
Sends a GET request asynchronously and returns a future with the response.
void set_rate_limit_rpm(long requests_per_minute, RateLimitType type=RateLimitType::RL_GENERAL, bool sequential=false)
Sets the rate limit based on requests per minute (RPM).
void clear_rate_limit(RateLimitType type=RateLimitType::RL_GENERAL)
Clears the configured rate limit of the specified type.
void set_referer(const std::string &value)
Sets the Referer header value.
void set_follow_location(bool value)
Configures whether to follow redirects automatically.
void set_proxy(const std::string &ip, const int port, const std::string &username, const std::string &password, ProxyType type=ProxyType::PROXY_HTTP)
Sets the proxy server address with authentication details.
void set_specific_rate_limit_key(const std::string &key)
Sets the partition key for the specific rate limit.
bool assign_rate_limit_handle(const HttpRateLimitHandlePtr &limit, RateLimitType type=RateLimitType::RL_GENERAL)
Assigns an existing rate-limit handle to future requests.
void set_cookie(const std::string &cookie)
Sets the cookie string for HTTP requests.
std::future< HttpResponsePtr > get(const std::string &path, const QueryParams &query, const Headers &headers, long specific_rate_limit_id)
Sends an asynchronous GET request with a temporary specific rate limit found by ID.
std::future< HttpResponsePtr > post(const std::string &path, const QueryParams &query, const Headers &headers, const std::string &content)
Sends a POST request asynchronously and returns a future with the response.
void set_accept_encoding(const std::string &value)
Sets a custom Accept-Encoding header value.
bool assign_rate_limit_id(long limit_id, RateLimitType type=RateLimitType::RL_GENERAL)
Assigns an existing rate limit to future requests by ID.
std::size_t in_flight_requests() const
Returns number of pending, active, and retry requests currently observed for this client group.
HttpClient(HttpClient &&)=delete
void set_general_rate_limit_key(const std::string &key)
Sets the partition key for the general rate limit.
void set_user_agent(const std::string &user_agent)
Sets the User-Agent header.
void set_origin(const std::string &value)
Sets the Origin header value.
bool request(const std::string &method, const std::string &path, const QueryParams &query, const Headers &headers, const std::string &content, const HttpRateLimitHandlePtr &specific_rate_limit, HttpResponseCallback callback)
Sends an HTTP request with a temporary specific rate limit.
HttpClient(const std::string &host)
Constructs an HttpClient with the specified host.
std::future< void > make_wait_requests_future()
Creates a future that becomes ready when all requests in this client group finish.
void set_max_in_flight(std::size_t max_in_flight)
Sets maximum number of requests this client may submit while its group is busy.
void set_proxy_tunnel(bool value)
Configures whether to use a tunneling proxy for HTTP requests.
bool post(const std::string &path, const QueryParams &query, const Headers &headers, const std::string &content, long specific_rate_limit_id, HttpResponseCallback callback)
Sends a POST request with a temporary specific rate limit found by ID.
static HttpResponsePtr make_submit_error_response(const SubmitResult &submit_result)
Creates a ready HTTP response describing a synchronous submission rejection.
bool m_owns_specific_rate_limit
Flag indicating if the client owns the specific rate limit.
static void ensure_initialized()
Ensures that the network worker and request manager are initialized.
bool post(const std::string &path, const QueryParams &query, const Headers &headers, const std::string &content, const HttpRateLimitHandlePtr &specific_rate_limit, HttpResponseCallback callback)
Sends a POST request with a temporary specific rate limit.
HttpClient & operator=(HttpClient &&)=delete
void set_host(const std::string &host)
Sets the host URL for the HTTP client.
bool get(const std::string &path, const QueryParams &query, const Headers &headers, HttpResponseCallback callback)
Sends a GET request.
std::size_t m_max_in_flight
Maximum number of in-flight requests for this client group, or 0 for disabled.
void set_debug_header(bool debug_header)
Enables or disables debug headers.
void set_rate_limit_key(const std::string &key)
Sets the partition key for both rate limits (general and specific).
std::future< HttpResponsePtr > submit_future_request(std::unique_ptr< HttpRequest > request_ptr)
void set_proxy_auth(const std::string &username, const std::string &password)
Sets proxy authentication credentials.
void set_headers(const kurlyk::Headers &headers)
Sets the default headers for HTTP requests.
HttpClient & operator=(const HttpClient &)=delete
void set_rate_limit_keys(const std::string &general_key, const std::string &specific_key)
Sets independent partition keys for general and specific rate limits.
bool set_rate_limit_id(long limit_id, RateLimitType type=RateLimitType::RL_GENERAL)
Sets the rate limit ID for the HTTP request (alias for assign_rate_limit_id).
void set_dnt(const bool value)
Sets the Do Not Track (DNT) header value.
std::mutex m_submit_mutex
Protects client-side submission settings and admission checks.
bool request(const std::string &method, const std::string &path, const QueryParams &query, const Headers &headers, const std::string &content, long specific_rate_limit_id, HttpResponseCallback callback)
Sends an HTTP request with a temporary specific rate limit found by ID.
void set_header(const std::string &name, const std::string &value)
void set_accept_encoding(bool identity=false, bool deflate=false, bool gzip=false, bool brotli=false)
Sets the Accept-Encoding header.
void set_proxy_type(ProxyType type)
Sets the proxy type.
void cancel_requests()
Cancels requests associated with this client and waits for cancellation callbacks.
uint64_t generate_group_id()
Generates a new group ID.
std::size_t group_request_count(uint64_t group_id) const
Counts pending, failed, and active requests for a group.
static HttpRequestManager & get_instance()
Get the singleton instance of HttpRequestManager.
void wait_requests_by_group_id(uint64_t group_id, std::function< void()> callback)
Registers a callback invoked after all requests from a group finish.
SubmitResult submit_request(std::unique_ptr< HttpRequest > request_ptr, HttpResponseCallback callback)
Attempts to enqueue a new HTTP request and reports the admission result.
uint64_t generate_request_id()
Generates a new unique request ID.
Represents an HTTP request configuration.
Represents an HTTP response.
void notify()
Notifies the worker to begin processing requests or tasks.
static NetworkWorker & get_instance()
Get the singleton instance of NetworkWorker.
void start(const bool use_async)
Starts the worker thread for asynchronous task processing.
#define KURLYK_AUTO_INIT_USE_ASYNC
Determines whether the NetworkWorker runs in a background thread during automatic initialization.
Definition kurlyk.hpp:20
@ QueueLimitExceeded
Operation was rejected because the bounded queue is already full.
std::error_code make_error_code(ClientError e)
Creates a std::error_code from a ClientError value.
Primary namespace for the Kurlyk library, encompassing initialization, request management,...
std::function< void(HttpResponsePtr response)> HttpResponseCallback
Callback invoked with an HTTP response.
RateLimitType
Defines rate limit scope categories.
Definition enums.hpp:24
@ RL_GENERAL
Applies globally to all requests.
Definition enums.hpp:25
@ RL_SPECIFIC
Applies to specific client/request.
Definition enums.hpp:26
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:172
ProxyType
Enumeration of supported proxy types compatible with libcurl.
Definition enums.hpp:12
@ PROXY_HTTP
HTTP proxy.
Definition enums.hpp:13
std::unique_ptr< HttpResponse > HttpResponsePtr
Owning pointer to an HTTP response.
HttpRateLimitHandlePtr get_rate_limit(long limit_id)
Returns a manager-owned rate-limit handle by ID.
Definition utils.hpp:44
utils::CaseInsensitiveMultimap Headers
Alias for HTTP headers, providing a case-insensitive unordered multimap.
std::shared_ptr< HttpRateLimitHandle > HttpRateLimitHandlePtr
Shared RAII handle for HTTP rate limits.
utils::CaseInsensitiveMultimap QueryParams
Alias for query parameters in HTTP requests, stored case-insensitively.
HttpResponsePtr make_submit_error_response(const SubmitResult &submit_result)
Creates a ready HTTP response describing a synchronous submission rejection.
Definition utils.hpp:156
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.