slumber_reqwest/lib.rs
1#![deny(missing_docs)]
2#![deny(missing_debug_implementations)]
3#![cfg_attr(docsrs, feature(doc_cfg))]
4#![cfg_attr(test, deny(warnings))]
5
6//! # reqwest
7//!
8//! The `reqwest` crate provides a convenient, higher-level HTTP
9//! [`Client`][client].
10//!
11//! It handles many of the things that most people just expect an HTTP client
12//! to do for them.
13//!
14//! - Async and [blocking] Clients
15//! - Plain bodies, [JSON](#json), [urlencoded](#forms), [multipart]
16//! - Customizable [redirect policy](#redirect-policies)
17//! - HTTP [Proxies](#proxies)
18//! - Uses [TLS](#tls) by default
19//! - Cookies
20//!
21//! The [`reqwest::Client`][client] is asynchronous (requiring Tokio). For
22//! applications wishing to only make a few HTTP requests, the
23//! [`reqwest::blocking`](blocking) API may be more convenient.
24//!
25//! Additional learning resources include:
26//!
27//! - [The Rust Cookbook](https://rust-lang-nursery.github.io/rust-cookbook/web/clients.html)
28//! - [reqwest Repository Examples](https://github.com/seanmonstar/reqwest/tree/master/examples)
29//!
30//! ## Commercial Support
31//!
32//! For private advice, support, reviews, access to the maintainer, and the
33//! like, reach out for [commercial support][sponsor].
34//!
35//! ## Making a GET request
36//!
37//! For a single request, you can use the [`get`][get] shortcut method.
38//!
39//! ```rust
40//! # async fn run() -> Result<(), reqwest::Error> {
41//! let body = reqwest::get("https://www.rust-lang.org")
42//! .await?
43//! .text()
44//! .await?;
45//!
46//! println!("body = {body:?}");
47//! # Ok(())
48//! # }
49//! ```
50//!
51//! **NOTE**: If you plan to perform multiple requests, it is best to create a
52//! [`Client`][client] and reuse it, taking advantage of keep-alive connection
53//! pooling.
54//!
55//! ## Making POST requests (or setting request bodies)
56//!
57//! There are several ways you can set the body of a request. The basic one is
58//! by using the `body()` method of a [`RequestBuilder`][builder]. This lets you set the
59//! exact raw bytes of what the body should be. It accepts various types,
60//! including `String` and `Vec<u8>`. If you wish to pass a custom
61//! type, you can use the `reqwest::Body` constructors.
62//!
63//! ```rust
64//! # use reqwest::Error;
65//! #
66//! # async fn run() -> Result<(), Error> {
67//! let client = reqwest::Client::new();
68//! let res = client.post("http://httpbin.org/post")
69//! .body("the exact body that is sent")
70//! .send()
71//! .await?;
72//! # Ok(())
73//! # }
74//! ```
75//!
76//! ### Forms
77//!
78//! It's very common to want to send form data in a request body. This can be
79//! done with any type that can be serialized into form data.
80//!
81//! This can be an array of tuples, or a `HashMap`, or a custom type that
82//! implements [`Serialize`][serde].
83//!
84//! The feature `form` is required.
85//!
86//! ```rust
87//! # use reqwest::Error;
88//! #
89//! # #[cfg(feature = "form")]
90//! # async fn run() -> Result<(), Error> {
91//! // This will POST a body of `foo=bar&baz=quux`
92//! let params = [("foo", "bar"), ("baz", "quux")];
93//! let client = reqwest::Client::new();
94//! let res = client.post("http://httpbin.org/post")
95//! .form(¶ms)
96//! .send()
97//! .await?;
98//! # Ok(())
99//! # }
100//! ```
101//!
102//! ### JSON
103//!
104//! There is also a `json` method helper on the [`RequestBuilder`][builder] that works in
105//! a similar fashion the `form` method. It can take any value that can be
106//! serialized into JSON.
107//!
108//! The feature `json` is required.
109//!
110//! ```rust
111//! # use reqwest::Error;
112//! # use std::collections::HashMap;
113//! #
114//! # #[cfg(feature = "json")]
115//! # async fn run() -> Result<(), Error> {
116//! // This will POST a body of `{"lang":"rust","body":"json"}`
117//! let mut map = HashMap::new();
118//! map.insert("lang", "rust");
119//! map.insert("body", "json");
120//!
121//! let client = reqwest::Client::new();
122//! let res = client.post("http://httpbin.org/post")
123//! .json(&map)
124//! .send()
125//! .await?;
126//! # Ok(())
127//! # }
128//! ```
129//!
130//! ## Redirect Policies
131//!
132//! By default, a `Client` will automatically handle HTTP redirects, having a
133//! maximum redirect chain of 10 hops. To customize this behavior, a
134//! [`redirect::Policy`][redirect] can be used with a `ClientBuilder`.
135//!
136//! ## Cookies
137//!
138//! The automatic storing and sending of session cookies can be enabled with
139//! the [`cookie_store`][ClientBuilder::cookie_store] method on `ClientBuilder`.
140//!
141//! ## Proxies
142//!
143//! **NOTE**: System proxies are enabled by default.
144//!
145//! System proxies look in environment variables to set HTTP or HTTPS proxies.
146//!
147//! `HTTP_PROXY` or `http_proxy` provide HTTP proxies for HTTP connections while
148//! `HTTPS_PROXY` or `https_proxy` provide HTTPS proxies for HTTPS connections.
149//! `ALL_PROXY` or `all_proxy` provide proxies for both HTTP and HTTPS connections.
150//! If both the all proxy and HTTP or HTTPS proxy variables are set the more specific
151//! HTTP or HTTPS proxies take precedence.
152//!
153//! These can be overwritten by adding a [`Proxy`] to `ClientBuilder`
154//! i.e. `let proxy = reqwest::Proxy::http("https://secure.example")?;`
155//! or disabled by calling `ClientBuilder::no_proxy()`.
156//!
157//! `socks` feature is required if you have configured socks proxy like this:
158//!
159//! ```bash
160//! export https_proxy=socks5://127.0.0.1:1086
161//! ```
162//!
163//! ## TLS
164//!
165//! A `Client` will use transport layer security (TLS) by default to connect to
166//! HTTPS destinations.
167//!
168//! - Additional server certificates can be configured on a `ClientBuilder`
169//! with the [`Certificate`] type.
170//! - Client certificates can be added to a `ClientBuilder` with the
171//! [`Identity`] type.
172//! - Various parts of TLS can also be configured or even disabled on the
173//! `ClientBuilder`.
174//!
175//! See more details in the [`tls`] module.
176//!
177//! ## WASM
178//!
179//! The Client implementation automatically switches to the WASM one when the target_arch is wasm32,
180//! the usage is basically the same as the async api. Some of the features are disabled in wasm
181//! : [`tls`], [`cookie`], [`blocking`], as well as various `ClientBuilder` methods such as `timeout()` and `connector_layer()`.
182//!
183//! TLS and cookies are provided through the browser environment, so reqwest can issue TLS requests with cookies,
184//! but has limited configuration.
185//!
186//! ## Optional Features
187//!
188//! The following are a list of [Cargo features][cargo-features] that can be
189//! enabled or disabled:
190//!
191//! - **http2** *(enabled by default)*: Enables HTTP/2 support.
192//! - **default-tls** *(enabled by default)*: Provides TLS support to connect
193//! over HTTPS.
194//! - **rustls**: Enables TLS functionality provided by `rustls`.
195//! - **rustls-no-provider**: Enables TLS provided by `rustls` without specifying a crypto provider.
196//! - **native-tls**: Enables TLS functionality provided by `native-tls`.
197//! - **native-tls-vendored**: Enables the `vendored` feature of `native-tls`.
198//! - **native-tls-no-alpn**: Enables `native-tls` without its `alpn` feature.
199//! - **native-tls-vendored-no-alpn**: Enables `native-tls-vendored` without its `alpn` feature.
200//! - **blocking**: Provides the [blocking][] client API.
201//! - **charset** *(enabled by default)*: Improved support for decoding text.
202//! - **cookies**: Provides cookie session support.
203//! - **gzip**: Provides response body gzip decompression.
204//! - **brotli**: Provides response body brotli decompression.
205//! - **zstd**: Provides response body zstd decompression.
206//! - **deflate**: Provides response body deflate decompression.
207//! - **query**: Provides query parameter serialization.
208//! - **form**: Provides form data serialization.
209//! - **json**: Provides serialization and deserialization for JSON bodies.
210//! - **multipart**: Provides functionality for multipart forms.
211//! - **stream**: Adds support for `futures::Stream`.
212//! - **socks**: Provides SOCKS5 proxy support.
213//! - **hickory-dns**: Enables a hickory-dns async resolver instead of default
214//! threadpool using `getaddrinfo`.
215//! - **system-proxy** *(enabled by default)*: Use Windows and macOS system
216//! proxy settings automatically.
217//!
218//! ## Unstable Features
219//!
220//! Some feature flags require additional opt-in by the application, by setting
221//! a `reqwest_unstable` flag.
222//!
223//! - **http3** *(unstable)*: Enables support for sending HTTP/3 requests.
224//!
225//! These features are unstable, and experimental. Details about them may be
226//! changed in patch releases.
227//!
228//! You can pass such a flag to the compiler via `.cargo/config`, or
229//! environment variables, such as:
230//!
231//! ```notrust
232//! RUSTFLAGS="--cfg reqwest_unstable" cargo build
233//! ```
234//!
235//! ## Sponsors
236//!
237//! Support this project by becoming a [sponsor][].
238//!
239//! [hyper]: https://hyper.rs
240//! [blocking]: ./blocking/index.html
241//! [client]: ./struct.Client.html
242//! [response]: ./struct.Response.html
243//! [get]: ./fn.get.html
244//! [builder]: ./struct.RequestBuilder.html
245//! [serde]: http://serde.rs
246//! [redirect]: crate::redirect
247//! [Proxy]: ./struct.Proxy.html
248//! [cargo-features]: https://doc.rust-lang.org/stable/cargo/reference/manifest.html#the-features-section
249//! [sponsor]: https://seanmonstar.com/sponsor
250
251#[cfg(all(feature = "http3", not(reqwest_unstable)))]
252compile_error!(
253 "\
254 The `http3` feature is unstable, and requires the \
255 `RUSTFLAGS='--cfg reqwest_unstable'` environment variable to be set.\
256"
257);
258
259// Ignore `unused_crate_dependencies` warnings.
260// Used in many features that they're not worth making it optional.
261use futures_core as _;
262use sync_wrapper as _;
263
264macro_rules! if_wasm {
265 ($($item:item)*) => {$(
266 #[cfg(target_arch = "wasm32")]
267 $item
268 )*}
269}
270
271macro_rules! if_hyper {
272 ($($item:item)*) => {$(
273 #[cfg(not(target_arch = "wasm32"))]
274 $item
275 )*}
276}
277
278pub use http::header;
279pub use http::Method;
280pub use http::{StatusCode, Version};
281pub use url::Url;
282
283// universal mods
284#[macro_use]
285mod error;
286// TODO: remove `if_hyper` if wasm has been migrated to new config system.
287if_hyper! {
288 mod config;
289}
290mod into_url;
291mod response;
292
293pub use self::error::{Error, Result};
294pub use self::into_url::IntoUrl;
295pub use self::response::ResponseBuilderExt;
296
297/// Shortcut method to quickly make a `GET` request.
298///
299/// See also the methods on the [`reqwest::Response`](./struct.Response.html)
300/// type.
301///
302/// **NOTE**: This function creates a new internal `Client` on each call,
303/// and so should not be used if making many requests. Create a
304/// [`Client`](./struct.Client.html) instead.
305///
306/// # Examples
307///
308/// ```rust
309/// # async fn run() -> Result<(), reqwest::Error> {
310/// let body = reqwest::get("https://www.rust-lang.org").await?
311/// .text().await?;
312/// # Ok(())
313/// # }
314/// ```
315///
316/// # Errors
317///
318/// This function fails if:
319///
320/// - native TLS backend cannot be initialized
321/// - supplied `Url` cannot be parsed
322/// - there was an error while sending request
323/// - redirect limit was exhausted
324pub async fn get<T: IntoUrl>(url: T) -> crate::Result<Response> {
325 Client::builder().build()?.get(url).send().await
326}
327
328fn _assert_impls() {
329 fn assert_send<T: Send>() {}
330 fn assert_sync<T: Sync>() {}
331 fn assert_clone<T: Clone>() {}
332
333 assert_send::<Client>();
334 assert_sync::<Client>();
335 assert_clone::<Client>();
336
337 assert_send::<Request>();
338 assert_send::<RequestBuilder>();
339
340 #[cfg(not(target_arch = "wasm32"))]
341 {
342 assert_send::<Response>();
343 }
344
345 assert_send::<Error>();
346 assert_sync::<Error>();
347
348 assert_send::<Body>();
349 assert_sync::<Body>();
350}
351
352if_hyper! {
353 #[cfg(test)]
354 #[macro_use]
355 extern crate doc_comment;
356
357 #[cfg(test)]
358 doctest!("../README.md");
359
360 pub use self::async_impl::{
361 Body, Client, ClientBuilder, Request, RequestBuilder, Response, Upgraded,
362 };
363 pub use self::proxy::{Proxy,NoProxy};
364 #[cfg(feature = "__tls")]
365 // Re-exports, to be removed in a future release
366 pub use tls::{Certificate, Identity};
367 #[cfg(feature = "multipart")]
368 pub use self::async_impl::multipart;
369
370
371 mod async_impl;
372 #[cfg(feature = "blocking")]
373 pub mod blocking;
374 mod connect;
375 #[cfg(feature = "cookies")]
376 pub mod cookie;
377 pub mod dns;
378 mod proxy;
379 pub mod redirect;
380 pub mod retry;
381 #[cfg(feature = "__tls")]
382 pub mod tls;
383 mod util;
384
385 #[cfg(docsrs)]
386 pub use connect::uds::UnixSocketProvider;
387}
388
389if_wasm! {
390 mod wasm;
391 mod util;
392
393 pub use self::wasm::{Body, Client, ClientBuilder, Request, RequestBuilder, Response};
394 #[cfg(feature = "multipart")]
395 pub use self::wasm::multipart;
396}