service futures + hmac checking working

This commit is contained in:
Michael 2018-08-16 16:49:29 +00:00
parent 77afb51582
commit f7d015fab5
4 changed files with 67 additions and 46 deletions

View file

@ -33,6 +33,7 @@ struct Opt {
struct Config {
secret: String,
outdir: PathBuf,
#[serde(default)]
disable_hmac_verify: bool,
}
@ -71,7 +72,7 @@ fn main() -> Result<(), Error> {
let left = SecStr::from(format!("sha1={}", signature));
let right = SecStr::from(auth.bytes().collect::<Vec<_>>());
assert!(left == right, "HMAC signature didn't match");
assert!(left == right, "HMAC signature didn't match",);
}
println!("gonna clone it to {:?}", config.outdir);

View file

@ -64,8 +64,8 @@ impl Handler {
"'{:?}' returned with a non-zero status code: {}\nstdout:\n{}\nstderr:\n{}",
self.exec,
output.status,
String::from_utf8(output.stdout).unwrap(),
String::from_utf8(output.stderr).unwrap()
String::from_utf8(output.stdout).unwrap_or_else(|_| String::new()),
String::from_utf8(output.stderr).unwrap_or_else(|_| String::new())
)));
}
Ok(json!({}))

View file

@ -25,7 +25,7 @@ use std::collections::HashMap;
use std::net::SocketAddrV4;
use std::path::{Path, PathBuf};
use std::str::FromStr;
use std::sync::{mpsc, Mutex};
use std::sync::{mpsc, Arc, Mutex};
use std::thread;
use std::time::Duration;
@ -47,10 +47,10 @@ lazy_static! {
static ref URIPATTERN: Regex = Regex::new(URIPATTERN_STR).unwrap();
// static ref HANDLERS: Mutex<HashMap<String, Box<Handler>>> = Mutex::new(HashMap::new());
static ref PROGRAMS: Mutex<HashMap<String, PathBuf>> = Mutex::new(HashMap::new());
static ref HOOKS: Mutex<HashMap<String, Hook>> = Mutex::new(HashMap::new());
static ref HOOKS: Arc<Mutex<HashMap<String, Hook>>> = Arc::new(Mutex::new(HashMap::new()));
}
const NOTFOUND: &str = "<html> <head> <style> * { font-family: sans-serif; } body { padding: 20px 60px; } </style> </head> <body> <h1>Looks like you took a wrong turn!</h1> <p>There's nothing to see here.</p> </body> </html>";
// const NOTFOUND: &str = "<html> <head> <style> * { font-family: sans-serif; } body { padding: 20px 60px; } </style> </head> <body> <h1>Looks like you took a wrong turn!</h1> <p>There's nothing to see here.</p> </body> </html>";
fn watch<P>(root: P) -> notify::Result<()>
where

View file

@ -1,52 +1,71 @@
use std::collections::HashMap;
use failure::{err_msg, Error};
use futures::{future, Future};
use hyper::{Body, Request, Response, StatusCode};
use futures::{future, Future, Stream};
use hyper::{Body, Error, Request, Response, StatusCode};
use {HOOKS, NOTFOUND, URIPATTERN};
use {HOOKS, URIPATTERN};
fn service_fn(req: Request<Body>) -> Result<Response<Body>, Error> {
pub fn dip_service(req: Request<Body>) -> Box<Future<Item = Response<Body>, Error = Error> + Send> {
let path = req.uri().path().to_owned();
let captures = URIPATTERN
.captures(path.as_ref())
.ok_or(err_msg("Did not match url pattern"))?;
let name = captures
.name("name")
.ok_or(err_msg("Missing name"))?
.as_str();
let hooks = HOOKS.lock().unwrap();
let hook = hooks
.get(name)
.ok_or(err_msg(format!("Hook '{}' doesn't exist", name)))?;
let req_obj = {
let headers = req.headers()
.clone()
.into_iter()
.filter_map(|(k, v)| {
let key = k.unwrap().as_str().to_owned();
v.to_str().map(|value| (key, value.to_owned())).ok()
})
.collect::<HashMap<_, _>>();
let method = req.method().as_str().to_owned();
// probably not idiomatically the best way to do it
// i was just trying to get something working
let body = "wip".to_owned();
json!({
"body": body,
"headers": headers,
"method": method,
})
let captures = match URIPATTERN.captures(path.as_ref()) {
Some(value) => value,
None => {
return Box::new(future::ok(
Response::builder()
.status(StatusCode::NOT_FOUND)
.body(Body::from("not found"))
.unwrap(),
))
}
};
hook.iter()
.fold(Ok(req_obj), |prev, handler| {
prev.and_then(|val| handler.run(val))
let name = match captures.name("name") {
Some(value) => value.as_str().to_owned(),
None => {
return Box::new(future::ok(
Response::builder()
.status(StatusCode::NOT_FOUND)
.body(Body::from("not found"))
.unwrap(),
))
}
};
// TODO: filter by method as well
let headers = req.headers()
.clone()
.into_iter()
.filter_map(|(k, v)| {
let key = k.unwrap().as_str().to_owned();
v.to_str().map(|value| (key, value.to_owned())).ok()
})
.map(|_| Response::new(Body::from("success")))
.collect::<HashMap<_, _>>();
let method = req.method().as_str().to_owned();
// probably not idiomatically the best way to do it
// i was just trying to get something working
let body = req.into_body();
Box::new(body.concat2().map(move |body| {
let req_obj = json!({
"body": String::from_utf8(body.to_vec()).unwrap(),
"headers": headers,
"method": method,
});
let hooks = HOOKS.lock().unwrap();
let hook = hooks.get(&name).unwrap();
let (code, msg) = hook.iter()
.fold(Ok(req_obj), |prev, handler| {
prev.and_then(|val| handler.run(val))
})
.map(|_| (StatusCode::ACCEPTED, "success".to_owned()))
.unwrap_or_else(|err| (StatusCode::BAD_REQUEST, format!("Error: {}", err)));
Response::builder()
.status(code)
.body(Body::from(msg))
.unwrap_or_else(|err| Response::new(Body::from(format!("{}", err))))
}))
}
pub fn dip_service(
/* pub fn dip_service(
req: Request<Body>,
) -> Box<Future<Item = Response<Body>, Error = String> + Send> {
let uri = req.uri().path().to_owned();
@ -58,3 +77,4 @@ pub fn dip_service(
.unwrap()
})))
}
*/