userver: userver/clients/http/request.hpp Source File
Loading...
Searching...
No Matches
request.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/clients/http/request.hpp
4/// @brief @copybrief clients::http::Request
5
6#include <memory>
7#include <string_view>
8#include <vector>
9
10#include <userver/clients/dns/resolver_fwd.hpp>
11#include <userver/clients/http/error.hpp>
12#include <userver/clients/http/plugin.hpp>
13#include <userver/clients/http/response.hpp>
14#include <userver/clients/http/response_future.hpp>
15#include <userver/concurrent/queue.hpp>
16#include <userver/crypto/certificate.hpp>
17#include <userver/crypto/private_key.hpp>
18#include <userver/http/http_version.hpp>
19#include <userver/utils/impl/source_location.hpp>
20
21USERVER_NAMESPACE_BEGIN
22
23namespace tracing {
24class TracingManagerBase;
25} // namespace tracing
26
27/// HTTP client helpers
28namespace clients::http {
29
30class RequestState;
31class StreamedResponse;
32class ConnectTo;
33class Form;
35class RequestStats;
36class DestinationStatistics;
37struct TestsuiteConfig;
38
39namespace impl {
40class EasyWrapper;
41} // namespace impl
42
43/// @brief HTTP request method
44enum class HttpMethod { kGet, kPost, kHead, kPut, kDelete, kPatch, kOptions };
45
46/// @brief Convert HTTP method enum value to string
47std::string_view ToStringView(HttpMethod method);
48
49/// @brief Convert HTTP method string to enum value
50HttpMethod HttpMethodFromString(std::string_view method_str);
51
52using USERVER_NAMESPACE::http::HttpVersion;
53
54enum class HttpAuthType {
55 kBasic, ///< "basic"
56 kDigest, ///< "digest"
57 kDigestIE, ///< "digest_ie"
58 kNegotiate, ///< "negotiate"
59 kNtlm, ///< "ntlm"
60 kNtlmWb, ///< "ntlm_wb"
61 kAny, ///< "any"
62 kAnySafe, ///< "any_safe"
63};
64
65enum class ProxyAuthType {
66 kBasic, ///< "basic"
67 kDigest, ///< "digest"
68 kDigestIE, ///< "digest_ie"
69 kBearer, ///< "bearer"
70 kNegotiate, ///< "negotiate"
71 kNtlm, ///< "ntlm"
72 kNtlmWb, ///< "ntlm_wb"
73 kAny, ///< "any"
74 kAnySafe, ///< "any_safe"
75};
76
77ProxyAuthType ProxyAuthTypeFromString(std::string_view auth_name);
78
79/// Class for creating and performing new http requests
80class Request final {
81public:
82 /// Request cookies container type
83 using Cookies = std::unordered_map<std::string, std::string, utils::StrCaseHash>;
84
85 /// @cond
86 // For internal use only.
87 explicit Request(
88 impl::EasyWrapper&&,
89 RequestStats&& req_stats,
90 const std::shared_ptr<DestinationStatistics>& dest_stats,
91 clients::dns::Resolver* resolver,
92 const std::vector<utils::NotNull<clients::http::Plugin*>>& plugins,
93 const tracing::TracingManagerBase& tracing_manager
94 );
95 /// @endcond
96
97 /// Specifies method
98 Request& method(HttpMethod method) &;
99 Request method(HttpMethod method) &&;
100 /// GET request
101 Request& get() &;
102 Request get() &&;
103 /// GET request with url
104 Request& get(std::string url) &;
105 Request get(std::string url) &&;
106 /// HEAD request
107 Request& head() &;
108 Request head() &&;
109 /// HEAD request with url
110 Request& head(std::string url) &;
111 Request head(std::string url) &&;
112 /// POST request
113 Request& post() &;
114 Request post() &&;
115 /// POST request with url and data
116 Request& post(std::string url, std::string data = {}) &;
117 Request post(std::string url, std::string data = {}) &&;
118 /// POST request with url and multipart/form-data
119 Request& post(std::string url, Form&& form) &;
120 Request post(std::string url, Form&& form) &&;
121 /// PUT request
122 Request& put() &;
123 Request put() &&;
124 /// PUT request with url and data
125 Request& put(std::string url, std::string data = {}) &;
126 Request put(std::string url, std::string data = {}) &&;
127
128 /// PATCH request
129 Request& patch() &;
130 Request patch() &&;
131 /// PATCH request with url and data
132 Request& patch(std::string url, std::string data = {}) &;
133 Request patch(std::string url, std::string data = {}) &&;
134
135 /// DELETE request
136 Request& delete_method() &;
137 Request delete_method() &&;
138 /// DELETE request with url
139 Request& delete_method(std::string url) &;
140 Request delete_method(std::string url) &&;
141 /// DELETE request with url and data
142 Request& delete_method(std::string url, std::string data) &;
143 Request delete_method(std::string url, std::string data) &&;
144
145 /// Set custom request method. Only replaces name of the HTTP method
146 Request& set_custom_http_request_method(std::string method) &;
147 Request set_custom_http_request_method(std::string method) &&;
148
149 /// url if you don't specify request type with url
150 Request& url(std::string url) &;
151 Request url(std::string url) &&;
152 /// data for POST request
153 Request& data(std::string data) &;
154 Request data(std::string data) &&;
155 /// form for POST request
156 Request& form(Form&& form) &;
157 Request form(Form&& form) &&;
158 /// Headers for request as map
159 Request& headers(const Headers& headers) &;
160 Request headers(const Headers& headers) &&;
161 /// Headers for request as list
162 Request& headers(const std::initializer_list<std::pair<utils::zstring_view, utils::zstring_view>>& headers) &;
163 Request headers(const std::initializer_list<std::pair<utils::zstring_view, utils::zstring_view>>& headers) &&;
164 /// Sets http auth type to use.
165 Request&
166 http_auth_type(HttpAuthType value, bool auth_only, utils::zstring_view user, utils::zstring_view password) &;
167 Request
168 http_auth_type(HttpAuthType value, bool auth_only, utils::zstring_view user, utils::zstring_view password) &&;
169 /// Proxy headers for request as map
170 Request& proxy_headers(const Headers& headers) &;
171 Request proxy_headers(const Headers& headers) &&;
172 /// Proxy headers for request as list
173 Request& proxy_headers(const std::initializer_list<std::pair<utils::zstring_view, utils::zstring_view>>& headers) &;
174 Request proxy_headers(const std::initializer_list<std::pair<utils::zstring_view, utils::zstring_view>>& headers) &&;
175 /// Sets the User-Agent header
176 Request& user_agent(utils::zstring_view value) &;
177 Request user_agent(utils::zstring_view value) &&;
178 /// Sets proxy to use. Example: [::1]:1080
179 Request& proxy(utils::zstring_view value) &;
180 Request proxy(utils::zstring_view value) &&;
181 /// Sets proxy auth type to use.
183 Request proxy_auth_type(ProxyAuthType value) &&;
184 /// Cookies for request as HashDos-safe map
185 Request& cookies(const Cookies& cookies) &;
186 Request cookies(const Cookies& cookies) &&;
187 /// Cookies for request as map
188 Request& cookies(const std::unordered_map<std::string, std::string>& cookies) &;
189 Request cookies(const std::unordered_map<std::string, std::string>& cookies) &&;
190 /// Follow redirects or not. Default: follow
191 Request& follow_redirects(bool follow = true) &;
192 Request follow_redirects(bool follow = true) &&;
193 /// Set timeout in ms for request
194 Request& timeout(long timeout_ms) &;
195 Request timeout(long timeout_ms) &&;
196 Request& timeout(std::chrono::milliseconds timeout_ms) & { return timeout(timeout_ms.count()); }
197 Request timeout(std::chrono::milliseconds timeout_ms) && { return std::move(this->timeout(timeout_ms.count())); }
198 /// Verify host and peer or not. Default: verify
199 Request& verify(bool verify = true) &;
200 Request verify(bool verify = true) &&;
201 /// Set file holding one or more certificates to verify the peer with
202 Request& ca_info(utils::zstring_view file_path) &;
203 Request ca_info(utils::zstring_view file_path) &&;
204 /// Set CA
205 Request& ca(crypto::Certificate cert) &;
206 Request ca(crypto::Certificate cert) &&;
207 /// Set CRL-file
208 Request& crl_file(utils::zstring_view file_path) &;
209 Request crl_file(utils::zstring_view file_path) &&;
210 /// Set private client key and certificate for request.
211 ///
212 /// @warning Do not use this function on MacOS as it may cause Segmentation
213 /// Fault on that platform.
215 Request client_key_cert(crypto::PrivateKey pkey, crypto::Certificate cert) &&;
216 /// Set HTTP version
217 Request& http_version(HttpVersion version) &;
218 Request http_version(HttpVersion version) &&;
219
220 /// Specify number of retries on incorrect status, if on_fails is True
221 /// retry on network error too. Retries = 3 means that maximum 3 request
222 /// will be performed.
223 ///
224 /// Retries use exponential backoff with jitter - an exponentially increasing
225 /// randomized delay is added before each retry of this request.
226 Request& retry(short retries = 3, bool on_fails = true) &;
227 Request retry(short retries = 3, bool on_fails = true) &&;
228
229 /// Set unix domain socket as connection endpoint and provide path to it
230 /// When enabled, request will connect to the Unix domain socket instead
231 /// of establishing a TCP connection to a host.
233 Request unix_socket_path(utils::zstring_view path) &&;
234
235 /// Set CURL_IPRESOLVE_V4 for ipv4 resolving
236 Request& use_ipv4() &;
237 Request use_ipv4() &&;
238 /// Set CURL_IPRESOLVE_V6 for ipv6 resolving
239 Request& use_ipv6() &;
240 Request use_ipv6() &&;
241
242 /// Set CURLOPT_CONNECT_TO option
243 /// @warning connect_to argument must outlive Request
244 Request& connect_to(const ConnectTo& connect_to) &;
245 Request connect_to(const ConnectTo& connect_to) &&;
246
247 template <typename T>
248 std::enable_if_t<std::is_same_v<ConnectTo, T>, Request&> connect_to(T&&) {
249 static_assert(!sizeof(T), "ConnectTo argument must not be temporary, it must outlive Request");
250 return *this;
251 }
252
253 /// Override list of plugins from @ref components::HttpClient for specific request
254 Request& SetPluginsList(const std::vector<utils::NotNull<Plugin*>>& plugins) &;
255
256 /// Override log URL. Useful for "there's a secret in the query".
257 /// @warning The query might be logged by other intermediate HTTP agents
258 /// (nginx, L7 balancer, etc.).
259 Request& SetLoggedUrl(std::string url) &;
260 Request SetLoggedUrl(std::string url) &&;
261
262 /// Set destination name in metric "httpclient.destinations.<name>".
263 /// If not set, defaults to HTTP path. Should be called for all requests
264 /// with parameters in HTTP path.
265 Request& SetDestinationMetricName(const std::string& destination) &;
266 Request SetDestinationMetricName(const std::string& destination) &&;
267
268 /// @cond
269 // Set testsuite related settings. For internal use only.
270 void SetTestsuiteConfig(const std::shared_ptr<const TestsuiteConfig>& config) &;
271
272 void SetAllowedUrlsExtra(const std::vector<std::string>& urls) &;
273
274 // Set deadline propagation settings. For internal use only.
275 void SetDeadlinePropagationConfig(const DeadlinePropagationConfig& deadline_propagation_config) &;
276 /// @endcond
277
278 /// Disable auto-decoding of received replies.
279 /// Useful to proxy replies 'as is'.
281 Request DisableReplyDecoding() &&;
282
283 void SetCancellationPolicy(CancellationPolicy cp);
284
285 /// Override the default tracing manager from HTTP client for this
286 /// particular request.
287 Request& SetTracingManager(const tracing::TracingManagerBase&) &;
288 Request SetTracingManager(const tracing::TracingManagerBase&) &&;
289
290 /// Perform request asynchronously.
291 ///
292 /// Works well with engine::WaitAny, engine::WaitAnyFor, and
293 /// engine::WaitUntil functions:
294 /// @snippet src/clients/http/client_wait_test.cpp HTTP Client - waitany
295 ///
296 /// Request object could be reused after retrieval of data from
297 /// ResponseFuture, all the setup holds:
298 /// @snippet src/clients/http/client_test.cpp HTTP Client - reuse async
299 [[nodiscard]] ResponseFuture async_perform(
300 utils::impl::SourceLocation location = utils::impl::SourceLocation::Current()
301 );
302
303 /// @brief Perform a request with streamed response body.
304 ///
305 /// The HTTP client uses queue producer.
306 /// StreamedResponse uses queue consumer.
307 [[nodiscard]] StreamedResponse async_perform_stream_body(
308 const std::shared_ptr<concurrent::StringStreamQueue>& queue,
309 utils::impl::SourceLocation location = utils::impl::SourceLocation::Current()
310 );
311
312 /// Calls async_perform and wait for timeout_ms on a future. Default time
313 /// for waiting will be timeout value if it was set. If error occurred it
314 /// will be thrown as exception.
315 ///
316 /// Request object could be reused after return from perform(), all the
317 /// setup holds:
318 /// @snippet src/clients/http/client_test.cpp HTTP Client - request reuse
319 [[nodiscard]] std::shared_ptr<Response> perform(
320 utils::impl::SourceLocation location = utils::impl::SourceLocation::Current()
321 );
322
323 /// Returns a reference to the original URL of a request
324 const std::string& GetUrl() const&;
325 const std::string& GetUrl() && = delete;
326
327 /// Returns a reference to the HTTP body of a request to send
328 const std::string& GetData() const&;
329 const std::string& GetData() && = delete;
330
331 /// Returns HTTP body of a request, leaving it empty
332 std::string ExtractData();
333
334private:
335 std::shared_ptr<RequestState> pimpl_;
336};
337
338} // namespace clients::http
339
340USERVER_NAMESPACE_END