Skip to content

Commit

Permalink
Update to Hyper 0.12
Browse files Browse the repository at this point in the history
This updates hyperlocal to the new Hyper 0.12 API.
  • Loading branch information
dylanmckay committed Jul 30, 2018
1 parent a14da42 commit b685e5c
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 193 deletions.
5 changes: 2 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ readme = "README.md"
[dependencies]
futures = "0.1"
hex = "0.2"
hyper = "0.11"
hyper = "0.12"
tokio-core = "0.1"
tokio-io = "0.1"
tokio-service = "0.1"
tokio-uds = "0.1"
tokio-uds = "0.2"
66 changes: 31 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,28 +33,26 @@ note the example below uses a crate called `service_fn` which exists [here](http
extern crate hyper;
extern crate hyperlocal;
extern crate futures;
extern crate tokio_service;
extern crate service_fn;

use hyper::{Result, Response};
use hyper::header::{ContentType, ContentLength};
use service_fn::service_fn;
use hyper::{header, Body, Request, Response};
use hyper::service::service_fn;
use std::io;

const PHRASE: &'static str = "It's a Unix system. I know this.";

fn run() -> Result<()> {
fn hello(_: Request<Body>) -> impl futures::Future<Item = Response<Body>, Error = io::Error> + Send {
futures::future::ok(
Response::builder()
.header(header::CONTENT_TYPE, "text/plain")
.header(header::CONTENT_LENGTH, PHRASE.len() as u64)
.body(PHRASE.into())
.expect("failed to create response")
)
}

fn run() -> io::Result<()> {
let path = "test.sock";
let hello = || {
Ok(service_fn(|_| {
Ok(
Response::<hyper::Body>::new()
.with_header(ContentLength(PHRASE.len() as u64))
.with_header(ContentType::plaintext())
.with_body(PHRASE),
)
}))
};
let svr = hyperlocal::server::Http::new().bind(path, hello)?;
let svr = hyperlocal::server::Http::new().bind(path, || service_fn(hello))?;
println!("Listening on unix://{path} with 1 thread.", path = path);
svr.run()?;
Ok(())
Expand Down Expand Up @@ -87,35 +85,33 @@ use std::io::{self, Write};

use futures::Stream;
use futures::Future;
use hyper::{Client, Result};
use hyper::{Client, rt};
use hyperlocal::{Uri, UnixConnector};
use tokio_core::reactor::Core;

fn run() -> Result<()> {
let mut core = Core::new()?;
let handle = core.handle();
let client = Client::configure()
.connector(UnixConnector::new(handle))
.build(&core.handle());

fn main() {
let client = Client::builder().
build::<_, ::hyper::Body>(UnixConnector::new());
let url = Uri::new("test.sock", "/").into();

let work = client
.get(Uri::new("test.sock", "/").into())
.get(url)
.and_then(|res| {
println!("Response: {}", res.status());
println!("Headers: \n{}", res.headers());
println!("Headers: {:#?}", res.headers());

res.body().for_each(|chunk| {
io::stdout().write_all(&chunk).map_err(From::from)
res.into_body().for_each(|chunk| {
io::stdout().write_all(&chunk)
.map_err(|e| panic!("example expects stdout is open, error={}", e))
})
})
.map(|_| {
println!("\n\nDone.");
})
.map_err(|err| {
eprintln!("Error {}", err);
});

core.run(work)
}

fn main() {
run().unwrap()
rt::run(work);
}
```

Expand Down
32 changes: 15 additions & 17 deletions examples/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,31 @@ use std::io::{self, Write};

use futures::Stream;
use futures::Future;
use hyper::{Client, Result};
use hyper::{Client, rt};
use hyperlocal::{Uri, UnixConnector};
use tokio_core::reactor::Core;

fn run() -> Result<()> {
let mut core = Core::new()?;
let handle = core.handle();
let client = Client::configure()
.connector(UnixConnector::new(handle))
.build(&core.handle());
fn main() {
let client = Client::builder().
build::<_, ::hyper::Body>(UnixConnector::new());
let url = Uri::new("test.sock", "/").into();

let work = client
.get(Uri::new("test.sock", "/").into())
.get(url)
.and_then(|res| {
println!("Response: {}", res.status());
println!("Headers: \n{}", res.headers());
println!("Headers: {:#?}", res.headers());

res.body().for_each(|chunk| {
io::stdout().write_all(&chunk).map_err(From::from)
res.into_body().for_each(|chunk| {
io::stdout().write_all(&chunk)
.map_err(|e| panic!("example expects stdout is open, error={}", e))
})
})
.map(|_| {
println!("\n\nDone.");
})
.map_err(|err| {
eprintln!("Error {}", err);
});

core.run(work)
}

fn main() {
run().unwrap()
rt::run(work);
}
35 changes: 13 additions & 22 deletions examples/server.rs
Original file line number Diff line number Diff line change
@@ -1,35 +1,26 @@
extern crate hyper;
extern crate hyperlocal;
extern crate futures;
extern crate tokio_service;

use futures::future::FutureResult;
use hyper::{Result, Request, Response};
use hyper::header::{ContentType, ContentLength};
use tokio_service::Service;
use hyper::{header, Body, Request, Response};
use hyper::service::service_fn;
use std::io;

const PHRASE: &'static str = "It's a Unix system. I know this.";

struct Hello;

impl Service for Hello {
type Request = Request;
type Response = Response;
type Error = hyper::Error;
type Future = FutureResult<Response, hyper::Error>;
fn call(&self, _req: Request) -> Self::Future {
futures::future::ok(
Response::new()
.with_header(ContentLength(PHRASE.len() as u64))
.with_header(ContentType::plaintext())
.with_body(PHRASE),
)
}
fn hello(_: Request<Body>) -> impl futures::Future<Item = Response<Body>, Error = io::Error> + Send {
futures::future::ok(
Response::builder()
.header(header::CONTENT_TYPE, "text/plain")
.header(header::CONTENT_LENGTH, PHRASE.len() as u64)
.body(PHRASE.into())
.expect("failed to create response")
)
}

fn run() -> Result<()> {
fn run() -> io::Result<()> {
let path = "test.sock";
let svr = hyperlocal::server::Http::new().bind(path, || Ok(Hello))?;
let svr = hyperlocal::server::Http::new().bind(path, || service_fn(hello))?;
println!("Listening on unix://{path} with 1 thread.", path = path);
svr.run()?;
Ok(())
Expand Down
72 changes: 20 additions & 52 deletions src/client/mod.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
//! Hyper client bindings for unix domain sockets

use std::io;
use std::clone::Clone;

use futures::IntoFuture;
use futures::{Future, IntoFuture};
use futures::future::{self, FutureResult};
use hyper::Uri as HyperUri;
use tokio_core::reactor::Handle;
use tokio_service::Service;
use hyper::client::connect::{Connect, Connected, Destination};
use tokio_uds::UnixStream;

use super::Uri;
Expand All @@ -26,70 +23,41 @@ const UNIX_SCHEME: &str = "unix";
/// ```no_run
/// extern crate hyper;
/// extern crate hyperlocal;
/// extern crate tokio_core;
///
/// let core = tokio_core::reactor::Core::new().unwrap();
/// let client = hyper::Client::configure()
/// .connector(
/// hyperlocal::UnixConnector::new(core.handle())
/// )
/// .build(&core.handle());
/// let client = hyper::Client::builder()
/// .build::<_, hyper::Body>(hyperlocal::UnixConnector::new());
/// ```
pub struct UnixConnector(Handle);
#[derive(Clone)]
pub struct UnixConnector;

impl UnixConnector {
pub fn new(handle: Handle) -> Self {
UnixConnector(handle)
pub fn new() -> Self {
UnixConnector
}
}

impl Service for UnixConnector {
type Request = HyperUri;
type Response = UnixStream;
impl Connect for UnixConnector {
type Transport = UnixStream;
type Error = io::Error;
type Future = FutureResult<UnixStream, io::Error>;
type Future = FutureResult<(UnixStream, Connected), io::Error>;

fn call(&self, uri: HyperUri) -> Self::Future {
if uri.scheme() != Some(UNIX_SCHEME) {
fn connect(&self, destination: Destination) -> Self::Future {
if destination.scheme() != UNIX_SCHEME {
return future::err(io::Error::new(
io::ErrorKind::InvalidInput,
format!("Invalid uri {}", uri),
format!("Invalid uri {:?}", destination),
));
}
match Uri::socket_path(&uri) {
Some(path) => UnixStream::connect(path, &self.0).into_future(),
match Uri::socket_path_dest(&destination) {
Some(ref path) => UnixStream::connect(path)
.wait() // We have to block because we
.map(|s| (s, Connected::new()))
.into_future(),
_ => future::err(io::Error::new(
io::ErrorKind::InvalidInput,
format!("Invalid uri {}", uri),
format!("Invalid uri {:?}", destination),
)),
}
}
}

impl Clone for UnixConnector {
fn clone(&self) -> Self {
UnixConnector(self.0.clone())
}
}

#[cfg(test)]
mod tests {
use super::*;
use tokio_core::reactor::Core;

#[test]
fn connector_rejects_non_unix_uris() {
let mut core = Core::new().unwrap();
let connector = UnixConnector::new(core.handle());
let work = connector.call("http://google.com".parse().unwrap());
assert!(core.run(work).is_err())
}

#[test]
fn connector_rejects_hand_crafted_unix_uris() {
let mut core = Core::new().unwrap();
let connector = UnixConnector::new(core.handle());
let work = connector.call("unix://google.com".parse().unwrap());
assert!(core.run(work).is_err())
}
}
31 changes: 20 additions & 11 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ extern crate hyper;
extern crate tokio_uds;
extern crate tokio_core;
extern crate tokio_io;
extern crate tokio_service;
extern crate hex;

use std::borrow::Cow;
Expand All @@ -32,14 +31,10 @@ pub use client::UnixConnector;
/// extern crate hyper;
/// extern crate hyperlocal;
///
/// let url = hyperlocal::Uri::new(
/// let url: hyper::Uri = hyperlocal::Uri::new(
/// "/path/to/socket", "/urlpath?key=value"
/// );
/// let req: hyper::Request<hyper::Body> =
/// hyper::Request::new(
/// hyper::Get,
/// url.into()
/// );
/// ).into();
/// let req = hyper::Request::get(url).body(()).unwrap();
/// ```
#[derive(Debug)]
pub struct Uri<'a> {
Expand Down Expand Up @@ -77,6 +72,10 @@ impl<'a> Uri<'a> {
})
.next()
}

fn socket_path_dest(dest: &hyper::client::connect::Destination) -> Option<String> {
format!("unix://{}", dest.host()).parse().ok().and_then(|uri| Self::socket_path(&uri))
}
}


Expand All @@ -94,9 +93,19 @@ mod tests {

#[test]
fn unix_uris_resolve_socket_path() {
let unix: HyperUri = "unix://666f6f2e736f636b:0/".parse().unwrap();
let path = Uri::socket_path(&unix).unwrap();
let path = Uri::socket_path(&"unix://666f6f2e736f636b:0/".parse().unwrap()).unwrap();
let expected = "foo.sock";
assert_eq!(path, expected);
}
}

#[test]
fn connector_rejects_non_unix_uris() {
assert_eq!(None, Uri::socket_path(&"http://google.com".parse().unwrap()));
}

#[test]
fn connector_rejects_hand_crafted_unix_uris() {
assert_eq!(None, Uri::socket_path(&"unix://google.com".parse().unwrap()));
}
}

Loading

0 comments on commit b685e5c

Please sign in to comment.