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:
@@ -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![
|
||||
|
||||
@@ -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");
|
||||
/// ```
|
||||
|
||||
@@ -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?;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
@@ -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
98
src/blocking/mod.rs
Normal 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()
|
||||
}
|
||||
@@ -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(())
|
||||
/// # }
|
||||
@@ -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(¶ms)
|
||||
/// .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;
|
||||
@@ -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))
|
||||
}
|
||||
35
src/error.rs
35
src/error.rs
@@ -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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
78
src/lib.rs
78
src/lib.rs
@@ -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(¶ms)
|
||||
//! .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() {
|
||||
|
||||
Reference in New Issue
Block a user