userver: userver/clients/http/client_core.hpp Source File
Loading...
Searching...
No Matches
client_core.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/clients/http/client_core.hpp
4/// @brief @copybrief clients::http::ClientCore
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/client.hpp>
16#include <userver/clients/http/config.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/impl/internal_tag.hpp>
22#include <userver/utils/not_null.hpp>
23#include <userver/utils/periodic_task.hpp>
24#include <userver/utils/swappingsmart.hpp>
25#include <userver/yaml_config/fwd.hpp>
26
27USERVER_NAMESPACE_BEGIN
28
29namespace tracing {
31} // namespace tracing
32
33namespace curl {
34class easy;
35class multi;
36class ConnectRateLimiter;
37} // namespace curl
38
39namespace engine::ev {
40class ThreadPool;
41} // namespace engine::ev
42
43namespace clients::http {
44namespace impl {
45class EasyWrapper;
46} // namespace impl
47
48struct TestsuiteConfig;
49class Statistics;
50struct PoolStatistics;
51struct InstanceStatistics;
52class DestinationStatistics;
53
54/// @ingroup userver_clients
55///
56/// @brief HTTP client that returns a HTTP request builder from
57/// CreateRequest().
58///
59/// Usually retrieved from @ref components::HttpClientCore component.
60///
61/// ## Example usage:
62///
63/// @snippet clients/http/client_test.cpp Sample HTTP Client usage
64class ClientCore final : public Client {
65public:
66 /// @cond
67 // For internal use only
68 ClientCore(utils::impl::InternalTag, ClientSettings settings, engine::TaskProcessor& fs_task_processor);
69 /// @endcond
70
71 ~ClientCore() override;
72
73 /// @brief Returns a HTTP request builder type with preset values of
74 /// User-Agent and some of the Testsuite stuff (if any).
75 ///
76 /// @note This method does not apply plugins, they could be applied
77 /// manually using @ref clients::http::Request::SetPluginsList()
78 /// @note This method is thread-safe despite being non-const.
79 Request CreateRequest() override;
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(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
107 // For internal use only.
108 void ResetUserAgent(std::optional<std::string> user_agent = std::nullopt);
109
110 // For internal use only.
111 void SetDnsResolver(clients::dns::Resolver* resolver);
112 /// @endcond
113
114private:
115 void ReinitEasy();
116
117 InstanceStatistics GetMultiStatistics(size_t n) const;
118
119 size_t FindMultiIndex(const curl::multi*) const;
120
121 // Functions for EasyWrapper that must be noexcept, as they are called from
122 // the EasyWrapper destructor.
123 friend class impl::EasyWrapper;
124 void IncPending() noexcept { ++pending_tasks_; }
125 void DecPending() noexcept { --pending_tasks_; }
126 void PushIdleEasy(std::shared_ptr<curl::easy>&& easy) noexcept;
127
128 std::shared_ptr<curl::easy> TryDequeueIdle() noexcept;
129
130 std::atomic<std::size_t> pending_tasks_{0};
131
132 const DeadlinePropagationConfig deadline_propagation_config_;
133 CancellationPolicy cancellation_policy_;
134
135 std::shared_ptr<DestinationStatistics> destination_statistics_;
136 std::unique_ptr<engine::ev::ThreadPool> thread_pool_;
137 std::vector<Statistics> statistics_;
138 std::vector<std::unique_ptr<curl::multi>> multis_;
139
140 static constexpr size_t kIdleQueueSize = 616;
141 static constexpr size_t kIdleQueueAlignment = 8;
142 using IdleQueueTraits = moodycamel::ConcurrentQueueDefaultTraits;
143 using IdleQueueValue = std::shared_ptr<curl::easy>;
144 using IdleQueue = moodycamel::ConcurrentQueue<IdleQueueValue, IdleQueueTraits>;
145 utils::FastPimpl<IdleQueue, kIdleQueueSize, kIdleQueueAlignment> idle_queue_;
146
147 engine::TaskProcessor& fs_task_processor_;
148 std::optional<std::string> user_agent_;
149
150 utils::SwappingSmart<const curl::easy> easy_;
151 utils::PeriodicTask easy_reinit_task_;
152
153 // Testsuite support
154 std::shared_ptr<const TestsuiteConfig> testsuite_config_;
155 rcu::Variable<std::vector<std::string>> allowed_urls_extra_;
156
157 std::shared_ptr<curl::ConnectRateLimiter> connect_rate_limiter_;
158
159 clients::dns::Resolver* resolver_{nullptr};
160 utils::NotNull<const tracing::TracingManagerBase*> tracing_manager_;
161};
162
163} // namespace clients::http
164
165USERVER_NAMESPACE_END