diff --git a/src/net.rs b/src/net.rs index 2146d413e7..90e6f76646 100644 --- a/src/net.rs +++ b/src/net.rs @@ -1,7 +1,7 @@ //! A collection of traits abstracting over Listeners and Streams. use std::any::{Any, TypeId}; use std::fmt; -use std::io::{self, Read, Write}; +use std::io::{self, ErrorKind, Read, Write}; use std::net::{SocketAddr, ToSocketAddrs, TcpStream, TcpListener, Shutdown}; use std::mem; use std::path::Path; @@ -292,10 +292,20 @@ impl NetworkStream for HttpStream { #[inline] fn close(&mut self, how: Shutdown) -> io::Result<()> { + #[inline] + fn shutdown(tcp: &mut TcpStream, how: Shutdown) -> io::Result<()> { + match tcp.shutdown(how) { + Ok(_) => Ok(()), + Err(ref e) if e.kind() == ErrorKind::NotConnected => Ok(()), + err => err + } + } + match *self { - HttpStream::Http(ref mut inner) => inner.0.shutdown(how), - HttpStream::Https(ref mut inner) => inner.get_mut().0.shutdown(how) + HttpStream::Http(ref mut inner) => shutdown(&mut inner.0, how), + HttpStream::Https(ref mut inner) => shutdown(&mut inner.get_mut().0, how) } + } } @@ -347,8 +357,19 @@ fn lift_ssl_error(ssl: SslError) -> io::Error { #[cfg(test)] mod tests { + use std::net::{Shutdown, TcpStream}; + use mock::MockStream; - use super::NetworkStream; + use super::{HttpStream, NetworkStream, CloneTcpStream}; + + #[test] + fn test_shutdown() { + let tcp = CloneTcpStream(TcpStream::connect("0.0.0.0:1111").unwrap()); + let mut stream = HttpStream::Http(tcp); + // see https://github.com/hyperium/hyper/issues/508 + stream.close(Shutdown::Write).unwrap(); + stream.close(Shutdown::Write).unwrap(); + } #[test] fn test_downcast_box_stream() {