This commit is contained in:
Michael 2018-08-15 22:20:52 +00:00 committed by Michael Zhang
parent fdb5c7a9b3
commit 8d50817587
No known key found for this signature in database
GPG key ID: A1B65B603268116B
5 changed files with 78 additions and 26 deletions

44
src/handler.rs Normal file
View file

@ -0,0 +1,44 @@
use std::path::PathBuf;
use std::process::Command;
use failure::{err_msg, Error};
use serde_json::Value as JsonValue;
use toml::Value as TomlValue;
use PROGRAMS;
pub struct Handler {
exec: PathBuf,
}
impl Handler {
pub fn from(config: &TomlValue) -> Result<Self, Error> {
let handler = config
.get("type")
.ok_or(err_msg("No 'type' found."))?
.as_str()
.ok_or(err_msg("'type' is not a string."))?;
let exec = {
let programs = PROGRAMS.lock().unwrap();
programs
.get(handler)
.ok_or(err_msg(format!("'{}' is not a valid executable", handler)))
.map(|value| value.clone())?
};
Ok(Handler { exec })
}
pub fn run(&self, _: Result<JsonValue, Error>) -> Result<JsonValue, Error> {
Command::new(&self.exec)
.output()
.map_err(|err| err_msg(format!("{}", err)))
.and_then(|output| {
if !output.status.success() {
return Err(err_msg(format!(
"'{:?}' returned with a non-zero status code: {}",
self.exec, output.status
)));
}
Ok(json!({}))
})
}
}

View file

@ -1 +0,0 @@
pub struct HandlerBuilder {}

View file

@ -1,17 +0,0 @@
mod builder;
use failure::Error;
use serde_json::Value as JsonValue;
use toml::Value as TomlValue;
pub use self::builder::*;
pub struct Handler {
pub handle: fn(Result<JsonValue, Error>) -> Result<JsonValue, Error>,
}
impl Handler {
pub fn from(config: &TomlValue) -> Result<Self, Error> {
bail!("rip")
}
}

View file

@ -52,7 +52,7 @@ impl Hook {
pub fn iter(&self) -> Iter<Handler> {
self.handlers.iter()
}
pub fn handle(&self, payload: &Request<Body>) -> Result<Response<Body>, Error> {
pub fn handle(&self, _payload: &Request<Body>) -> Result<Response<Body>, Error> {
Ok(Response::new(Body::from("lol")))
}
}

View file

@ -1,6 +1,5 @@
//! # Dip
#[macro_use]
extern crate failure;
extern crate hyper;
extern crate serde;
@ -13,11 +12,11 @@ extern crate regex;
extern crate toml;
extern crate walkdir;
pub mod handlers;
pub mod handler;
pub mod hook;
use std::collections::HashMap;
use std::path::Path;
use std::path::{Path, PathBuf};
use std::sync::{mpsc, Mutex};
use std::thread;
use std::time::Duration;
@ -30,7 +29,7 @@ use notify::{RecommendedWatcher, RecursiveMode, Watcher};
use regex::Regex;
use walkdir::WalkDir;
pub use handlers::Handler;
pub use handler::*;
use hook::*;
const URIPATTERN_STR: &str = r"/webhook/(?P<name>[A-Za-z._][A-Za-z0-9._]*)";
@ -38,6 +37,7 @@ const URIPATTERN_STR: &str = r"/webhook/(?P<name>[A-Za-z._][A-Za-z0-9._]*)";
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());
}
@ -70,7 +70,7 @@ fn service_fn(req: &Request<Body>) -> Result<Response<Body>, Error> {
"method": req.method().as_str(),
});
hook.iter()
.fold(Ok(req_obj), |prev, handler| (handler.handle)(prev))
.fold(Ok(req_obj), |prev, handler| handler.run(prev))
.map(|_| Response::new(Body::from("success")))
}
@ -91,8 +91,34 @@ where
println!("Reloading config...");
// hold on to the lock while config is being reloaded
{
let mut handlers = HANDLERS.lock().unwrap();
handlers.clear();
let mut programs = PROGRAMS.lock().unwrap();
programs.clear();
let programs_dir = {
let mut p = root.as_ref().to_path_buf();
p.push("handlers");
p
};
if programs_dir.exists() {
for entry in WalkDir::new(programs_dir) {
let path = match entry.as_ref().map(|e| e.path()) {
Ok(path) => path,
_ => continue,
};
if !path.is_file() {
continue;
}
match path
.file_name()
.and_then(|s| s.to_str())
.ok_or(err_msg("???"))
.map(|s| {
let filename = s.to_owned();
programs.insert(filename, path.to_path_buf())
}) {
_ => (), // don't care
}
}
}
}
{
let mut hooks = HOOKS.lock().unwrap();