Merge branch 'form'
This commit is contained in:
		| @@ -13,6 +13,7 @@ hyper = { version = "0.9" , default-features = false } | ||||
| log = "0.3" | ||||
| serde = "0.8" | ||||
| serde_json = "0.8" | ||||
| serde_urlencoded = "0.3" | ||||
| url = "1.0" | ||||
|  | ||||
| [dependencies.native-tls] | ||||
|   | ||||
| @@ -9,6 +9,7 @@ use hyper::{Url}; | ||||
|  | ||||
| use serde::Serialize; | ||||
| use serde_json; | ||||
| use serde_urlencoded; | ||||
|  | ||||
| use ::body::{self, Body}; | ||||
|  | ||||
| @@ -94,7 +95,7 @@ pub struct RequestBuilder<'a> { | ||||
|     _version: HttpVersion, | ||||
|     headers: Headers, | ||||
|  | ||||
|     body: Option<Body>, | ||||
|     body: Option<::Result<Body>>, | ||||
| } | ||||
|  | ||||
| impl<'a> RequestBuilder<'a> { | ||||
| @@ -122,7 +123,30 @@ impl<'a> RequestBuilder<'a> { | ||||
|  | ||||
|     /// Set the request body. | ||||
|     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 | ||||
|     } | ||||
|  | ||||
| @@ -136,14 +160,15 @@ impl<'a> RequestBuilder<'a> { | ||||
|     /// let mut map = HashMap::new(); | ||||
|     /// map.insert("lang", "rust"); | ||||
|     /// | ||||
|     /// let res = reqwest::post("http://www.rust-lang.org") | ||||
|     ///     .json(map) | ||||
|     /// let client = reqwest::Client::new().unwrap(); | ||||
|     /// let res = client.post("http://httpbin.org") | ||||
|     ///     .json(&map) | ||||
|     ///     .send(); | ||||
|     /// ``` | ||||
|     pub fn json<T: Serialize>(mut self, json: T) -> RequestBuilder<'a> { | ||||
|         let body = serde_json::to_vec(&json).expect("serde to_vec cannot fail"); | ||||
|     pub fn json<T: Serialize>(mut self, json: &T) -> RequestBuilder<'a> { | ||||
|         let body = serde_json::to_vec(json).expect("serde to_vec cannot fail"); | ||||
|         self.headers.set(ContentType::json()); | ||||
|         self.body = Some(body.into()); | ||||
|         self.body = Some(Ok(body.into())); | ||||
|         self | ||||
|     } | ||||
|  | ||||
| @@ -157,7 +182,10 @@ impl<'a> RequestBuilder<'a> { | ||||
|         let mut method = self.method; | ||||
|         let mut url = try!(self.url); | ||||
|         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; | ||||
|  | ||||
|   | ||||
							
								
								
									
										14
									
								
								src/error.rs
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								src/error.rs
									
									
									
									
									
								
							| @@ -6,6 +6,11 @@ use std::fmt; | ||||
| pub enum Error { | ||||
|     /// An HTTP error from the `hyper` crate. | ||||
|     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. | ||||
|     TooManyRedirects, | ||||
|     #[doc(hidden)] | ||||
| @@ -16,6 +21,7 @@ impl fmt::Display for Error { | ||||
|     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||||
|         match *self { | ||||
|             Error::Http(ref e) => fmt::Display::fmt(e, f), | ||||
|             Error::Serialize(ref e) => fmt::Display::fmt(e, f), | ||||
|             Error::TooManyRedirects => { | ||||
|                 f.pad("Too many redirects") | ||||
|             }, | ||||
| @@ -28,6 +34,7 @@ impl StdError for Error { | ||||
|     fn description(&self) -> &str { | ||||
|         match *self { | ||||
|             Error::Http(ref e) => e.description(), | ||||
|             Error::Serialize(ref e) => e.description(), | ||||
|             Error::TooManyRedirects => "Too many redirects", | ||||
|             Error::__DontMatchMe => unreachable!() | ||||
|         } | ||||
| @@ -36,6 +43,7 @@ impl StdError for Error { | ||||
|     fn cause(&self) -> Option<&StdError> { | ||||
|         match *self { | ||||
|             Error::Http(ref e) => Some(e), | ||||
|             Error::Serialize(ref e) => Some(&**e), | ||||
|             Error::TooManyRedirects => None, | ||||
|             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`. | ||||
| 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. | ||||
| //! | ||||
| //! - Uses system-native TLS | ||||
| //! - Plain bodies, JSON, urlencoded, multipart | ||||
| //! - Customizable redirect policy | ||||
| //! - Cookies | ||||
| //! - Plain bodies, JSON, urlencoded, (TODO: multipart) | ||||
| //! - (TODO: Customizable redirect policy) | ||||
| //! - (TODO: Cookies) | ||||
| //! | ||||
| //! The `reqwest::Client` is synchronous, making it a great fit for | ||||
| //! 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] | ||||
| //! 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; | ||||
|  | ||||
| #[macro_use] extern crate log; | ||||
| #[cfg(feature = "tls")] extern crate native_tls; | ||||
| extern crate serde; | ||||
| extern crate serde_json; | ||||
| extern crate serde_urlencoded; | ||||
| extern crate url; | ||||
|  | ||||
| pub use hyper::header; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user