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 {
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
54/// HTTP Authorization types
55enum class HttpAuthType {
56 kBasic, ///< "basic"
57 kDigest, ///< "digest"
58 kDigestIE, ///< "digest_ie"
59 kNegotiate, ///< "negotiate"
60 kNtlm, ///< "ntlm"
61 kNtlmWb, ///< "ntlm_wb"
62 kAny, ///< "any"
63 kAnySafe, ///< "any_safe"
64};
65
66/// HTTP Proxy Authorization types
67enum class ProxyAuthType {
68 kBasic, ///< "basic"
69 kDigest, ///< "digest"
70 kDigestIE, ///< "digest_ie"
71 kBearer, ///< "bearer"
72 kNegotiate, ///< "negotiate"
73 kNtlm, ///< "ntlm"
74 kNtlmWb, ///< "ntlm_wb"
75 kAny, ///< "any"
76 kAnySafe, ///< "any_safe"
77};
78
79ProxyAuthType ProxyAuthTypeFromString(std::string_view auth_name);
80
81/// @brief Class for creating and performing new http requests, usually retieved from @ref clients::http::Client.
82class Request final {
83public:
84 /// Request cookies container type
85 using Cookies = std::unordered_map<std::string, std::string, utils::StrCaseHash>;
86
87 /// @cond
88 // For internal use only.
89 explicit Request(
90 impl::EasyWrapper&&,
91 RequestStats&& req_stats,
92 const std::shared_ptr<DestinationStatistics>& dest_stats,
93 clients::dns::Resolver* resolver,
94 const std::vector<utils::NotNull<clients::http::Plugin*>>& plugins,
95 const tracing::TracingManagerBase& tracing_manager
96 );
97 /// @endcond
98
99 /// Specifies method
100 Request& method(HttpMethod method) &;
101 /// @overload
102 Request method(HttpMethod method) &&;
103
104 /// GET request
105 Request& get() &;
106 /// @overload
107 Request get() &&;
108 /// @overload
109 Request& get(std::string url) &;
110 /// @overload
111 Request get(std::string url) &&;
112
113 /// HEAD request
114 Request& head() &;
115 /// @overload
116 Request head() &&;
117 /// @overload
118 Request& head(std::string url) &;
119 /// @overload
120 Request head(std::string url) &&;
121
122 /// POST request
123 Request& post() &;
124 /// @overload
125 Request post() &&;
126 /// @overload
127 Request& post(std::string url, std::string data = {}) &;
128 /// @overload
129 Request post(std::string url, std::string data = {}) &&;
130 /// @overload
131 Request& post(std::string url, Form&& form) &;
132 /// @overload
133 Request post(std::string url, Form&& form) &&;
134
135 /// PUT request
136 Request& put() &;
137 /// @overload
138 Request put() &&;
139 /// @overload
140 Request& put(std::string url, std::string data = {}) &;
141 /// @overload
142 Request put(std::string url, std::string data = {}) &&;
143
144 /// PATCH request
145 Request& patch() &;
146 /// @overload
147 Request patch() &&;
148 /// @overload
149 Request& patch(std::string url, std::string data = {}) &;
150 /// @overload
151 Request patch(std::string url, std::string data = {}) &&;
152
153 /// DELETE request
154 Request& delete_method() &;
155 /// @overload
156 Request delete_method() &&;
157 /// @overload
158 Request& delete_method(std::string url) &;
159 /// @overload
160 Request delete_method(std::string url) &&;
161 /// @overload
162 Request& delete_method(std::string url, std::string data) &;
163 /// @overload
164 Request delete_method(std::string url, std::string data) &&;
165
166 /// Set custom request method. Only replaces name of the HTTP method
167 Request& set_custom_http_request_method(std::string method) &;
168 /// @overload
169 Request set_custom_http_request_method(std::string method) &&;
170
171 /// url if you don't specify request type with url
172 Request& url(std::string url) &;
173 /// @overload
174 Request url(std::string url) &&;
175
176 /// Set data for POST request
177 Request& data(std::string data) &;
178 /// @overload
179 Request data(std::string data) &&;
180
181 /// Set 'form' for POST request
182 Request& form(Form&& form) &;
183 /// @overload
184 Request form(Form&& form) &&;
185
186 /// Set headers for request
187 Request& headers(const Headers& headers) &;
188 /// @overload
189 Request headers(const Headers& headers) &&;
190 /// @overload
191 Request& headers(const std::initializer_list<std::pair<utils::zstring_view, utils::zstring_view>>& headers) &;
192 /// @overload
193 Request headers(const std::initializer_list<std::pair<utils::zstring_view, utils::zstring_view>>& headers) &&;
194
195 /// Sets http auth type to use.
196 Request&
197 http_auth_type(HttpAuthType value, bool auth_only, utils::zstring_view user, utils::zstring_view password) &;
198 /// @overload
199 Request
200 http_auth_type(HttpAuthType value, bool auth_only, utils::zstring_view user, utils::zstring_view password) &&;
201
202 /// Set proxy headers for request
203 Request& proxy_headers(const Headers& headers) &;
204 /// @overload
205 Request proxy_headers(const Headers& headers) &&;
206 /// @overload
207 Request& proxy_headers(const std::initializer_list<std::pair<utils::zstring_view, utils::zstring_view>>& headers) &;
208 /// @overload
209 Request proxy_headers(const std::initializer_list<std::pair<utils::zstring_view, utils::zstring_view>>& headers) &&;
210
211 /// Sets the User-Agent header
212 Request& user_agent(utils::zstring_view value) &;
213 /// @overload
214 Request user_agent(utils::zstring_view value) &&;
215
216 /// Sets proxy to use.
217 ///
218 /// Example: [::1]:1080
219 /// Empty string disables proxy.
220 Request& proxy(utils::zstring_view value) &;
221 /// @overload
222 Request proxy(utils::zstring_view value) &&;
223
224 /// Sets proxy auth type to use.
226 /// @overload
228
229 /// Cookies for request as HashDos-safe map
230 Request& cookies(const Cookies& cookies) &;
231 /// Cookies for request as HashDos-safe map
232 Request cookies(const Cookies& cookies) &&;
233
234 /// Cookies for request as map
235 Request& cookies(const std::unordered_map<std::string, std::string>& cookies) &;
236 /// Cookies for request as map
237 Request cookies(const std::unordered_map<std::string, std::string>& cookies) &&;
238
239 /// Follow redirects or not. Default: follow
240 Request& follow_redirects(bool follow = true) &;
241 /// @overload
242 Request follow_redirects(bool follow = true) &&;
243
244 /// The maximum time in milliseconds for the entire transfer operation (from name lookup and connection
245 /// construction to the end of data acquisition).
246 Request& timeout(long timeout_ms) &;
247 /// @overload
248 Request timeout(long timeout_ms) &&;
249 /// @overload
250 Request& timeout(std::chrono::milliseconds timeout_ms) & { return timeout(timeout_ms.count()); }
251 /// @overload
252 Request timeout(std::chrono::milliseconds timeout_ms) && { return std::move(this->timeout(timeout_ms.count())); }
253
254 /// Verify host and peer or not. Default: verify
255 Request& verify(bool verify = true) &;
256 /// @overload
257 Request verify(bool verify = true) &&;
258
259 /// Set file holding one or more certificates to verify the peer with
260 Request& ca_info(utils::zstring_view file_path) &;
261 /// @overload
262 Request ca_info(utils::zstring_view file_path) &&;
263
264 /// Set CA
265 Request& ca(crypto::Certificate cert) &;
266 /// @overload
267 Request ca(crypto::Certificate cert) &&;
268
269 /// Set CRL-file
270 Request& crl_file(utils::zstring_view file_path) &;
271 /// @overload
272 Request crl_file(utils::zstring_view file_path) &&;
273
274 /// Set private client key and certificate for request.
275 ///
276 /// @warning Do not use this function on MacOS as it may cause Segmentation Fault on that platform.
278 /// @overload
280
281 /// Set HTTP version
282 Request& http_version(HttpVersion version) &;
283 /// @overload
284 Request http_version(HttpVersion version) &&;
285
286 /// Specify number of retries on incorrect status, if on_fails is True
287 /// retry on network error too. Retries = 3 means that maximum 3 request will be performed.
288 ///
289 /// Retries use exponential backoff with jitter - an exponentially increasing
290 /// randomized delay is added before each retry of this request.
291 Request& retry(short retries = 3, bool on_fails = true) &;
292 Request retry(short retries = 3, bool on_fails = true) &&;
293
294 /// Set unix domain socket as connection endpoint and provide path to it
295 /// When enabled, request will connect to the Unix domain socket instead
296 /// of establishing a TCP connection to a host.
298 Request unix_socket_path(utils::zstring_view path) &&;
299
300 /// Set CURL_IPRESOLVE_V4 for ipv4 resolving
301 Request& use_ipv4() &;
302 /// @overload
303 Request use_ipv4() &&;
304
305 /// Set CURL_IPRESOLVE_V6 for ipv6 resolving
306 Request& use_ipv6() &;
307 /// @overload
308 Request use_ipv6() &&;
309
310 /// Set CURLOPT_CONNECT_TO option
311 /// @warning connect_to argument must outlive Request
312 Request& connect_to(const ConnectTo& connect_to) &;
313 /// @overload
314 Request connect_to(const ConnectTo& connect_to) &&;
315
316 /// @overload
317 template <typename T>
318 std::enable_if_t<std::is_same_v<ConnectTo, T>, Request&> connect_to(T&&) {
319 static_assert(!sizeof(T), "ConnectTo argument must not be temporary, it must outlive Request");
320 return *this;
321 }
322
323 /// Override list of plugins from @ref components::HttpClient for specific request
324 Request& SetPluginsList(const std::vector<utils::NotNull<Plugin*>>& plugins) &;
325
326 /// Override log URL. Useful for "there's a secret in the query".
327 /// @warning The query might be logged by other intermediate HTTP agents (nginx, L7 balancer, etc.).
328 Request& SetLoggedUrl(std::string url) &;
329 /// @overload
330 Request SetLoggedUrl(std::string url) &&;
331
332 /// Set URL template (low-cardinality) for tracing, i.e. `/v1/user/{user_id}`
333 /// @see https://opentelemetry.io/docs/specs/semconv/registry/attributes/url/
334 Request& SetUrlTemplate(std::string url_template) &;
335 /// @overload
336 Request SetUrlTemplate(std::string url_template) &&;
337
338 /// Set destination name in metric "httpclient.destinations.<name>".
339 /// If not set, defaults to HTTP path. Should be called for all requests
340 /// with parameters in HTTP path.
341 Request& SetDestinationMetricName(const std::string& destination) &;
342 /// @overload
343 Request SetDestinationMetricName(const std::string& destination) &&;
344
345 /// @cond
346 // Set testsuite related settings. For internal use only.
347 void SetTestsuiteConfig(const std::shared_ptr<const TestsuiteConfig>& config) &;
348
349 void SetAllowedUrlsExtra(const std::vector<std::string>& urls) &;
350
351 // Set deadline propagation settings. For internal use only.
352 void SetDeadlinePropagationConfig(const DeadlinePropagationConfig& deadline_propagation_config) &;
353 /// @endcond
354
355 /// Disable auto-decoding of received replies. Useful to proxy replies 'as is'.
357 /// @overload
359
360 void SetCancellationPolicy(CancellationPolicy cp);
361
362 /// Override the default tracing manager from HTTP client for this particular request.
364 /// @overload
366
367 /// Perform request asynchronously.
368 ///
369 /// Works well with engine::WaitAny, engine::WaitAnyFor, and engine::WaitUntil functions:
370 /// @snippet src/clients/http/client_wait_test.cpp HTTP Client - waitany
371 ///
372 /// Request object could be reused after retrieval of data from ResponseFuture, all the setup holds:
373 /// @snippet src/clients/http/client_test.cpp HTTP Client - reuse async
374 [[nodiscard]] ResponseFuture async_perform(
375 utils::impl::SourceLocation location = utils::impl::SourceLocation::Current()
376 );
377
378 /// @brief Perform a request with streamed response body.
379 ///
380 /// The HTTP client uses queue producer. StreamedResponse uses queue consumer.
381 [[nodiscard]] StreamedResponse async_perform_stream_body(
382 const std::shared_ptr<concurrent::StringStreamQueue>& queue,
383 utils::impl::SourceLocation location = utils::impl::SourceLocation::Current()
384 );
385
386 /// Calls async_perform and wait for timeout_ms on a future. Default time for waiting will be timeout value if it
387 /// was set. If error occurred it will be thrown as exception.
388 ///
389 /// Request object could be reused after return from perform(), all the setup holds:
390 /// @snippet src/clients/http/client_test.cpp HTTP Client - request reuse
391 [[nodiscard]] std::shared_ptr<Response> perform(
392 utils::impl::SourceLocation location = utils::impl::SourceLocation::Current()
393 );
394
395 /// Returns a reference to the original URL of a request
396 const std::string& GetUrl() const&;
397 /// @overload
398 const std::string& GetUrl() && = delete;
399
400 /// Returns a reference to the HTTP body of a request to send
401 const std::string& GetData() const&;
402 /// @overload
403 const std::string& GetData() && = delete;
404
405 /// Returns HTTP body of a request, leaving it empty
406 std::string ExtractData();
407
408private:
409 std::shared_ptr<RequestState> pimpl_;
410};
411
412} // namespace clients::http
413
414USERVER_NAMESPACE_END