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