diff --git a/examples/github.rs b/examples/github.rs index 68d0b96..33d5459 100644 --- a/examples/github.rs +++ b/examples/github.rs @@ -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::>()); - assert!(left == right, "HMAC signature didn't match"); + assert!(left == right, "HMAC signature didn't match",); } println!("gonna clone it to {:?}", config.outdir); diff --git a/src/handler.rs b/src/handler.rs index b01b3b6..0f8a9b6 100644 --- a/src/handler.rs +++ b/src/handler.rs @@ -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!({})) diff --git a/src/lib.rs b/src/lib.rs index 8088266..721b09d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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>> = Mutex::new(HashMap::new()); static ref PROGRAMS: Mutex> = Mutex::new(HashMap::new()); - static ref HOOKS: Mutex> = Mutex::new(HashMap::new()); + static ref HOOKS: Arc>> = Arc::new(Mutex::new(HashMap::new())); } -const NOTFOUND: &str = "

Looks like you took a wrong turn!

There's nothing to see here.

"; +// const NOTFOUND: &str = "

Looks like you took a wrong turn!

There's nothing to see here.

"; fn watch

(root: P) -> notify::Result<()> where diff --git a/src/service.rs b/src/service.rs index b81011b..e72ef37 100644 --- a/src/service.rs +++ b/src/service.rs @@ -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) -> Result, Error> { +pub fn dip_service(req: Request) -> Box, 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::>(); - 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::>(); + 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, ) -> Box, Error = String> + Send> { let uri = req.uri().path().to_owned(); @@ -58,3 +77,4 @@ pub fn dip_service( .unwrap() }))) } +*/