improvements
This commit is contained in:
		| @@ -4,7 +4,9 @@ extern crate env_logger; | |||||||
| fn main() { | fn main() { | ||||||
|     env_logger::init().unwrap(); |     env_logger::init().unwrap(); | ||||||
|  |  | ||||||
|     let mut res = request::get("https://rust-lang.org").unwrap(); |     println!("GET https://www.rust-lang.org"); | ||||||
|  |  | ||||||
|  |     let mut res = request::get("https://www.rust-lang.org").unwrap(); | ||||||
|  |  | ||||||
|     println!("Status: {}", res.status()); |     println!("Status: {}", res.status()); | ||||||
|     println!("Headers:\n{}", res.headers()); |     println!("Headers:\n{}", res.headers()); | ||||||
|   | |||||||
							
								
								
									
										37
									
								
								src/body.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								src/body.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | |||||||
|  | use std::io::Read; | ||||||
|  |  | ||||||
|  | pub struct Body(Kind); | ||||||
|  |  | ||||||
|  | impl Body { | ||||||
|  |     pub fn sized(reader: (), len: u64) -> Body { | ||||||
|  |         unimplemented!() | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     pub fn chunked(reader: ()) -> Body { | ||||||
|  |         unimplemented!() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | enum Kind { | ||||||
|  |     Length, | ||||||
|  |     Chunked | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl From<Vec<u8>> for Body { | ||||||
|  |     #[inline] | ||||||
|  |     fn from(v: Vec<u8>) -> Body { | ||||||
|  |         unimplemented!() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl From<String> for Body { | ||||||
|  |     #[inline] | ||||||
|  |     fn from(s: String) -> Body { | ||||||
|  |         s.into_bytes().into() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /// Wraps a `std::io::Write`. | ||||||
|  | pub struct Pipe(Kind); | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -3,7 +3,8 @@ use std::io::{self, Read}; | |||||||
| use hyper::{Method, StatusCode, HttpVersion, Url}; | use hyper::{Method, StatusCode, HttpVersion, Url}; | ||||||
| use hyper::header::Headers; | use hyper::header::Headers; | ||||||
|  |  | ||||||
| use super::sync; | use ::body::Body; | ||||||
|  | use ::sync; | ||||||
|  |  | ||||||
| pub struct Client { | pub struct Client { | ||||||
|     inner: sync::Client, |     inner: sync::Client, | ||||||
| @@ -42,20 +43,31 @@ pub struct RequestBuilder<'a> { | |||||||
|     version: HttpVersion, |     version: HttpVersion, | ||||||
|     headers: Headers, |     headers: Headers, | ||||||
|  |  | ||||||
|     body: Option<()>, |     body: Option<Body>, | ||||||
| } | } | ||||||
|  |  | ||||||
| impl<'a> RequestBuilder<'a> { | impl<'a> RequestBuilder<'a> { | ||||||
|     pub fn body(mut self, body: ()) -> RequestBuilder<'a> { |  | ||||||
|         self.body = Some(body); |     pub fn header<H: ::header::Header>(mut self, header: H) -> RequestBuilder<'a> { | ||||||
|  |         self.headers.set(header); | ||||||
|         self |         self | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     pub fn send(mut self) -> Result<Response, String> { |     pub fn headers(mut self, headers: ::header::Headers) -> RequestBuilder<'a> { | ||||||
|         self.headers.set(::hyper::header::ContentLength(0)); |         self.headers.extend(headers.iter()); | ||||||
|  |         self | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     pub fn body<T: Into<Body>>(mut self, body: T) -> RequestBuilder<'a> { | ||||||
|  |         self.body = Some(body.into()); | ||||||
|  |         self | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     pub fn send(mut self) -> ::Result<Response> { | ||||||
|  |         self.headers.set(::header::ContentLength(0)); | ||||||
|         let req = try!(self.client.inner.request(self.method, self.url, self.version, self.headers)); |         let req = try!(self.client.inner.request(self.method, self.url, self.version, self.headers)); | ||||||
|  |  | ||||||
|         let res = try!(req.end().map_err(|e| format!("RequestError: end: {}", e))); |         let res = try!(req.end()); | ||||||
|         Ok(Response { |         Ok(Response { | ||||||
|             inner: res |             inner: res | ||||||
|         }) |         }) | ||||||
|   | |||||||
							
								
								
									
										14
									
								
								src/error.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/error.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | |||||||
|  | #[derive(Debug)] | ||||||
|  | pub enum Error { | ||||||
|  |     Http(::hyper::Error), | ||||||
|  |     #[doc(hidden)] | ||||||
|  |     __DontMatchMe, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl From<::hyper::Error> for Error { | ||||||
|  |     fn from(err: ::hyper::Error) -> Error { | ||||||
|  |         Error::Http(err) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | pub type Result<T> = ::std::result::Result<T, Error>; | ||||||
							
								
								
									
										11
									
								
								src/lib.rs
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								src/lib.rs
									
									
									
									
									
								
							| @@ -1,14 +1,21 @@ | |||||||
|  | #![allow(warnings)] | ||||||
|  |  | ||||||
|  |  | ||||||
| extern crate hyper; | extern crate hyper; | ||||||
|  |  | ||||||
| #[macro_use] extern crate log; | #[macro_use] extern crate log; | ||||||
|  |  | ||||||
| pub use hyper::{Method, StatusCode, header, Url}; | pub use hyper::{Method, StatusCode, header, Url}; | ||||||
| pub use self::client::{Client, Response}; |  | ||||||
|  |  | ||||||
|  | pub use self::client::{Client, Response}; | ||||||
|  | pub use self::error::{Error, Result}; | ||||||
|  |  | ||||||
|  | mod body; | ||||||
| mod client; | mod client; | ||||||
|  | mod error; | ||||||
| mod sync; | mod sync; | ||||||
|  |  | ||||||
| pub fn get(url: &str) -> Result<Response, String> { | pub fn get(url: &str) -> ::Result<Response> { | ||||||
|     let client = Client::new(); |     let client = Client::new(); | ||||||
|     client.get(url).send() |     client.get(url).send() | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										34
									
								
								src/sync.rs
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								src/sync.rs
									
									
									
									
									
								
							| @@ -18,7 +18,7 @@ impl Client { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     pub fn request(&self, method: Method, url: Url, version: HttpVersion, headers: Headers) -> Result<Request, String> { |     pub fn request(&self, method: Method, url: Url, version: HttpVersion, headers: Headers) -> ::Result<Request> { | ||||||
|         let (ctrl_tx, ctrl_rx) = mpsc::channel(); |         let (ctrl_tx, ctrl_rx) = mpsc::channel(); | ||||||
|         let (res_tx, res_rx) = mpsc::channel(); |         let (res_tx, res_rx) = mpsc::channel(); | ||||||
|         let (action_tx, rx) = mpsc::channel(); |         let (action_tx, rx) = mpsc::channel(); | ||||||
| @@ -26,7 +26,7 @@ impl Client { | |||||||
|  |  | ||||||
|         let timeout = Duration::from_secs(10); |         let timeout = Duration::from_secs(10); | ||||||
|  |  | ||||||
|         try!(self.inner.request(url, SynchronousHandler { |         self.inner.request(url, SynchronousHandler { | ||||||
|             read_timeout: timeout, |             read_timeout: timeout, | ||||||
|             write_timeout: timeout, |             write_timeout: timeout, | ||||||
|  |  | ||||||
| @@ -37,29 +37,32 @@ impl Client { | |||||||
|             reading: None, |             reading: None, | ||||||
|             writing: None, |             writing: None, | ||||||
|             request: Some((method, version, headers)), |             request: Some((method, version, headers)), | ||||||
|         }).map_err(|e| format!("RequestError: {}", e))); |         }).ok().expect("client dropped early"); | ||||||
|  |  | ||||||
|  |         // connecting | ||||||
|  |         let ctrl = try!(ctrl_rx.recv().expect("ctrl_rx dropped early")); | ||||||
|  |  | ||||||
|         Ok(Request { |         Ok(Request { | ||||||
|             res_rx: res_rx, |             res_rx: res_rx, | ||||||
|             tx: action_tx, |             tx: action_tx, | ||||||
|             rx: action_rx, |             rx: action_rx, | ||||||
|             ctrl: try!(ctrl_rx.recv().map_err(|e| format!("RequestError: waiting for Control: {}", e))), |             ctrl: ctrl, | ||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| pub struct Request { | pub struct Request { | ||||||
|     res_rx: mpsc::Receiver<hyper::client::Response>, |     res_rx: mpsc::Receiver<::hyper::Result<hyper::client::Response>>, | ||||||
|     tx: mpsc::Sender<Action>, |     tx: mpsc::Sender<Action>, | ||||||
|     rx: mpsc::Receiver<io::Result<usize>>, |     rx: mpsc::Receiver<io::Result<usize>>, | ||||||
|     ctrl: hyper::Control, |     ctrl: hyper::Control, | ||||||
| } | } | ||||||
|  |  | ||||||
| impl Request { | impl Request { | ||||||
|     pub fn end(self) -> Result<Response, String> { |     pub fn end(self) -> ::Result<Response> { | ||||||
|         trace!("Request.end"); |         trace!("Request.end"); | ||||||
|         self.ctrl.ready(Next::read()).unwrap(); |         self.ctrl.ready(Next::read()).unwrap(); | ||||||
|         let res = try!(self.res_rx.recv().map_err(|e| format!("RequestError: end = {}", e))); |         let res = try!(self.res_rx.recv().expect("res_tx dropped early")); | ||||||
|         Ok(Response { |         Ok(Response { | ||||||
|             status: res.status().clone(), |             status: res.status().clone(), | ||||||
|             headers: res.headers().clone(), |             headers: res.headers().clone(), | ||||||
| @@ -108,8 +111,8 @@ struct SynchronousHandler { | |||||||
|     read_timeout: Duration, |     read_timeout: Duration, | ||||||
|     write_timeout: Duration, |     write_timeout: Duration, | ||||||
|  |  | ||||||
|     ctrl_tx: mpsc::Sender<Control>, |     ctrl_tx: mpsc::Sender<::hyper::Result<Control>>, | ||||||
|     res_tx: mpsc::Sender<hyper::client::Response>, |     res_tx: mpsc::Sender<::hyper::Result<hyper::client::Response>>, | ||||||
|     tx: mpsc::Sender<io::Result<usize>>, |     tx: mpsc::Sender<io::Result<usize>>, | ||||||
|     rx: mpsc::Receiver<Action>, |     rx: mpsc::Receiver<Action>, | ||||||
|     reading: Option<(*mut u8, usize)>, |     reading: Option<(*mut u8, usize)>, | ||||||
| @@ -189,7 +192,7 @@ impl hyper::client::Handler<hyper::client::DefaultTransport> for SynchronousHand | |||||||
|  |  | ||||||
|     fn on_response(&mut self, res: hyper::client::Response) -> Next { |     fn on_response(&mut self, res: hyper::client::Response) -> Next { | ||||||
|         trace!("on_response {:?}", res); |         trace!("on_response {:?}", res); | ||||||
|         if let Err(_) = self.res_tx.send(res) { |         if let Err(_) = self.res_tx.send(Ok(res)) { | ||||||
|             return Next::end(); |             return Next::end(); | ||||||
|         } |         } | ||||||
|         self.next() |         self.next() | ||||||
| @@ -206,15 +209,20 @@ impl hyper::client::Handler<hyper::client::DefaultTransport> for SynchronousHand | |||||||
|         self.next() |         self.next() | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     fn on_error(&mut self, err: ::hyper::Error) -> Next { | ||||||
|  |         debug!("on_error {:?}", err); | ||||||
|  |         let _ = self.ctrl_tx.send(Err(err)); | ||||||
|  |         Next::remove() | ||||||
|  |     } | ||||||
|  |  | ||||||
|     fn on_control(&mut self, ctrl: Control) { |     fn on_control(&mut self, ctrl: Control) { | ||||||
|         self.ctrl_tx.send(ctrl).unwrap(); |         let _ = self.ctrl_tx.send(Ok(ctrl)); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| enum Action { | enum Action { | ||||||
|     Read(*mut u8, usize), |     Read(*mut u8, usize), | ||||||
|     Write(*const u8, usize), |     Write(*const u8, usize), | ||||||
|     //Request(Method, RequestUri, HttpVersion, Headers), |  | ||||||
| } | } | ||||||
|  |  | ||||||
| unsafe impl Send for Action {} | unsafe impl Send for Action {} | ||||||
| @@ -228,6 +236,8 @@ mod tests { | |||||||
|  |  | ||||||
|     #[test] |     #[test] | ||||||
|     fn test_get() { |     fn test_get() { | ||||||
|  |         extern crate env_logger; | ||||||
|  |         env_logger::init().unwrap(); | ||||||
|         let server = TcpListener::bind("127.0.0.1:0").unwrap(); |         let server = TcpListener::bind("127.0.0.1:0").unwrap(); | ||||||
|         let addr = server.local_addr().unwrap(); |         let addr = server.local_addr().unwrap(); | ||||||
|         thread::spawn(move || { |         thread::spawn(move || { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user