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