feat(net): add socket timeouts to Server and Client
While these methods are marked unstable in libstd, this is behind a feature flag, `timeouts`. The Client and Server both have `set_read_timeout` and `set_write_timeout` methods, that will affect all connections with that entity. BREAKING CHANGE: Any custom implementation of NetworkStream must now implement `set_read_timeout` and `set_write_timeout`, so those will break. Most users who only use the provided streams should work with no changes needed. Closes #315
This commit is contained in:
		| @@ -4,6 +4,8 @@ use std::cmp::min; | ||||
| use std::fmt; | ||||
| use std::io::{self, Write, BufWriter, BufRead, Read}; | ||||
| use std::net::Shutdown; | ||||
| #[cfg(feature = "timeouts")] | ||||
| use std::time::Duration; | ||||
|  | ||||
| use httparse; | ||||
|  | ||||
| @@ -192,6 +194,19 @@ impl HttpMessage for Http11Message { | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     #[cfg(feature = "timeouts")] | ||||
|     #[inline] | ||||
|     fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> { | ||||
|         self.get_ref().set_read_timeout(dur) | ||||
|     } | ||||
|  | ||||
|     #[cfg(feature = "timeouts")] | ||||
|     #[inline] | ||||
|     fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> { | ||||
|         self.get_ref().set_write_timeout(dur) | ||||
|     } | ||||
|  | ||||
|     #[inline] | ||||
|     fn close_connection(&mut self) -> ::Result<()> { | ||||
|         try!(self.get_mut().close(Shutdown::Both)); | ||||
|         Ok(()) | ||||
| @@ -214,13 +229,27 @@ impl Http11Message { | ||||
|  | ||||
|     /// Gets a mutable reference to the underlying `NetworkStream`, regardless of the state of the | ||||
|     /// `Http11Message`. | ||||
|     pub fn get_mut(&mut self) -> &mut Box<NetworkStream + Send> { | ||||
|     pub fn get_ref(&self) -> &(NetworkStream + Send) { | ||||
|         if self.stream.is_some() { | ||||
|             self.stream.as_mut().unwrap() | ||||
|             &**self.stream.as_ref().unwrap() | ||||
|         } else if self.writer.is_some() { | ||||
|             self.writer.as_mut().unwrap().get_mut().get_mut() | ||||
|             &**self.writer.as_ref().unwrap().get_ref().get_ref() | ||||
|         } else if self.reader.is_some() { | ||||
|             self.reader.as_mut().unwrap().get_mut().get_mut() | ||||
|             &**self.reader.as_ref().unwrap().get_ref().get_ref() | ||||
|         } else { | ||||
|             panic!("Http11Message lost its underlying stream somehow"); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// Gets a mutable reference to the underlying `NetworkStream`, regardless of the state of the | ||||
|     /// `Http11Message`. | ||||
|     pub fn get_mut(&mut self) -> &mut (NetworkStream + Send) { | ||||
|         if self.stream.is_some() { | ||||
|             &mut **self.stream.as_mut().unwrap() | ||||
|         } else if self.writer.is_some() { | ||||
|             &mut **self.writer.as_mut().unwrap().get_mut().get_mut() | ||||
|         } else if self.reader.is_some() { | ||||
|             &mut **self.reader.as_mut().unwrap().get_mut().get_mut() | ||||
|         } else { | ||||
|             panic!("Http11Message lost its underlying stream somehow"); | ||||
|         } | ||||
| @@ -344,6 +373,16 @@ impl<R: Read> HttpReader<R> { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// Gets a borrowed reference to the underlying Reader. | ||||
|     pub fn get_ref(&self) -> &R { | ||||
|         match *self { | ||||
|             SizedReader(ref r, _) => r, | ||||
|             ChunkedReader(ref r, _) => r, | ||||
|             EofReader(ref r) => r, | ||||
|             EmptyReader(ref r) => r, | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// Gets a mutable reference to the underlying Reader. | ||||
|     pub fn get_mut(&mut self) -> &mut R { | ||||
|         match *self { | ||||
|   | ||||
| @@ -4,6 +4,8 @@ use std::io::{self, Write, Read, Cursor}; | ||||
| use std::net::Shutdown; | ||||
| use std::ascii::AsciiExt; | ||||
| use std::mem; | ||||
| #[cfg(feature = "timeouts")] | ||||
| use std::time::Duration; | ||||
|  | ||||
| use http::{ | ||||
|     Protocol, | ||||
| @@ -398,6 +400,19 @@ impl<S> HttpMessage for Http2Message<S> where S: CloneableStream { | ||||
|         Ok(head) | ||||
|     } | ||||
|  | ||||
|     #[cfg(feature = "timeouts")] | ||||
|     #[inline] | ||||
|     fn set_read_timeout(&self, _dur: Option<Duration>) -> io::Result<()> { | ||||
|         Ok(()) | ||||
|     } | ||||
|  | ||||
|     #[cfg(feature = "timeouts")] | ||||
|     #[inline] | ||||
|     fn set_write_timeout(&self, _dur: Option<Duration>) -> io::Result<()> { | ||||
|         Ok(()) | ||||
|     } | ||||
|  | ||||
|     #[inline] | ||||
|     fn close_connection(&mut self) -> ::Result<()> { | ||||
|         Ok(()) | ||||
|     } | ||||
|   | ||||
| @@ -1,12 +1,16 @@ | ||||
| //! Defines the `HttpMessage` trait that serves to encapsulate the operations of a single | ||||
| //! request-response cycle on any HTTP connection. | ||||
|  | ||||
| use std::fmt::Debug; | ||||
| use std::any::{Any, TypeId}; | ||||
| use std::fmt::Debug; | ||||
| use std::io::{Read, Write}; | ||||
|  | ||||
| use std::mem; | ||||
|  | ||||
| #[cfg(feature = "timeouts")] | ||||
| use std::io; | ||||
| #[cfg(feature = "timeouts")] | ||||
| use std::time::Duration; | ||||
|  | ||||
| use typeable::Typeable; | ||||
|  | ||||
| use header::Headers; | ||||
| @@ -62,7 +66,10 @@ pub trait HttpMessage: Write + Read + Send + Any + Typeable + Debug { | ||||
|     fn get_incoming(&mut self) -> ::Result<ResponseHead>; | ||||
|     /// Set the read timeout duration for this message. | ||||
|     #[cfg(feature = "timeouts")] | ||||
|     fn set_read_timeout(&self, dur: Option<Duration>) -> ::Result<()>; | ||||
|     fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()>; | ||||
|     /// Set the write timeout duration for this message. | ||||
|     #[cfg(feature = "timeouts")] | ||||
|     fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()>; | ||||
|     /// Closes the underlying HTTP connection. | ||||
|     fn close_connection(&mut self) -> ::Result<()>; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user