add native-tls and serde json support
This commit is contained in:
		| @@ -1,35 +1,58 @@ | ||||
| use std::io::{self, Read}; | ||||
|  | ||||
| use hyper::header::Headers; | ||||
| use hyper::header::{Headers, ContentType, UserAgent}; | ||||
| use hyper::method::Method; | ||||
| use hyper::status::StatusCode; | ||||
| use hyper::version::HttpVersion; | ||||
| use hyper::{Url}; | ||||
|  | ||||
| use ::body::Body; | ||||
| use serde::Serialize; | ||||
| use serde_json; | ||||
|  | ||||
| use ::body::{self, Body}; | ||||
|  | ||||
| static DEFAULT_USER_AGENT: &'static str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION")); | ||||
|  | ||||
| /// A `Client` to make Requests with. | ||||
| /// | ||||
| /// The Client has various configuration values to tweak, but the defaults | ||||
| /// are set to what is usually the most commonly desired value. | ||||
| /// | ||||
| /// The `Client` holds a connection pool internally, so it is advised that | ||||
| /// you create one and reuse it. | ||||
| pub struct Client { | ||||
|     inner: ::hyper::Client, | ||||
| } | ||||
|  | ||||
| impl Client { | ||||
|     /// Constructs a new `Client`. | ||||
|     pub fn new() -> Client { | ||||
|         Client { | ||||
|             inner: ::hyper::Client::new(), | ||||
|             inner: new_hyper_client() | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// Convenience method to make a `GET` request to a URL. | ||||
|     pub fn get(&self, url: &str) -> RequestBuilder { | ||||
|         self.request(Method::Get, Url::parse(url).unwrap()) | ||||
|     } | ||||
|  | ||||
|     /// Convenience method to make a `POST` request to a URL. | ||||
|     pub fn post(&self, url: &str) -> RequestBuilder { | ||||
|         self.request(Method::Post, Url::parse(url).unwrap()) | ||||
|     } | ||||
|  | ||||
|     /// Start building a `Request` with the `Method` and `Url`. | ||||
|     /// | ||||
|     /// Returns a `RequestBuilder`, which will allow setting headers and | ||||
|     /// request body before sending. | ||||
|     pub fn request(&self, method: Method, url: Url) -> RequestBuilder { | ||||
|         debug!("request {:?} \"{}\"", method, url); | ||||
|         RequestBuilder { | ||||
|             client: self, | ||||
|             method: method, | ||||
|             url: url, | ||||
|             version: HttpVersion::Http11, | ||||
|             _version: HttpVersion::Http11, | ||||
|             headers: Headers::new(), | ||||
|  | ||||
|             body: None, | ||||
| @@ -37,39 +60,75 @@ impl Client { | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[cfg(not(feature = "tls"))] | ||||
| fn new_hyper_client() -> ::hyper::Client { | ||||
|     ::hyper::Client::new() | ||||
| } | ||||
|  | ||||
| #[cfg(feature = "tls")] | ||||
| fn new_hyper_client() -> ::hyper::Client { | ||||
|     use tls::TlsClient; | ||||
|     ::hyper::Client::with_connector( | ||||
|         ::hyper::client::Pool::with_connector( | ||||
|             Default::default(), | ||||
|             ::hyper::net::HttpsConnector::new(TlsClient::new().unwrap()) | ||||
|         ) | ||||
|     ) | ||||
| } | ||||
|  | ||||
|  | ||||
| /// A builder to construct the properties of a `Request`. | ||||
| pub struct RequestBuilder<'a> { | ||||
|     client: &'a Client, | ||||
|  | ||||
|     method: Method, | ||||
|     url: Url, | ||||
|     version: HttpVersion, | ||||
|     _version: HttpVersion, | ||||
|     headers: Headers, | ||||
|  | ||||
|     body: Option<Body>, | ||||
| } | ||||
|  | ||||
| impl<'a> RequestBuilder<'a> { | ||||
|  | ||||
|     /// Add a `Header` to this Request. | ||||
|     pub fn header<H: ::header::Header + ::header::HeaderFormat>(mut self, header: H) -> RequestBuilder<'a> { | ||||
|         self.headers.set(header); | ||||
|         self | ||||
|     } | ||||
|  | ||||
|     /// Add a set of Headers to the existing ones on this Request. | ||||
|     /// | ||||
|     /// The headers will be merged in to any already set. | ||||
|     pub fn headers(mut self, headers: ::header::Headers) -> RequestBuilder<'a> { | ||||
|         self.headers.extend(headers.iter()); | ||||
|         self | ||||
|     } | ||||
|  | ||||
|     /// Set the request body. | ||||
|     pub fn body<T: Into<Body>>(mut self, body: T) -> RequestBuilder<'a> { | ||||
|         self.body = Some(body.into()); | ||||
|         self | ||||
|     } | ||||
|  | ||||
|     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 | ||||
|     } | ||||
|  | ||||
|     /// Constructs the Request and sends it the target URL, returning a Response. | ||||
|     pub fn send(mut self) -> ::Result<Response> { | ||||
|         let req = self.client.inner.request(self.method, self.url) | ||||
|         if !self.headers.has::<UserAgent>() { | ||||
|             self.headers.set(UserAgent(DEFAULT_USER_AGENT.to_owned())); | ||||
|         } | ||||
|  | ||||
|         let mut req = self.client.inner.request(self.method, self.url) | ||||
|             .headers(self.headers); | ||||
|  | ||||
|         //TODO: body | ||||
|         if let Some(ref b) = self.body { | ||||
|             let body = body::as_hyper_body(b); | ||||
|             req = req.body(body); | ||||
|         } | ||||
|  | ||||
|         let res = try!(req.send()); | ||||
|         Ok(Response { | ||||
| @@ -78,24 +137,29 @@ impl<'a> RequestBuilder<'a> { | ||||
|     } | ||||
| } | ||||
|  | ||||
| /// A Response to a submitted `Request`. | ||||
| pub struct Response { | ||||
|     inner: ::hyper::client::Response, | ||||
| } | ||||
|  | ||||
| impl Response { | ||||
|     /// Get the `StatusCode`. | ||||
|     pub fn status(&self) -> &StatusCode { | ||||
|         &self.inner.status | ||||
|     } | ||||
|  | ||||
|     /// Get the `Headers`. | ||||
|     pub fn headers(&self) -> &Headers { | ||||
|         &self.inner.headers | ||||
|     } | ||||
|  | ||||
|     /// Get the `HttpVersion`. | ||||
|     pub fn version(&self) -> &HttpVersion { | ||||
|         &self.inner.version | ||||
|     } | ||||
| } | ||||
|  | ||||
| /// Read the body of the Response. | ||||
| impl Read for Response { | ||||
|     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { | ||||
|         self.inner.read(buf) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user