Skip to main content

reqwest/
lib.rs

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