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