add form() method
This commit is contained in:
@@ -13,6 +13,7 @@ hyper = { version = "0.9" , default-features = false }
|
|||||||
log = "0.3"
|
log = "0.3"
|
||||||
serde = "0.8"
|
serde = "0.8"
|
||||||
serde_json = "0.8"
|
serde_json = "0.8"
|
||||||
|
serde_urlencoded = "0.3"
|
||||||
url = "1.0"
|
url = "1.0"
|
||||||
|
|
||||||
[dependencies.native-tls]
|
[dependencies.native-tls]
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ use hyper::{Url};
|
|||||||
|
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use serde_json;
|
use serde_json;
|
||||||
|
use serde_urlencoded;
|
||||||
|
|
||||||
use ::body::{self, Body};
|
use ::body::{self, Body};
|
||||||
|
|
||||||
@@ -94,7 +95,7 @@ pub struct RequestBuilder<'a> {
|
|||||||
_version: HttpVersion,
|
_version: HttpVersion,
|
||||||
headers: Headers,
|
headers: Headers,
|
||||||
|
|
||||||
body: Option<Body>,
|
body: Option<::Result<Body>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> RequestBuilder<'a> {
|
impl<'a> RequestBuilder<'a> {
|
||||||
@@ -122,7 +123,30 @@ impl<'a> RequestBuilder<'a> {
|
|||||||
|
|
||||||
/// Set the request body.
|
/// Set the request body.
|
||||||
pub fn body<T: Into<Body>>(mut self, body: T) -> RequestBuilder<'a> {
|
pub fn body<T: Into<Body>>(mut self, body: T) -> RequestBuilder<'a> {
|
||||||
self.body = Some(body.into());
|
self.body = Some(Ok(body.into()));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Send a form body.
|
||||||
|
///
|
||||||
|
/// Sets the body to the url encoded serialization of the passed value,
|
||||||
|
/// and also sets the `Content-Type: application/www-form-url-encoded`
|
||||||
|
/// header.
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// # use std::collections::HashMap;
|
||||||
|
/// let mut params = HashMap::new();
|
||||||
|
/// params.insert("lang", "rust");
|
||||||
|
///
|
||||||
|
/// let client = reqwest::Client::new().unwrap();
|
||||||
|
/// let res = client.post("http://httpbin.org")
|
||||||
|
/// .form(¶ms)
|
||||||
|
/// .send();
|
||||||
|
/// ```
|
||||||
|
pub fn form<T: Serialize>(mut self, form: &T) -> RequestBuilder<'a> {
|
||||||
|
let body = serde_urlencoded::to_string(form).map_err(::Error::from);
|
||||||
|
self.headers.set(ContentType::form_url_encoded());
|
||||||
|
self.body = Some(body.map(|b| b.into()));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,14 +160,15 @@ impl<'a> RequestBuilder<'a> {
|
|||||||
/// let mut map = HashMap::new();
|
/// let mut map = HashMap::new();
|
||||||
/// map.insert("lang", "rust");
|
/// map.insert("lang", "rust");
|
||||||
///
|
///
|
||||||
/// let res = reqwest::post("http://www.rust-lang.org")
|
/// let client = reqwest::Client::new().unwrap();
|
||||||
/// .json(map)
|
/// let res = client.post("http://httpbin.org")
|
||||||
|
/// .json(&map)
|
||||||
/// .send();
|
/// .send();
|
||||||
/// ```
|
/// ```
|
||||||
pub fn json<T: Serialize>(mut self, json: T) -> RequestBuilder<'a> {
|
pub fn json<T: Serialize>(mut self, json: &T) -> RequestBuilder<'a> {
|
||||||
let body = serde_json::to_vec(&json).expect("serde to_vec cannot fail");
|
let body = serde_json::to_vec(json).expect("serde to_vec cannot fail");
|
||||||
self.headers.set(ContentType::json());
|
self.headers.set(ContentType::json());
|
||||||
self.body = Some(body.into());
|
self.body = Some(Ok(body.into()));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,7 +182,10 @@ impl<'a> RequestBuilder<'a> {
|
|||||||
let mut method = self.method;
|
let mut method = self.method;
|
||||||
let mut url = try!(self.url);
|
let mut url = try!(self.url);
|
||||||
let mut headers = self.headers;
|
let mut headers = self.headers;
|
||||||
let mut body = self.body;
|
let mut body = match self.body {
|
||||||
|
Some(b) => Some(try!(b)),
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
|
||||||
let mut redirect_count = 0;
|
let mut redirect_count = 0;
|
||||||
|
|
||||||
|
|||||||
14
src/error.rs
14
src/error.rs
@@ -6,6 +6,11 @@ use std::fmt;
|
|||||||
pub enum Error {
|
pub enum Error {
|
||||||
/// An HTTP error from the `hyper` crate.
|
/// An HTTP error from the `hyper` crate.
|
||||||
Http(::hyper::Error),
|
Http(::hyper::Error),
|
||||||
|
/// An error trying to serialize a value.
|
||||||
|
///
|
||||||
|
/// This may be serializing a value that is illegal in JSON or
|
||||||
|
/// form-url-encoded bodies.
|
||||||
|
Serialize(Box<StdError>),
|
||||||
/// A request tried to redirect too many times.
|
/// A request tried to redirect too many times.
|
||||||
TooManyRedirects,
|
TooManyRedirects,
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
@@ -16,6 +21,7 @@ impl fmt::Display for Error {
|
|||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match *self {
|
match *self {
|
||||||
Error::Http(ref e) => fmt::Display::fmt(e, f),
|
Error::Http(ref e) => fmt::Display::fmt(e, f),
|
||||||
|
Error::Serialize(ref e) => fmt::Display::fmt(e, f),
|
||||||
Error::TooManyRedirects => {
|
Error::TooManyRedirects => {
|
||||||
f.pad("Too many redirects")
|
f.pad("Too many redirects")
|
||||||
},
|
},
|
||||||
@@ -28,6 +34,7 @@ impl StdError for Error {
|
|||||||
fn description(&self) -> &str {
|
fn description(&self) -> &str {
|
||||||
match *self {
|
match *self {
|
||||||
Error::Http(ref e) => e.description(),
|
Error::Http(ref e) => e.description(),
|
||||||
|
Error::Serialize(ref e) => e.description(),
|
||||||
Error::TooManyRedirects => "Too many redirects",
|
Error::TooManyRedirects => "Too many redirects",
|
||||||
Error::__DontMatchMe => unreachable!()
|
Error::__DontMatchMe => unreachable!()
|
||||||
}
|
}
|
||||||
@@ -36,6 +43,7 @@ impl StdError for Error {
|
|||||||
fn cause(&self) -> Option<&StdError> {
|
fn cause(&self) -> Option<&StdError> {
|
||||||
match *self {
|
match *self {
|
||||||
Error::Http(ref e) => Some(e),
|
Error::Http(ref e) => Some(e),
|
||||||
|
Error::Serialize(ref e) => Some(&**e),
|
||||||
Error::TooManyRedirects => None,
|
Error::TooManyRedirects => None,
|
||||||
Error::__DontMatchMe => unreachable!()
|
Error::__DontMatchMe => unreachable!()
|
||||||
}
|
}
|
||||||
@@ -54,7 +62,11 @@ impl From<::url::ParseError> for Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<::serde_urlencoded::ser::Error> for Error {
|
||||||
|
fn from(err: ::serde_urlencoded::ser::Error) -> Error {
|
||||||
|
Error::Serialize(Box::new(err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A `Result` alias where the `Err` case is `reqwest::Error`.
|
/// A `Result` alias where the `Err` case is `reqwest::Error`.
|
||||||
pub type Result<T> = ::std::result::Result<T, Error>;
|
pub type Result<T> = ::std::result::Result<T, Error>;
|
||||||
|
|||||||
63
src/lib.rs
63
src/lib.rs
@@ -9,9 +9,9 @@
|
|||||||
//! to do for them.
|
//! to do for them.
|
||||||
//!
|
//!
|
||||||
//! - Uses system-native TLS
|
//! - Uses system-native TLS
|
||||||
//! - Plain bodies, JSON, urlencoded, multipart
|
//! - Plain bodies, JSON, urlencoded, (TODO: multipart)
|
||||||
//! - Customizable redirect policy
|
//! - (TODO: Customizable redirect policy)
|
||||||
//! - Cookies
|
//! - (TODO: Cookies)
|
||||||
//!
|
//!
|
||||||
//! The `reqwest::Client` is synchronous, making it a great fit for
|
//! The `reqwest::Client` is synchronous, making it a great fit for
|
||||||
//! applications that only require a few HTTP requests, and wish to handle
|
//! applications that only require a few HTTP requests, and wish to handle
|
||||||
@@ -32,12 +32,69 @@
|
|||||||
//!
|
//!
|
||||||
//! If you plan to perform multiple requests, it is best to create a [`Client`][client]
|
//! 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.
|
//! 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`][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.
|
||||||
|
//!
|
||||||
|
//! ```no_run
|
||||||
|
//! let client = reqwest::Client::new().unwrap();
|
||||||
|
//! let res = client.post("http://httpbin.org/post")
|
||||||
|
//! .body("the exact body that is sent")
|
||||||
|
//! .send();
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! ### Forms
|
||||||
|
//!
|
||||||
|
//! It's very common to want to send form data in a request body. This can be
|
||||||
|
//! done with any type that can be serialized into form data.
|
||||||
|
//!
|
||||||
|
//! This can be an array of tuples, or a `HashMap`, or a custom type that
|
||||||
|
//! implements [`Serialize`][serde].
|
||||||
|
//!
|
||||||
|
//! ```no_run
|
||||||
|
//! // This will POST a body of `foo=bar&baz=quux`
|
||||||
|
//! let params = [("foo", "bar"), ("baz", "quux")];
|
||||||
|
//! let client = reqwest::Client::new().unwrap();
|
||||||
|
//! let res = client.post("http://httpbin.org/post")
|
||||||
|
//! .form(¶ms)
|
||||||
|
//! .send();
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! ### JSON
|
||||||
|
//!
|
||||||
|
//! There is also a `json` method helper on the [`RequestBuilder`][builder] that works in
|
||||||
|
//! a similar fashion the `form` method. It can take any value that can be
|
||||||
|
//! serialized into JSON.
|
||||||
|
//!
|
||||||
|
//! ```no_run
|
||||||
|
//! # use std::collections::HashMap;
|
||||||
|
//! // This will POST a body of `{"lang":"rust","body":"json"}`
|
||||||
|
//! let mut map = HashMap::new();
|
||||||
|
//! map.insert("lang", "rust");
|
||||||
|
//! map.insert("body", "json");
|
||||||
|
//!
|
||||||
|
//! let client = reqwest::Client::new().unwrap();
|
||||||
|
//! let res = client.post("http://httpbin.org/post")
|
||||||
|
//! .json(&map)
|
||||||
|
//! .send();
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! [hyper]: http://hyper.rs
|
||||||
|
//! [client]: ./struct.Client.html
|
||||||
|
//! [builder]: ./client/struct.RequestBuilder.html
|
||||||
|
//! [serde]: http://serde.rs
|
||||||
extern crate hyper;
|
extern crate hyper;
|
||||||
|
|
||||||
#[macro_use] extern crate log;
|
#[macro_use] extern crate log;
|
||||||
#[cfg(feature = "tls")] extern crate native_tls;
|
#[cfg(feature = "tls")] extern crate native_tls;
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
extern crate serde_json;
|
extern crate serde_json;
|
||||||
|
extern crate serde_urlencoded;
|
||||||
extern crate url;
|
extern crate url;
|
||||||
|
|
||||||
pub use hyper::header;
|
pub use hyper::header;
|
||||||
|
|||||||
Reference in New Issue
Block a user