From ee0afaa085dce01df3e555b25746dbf052227730 Mon Sep 17 00:00:00 2001 From: softprops Date: Sat, 2 Jan 2016 12:05:55 -0500 Subject: [PATCH] sketching --- .gitignore | 2 + Cargo.toml | 9 +++++ src/lib.rs | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 10 +++++ 4 files changed, 124 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 src/lib.rs create mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a9d37c5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +target +Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..0eac253 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "hyperlocal" +version = "0.1.0" +authors = ["softprops "] + +[dependencies] +hyper = "0.7" +unix_socket = "0.5" +url = "0.5" \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..993a619 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,103 @@ +extern crate hyper; +extern crate unix_socket; +extern crate url; + +use hyper::client::IntoUrl; +use hyper::net::{NetworkConnector}; +use std::io::{self, Read, Write}; +use std::net::SocketAddr; +use std::time::Duration; +use unix_socket::UnixStream; +use url::{parse_path, Host, Url, SchemeData, RelativeSchemeData}; +use url::ParseError as UrlError; + +pub struct SocketConnector; + +pub struct SocketStream(pub UnixStream); + +impl NetworkConnector for SocketConnector { + type Stream = SocketStream; + + fn connect(&self, host: &str, _: u16, scheme: &str) -> hyper::Result { + Ok(try!(match scheme { + "unix" => { + Ok(SocketStream(try!(UnixStream::connect(host)))) + }, + _ => { + Err(io::Error::new(io::ErrorKind::InvalidInput, + "Invalid scheme for Http")) + } + })) + } +} + +impl hyper::net::NetworkStream for SocketStream { + #[inline] + fn peer_addr(&mut self) -> io::Result { + // self.0.peer_addr() + Err(io::Error::new(io::ErrorKind::InvalidInput, "unix domain sockets do not apply here")) + } + + #[inline] + fn set_read_timeout(&self, dur: Option) -> io::Result<()> { + self.0.set_read_timeout(dur) + } + + #[inline] + fn set_write_timeout(&self, dur: Option) -> io::Result<()> { + self.0.set_write_timeout(dur) + } +} + + +impl Read for SocketStream { + #[inline] + fn read(&mut self, buf: &mut [u8]) -> std::io::Result { + self.0.read(buf) + } +} + +impl Write for SocketStream { + #[inline] + fn write(&mut self, msg: &[u8]) -> std::io::Result { + self.0.write(msg) + } + + #[inline] + fn flush(&mut self) -> std::io::Result<()> { + self.0.flush() + } +} + +pub struct DomainUrl<'a> { + socket: &'a str, + path: &'a str +} + +impl<'a> DomainUrl<'a> { + pub fn new(socket: &'a str, path: &'a str) -> DomainUrl<'a> { + DomainUrl { + socket: socket, path: path + } + } +} + +impl<'a> IntoUrl for DomainUrl<'a> { + fn into_url(self) -> Result { + let (path, query, fragment) = try!(parse_path(self.path)); + Ok(Url { + scheme: "unix".to_owned(), + scheme_data: SchemeData::Relative( + RelativeSchemeData { + username: "".to_owned(), + password: None, + host: Host::Domain(self.socket.to_owned()), + port: Some(0), + default_port: None, + path: path + }), + query: query, + fragment: fragment + }) + } +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..3eef61f --- /dev/null +++ b/src/main.rs @@ -0,0 +1,10 @@ +extern crate hyper; +extern crate hyperlocal; + +use hyperlocal::{DomainUrl, SocketConnector}; + +fn main() { + let client = hyper::Client::with_connector(hyperlocal::SocketConnector); + let mut res = client.get(DomainUrl::new("/var/run/docker.sock", "info")).send().unwrap(); + std::io::copy(&mut res, &mut std::io::stdout()).unwrap(); +}