Make the async Client default (#626)

The previously default Client is moved to `reqwest::blocking`, while the
async client becomes the main API.

Closes #622
This commit is contained in:
Sean McArthur
2019-09-09 17:20:51 -07:00
committed by GitHub
parent 5fb04356fc
commit 87a09322d6
30 changed files with 1110 additions and 1066 deletions

View File

@@ -33,7 +33,7 @@ impl Body {
/// # Example
///
/// ```
/// # use reqwest::r#async::Body;
/// # use reqwest::Body;
/// # use futures;
/// # fn main() {
/// let chunks: Vec<Result<_, ::std::io::Error>> = vec![

View File

@@ -61,7 +61,7 @@ impl Form {
/// # Examples
///
/// ```
/// let form = reqwest::r#async::multipart::Form::new()
/// let form = reqwest::multipart::Form::new()
/// .text("username", "seanmonstar")
/// .text("password", "secret");
/// ```

View File

@@ -194,8 +194,8 @@ impl RequestBuilder {
/// # use reqwest::Error;
///
/// # async fn run() -> Result<(), Error> {
/// let client = reqwest::r#async::Client::new();
/// let form = reqwest::r#async::multipart::Form::new()
/// let client = reqwest::Client::new();
/// let form = reqwest::multipart::Form::new()
/// .text("key3", "value3")
/// .text("key4", "value4");
///
@@ -329,7 +329,7 @@ impl RequestBuilder {
/// # use reqwest::Error;
/// #
/// # async fn run() -> Result<(), Error> {
/// let response = reqwest::r#async::Client::new()
/// let response = reqwest::Client::new()
/// .get("https://hyper.rs")
/// .send()
/// .await?;

View File

@@ -186,7 +186,7 @@ impl Response {
/// # Example
///
/// ```
/// # use reqwest::r#async::Response;
/// # use reqwest::Response;
/// fn on_response(res: Response) {
/// match res.error_for_status() {
/// Ok(_res) => (),
@@ -216,7 +216,7 @@ impl Response {
/// # Example
///
/// ```
/// # use reqwest::r#async::Response;
/// # use reqwest::Response;
/// fn on_response(res: &Response) {
/// match res.error_for_status_ref() {
/// Ok(_res) => (),
@@ -347,25 +347,6 @@ struct ResponseUrl(Url);
pub trait ResponseBuilderExt {
/// A builder method for the `http::response::Builder` type that allows the user to add a `Url`
/// to the `http::Response`
///
/// # Example
///
/// ```
/// # extern crate url;
/// # extern crate http;
/// # extern crate reqwest;
/// # use std::error::Error;
/// use url::Url;
/// use http::response::Builder;
/// use reqwest::r#async::ResponseBuilderExt;
/// # fn main() -> Result<(), Box<dyn Error>> {
/// let response = Builder::new()
/// .status(200)
/// .url(Url::parse("http://example.com")?)
/// .body(())?;
///
/// # Ok(())
/// # }
fn url(&mut self, url: Url) -> &mut Self;
}

View File

@@ -32,7 +32,7 @@ impl Body {
///
/// ```rust
/// # use std::fs::File;
/// # use reqwest::Body;
/// # use reqwest::blocking::Body;
/// # fn run() -> Result<(), Box<std::error::Error>> {
/// let file = File::open("national_secrets.txt")?;
/// let body = Body::new(file);
@@ -45,7 +45,7 @@ impl Body {
/// it can be reused.
///
/// ```rust
/// # use reqwest::Body;
/// # use reqwest::blocking::Body;
/// # fn run() -> Result<(), Box<std::error::Error>> {
/// let s = "A stringy body";
/// let body = Body::from(s);
@@ -64,7 +64,7 @@ impl Body {
///
/// ```rust
/// # use std::fs::File;
/// # use reqwest::Body;
/// # use reqwest::blocking::Body;
/// # fn run() -> Result<(), Box<std::error::Error>> {
/// let file = File::open("a_large_file.txt")?;
/// let file_size = file.metadata()?.len();

View File

@@ -10,9 +10,10 @@ use futures::{StreamExt, TryFutureExt};
use log::{error, trace};
use crate::request::{Request, RequestBuilder};
use crate::response::Response;
use crate::{async_impl, header, wait, IntoUrl, Method, Proxy, RedirectPolicy};
use super::request::{Request, RequestBuilder};
use super::response::Response;
use super::wait;
use crate::{async_impl, header, IntoUrl, Method, Proxy, RedirectPolicy};
#[cfg(feature = "tls")]
use crate::{Certificate, Identity};
@@ -28,9 +29,9 @@ use crate::{Certificate, Identity};
/// # Examples
///
/// ```rust
/// # use reqwest::{Error, Client};
/// use reqwest::blocking::Client;
/// #
/// # fn run() -> Result<(), Error> {
/// # fn run() -> Result<(), reqwest::Error> {
/// let client = Client::new();
/// let resp = client.get("http://httpbin.org/").send()?;
/// # drop(resp);
@@ -51,7 +52,7 @@ pub struct Client {
/// # fn run() -> Result<(), reqwest::Error> {
/// use std::time::Duration;
///
/// let client = reqwest::Client::builder()
/// let client = reqwest::blocking::Client::builder()
/// .gzip(true)
/// .timeout(Duration::from_secs(10))
/// .build()?;
@@ -130,7 +131,7 @@ impl ClientBuilder {
/// let cert = reqwest::Certificate::from_der(&buf)?;
///
/// // get a client builder
/// let client = reqwest::Client::builder()
/// let client = reqwest::blocking::Client::builder()
/// .add_root_certificate(cert)
/// .build()?;
/// # drop(client);
@@ -170,7 +171,7 @@ impl ClientBuilder {
/// let pkcs12 = reqwest::Identity::from_pem(&buf)?;
///
/// // get a client builder
/// let client = reqwest::Client::builder()
/// let client = reqwest::blocking::Client::builder()
/// .identity(pkcs12)
/// .build()?;
/// # drop(client);
@@ -224,7 +225,7 @@ impl ClientBuilder {
/// headers.insert(header::AUTHORIZATION, header::HeaderValue::from_static("secret"));
///
/// // get a client builder
/// let client = reqwest::Client::builder()
/// let client = reqwest::blocking::Client::builder()
/// .default_headers(headers)
/// .build()?;
/// let res = client.get("https://www.rust-lang.org").send()?;
@@ -241,7 +242,7 @@ impl ClientBuilder {
/// headers.insert(header::AUTHORIZATION, header::HeaderValue::from_static("secret"));
///
/// // get a client builder
/// let client = reqwest::Client::builder()
/// let client = reqwest::blocking::Client::builder()
/// .default_headers(headers)
/// .build()?;
/// let res = client
@@ -337,7 +338,7 @@ impl ClientBuilder {
/// # Example
///
/// ```
/// let client = reqwest::Client::builder()
/// let client = reqwest::blocking::Client::builder()
/// .h2_prior_knowledge()
/// .build().unwrap();
/// ```
@@ -350,7 +351,7 @@ impl ClientBuilder {
/// # Example
///
/// ```
/// let client = reqwest::Client::builder()
/// let client = reqwest::blocking::Client::builder()
/// .http1_title_case_headers()
/// .build().unwrap();
/// ```
@@ -365,7 +366,7 @@ impl ClientBuilder {
/// ```
/// use std::net::IpAddr;
/// let local_addr = IpAddr::from([12, 4, 1, 8]);
/// let client = reqwest::Client::builder()
/// let client = reqwest::blocking::Client::builder()
/// .local_address(local_addr)
/// .build().unwrap();
/// ```
@@ -386,7 +387,7 @@ impl ClientBuilder {
/// # Example
///
/// ```
/// let client = reqwest::Client::builder()
/// let client = reqwest::blocking::Client::builder()
/// .cookie_store(true)
/// .build()
/// .unwrap();

98
src/blocking/mod.rs Normal file
View File

@@ -0,0 +1,98 @@
//! A blocking Client API.
//!
//! The blocking `Client` will block the current thread to execute, instead
//! of returning futures that need to be executed on a runtime.
//!
//! ## Making a GET request
//!
//! For a single request, you can use the [`get`](get) shortcut method.
//!
//! ```rust
//! # use reqwest::{Error, Response};
//!
//! # fn run() -> Result<(), Error> {
//! let body = reqwest::blocking::get("https://www.rust-lang.org")?
//! .text()?;
//!
//! println!("body = {:?}", body);
//! # Ok(())
//! # }
//! ```
//!
//! Additionally, the blocking [`Response`](Response) struct implements Rust's
//! `Read` trait, so many useful standard library and third party crates will
//! have convenience methods that take a `Response` anywhere `T: Read` is
//! acceptable.
//!
//! **NOTE**: If you plan to perform multiple requests, it is best to create a
//! [`Client`](Client) and reuse it, taking advantage of keep-alive connection
//! pooling.
//!
//! ## Making POST requests (or setting request bodies)
//!
//! There are several ways you can set the body of a request. The basic one is
//! by using the `body()` method of a [`RequestBuilder`](RequestBuilder). This lets you set the
//! exact raw bytes of what the body should be. It accepts various types,
//! including `String`, `Vec<u8>`, and `File`. If you wish to pass a custom
//! Reader, you can use the `reqwest::blocking::Body::new()` constructor.
//!
//! ```rust
//! # use reqwest::Error;
//! #
//! # fn run() -> Result<(), Error> {
//! let client = reqwest::blocking::Client::new();
//! let res = client.post("http://httpbin.org/post")
//! .body("the exact body that is sent")
//! .send()?;
//! # Ok(())
//! # }
//! ```
//!
//! ## And More
//!
//! Most features available to the asynchronous `Client` are also available,
//! on the blocking `Client`, see those docs for more.
mod body;
mod client;
pub mod multipart;
mod request;
mod response;
mod wait;
pub(crate) use self::wait::Waited;
pub use self::body::Body;
pub use self::client::{Client, ClientBuilder};
pub use self::request::{Request, RequestBuilder};
pub use self::response::Response;
/// Shortcut method to quickly make a *blocking* `GET` request.
///
/// **NOTE**: This function creates a new internal `Client` on each call,
/// and so should not be used if making many requests. Create a
/// [`Client`](./struct.Client.html) instead.
///
/// # Examples
///
/// ```rust
/// # fn run() -> Result<(), reqwest::Error> {
/// let body = reqwest::blocking::get("https://www.rust-lang.org")?
/// .text()?;
/// # Ok(())
/// # }
/// # fn main() { }
/// ```
///
/// # Errors
///
/// This function fails if:
///
/// - native TLS backend cannot be initialized
/// - supplied `Url` cannot be parsed
/// - there was an error while sending request
/// - redirect loop was detected
/// - redirect limit was exhausted
pub fn get<T: crate::IntoUrl>(url: T) -> crate::Result<Response> {
Client::builder().build()?.get(url).send()
}

View File

@@ -7,7 +7,7 @@
//! # Example
//!
//! ```
//! use reqwest::multipart;
//! use reqwest::blocking::multipart;
//!
//! # fn run() -> Result<(), Box<dyn std::error::Error>> {
//! let form = multipart::Form::new()
@@ -25,7 +25,7 @@
//! let form = form.part("biography", bio);
//!
//! // And finally, send the form
//! let client = reqwest::Client::new();
//! let client = reqwest::blocking::Client::new();
//! let resp = client
//! .post("http://localhost:8080/user")
//! .multipart(form)
@@ -44,8 +44,8 @@ use std::path::Path;
use mime_guess::{self, Mime};
use super::Body;
use crate::async_impl::multipart::{FormParts, PartMetadata, PartProps};
use crate::Body;
/// A multipart/form-data request.
pub struct Form {
@@ -77,7 +77,7 @@ impl Form {
/// # Examples
///
/// ```
/// let form = reqwest::multipart::Form::new()
/// let form = reqwest::blocking::multipart::Form::new()
/// .text("username", "seanmonstar")
/// .text("password", "secret");
/// ```
@@ -97,7 +97,7 @@ impl Form {
///
/// ```no_run
/// # fn run() -> std::io::Result<()> {
/// let files = reqwest::multipart::Form::new()
/// let files = reqwest::blocking::multipart::Form::new()
/// .file("key", "/path/to/file")?;
/// # Ok(())
/// # }

View File

@@ -1,14 +1,16 @@
use std::fmt;
use base64::encode;
use http::HttpTryFrom;
use serde::Serialize;
use serde_json;
use serde_urlencoded;
use crate::body::{self, Body};
use super::body::{self, Body};
use super::multipart;
use super::Client;
use crate::header::{HeaderMap, HeaderName, HeaderValue, CONTENT_TYPE};
use crate::{async_impl, Client, Method, Url};
use http::HttpTryFrom;
use crate::{async_impl, Method, Url};
/// A request which can be executed with `Client::execute()`.
pub struct Request {
@@ -128,7 +130,7 @@ impl RequestBuilder {
/// use reqwest::header::USER_AGENT;
///
/// # fn run() -> Result<(), Box<std::error::Error>> {
/// let client = reqwest::Client::new();
/// let client = reqwest::blocking::Client::new();
/// let res = client.get("https://www.rust-lang.org")
/// .header(USER_AGENT, "foo")
/// .send()?;
@@ -175,7 +177,7 @@ impl RequestBuilder {
///
/// # fn run() -> Result<(), Box<std::error::Error>> {
/// let file = fs::File::open("much_beauty.png")?;
/// let client = reqwest::Client::new();
/// let client = reqwest::blocking::Client::new();
/// let res = client.post("http://httpbin.org/post")
/// .headers(construct_headers())
/// .body(file)
@@ -190,36 +192,11 @@ impl RequestBuilder {
self
}
/// Set a header with a type implementing hyper v0.11's `Header` trait.
///
/// This method is provided to ease migration, and requires the `hyper-011`
/// Cargo feature enabled on `reqwest`.
#[cfg(feature = "hyper-011")]
pub fn header_011<H>(self, header: H) -> RequestBuilder
where
H: crate::hyper_011::header::Header,
{
let mut headers = crate::hyper_011::Headers::new();
headers.set(header);
let map = crate::header::HeaderMap::from(headers);
self.headers(map)
}
/// Set multiple headers using hyper v0.11's `Headers` map.
///
/// This method is provided to ease migration, and requires the `hyper-011`
/// Cargo feature enabled on `reqwest`.
#[cfg(feature = "hyper-011")]
pub fn headers_011(self, headers: crate::hyper_011::Headers) -> RequestBuilder {
let map = crate::header::HeaderMap::from(headers);
self.headers(map)
}
/// Enable HTTP basic authentication.
///
/// ```rust
/// # fn run() -> Result<(), Box<std::error::Error>> {
/// let client = reqwest::Client::new();
/// let client = reqwest::blocking::Client::new();
/// let resp = client.delete("http://httpbin.org/delete")
/// .basic_auth("admin", Some("good password"))
/// .send()?;
@@ -243,7 +220,7 @@ impl RequestBuilder {
///
/// ```rust
/// # fn run() -> Result<(), Box<std::error::Error>> {
/// let client = reqwest::Client::new();
/// let client = reqwest::blocking::Client::new();
/// let resp = client.delete("http://httpbin.org/delete")
/// .bearer_auth("token")
/// .send()?;
@@ -266,7 +243,7 @@ impl RequestBuilder {
///
/// ```rust
/// # fn run() -> Result<(), Box<std::error::Error>> {
/// let client = reqwest::Client::new();
/// let client = reqwest::blocking::Client::new();
/// let res = client.post("http://httpbin.org/post")
/// .body("from a &str!")
/// .send()?;
@@ -277,10 +254,9 @@ impl RequestBuilder {
/// Using a `File`:
///
/// ```rust
/// # use std::fs;
/// # fn run() -> Result<(), Box<std::error::Error>> {
/// let file = fs::File::open("from_a_file.txt")?;
/// let client = reqwest::Client::new();
/// let file = std::fs::File::open("from_a_file.txt")?;
/// let client = reqwest::blocking::Client::new();
/// let res = client.post("http://httpbin.org/post")
/// .body(file)
/// .send()?;
@@ -295,7 +271,7 @@ impl RequestBuilder {
/// # fn run() -> Result<(), Box<std::error::Error>> {
/// // from bytes!
/// let bytes: Vec<u8> = vec![1, 10, 100];
/// let client = reqwest::Client::new();
/// let client = reqwest::blocking::Client::new();
/// let res = client.post("http://httpbin.org/post")
/// .body(bytes)
/// .send()?;
@@ -322,7 +298,7 @@ impl RequestBuilder {
/// # use reqwest::Error;
/// #
/// # fn run() -> Result<(), Error> {
/// let client = reqwest::Client::new();
/// let client = reqwest::blocking::Client::new();
/// let res = client.get("http://httpbin.org")
/// .query(&[("lang", "rust")])
/// .send()?;
@@ -375,7 +351,7 @@ impl RequestBuilder {
/// let mut params = HashMap::new();
/// params.insert("lang", "rust");
///
/// let client = reqwest::Client::new();
/// let client = reqwest::blocking::Client::new();
/// let res = client.post("http://httpbin.org")
/// .form(&params)
/// .send()?;
@@ -420,7 +396,7 @@ impl RequestBuilder {
/// let mut map = HashMap::new();
/// map.insert("lang", "rust");
///
/// let client = reqwest::Client::new();
/// let client = reqwest::blocking::Client::new();
/// let res = client.post("http://httpbin.org")
/// .json(&map)
/// .send()?;
@@ -456,8 +432,8 @@ impl RequestBuilder {
/// # use reqwest::Error;
///
/// # fn run() -> Result<(), Box<std::error::Error>> {
/// let client = reqwest::Client::new();
/// let form = reqwest::multipart::Form::new()
/// let client = reqwest::blocking::Client::new();
/// let form = reqwest::blocking::multipart::Form::new()
/// .text("key3", "value3")
/// .file("file", "/path/to/field")?;
///
@@ -469,7 +445,7 @@ impl RequestBuilder {
/// ```
///
/// See [`multipart`](multipart/) for more examples.
pub fn multipart(self, mut multipart: crate::multipart::Form) -> RequestBuilder {
pub fn multipart(self, mut multipart: multipart::Form) -> RequestBuilder {
let mut builder = self.header(
CONTENT_TYPE,
format!("multipart/form-data; boundary={}", multipart.boundary()).as_str(),
@@ -495,7 +471,7 @@ impl RequestBuilder {
///
/// This method fails if there was an error while sending request,
/// redirect loop was detected or redirect limit was exhausted.
pub fn send(self) -> crate::Result<crate::Response> {
pub fn send(self) -> crate::Result<super::Response> {
self.client.execute(self.request?)
}
@@ -510,7 +486,7 @@ impl RequestBuilder {
///
/// ```rust
/// # fn run() -> Result<(), Box<std::error::Error>> {
/// let client = reqwest::Client::new();
/// let client = reqwest::blocking::Client::new();
/// let builder = client.post("http://httpbin.org/post")
/// .body("from a &str!");
/// let clone = builder.try_clone();
@@ -523,7 +499,7 @@ impl RequestBuilder {
///
/// ```rust
/// # fn run() -> Result<(), Box<std::error::Error>> {
/// let client = reqwest::Client::new();
/// let client = reqwest::blocking::Client::new();
/// let builder = client.get("http://httpbin.org/get");
/// let clone = builder.try_clone();
/// assert!(clone.is_some());
@@ -535,9 +511,9 @@ impl RequestBuilder {
///
/// ```rust
/// # fn run() -> Result<(), Box<std::error::Error>> {
/// let client = reqwest::Client::new();
/// let client = reqwest::blocking::Client::new();
/// let builder = client.get("http://httpbin.org/get")
/// .body(reqwest::Body::new(std::io::empty()));
/// .body(reqwest::blocking::Body::new(std::io::empty()));
/// let clone = builder.try_clone();
/// assert!(clone.is_none());
/// # Ok(())
@@ -572,8 +548,9 @@ fn fmt_request_fields<'a, 'b>(
#[cfg(test)]
mod tests {
use super::super::{body, Client};
use crate::header::{HeaderMap, HeaderValue, ACCEPT, CONTENT_TYPE, HOST};
use crate::{body, Client, Method};
use crate::Method;
use serde::Serialize;
use serde_json;
use serde_urlencoded;

View File

@@ -6,12 +6,13 @@ use std::pin::Pin;
use std::time::Duration;
use http;
use hyper::header::HeaderMap;
use serde::de::DeserializeOwned;
use crate::client::KeepCoreThreadAlive;
use super::client::KeepCoreThreadAlive;
use super::wait;
use crate::cookie;
use crate::{async_impl, wait, StatusCode, Url, Version};
use hyper::header::HeaderMap;
use crate::{async_impl, StatusCode, Url, Version};
/// A Response to a submitted `Request`.
pub struct Response {
@@ -49,7 +50,7 @@ impl Response {
///
/// ```rust
/// # fn run() -> Result<(), Box<std::error::Error>> {
/// let resp = reqwest::get("http://httpbin.org/get")?;
/// let resp = reqwest::blocking::get("http://httpbin.org/get")?;
/// if resp.status().is_success() {
/// println!("success!");
/// } else if resp.status().is_server_error() {
@@ -64,7 +65,7 @@ impl Response {
/// Checking for specific status codes:
///
/// ```rust
/// use reqwest::Client;
/// use reqwest::blocking::Client;
/// use reqwest::StatusCode;
/// # fn run() -> Result<(), Box<std::error::Error>> {
/// let client = Client::new();
@@ -95,7 +96,7 @@ impl Response {
/// Saving an etag when caching a file:
///
/// ```
/// use reqwest::Client;
/// use reqwest::blocking::Client;
/// use reqwest::header::ETAG;
///
/// # fn run() -> Result<(), Box<std::error::Error>> {
@@ -136,7 +137,7 @@ impl Response {
///
/// ```rust
/// # fn run() -> Result<(), Box<std::error::Error>> {
/// let resp = reqwest::get("http://httpbin.org/redirect/1")?;
/// let resp = reqwest::blocking::get("http://httpbin.org/redirect/1")?;
/// assert_eq!(resp.url().as_str(), "http://httpbin.org/get");
/// # Ok(())
/// # }
@@ -152,7 +153,7 @@ impl Response {
///
/// ```rust
/// # fn run() -> Result<(), Box<std::error::Error>> {
/// let resp = reqwest::get("http://httpbin.org/redirect/1")?;
/// let resp = reqwest::blocking::get("http://httpbin.org/redirect/1")?;
/// println!("httpbin.org address: {:?}", resp.remote_addr());
/// # Ok(())
/// # }
@@ -189,7 +190,7 @@ impl Response {
/// }
///
/// # fn run() -> Result<(), Error> {
/// let json: Ip = reqwest::get("http://httpbin.org/ip")?.json()?;
/// let json: Ip = reqwest::blocking::get("http://httpbin.org/ip")?.json()?;
/// # Ok(())
/// # }
/// #
@@ -223,7 +224,7 @@ impl Response {
/// ```rust
/// # extern crate reqwest;
/// # fn run() -> Result<(), Box<std::error::Error>> {
/// let content = reqwest::get("http://httpbin.org/range/26")?.text()?;
/// let content = reqwest::blocking::get("http://httpbin.org/range/26")?.text()?;
/// # Ok(())
/// # }
/// ```
@@ -250,7 +251,8 @@ impl Response {
/// ```rust
/// # extern crate reqwest;
/// # fn run() -> Result<(), Box<std::error::Error>> {
/// let content = reqwest::get("http://httpbin.org/range/26")?.text_with_charset("utf-8")?;
/// let content = reqwest::blocking::get("http://httpbin.org/range/26")?
/// .text_with_charset("utf-8")?;
/// # Ok(())
/// # }
/// ```
@@ -282,7 +284,7 @@ impl Response {
///
/// ```rust
/// # fn run() -> Result<(), Box<std::error::Error>> {
/// let mut resp = reqwest::get("http://httpbin.org/range/5")?;
/// let mut resp = reqwest::blocking::get("http://httpbin.org/range/5")?;
/// let mut buf: Vec<u8> = vec![];
/// resp.copy_to(&mut buf)?;
/// assert_eq!(b"abcde", buf.as_slice());
@@ -303,7 +305,7 @@ impl Response {
/// ```rust,no_run
/// # extern crate reqwest;
/// # fn run() -> Result<(), Box<std::error::Error>> {
/// let res = reqwest::get("http://httpbin.org/status/400")?
/// let res = reqwest::blocking::get("http://httpbin.org/status/400")?
/// .error_for_status();
/// if let Err(err) = res {
/// assert_eq!(err.status(), Some(reqwest::StatusCode::BAD_REQUEST));
@@ -312,7 +314,6 @@ impl Response {
/// # }
/// # fn main() {}
/// ```
#[inline]
pub fn error_for_status(self) -> crate::Result<Self> {
let Response {
body,
@@ -335,7 +336,7 @@ impl Response {
/// ```rust,no_run
/// # extern crate reqwest;
/// # fn run() -> Result<(), Box<std::error::Error>> {
/// let res = reqwest::get("http://httpbin.org/status/400")?;
/// let res = reqwest::blocking::get("http://httpbin.org/status/400")?;
/// let res = res.error_for_status_ref();
/// if let Err(err) = res {
/// assert_eq!(err.status(), Some(reqwest::StatusCode::BAD_REQUEST));
@@ -344,7 +345,6 @@ impl Response {
/// # }
/// # fn main() {}
/// ```
#[inline]
pub fn error_for_status_ref(&self) -> crate::Result<&Self> {
self.inner.error_for_status_ref().and_then(|_| Ok(self))
}

View File

@@ -20,15 +20,15 @@ use crate::{StatusCode, Url};
/// }
/// # fn main() { }
///
/// fn run() {
/// match make_request() {
/// async fn run() {
/// match make_request().await {
/// Err(e) => handler(e),
/// Ok(_) => return,
/// }
/// }
/// // Response is not a json object conforming to the Simple struct
/// fn make_request() -> Result<Simple, reqwest::Error> {
/// reqwest::get("http://httpbin.org/ip")?.json()
/// async fn make_request() -> Result<Simple, reqwest::Error> {
/// reqwest::get("http://httpbin.org/ip").await?.json().await
/// }
///
/// fn handler(e: reqwest::Error) {
@@ -75,9 +75,9 @@ impl Error {
/// # Examples
///
/// ```
/// # fn run() {
/// # async fn run() {
/// // displays last stop of a redirect loop
/// let response = reqwest::get("http://site.with.redirect.loop");
/// let response = reqwest::get("http://site.with.redirect.loop").await;
/// if let Err(e) = response {
/// if e.is_redirect() {
/// if let Some(final_stop) = e.url() {
@@ -108,14 +108,14 @@ impl Error {
/// extern crate url;
/// # extern crate reqwest;
/// // retries requests with no host on localhost
/// # fn run() {
/// # async fn run() {
/// let invalid_request = "http://";
/// let mut response = reqwest::get(invalid_request);
/// let mut response = reqwest::get(invalid_request).await;
/// if let Err(e) = response {
/// match e.get_ref().and_then(|e| e.downcast_ref::<url::ParseError>()) {
/// Some(&url::ParseError::EmptyHost) => {
/// let valid_request = format!("{}{}",invalid_request, "localhost");
/// response = reqwest::get(&valid_request);
/// response = reqwest::get(&valid_request).await;
/// },
/// _ => (),
/// }
@@ -123,7 +123,6 @@ impl Error {
/// # }
/// # fn main() {}
/// ```
#[inline]
pub fn get_ref(&self) -> Option<&(dyn StdError + Send + Sync + 'static)> {
match self.inner.kind {
Kind::Http(ref e) => Some(e),
@@ -152,7 +151,6 @@ impl Error {
}
/// Returns true if the error is related to HTTP.
#[inline]
pub fn is_http(&self) -> bool {
match self.inner.kind {
Kind::Http(_) => true,
@@ -175,7 +173,6 @@ impl Error {
}
/// Returns true if the error is serialization related.
#[inline]
pub fn is_serialization(&self) -> bool {
match self.inner.kind {
Kind::Json(_) | Kind::UrlEncoded(_) => true,
@@ -184,7 +181,6 @@ impl Error {
}
/// Returns true if the error is from a `RedirectPolicy`.
#[inline]
pub fn is_redirect(&self) -> bool {
match self.inner.kind {
Kind::TooManyRedirects | Kind::RedirectLoop => true,
@@ -193,7 +189,6 @@ impl Error {
}
/// Returns true if the error is from a request returning a 4xx error.
#[inline]
pub fn is_client_error(&self) -> bool {
match self.inner.kind {
Kind::Status(code) => code.is_client_error(),
@@ -202,7 +197,6 @@ impl Error {
}
/// Returns true if the error is from a request returning a 5xx error.
#[inline]
pub fn is_server_error(&self) -> bool {
match self.inner.kind {
Kind::Status(code) => code.is_server_error(),
@@ -211,7 +205,6 @@ impl Error {
}
/// Returns the status code, if the error was generated from a response.
#[inline]
pub fn status(&self) -> Option<StatusCode> {
match self.inner.kind {
Kind::Status(code) => Some(code),
@@ -466,15 +459,15 @@ impl From<rustls::TLSError> for Kind {
}
}
impl<T> From<crate::wait::Waited<T>> for Kind
impl<T> From<crate::blocking::Waited<T>> for Kind
where
T: Into<Kind>,
{
fn from(err: crate::wait::Waited<T>) -> Kind {
fn from(err: crate::blocking::Waited<T>) -> Kind {
match err {
crate::wait::Waited::TimedOut => io_timeout().into(),
crate::wait::Waited::Executor(e) => e.into(),
crate::wait::Waited::Inner(e) => e.into(),
crate::blocking::Waited::TimedOut => io_timeout().into(),
crate::blocking::Waited::Executor(e) => e.into(),
crate::blocking::Waited::Inner(e) => e.into(),
}
}
}

View File

@@ -11,15 +11,16 @@
//! It handles many of the things that most people just expect an HTTP client
//! to do for them.
//!
//! - Async and [blocking](blocking) Clients
//! - Plain bodies, [JSON](#json), [urlencoded](#forms), [multipart](multipart)
//! - Customizable [redirect policy](#redirect-policy)
//! - HTTP [Proxies](#proxies)
//! - Uses system-native [TLS](#tls)
//! - Cookies
//!
//! The [`reqwest::Client`][client] is synchronous, making it a great fit for
//! applications that only require a few HTTP requests, and wish to handle
//! them synchronously.
//! The [`reqwest::Client`][client] is asynchronous. For applications wishing
//! to only make a few HTTP requests, the [`reqwest::blocking`](blocking) API
//! may be more convenient.
//!
//! Additional learning resources include:
//!
@@ -31,22 +32,17 @@
//! For a single request, you can use the [`get`][get] shortcut method.
//!
//! ```rust
//! # use reqwest::{Error, Response};
//!
//! # fn run() -> Result<(), Error> {
//! let body = reqwest::get("https://www.rust-lang.org")?
//! .text()?;
//! # async fn run() -> Result<(), reqwest::Error> {
//! let body = reqwest::get("https://www.rust-lang.org")
//! .await?
//! .text()
//! .await?;
//!
//! println!("body = {:?}", body);
//! # Ok(())
//! # }
//! ```
//!
//! Additionally, reqwest's [`Response`][response] struct implements Rust's
//! `Read` trait, so many useful standard library and third party crates will
//! have convenience methods that take a `Response` anywhere `T: Read` is
//! acceptable.
//!
//! **NOTE**: If you plan to perform multiple requests, it is best to create a
//! [`Client`][client] and reuse it, taking advantage of keep-alive connection
//! pooling.
@@ -57,16 +53,17 @@
//! by using the `body()` method of a [`RequestBuilder`][builder]. This lets you set the
//! exact raw bytes of what the body should be. It accepts various types,
//! including `String`, `Vec<u8>`, and `File`. If you wish to pass a custom
//! Reader, you can use the `reqwest::Body::new()` constructor.
//! type, you can use the `reqwest::Body` constructors.
//!
//! ```rust
//! # use reqwest::Error;
//! #
//! # fn run() -> Result<(), Error> {
//! # async fn run() -> Result<(), Error> {
//! let client = reqwest::Client::new();
//! let res = client.post("http://httpbin.org/post")
//! .body("the exact body that is sent")
//! .send()?;
//! .send()
//! .await?;
//! # Ok(())
//! # }
//! ```
@@ -82,13 +79,14 @@
//! ```rust
//! # use reqwest::Error;
//! #
//! # fn run() -> Result<(), Error> {
//! # async fn run() -> Result<(), Error> {
//! // This will POST a body of `foo=bar&baz=quux`
//! let params = [("foo", "bar"), ("baz", "quux")];
//! let client = reqwest::Client::new();
//! let res = client.post("http://httpbin.org/post")
//! .form(&params)
//! .send()?;
//! .send()
//! .await?;
//! # Ok(())
//! # }
//! ```
@@ -103,7 +101,7 @@
//! # use reqwest::Error;
//! # use std::collections::HashMap;
//! #
//! # fn run() -> Result<(), Error> {
//! # async fn run() -> Result<(), Error> {
//! // This will POST a body of `{"lang":"rust","body":"json"}`
//! let mut map = HashMap::new();
//! map.insert("lang", "rust");
@@ -112,7 +110,8 @@
//! let client = reqwest::Client::new();
//! let res = client.post("http://httpbin.org/post")
//! .json(&map)
//! .send()?;
//! .send()
//! .await?;
//! # Ok(())
//! # }
//! ```
@@ -157,8 +156,6 @@
//! `native-tls` library to connect over HTTPS.
//! - **default-tls-vendored**: Enables the `vendored` feature of `native-tls`.
//! - **rustls-tls**: Provides TLS support via the `rustls` library.
//! - **socks**: Provides SOCKS5 proxy support.
//! - **hyper-011**: Provides support for hyper's old typed headers.
//!
//!
//! [hyper]: http://hyper.rs
@@ -171,12 +168,11 @@
//! [Proxy]: ./struct.Proxy.html
//! [cargo-features]: https://doc.rust-lang.org/stable/cargo/reference/manifest.html#the-features-section
////! - **socks**: Provides SOCKS5 proxy support.
////! - **trust-dns**: Enables a trust-dns async resolver instead of default
////! threadpool using `getaddrinfo`.
extern crate cookie as cookie_crate;
#[cfg(feature = "hyper-011")]
pub use hyper_old_types as hyper_011;
#[cfg(test)]
#[macro_use]
@@ -191,14 +187,17 @@ pub use hyper::{StatusCode, Version};
pub use url::ParseError as UrlError;
pub use url::Url;
pub use self::body::Body;
pub use self::client::{Client, ClientBuilder};
pub use self::r#async::{
multipart, Body, Client, ClientBuilder, Decoder, Request, RequestBuilder, Response,
};
//pub use self::body::Body;
//pub use self::client::{Client, ClientBuilder};
pub use self::error::{Error, Result};
pub use self::into_url::IntoUrl;
pub use self::proxy::Proxy;
pub use self::redirect::{RedirectAction, RedirectAttempt, RedirectPolicy};
pub use self::request::{Request, RequestBuilder};
pub use self::response::Response;
//pub use self::request::{Request, RequestBuilder};
//pub use self::response::Response;
#[cfg(feature = "tls")]
pub use self::tls::{Certificate, Identity};
@@ -207,8 +206,7 @@ pub use self::tls::{Certificate, Identity};
mod error;
mod async_impl;
mod body;
mod client;
pub mod blocking;
mod connect;
pub mod cookie;
//#[cfg(feature = "trust-dns")]
@@ -216,19 +214,16 @@ pub mod cookie;
mod into_url;
mod proxy;
mod redirect;
mod request;
mod response;
#[cfg(feature = "tls")]
mod tls;
mod wait;
pub mod multipart;
//pub mod multipart;
/// An 'async' implementation of the reqwest `Client`.
#[doc(hidden)]
#[deprecated(note = "types moved to top of crate")]
pub mod r#async {
pub use crate::async_impl::{
multipart, Body, Chunk, Client, ClientBuilder, Decoder, Request, RequestBuilder, Response,
ResponseBuilderExt,
};
}
@@ -244,12 +239,11 @@ pub mod r#async {
/// # Examples
///
/// ```rust
/// # fn run() -> Result<(), reqwest::Error> {
/// let body = reqwest::get("https://www.rust-lang.org")?
/// .text()?;
/// # async fn run() -> Result<(), reqwest::Error> {
/// let body = reqwest::get("https://www.rust-lang.org").await?
/// .text().await?;
/// # Ok(())
/// # }
/// # fn main() { }
/// ```
///
/// # Errors
@@ -261,8 +255,8 @@ pub mod r#async {
/// - there was an error while sending request
/// - redirect loop was detected
/// - redirect limit was exhausted
pub fn get<T: IntoUrl>(url: T) -> crate::Result<Response> {
Client::builder().build()?.get(url).send()
pub async fn get<T: IntoUrl>(url: T) -> crate::Result<Response> {
Client::builder().build()?.get(url).send().await
}
fn _assert_impls() {