userver: userver/clients/http/client.hpp Source File
Loading...
Searching...
No Matches
client.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/clients/http/client.hpp
4/// @brief @copybrief clients::http::Client
5
6#ifdef USERVER_TVM2_HTTP_CLIENT
7#error Use clients::Http from clients/http.hpp instead
8#endif
9
10#include <memory>
11
12#include <userver/moodycamel/concurrentqueue_fwd.h>
13
14#include <userver/clients/dns/resolver_fwd.hpp>
15#include <userver/clients/http/config.hpp>
16#include <userver/clients/http/plugin.hpp>
17#include <userver/clients/http/request.hpp>
18#include <userver/engine/task/task_processor_fwd.hpp>
19#include <userver/rcu/rcu.hpp>
20#include <userver/utils/fast_pimpl.hpp>
21#include <userver/utils/not_null.hpp>
22#include <userver/utils/periodic_task.hpp>
23#include <userver/utils/swappingsmart.hpp>
24#include <userver/yaml_config/fwd.hpp>
25
26USERVER_NAMESPACE_BEGIN
27
28namespace tracing {
29class TracingManagerBase;
30} // namespace tracing
31
32namespace curl {
33class easy;
34class multi;
35class ConnectRateLimiter;
36} // namespace curl
37
38namespace engine::ev {
39class ThreadPool;
40} // namespace engine::ev
41
42namespace clients::http {
43namespace impl {
44class EasyWrapper;
45} // namespace impl
46
47struct TestsuiteConfig;
48class Statistics;
49struct PoolStatistics;
50struct InstanceStatistics;
51class DestinationStatistics;
52
53/// @ingroup userver_clients
54///
55/// @brief HTTP client that returns a HTTP request builder from
56/// CreateRequest().
57///
58/// Usually retrieved from components::HttpClient component.
59///
60/// ## Example usage:
61///
62/// @snippet clients/http/client_test.cpp Sample HTTP Client usage
63class Client final {
64public:
65 Client(
66 ClientSettings settings,
67 engine::TaskProcessor& fs_task_processor,
68 std::vector<utils::NotNull<clients::http::Plugin*>> plugins
69 );
70
71 ~Client();
72
73 /// @brief Returns a HTTP request builder type with preset values of
74 /// User-Agent, Proxy and some of the Testsuite suff (if any).
75 ///
76 /// @note This method is thread-safe despite being non-const.
77 Request CreateRequest();
78
79 /// Providing CreateNonSignedRequest() function for the clients::Http alias.
80 ///
81 /// @note This method is thread-safe despite being non-const.
83
84 /// @cond
85 // For internal use only.
86 void SetMultiplexingEnabled(bool enabled);
87
88 // For internal use only.
89 void SetMaxHostConnections(size_t max_host_connections);
90
91 // For internal use only.
92 PoolStatistics GetPoolStatistics() const;
93
94 // Set max number of automatically created destination metrics.
95 // For internal use only.
96 void SetDestinationMetricsAutoMaxSize(size_t max_size);
97
98 // For internal use only.
99 const http::DestinationStatistics& GetDestinationStatistics() const;
100
101 // For internal use only.
102 void SetTestsuiteConfig(const TestsuiteConfig& config);
103
104 // For internal use only.
105 void SetAllowedUrlsExtra(std::vector<std::string>&& urls);
106
107 // For internal use only.
108 void SetConfig(const impl::Config&);
109 /// @endcond
110
111 /// @brief Sets User-Agent headers for all the requests or removes that
112 /// header.
113 ///
114 /// By default User-Agent is set by components::HttpClient to the
115 /// userver identity string.
116 void ResetUserAgent(std::optional<std::string> user_agent = std::nullopt);
117
118 /// @brief Returns the current proxy that is automatically used for each
119 /// request.
120 ///
121 /// @warning The value may become immediately obsolete as the proxy could be
122 /// concurrently changed from runtime config.
123 std::string GetProxy() const;
124
125 /// @brief Sets the DNS resolver to use.
126 ///
127 /// If given nullptr, the default resolver will be used
128 /// (most likely getaddrinfo).
129 void SetDnsResolver(clients::dns::Resolver* resolver);
130
131private:
132 void ReinitEasy();
133
134 InstanceStatistics GetMultiStatistics(size_t n) const;
135
136 size_t FindMultiIndex(const curl::multi*) const;
137
138 // Functions for EasyWrapper that must be noexcept, as they are called from
139 // the EasyWrapper destructor.
140 friend class impl::EasyWrapper;
141 void IncPending() noexcept { ++pending_tasks_; }
142 void DecPending() noexcept { --pending_tasks_; }
143 void PushIdleEasy(std::shared_ptr<curl::easy>&& easy) noexcept;
144
145 std::shared_ptr<curl::easy> TryDequeueIdle() noexcept;
146
147 std::atomic<std::size_t> pending_tasks_{0};
148
149 const DeadlinePropagationConfig deadline_propagation_config_;
150 CancellationPolicy cancellation_policy_;
151
152 std::shared_ptr<DestinationStatistics> destination_statistics_;
153 std::unique_ptr<engine::ev::ThreadPool> thread_pool_;
154 std::vector<Statistics> statistics_;
155 std::vector<std::unique_ptr<curl::multi>> multis_;
156
157 static constexpr size_t kIdleQueueSize = 616;
158 static constexpr size_t kIdleQueueAlignment = 8;
159 using IdleQueueTraits = moodycamel::ConcurrentQueueDefaultTraits;
160 using IdleQueueValue = std::shared_ptr<curl::easy>;
161 using IdleQueue = moodycamel::ConcurrentQueue<IdleQueueValue, IdleQueueTraits>;
162 utils::FastPimpl<IdleQueue, kIdleQueueSize, kIdleQueueAlignment> idle_queue_;
163
164 engine::TaskProcessor& fs_task_processor_;
165 std::optional<std::string> user_agent_;
166 rcu::Variable<std::string> proxy_;
167
168 utils::SwappingSmart<const curl::easy> easy_;
169 utils::PeriodicTask easy_reinit_task_;
170
171 // Testsuite support
172 std::shared_ptr<const TestsuiteConfig> testsuite_config_;
173 rcu::Variable<std::vector<std::string>> allowed_urls_extra_;
174
175 std::shared_ptr<curl::ConnectRateLimiter> connect_rate_limiter_;
176
177 clients::dns::Resolver* resolver_{nullptr};
178 utils::NotNull<const tracing::TracingManagerBase*> tracing_manager_;
179 std::vector<utils::NotNull<clients::http::Plugin*>> plugins_;
180};
181
182} // namespace clients::http
183
184USERVER_NAMESPACE_END