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:
		
							
								
								
									
										59
									
								
								src/net.rs
									
									
									
									
									
								
							
							
						
						
									
										59
									
								
								src/net.rs
									
									
									
									
									
								
							| @@ -8,6 +8,9 @@ use std::mem; | ||||
| #[cfg(feature = "openssl")] | ||||
| pub use self::openssl::Openssl; | ||||
|  | ||||
| #[cfg(feature = "timeouts")] | ||||
| use std::time::Duration; | ||||
|  | ||||
| use typeable::Typeable; | ||||
| use traitobject; | ||||
|  | ||||
| @@ -21,8 +24,6 @@ pub enum Streaming {} | ||||
| pub trait NetworkListener: Clone { | ||||
|     /// The stream produced for each connection. | ||||
|     type Stream: NetworkStream + Send + Clone; | ||||
|     /// Listens on a socket. | ||||
|     //fn listen<To: ToSocketAddrs>(&mut self, addr: To) -> io::Result<Self::Acceptor>; | ||||
|  | ||||
|     /// Returns an iterator of streams. | ||||
|     fn accept(&mut self) -> ::Result<Self::Stream>; | ||||
| @@ -30,9 +31,6 @@ pub trait NetworkListener: Clone { | ||||
|     /// Get the address this Listener ended up listening on. | ||||
|     fn local_addr(&mut self) -> io::Result<SocketAddr>; | ||||
|  | ||||
|     /// Closes the Acceptor, so no more incoming connections will be handled. | ||||
| //    fn close(&mut self) -> io::Result<()>; | ||||
|  | ||||
|     /// Returns an iterator over incoming connections. | ||||
|     fn incoming(&mut self) -> NetworkConnections<Self> { | ||||
|         NetworkConnections(self) | ||||
| @@ -53,6 +51,12 @@ impl<'a, N: NetworkListener + 'a> Iterator for NetworkConnections<'a, N> { | ||||
| pub trait NetworkStream: Read + Write + Any + Send + Typeable { | ||||
|     /// Get the remote address of the underlying connection. | ||||
|     fn peer_addr(&mut self) -> io::Result<SocketAddr>; | ||||
|     /// Set the maximum time to wait for a read to complete. | ||||
|     #[cfg(feature = "timeouts")] | ||||
|     fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()>; | ||||
|     /// Set the maximum time to wait for a write to complete. | ||||
|     #[cfg(feature = "timeouts")] | ||||
|     fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()>; | ||||
|     /// This will be called when Stream should no longer be kept alive. | ||||
|     #[inline] | ||||
|     fn close(&mut self, _how: Shutdown) -> io::Result<()> { | ||||
| @@ -222,6 +226,18 @@ impl NetworkStream for HttpStream { | ||||
|             self.0.peer_addr() | ||||
|     } | ||||
|  | ||||
|     #[cfg(feature = "timeouts")] | ||||
|     #[inline] | ||||
|     fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> { | ||||
|         self.0.set_read_timeout(dur) | ||||
|     } | ||||
|  | ||||
|     #[cfg(feature = "timeouts")] | ||||
|     #[inline] | ||||
|     fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> { | ||||
|         self.0.set_write_timeout(dur) | ||||
|     } | ||||
|  | ||||
|     #[inline] | ||||
|     fn close(&mut self, how: Shutdown) -> io::Result<()> { | ||||
|         match self.0.shutdown(how) { | ||||
| @@ -312,6 +328,24 @@ impl<S: NetworkStream> NetworkStream for HttpsStream<S> { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     #[cfg(feature = "timeouts")] | ||||
|     #[inline] | ||||
|     fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> { | ||||
|         match *self { | ||||
|             HttpsStream::Http(ref inner) => inner.0.set_read_timeout(dur), | ||||
|             HttpsStream::Https(ref inner) => inner.set_read_timeout(dur) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     #[cfg(feature = "timeouts")] | ||||
|     #[inline] | ||||
|     fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> { | ||||
|         match *self { | ||||
|             HttpsStream::Http(ref inner) => inner.0.set_read_timeout(dur), | ||||
|             HttpsStream::Https(ref inner) => inner.set_read_timeout(dur) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     #[inline] | ||||
|     fn close(&mut self, how: Shutdown) -> io::Result<()> { | ||||
|         match *self { | ||||
| @@ -397,6 +431,9 @@ mod openssl { | ||||
|     use std::net::{SocketAddr, Shutdown}; | ||||
|     use std::path::Path; | ||||
|     use std::sync::Arc; | ||||
|     #[cfg(feature = "timeouts")] | ||||
|     use std::time::Duration; | ||||
|  | ||||
|     use openssl::ssl::{Ssl, SslContext, SslStream, SslMethod, SSL_VERIFY_NONE}; | ||||
|     use openssl::ssl::error::StreamError as SslIoError; | ||||
|     use openssl::ssl::error::SslError; | ||||
| @@ -475,6 +512,18 @@ mod openssl { | ||||
|             self.get_mut().peer_addr() | ||||
|         } | ||||
|  | ||||
|         #[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) | ||||
|         } | ||||
|  | ||||
|         fn close(&mut self, how: Shutdown) -> io::Result<()> { | ||||
|             self.get_mut().close(how) | ||||
|         } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user