From ebd1c563bff6ea0852a0ae7167b9c9cebc16c51c Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Thu, 7 May 2015 10:14:56 -0700 Subject: [PATCH] fix(net): ignore NotConnected error in NetworkStream.close On OSX, calling shutdown a second time will return a NotConnected error. This commit will just ignore it, since we can agree that if a stream is "not connected", it is in fact "closed". Closes #508 --- src/net.rs | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) 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() {