From 1a91835abaa804aabf2e9bb45e9ab087274b8a18 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Wed, 12 Aug 2015 14:12:16 -0700 Subject: [PATCH 1/2] feat(net): impl downcast methods for NetworkStream (without + Send) Closes #521 --- src/net.rs | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/src/net.rs b/src/net.rs index 5c8a1774f4..602bfee946 100644 --- a/src/net.rs +++ b/src/net.rs @@ -84,6 +84,61 @@ impl fmt::Debug for Box { } } +impl NetworkStream { + unsafe fn downcast_ref_unchecked(&self) -> &T { + mem::transmute(traitobject::data(self)) + } + + unsafe fn downcast_mut_unchecked(&mut self) -> &mut T { + mem::transmute(traitobject::data_mut(self)) + } + + unsafe fn downcast_unchecked(self: Box) -> Box { + let raw: *mut NetworkStream = mem::transmute(self); + mem::transmute(traitobject::data_mut(raw)) + } +} + +impl NetworkStream { + /// Is the underlying type in this trait object a T? + #[inline] + pub fn is(&self) -> bool { + (*self).get_type() == TypeId::of::() + } + + /// If the underlying type is T, get a reference to the contained data. + #[inline] + pub fn downcast_ref(&self) -> Option<&T> { + if self.is::() { + Some(unsafe { self.downcast_ref_unchecked() }) + } else { + None + } + } + + /// If the underlying type is T, get a mutable reference to the contained + /// data. + #[inline] + pub fn downcast_mut(&mut self) -> Option<&mut T> { + if self.is::() { + Some(unsafe { self.downcast_mut_unchecked() }) + } else { + None + } + } + + /// If the underlying type is T, extract it. + #[inline] + pub fn downcast(self: Box) + -> Result, Box> { + if self.is::() { + Ok(unsafe { self.downcast_unchecked() }) + } else { + Err(self) + } + } +} + impl NetworkStream + Send { unsafe fn downcast_ref_unchecked(&self) -> &T { mem::transmute(traitobject::data(self)) From 7909829f98bd9a2f454430f89b6143b977aedb35 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Wed, 12 Aug 2015 14:13:14 -0700 Subject: [PATCH 2/2] feat(server): add Request.ssl() to get underlying ssl stream Closes #627 --- src/server/request.rs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/server/request.rs b/src/server/request.rs index adda55ee94..b8e0fd2958 100644 --- a/src/server/request.rs +++ b/src/server/request.rs @@ -64,6 +64,38 @@ impl<'a, 'b: 'a> Request<'a, 'b> { }) } + /// Get a reference to the underlying `NetworkStream`. + #[inline] + pub fn downcast_ref(&self) -> Option<&T> { + self.body.get_ref().get_ref().downcast_ref() + } + + /// Get a reference to the underlying Ssl stream, if connected + /// over HTTPS. + /// + /// # Example + /// + /// ```rust + /// # extern crate hyper; + /// # #[cfg(feature = "openssl")] + /// extern crate openssl; + /// # #[cfg(feature = "openssl")] + /// use openssl::ssl::SslStream; + /// # fn main() {} + /// # #[cfg(feature = "openssl")] + /// # fn doc_ssl(req: hyper::server::Request) { + /// let maybe_ssl = req.ssl::(); + /// # } + /// ``` + #[inline] + pub fn ssl(&self) -> Option<&T> { + use ::net::HttpsStream; + match self.downcast_ref() { + Some(&HttpsStream::Https(ref s)) => Some(s), + _ => None + } + } + /// Deconstruct a Request into its constituent parts. #[inline] pub fn deconstruct(self) -> (SocketAddr, Method, Headers,