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