From bdc9a8bb07afb10df5cef54f4a5f8ab36c2e253a Mon Sep 17 00:00:00 2001 From: Kornel Date: Fri, 17 Aug 2018 17:04:16 +0100 Subject: [PATCH] Optionally support tokio-uds's UnixStream as IoStream (#472) --- CHANGES.md | 2 ++ Cargo.toml | 6 ++++++ src/client/connector.rs | 4 ++++ src/lib.rs | 4 ++++ src/server/mod.rs | 18 ++++++++++++++++++ tests/test_client.rs | 10 ++++++++++ 6 files changed, 44 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index e73b929aa..9dd908aeb 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,6 +10,8 @@ * Allow to customize connection handshake process via `HttpServer::listen_with()` and `HttpServer::bind_with()` methods +* Support making client connections via `tokio-uds`'s `UnixStream` when "uds" feature is enabled #472 + ### Changed * It is allowed to use function with up to 10 parameters for handler with `extractor parameters`. diff --git a/Cargo.toml b/Cargo.toml index 3bfac16c1..3d72f41c2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,6 +40,9 @@ alpn = ["openssl", "tokio-openssl"] # rustls rust-tls = ["rustls", "tokio-rustls", "webpki", "webpki-roots"] +# unix sockets +uds = ["tokio-uds"] + # sessions feature, session require "ring" crate and c compiler session = ["cookie/secure"] @@ -112,6 +115,9 @@ tokio-rustls = { version = "0.7", optional = true } webpki = { version = "0.18", optional = true } webpki-roots = { version = "0.15", optional = true } +# unix sockets +tokio-uds = { version="0.2", optional = true } + # forked url_encoded itoa = "0.4" dtoa = "0.4" diff --git a/src/client/connector.rs b/src/client/connector.rs index ef66cd734..75b2e149f 100644 --- a/src/client/connector.rs +++ b/src/client/connector.rs @@ -1287,6 +1287,10 @@ impl Connection { } /// Create a new connection from an IO Stream + /// + /// The stream can be a `UnixStream` if the Unix-only "uds" feature is enabled. + /// + /// See also `ClientRequestBuilder::with_connection()`. pub fn from_stream(io: T) -> Connection { Connection::new(Key::empty(), None, Box::new(io)) } diff --git a/src/lib.rs b/src/lib.rs index c6d3453a2..3f1dafc16 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -66,6 +66,8 @@ //! * `tls` - enables ssl support via `native-tls` crate //! * `alpn` - enables ssl support via `openssl` crate, require for `http/2` //! support +//! * `uds` - enables support for making client requests via Unix Domain Sockets. +//! Unix only. Not necessary for *serving* requests. //! * `session` - enables session support, includes `ring` crate as //! dependency //! * `brotli` - enables `brotli` compression support, requires `c` @@ -120,6 +122,8 @@ extern crate tokio_io; extern crate tokio_reactor; extern crate tokio_tcp; extern crate tokio_timer; +#[cfg(all(unix, feature = "uds"))] +extern crate tokio_uds; extern crate url; #[macro_use] extern crate serde; diff --git a/src/server/mod.rs b/src/server/mod.rs index f33a345e5..cccdf8267 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -421,6 +421,24 @@ pub trait IoStream: AsyncRead + AsyncWrite + 'static { } } +#[cfg(all(unix, feature = "uds"))] +impl IoStream for ::tokio_uds::UnixStream { + #[inline] + fn shutdown(&mut self, how: Shutdown) -> io::Result<()> { + ::tokio_uds::UnixStream::shutdown(self, how) + } + + #[inline] + fn set_nodelay(&mut self, _nodelay: bool) -> io::Result<()> { + Ok(()) + } + + #[inline] + fn set_linger(&mut self, _dur: Option) -> io::Result<()> { + Ok(()) + } +} + impl IoStream for TcpStream { #[inline] fn shutdown(&mut self, how: Shutdown) -> io::Result<()> { diff --git a/tests/test_client.rs b/tests/test_client.rs index 5e6856998..16d95bf29 100644 --- a/tests/test_client.rs +++ b/tests/test_client.rs @@ -5,6 +5,8 @@ extern crate bytes; extern crate flate2; extern crate futures; extern crate rand; +#[cfg(all(unix, feature = "uds"))] +extern crate tokio_uds; use std::io::Read; @@ -198,6 +200,14 @@ fn test_client_gzip_encoding_large_random() { assert_eq!(bytes, Bytes::from(data)); } + +#[cfg(all(unix, feature = "uds"))] +#[test] +fn test_compatible_with_unix_socket_stream() { + let (stream, _) = tokio_uds::UnixStream::pair().unwrap(); + let _ = client::Connection::from_stream(stream); +} + #[cfg(feature = "brotli")] #[test] fn test_client_brotli_encoding() {