extern crate hyper;
extern crate futures;
extern crate http_signatures;
use std::io::{Cursor, Read};
use futures::{Future, IntoFuture};
use hyper::header::ContentLength;
use hyper::server::{Http, Request, Response, Service};
use http_signatures::{GetKey, VerifyHeader};
#[derive(Debug)]
enum Error {
FileError,
}
#[derive(Clone)]
struct MyKeyGetter {
key: Vec<u8>,
}
impl MyKeyGetter {
fn new(filename: &str) -> Result<Self, Error> {
let mut key = Vec::new();
std::fs::File::open(filename)
.map_err(|_| Error::FileError)?
.read_to_end(&mut key)
.map_err(|_| Error::FileError)?;
Ok(MyKeyGetter { key })
}
}
impl GetKey for MyKeyGetter {
type Key = Cursor<Vec<u8>>;
type Error = Error;
fn get_key(self, _key_id: &str) -> Result<Self::Key, Self::Error> {
Ok(Cursor::new(self.key.clone()))
}
}
struct HelloWorld {
key_getter: MyKeyGetter,
}
impl HelloWorld {
fn new(filename: &str) -> Result<Self, Error> {
Ok(HelloWorld { key_getter: MyKeyGetter::new(filename)? })
}
}
const PHRASE: &'static str = "Hewwo, Mr. Obama???";
impl Service for HelloWorld {
type Request = Request;
type Response = Response;
type Error = hyper::Error;
type Future = Box<Future<Item = Self::Response, Error = Self::Error>>;
fn call(&self, req: Request) -> Self::Future {
let verified = req.verify_signature_header(self.key_getter.clone())
.map_err(|_| hyper::Error::Header);
Box::new(verified.into_future().and_then(|_| {
println!("Succesfully verified request!");
Ok(
Response::new()
.with_header(ContentLength(PHRASE.len() as u64))
.with_body(PHRASE),
)
}))
}
}
fn main() {
let addr = "127.0.0.1:3000".parse().unwrap();
let server = Http::new()
.bind(&addr, || {
Ok(HelloWorld::new("test/assets/public.der").unwrap())
})
.unwrap();
server.run().unwrap();
}