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