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