2#ifndef _KURLYK_HTTP_CLIENT_HPP_INCLUDED
3#define _KURLYK_HTTP_CLIENT_HPP_INCLUDED
38 instance.remove_limit(
m_request.general_rate_limit_id);
41 instance.remove_limit(
m_request.specific_rate_limit_id);
48 auto promise = std::make_shared<std::promise<void>>();
49 auto future = promise->get_future();
53 } catch (
const std::future_error& e) {
54 if (e.code() == std::make_error_condition(std::future_errc::promise_already_satisfied)) {
59 }
catch (
const std::exception& e) {
68 }
catch (
const std::exception& e) {
95 instance.remove_limit(
m_request.general_rate_limit_id);
97 m_request.general_rate_limit_id = limit_id;
102 instance.remove_limit(
m_request.specific_rate_limit_id);
104 m_request.specific_rate_limit_id = limit_id;
125 long requests_per_period,
132 instance.remove_limit(
m_request.general_rate_limit_id);
134 m_request.general_rate_limit_id = instance.create_rate_limit(requests_per_period, period_ms);
139 instance.remove_limit(
m_request.specific_rate_limit_id);
141 m_request.specific_rate_limit_id = instance.create_rate_limit(requests_per_period, period_ms);
151 long requests_per_minute,
153 long period_ms = 60000;
161 long requests_per_second,
163 long period_ms = 1000;
173 bool identity =
false,
174 bool deflate =
false,
176 bool brotli =
false) {
177 m_request.set_accept_encoding(identity, deflate, gzip, brotli);
189 m_request.headers.emplace(
"Accept-Language", value);
195 m_request.headers.emplace(
"Content-Type", value);
201 m_request.headers.emplace(
"Origin", value);
207 m_request.headers.emplace(
"Referer", value);
213 if (value)
m_request.headers.emplace(
"dnt",
"1");
252 const std::string& ip,
265 const std::string& ip,
267 const std::string& username,
268 const std::string& password,
270 m_request.set_proxy(ip, port, username, password, type);
277 const std::string& username,
278 const std::string& password) {
279 m_request.set_proxy_auth(username, password);
304 m_request.set_retry_attempts(retry_attempts, retry_delay_ms);
357 m_request.set_connect_timeout(connect_timeout);
383 std::unique_ptr<HttpRequest> request_ptr,
386 std::move(request_ptr), std::move(callback));
390 return submit_result;
402 const std::string &method,
403 const std::string& path,
406 const std::string &content,
408# if __cplusplus >= 201402L
409 std::unique_ptr<HttpRequest> request_ptr = std::make_unique<HttpRequest>(
m_request);
411 std::unique_ptr<HttpRequest> request_ptr = std::unique_ptr<HttpRequest>(
new HttpRequest(
m_request));
413 request_ptr->method = method;
414 request_ptr->set_url(
m_host, path, query);
415 request_ptr->headers.insert(headers.begin(), headers.end());
416 request_ptr->content = content;
417 return request(std::move(request_ptr), std::move(callback));
430 const std::string &method,
431 const std::string& path,
434 const std::string &content,
435 long specific_rate_limit_id,
437# if __cplusplus >= 201402L
438 std::unique_ptr<HttpRequest> request_ptr = std::make_unique<HttpRequest>(
m_request);
440 std::unique_ptr<HttpRequest> request_ptr = std::unique_ptr<HttpRequest>(
new HttpRequest(
m_request));
442 request_ptr->method = method;
443 request_ptr->set_url(
m_host, path, query);
444 request_ptr->headers.insert(headers.begin(), headers.end());
445 request_ptr->content = content;
451 request_ptr->specific_rate_limit_id = specific_rate_limit_id;
454 return request(std::move(request_ptr), std::move(callback));
464 const std::string& path,
468 return request(
"GET", path, query, headers, std::string(), std::move(callback));
479 const std::string& path,
482 const std::string& content,
484 return request(
"POST", path, query, headers, content, std::move(callback));
495 const std::string& path,
498 long specific_rate_limit_id,
500 return request(
"GET", path, query, headers, std::string(), specific_rate_limit_id, std::move(callback));
512 const std::string& path,
515 const std::string& content,
516 long specific_rate_limit_id,
518 return request(
"POST", path, query, headers, content, specific_rate_limit_id, std::move(callback));
529 const std::string& method,
530 const std::string& path,
533 const std::string& content) {
534# if __cplusplus >= 201402L
535 auto request_ptr = std::make_unique<HttpRequest>(
m_request);
539 request_ptr->method = method;
540 request_ptr->set_url(
m_host, path, query);
541 request_ptr->headers.insert(headers.begin(), headers.end());
542 request_ptr->content = content;
544 auto promise = std::make_shared<std::promise<HttpResponsePtr>>();
545 auto future = promise->get_future();
552 promise, std::move(request_ptr), std::move(callback));
566 const std::string& method,
567 const std::string& path,
570 const std::string& content,
571 long specific_rate_limit_id) {
572# if __cplusplus >= 201402L
573 auto request_ptr = std::make_unique<HttpRequest>(
m_request);
577 request_ptr->method = method;
578 request_ptr->set_url(
m_host, path, query);
579 request_ptr->headers.insert(headers.begin(), headers.end());
580 request_ptr->content = content;
586 request_ptr->specific_rate_limit_id = specific_rate_limit_id;
589 auto promise = std::make_shared<std::promise<HttpResponsePtr>>();
590 auto future = promise->get_future();
597 promise, std::move(request_ptr), std::move(callback));
607 std::future<HttpResponsePtr>
get(
608 const std::string& path,
611 return request(
"GET", path, query, headers, std::string());
620 std::future<HttpResponsePtr>
post(
621 const std::string& path,
624 const std::string& content) {
625 return request(
"POST", path, query, headers, content);
634 std::future<HttpResponsePtr>
get(
635 const std::string& path,
638 long specific_rate_limit_id) {
639 return request(
"GET", path, query, headers, std::string(), specific_rate_limit_id);
649 std::future<HttpResponsePtr>
post(
650 const std::string& path,
653 const std::string& content,
654 long specific_rate_limit_id) {
655 return request(
"POST", path, query, headers, content, specific_rate_limit_id);
669 std::unique_ptr<HttpRequest> request_ptr,
671 return submit_request(std::move(request_ptr), std::move(callback)).accepted;
678 std::shared_ptr<std::promise<HttpResponsePtr>> promise,
680 if (!response || !response->ready)
return;
682 promise->set_value(std::move(response));
683 }
catch (
const std::future_error& e) {
684 if (e.code() == std::make_error_condition(std::future_errc::promise_already_satisfied)) {
689 }
catch (
const std::exception& e) {
700# if __cplusplus >= 201402L
701 auto response = std::make_unique<HttpResponse>();
703 auto response = std::unique_ptr<HttpResponse>(
new HttpResponse());
705 response->ready =
true;
706 response->status_code = 0;
707 response->error_code = submit_result.
error_code;
708 response->error_message = submit_result.
error_code.message();
717 std::shared_ptr<std::promise<HttpResponsePtr>> promise,
718 std::unique_ptr<HttpRequest> request_ptr,
722 if (!submit_result) {
725 }
catch (
const std::exception& e) {
728 promise->set_exception(std::current_exception());
733 promise->set_exception(std::current_exception());
740 static bool is_initialized =
false;
741 if (!is_initialized) {
742 is_initialized =
true;
#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 specific rate limit 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.
~HttpClient()
Destroys the client, cancels its active request, and releases owned rate limits.
HttpRequest m_request
The request object used for configuring and sending requests.
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_rate_limit(long requests_per_period, long period_ms, RateLimitType type=RateLimitType::RL_GENERAL)
Sets the rate limit for HTTP requests.
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 specified method, path, specific rate limit ID and parameters,...
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.
void 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).
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 specific rate limit ID and returns a future with the respon...
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.
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 > 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.
void set_rate_limit_rps(long requests_per_second, RateLimitType type=RateLimitType::RL_GENERAL)
Sets the rate limit based on requests per second (RPS).
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.
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.
bool is_general_limit_owned
Flag indicating if the client owns the general rate limit.
void assign_rate_limit_id(long limit_id, RateLimitType type=RateLimitType::RL_GENERAL)
Assigns an existing rate limit to the HTTP request.
void set_retry_attempts(long retry_attempts, long retry_delay_ms)
Sets retry attempts and delay between retries for HTTP requests.
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_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_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 specific rate limit ID and returns a future with the respons...
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.
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.
HttpClient(const std::string &host)
Constructs an HttpClient with the specified host.
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 specific rate limit ID.
static HttpResponsePtr make_submit_error_response(const SubmitResult &submit_result)
Creates a ready HTTP response describing a synchronous submission rejection.
static void ensure_initialized()
Ensures that the network worker and request manager are initialized.
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.
void set_debug_header(bool debug_header)
Enables or disables debug headers.
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.
void set_dnt(const bool value)
Sets the Do Not Track (DNT) header value.
bool is_specific_limit_owned
Flag indicating if the client owns the specific rate limit.
void set_rate_limit_rpm(long requests_per_minute, RateLimitType type=RateLimitType::RL_GENERAL)
Sets the rate limit based on requests per minute (RPM).
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 the specified method, path, parameters, and specific rate limit ID.
void operator=(const HttpClient &)=delete
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 the active request associated with this client and waits for its completion.
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.
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.
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.
RateLimitType
Defines rate limit scope categories.
@ RL_GENERAL
Applies globally to all requests.
@ RL_SPECIFIC
Applies to specific client/request.
void safe_set_response(std::shared_ptr< std::promise< HttpResponsePtr > > promise, HttpResponsePtr response)
Safely sets an HTTP response on the provided promise.
ProxyType
Enumeration of supported proxy types compatible with libcurl.
std::unique_ptr< HttpResponse > HttpResponsePtr
A unique pointer to an HttpResponse object for memory management.
utils::CaseInsensitiveMultimap Headers
Alias for HTTP headers, providing a case-insensitive unordered multimap.
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.
Represents the synchronous result of trying to enqueue or submit work.
std::error_code error_code
Describes the rejection reason when accepted is false.