fix(client): close connection when there is an Error
This commit is contained in:
		| @@ -101,11 +101,17 @@ impl Request<Fresh> { | ||||
|     /// Consume a Fresh Request, writing the headers and method, | ||||
|     /// returning a Streaming Request. | ||||
|     pub fn start(mut self) -> ::Result<Request<Streaming>> { | ||||
|         let head = try!(self.message.set_outgoing(RequestHead { | ||||
|         let head = match self.message.set_outgoing(RequestHead { | ||||
|             headers: self.headers, | ||||
|             method: self.method, | ||||
|             url: self.url, | ||||
|         })); | ||||
|         }) { | ||||
|             Ok(head) => head, | ||||
|             Err(e) => { | ||||
|                 let _ = self.message.close_connection(); | ||||
|                 return Err(From::from(e)); | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         Ok(Request { | ||||
|             method: head.method, | ||||
| @@ -134,17 +140,30 @@ impl Request<Streaming> { | ||||
| impl Write for Request<Streaming> { | ||||
|     #[inline] | ||||
|     fn write(&mut self, msg: &[u8]) -> io::Result<usize> { | ||||
|         self.message.write(msg) | ||||
|         match self.message.write(msg) { | ||||
|             Ok(n) => Ok(n), | ||||
|             Err(e) => { | ||||
|                 let _ = self.message.close_connection(); | ||||
|                 Err(e) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     #[inline] | ||||
|     fn flush(&mut self) -> io::Result<()> { | ||||
|         self.message.flush() | ||||
|         match self.message.flush() { | ||||
|             Ok(r) => Ok(r), | ||||
|             Err(e) => { | ||||
|                 let _ = self.message.close_connection(); | ||||
|                 Err(e) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use std::io::Write; | ||||
|     use std::str::from_utf8; | ||||
|     use url::Url; | ||||
|     use method::Method::{Get, Head, Post}; | ||||
| @@ -237,4 +256,24 @@ mod tests { | ||||
|         assert!(!s.contains("Content-Length:")); | ||||
|         assert!(s.contains("Transfer-Encoding:")); | ||||
|     } | ||||
|  | ||||
|     #[test] | ||||
|     fn test_write_error_closes() { | ||||
|         let url = Url::parse("http://hyper.rs").unwrap(); | ||||
|         let req = Request::with_connector( | ||||
|             Get, url, &mut MockConnector | ||||
|         ).unwrap(); | ||||
|         let mut req = req.start().unwrap(); | ||||
|  | ||||
|         req.message.downcast_mut::<Http11Message>().unwrap() | ||||
|             .get_mut().downcast_mut::<MockStream>().unwrap() | ||||
|             .error_on_write = true; | ||||
|  | ||||
|         req.write(b"foo").unwrap(); | ||||
|         assert!(req.flush().is_err()); | ||||
|  | ||||
|         assert!(req.message.downcast_ref::<Http11Message>().unwrap() | ||||
|             .get_ref().downcast_ref::<MockStream>().unwrap() | ||||
|             .is_closed); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -37,7 +37,13 @@ impl Response { | ||||
|     /// Creates a new response received from the server on the given `HttpMessage`. | ||||
|     pub fn with_message(url: Url, mut message: Box<HttpMessage>) -> ::Result<Response> { | ||||
|         trace!("Response::with_message"); | ||||
|         let ResponseHead { headers, raw_status, version } = try!(message.get_incoming()); | ||||
|         let ResponseHead { headers, raw_status, version } = match message.get_incoming() { | ||||
|             Ok(head) => head, | ||||
|             Err(e) => { | ||||
|                 let _ = message.close_connection(); | ||||
|                 return Err(From::from(e)); | ||||
|             } | ||||
|         }; | ||||
|         let status = status::StatusCode::from_u16(raw_status.0); | ||||
|         debug!("version={:?}, status={:?}", version, status); | ||||
|         debug!("headers={:?}", headers); | ||||
| @@ -54,6 +60,7 @@ impl Response { | ||||
|     } | ||||
|  | ||||
|     /// Get the raw status code and reason. | ||||
|     #[inline] | ||||
|     pub fn status_raw(&self) -> &RawStatus { | ||||
|         &self.status_raw | ||||
|     } | ||||
| @@ -68,6 +75,10 @@ impl Read for Response { | ||||
|                 self.is_drained = true; | ||||
|                 Ok(0) | ||||
|             }, | ||||
|             Err(e) => { | ||||
|                 let _ = self.message.close_connection(); | ||||
|                 Err(e) | ||||
|             } | ||||
|             r => r | ||||
|         } | ||||
|     } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user