diff --git a/src/cgi.rs b/src/cgi.rs index f86c6d9..31e795a 100644 --- a/src/cgi.rs +++ b/src/cgi.rs @@ -32,11 +32,14 @@ pub async fn cgi( envs.insert("QUERY_STRING", q); } - if srv.cgienv.len() != 0 { - for (k, v) in srv.cgienv.iter() { - envs.insert(&k, &v); + match &srv.server.cgienv { + Some(c) => { + for (k, v) in c.iter() { + envs.insert(&k, &v); + } } - }; + None => {} + } let cmd = Command::new(path.to_str().unwrap()) .env_clear() diff --git a/src/config.rs b/src/config.rs index b4da1e1..4b140b4 100644 --- a/src/config.rs +++ b/src/config.rs @@ -27,17 +27,8 @@ pub struct Server { #[derive(Debug, Clone)] pub struct ServerCfg { - pub hostname: String, - pub dir: String, - pub key: String, - pub cert: String, - pub index: String, - pub cgi: String, - pub cgienv: HashMap, - pub usrdir: bool, pub port: u16, - pub proxy: HashMap, - pub redirect: HashMap, + pub server: Server, } impl Config { @@ -49,50 +40,11 @@ impl Config { pub fn to_map(&self) -> HashMap { let mut map = HashMap::new(); for srv in &self.server { - let cgi = match srv.cgi.to_owned() { - Some(c) => c, - None => "".to_string(), - }; - let usrdir = match srv.usrdir { - Some(u) => u, - None => false, - }; - let mut pmap = HashMap::new(); - match &srv.proxy { - Some(pr) => pmap = pr.clone(), - None => {} - }; - - let mut rmap = HashMap::new(); - match &srv.redirect { - Some(r) => rmap = r.clone(), - None => {} - }; - - let mut cmap = HashMap::new(); - match &srv.cgienv { - Some(c) => cmap = c.clone(), - None => {} - }; - let index = match srv.index.to_owned() { - Some(i) => i, - None => "index.gemini".to_string() - }; - map.insert( srv.hostname.clone(), ServerCfg { - hostname: srv.hostname.clone(), - dir: srv.dir.clone(), - key: srv.key.clone(), - cert: srv.cert.clone(), - index: index.to_string(), - cgi: cgi, - cgienv: cmap.clone(), - usrdir: usrdir, port: self.port.clone(), - proxy: pmap.clone(), - redirect: rmap.clone(), + server: srv.clone(), }, ); } diff --git a/src/conn.rs b/src/conn.rs index 6f1d4e1..57aa509 100644 --- a/src/conn.rs +++ b/src/conn.rs @@ -27,7 +27,8 @@ impl Connection { Some(m) => m, None => &stat.to_str(), }; - self.send_raw(format!("{}\t{}\r\n", stat as u8, meta).as_bytes()).await?; + self.send_raw(format!("{}\t{}\r\n", stat as u8, meta).as_bytes()) + .await?; if let Some(b) = body { self.send_raw(b.as_bytes()).await?; } diff --git a/src/main.rs b/src/main.rs index d62a52e..a342b06 100644 --- a/src/main.rs +++ b/src/main.rs @@ -41,10 +41,10 @@ fn get_mime(path: &PathBuf) -> String { _ => { m = mime_guess::from_ext(ext).first().unwrap(); m.essence_str() - }, + } }; - return mime.to_string() + return mime.to_string(); } async fn get_binary(mut con: conn::Connection, path: PathBuf, meta: String) -> io::Result<()> { @@ -99,6 +99,10 @@ async fn handle_connection( mut con: conn::Connection, srv: &config::ServerCfg, ) -> Result<(), io::Error> { + let index = match &srv.server.index { + Some(i) => i.clone(), + None => "index.gemini".to_string(), + }; let mut buffer = [0; 1024]; con.stream.read(&mut buffer).await?; let mut request = match String::from_utf8(buffer[..].to_vec()) { @@ -122,7 +126,7 @@ async fn handle_connection( } }; - if Some(srv.hostname.as_str()) != url.host_str() { + if Some(srv.server.hostname.as_str()) != url.host_str() { logger::logger(con.peer_addr, Status::ProxyRequestRefused, &request); con.send_status(Status::ProxyRequestRefused, None).await?; return Ok(()); @@ -145,20 +149,23 @@ async fn handle_connection( return Ok(()); } - if srv.redirect.len() != 0 { - let u = url.path().trim_end_matches("/"); - match srv.redirect.get(u) { - Some(r) => { - logger::logger(con.peer_addr, Status::RedirectTemporary, &request); - con.send_status(Status::RedirectTemporary, Some(r)).await?; - return Ok(()); + match &srv.server.redirect { + Some(re) => { + let u = url.path().trim_end_matches("/"); + match re.get(u) { + Some(r) => { + logger::logger(con.peer_addr, Status::RedirectTemporary, &request); + con.send_status(Status::RedirectTemporary, Some(r)).await?; + return Ok(()); + } + None => {} } - None => {} } + None => {} } - if srv.proxy.len() != 0 { - match url.path_segments().map(|c| c.collect::>()) { - Some(s) => match srv.proxy.get(s[0]) { + match &srv.server.proxy { + Some(pr) => match url.path_segments().map(|c| c.collect::>()) { + Some(s) => match pr.get(s[0]) { Some(p) => { revproxy::proxy(p.to_string(), url, con).await?; return Ok(()); @@ -166,12 +173,13 @@ async fn handle_connection( None => {} }, None => {} - } + }, + None => {} } let mut path = PathBuf::new(); - if url.path().starts_with("/~") && srv.usrdir == true { + if url.path().starts_with("/~") && srv.server.usrdir.is_some() { let usr = url.path().trim_start_matches("/~"); let usr: Vec<&str> = usr.splitn(2, "/").collect(); path.push("/home/"); @@ -181,7 +189,7 @@ async fn handle_connection( path.push(format!("{}/{}/", usr[0], "public_gemini")); } } else { - path.push(&srv.dir); + path.push(&srv.server.dir); if url.path() != "" || url.path() != "/" { path.push(url.path().trim_start_matches("/")); } @@ -208,8 +216,8 @@ async fn handle_connection( .await?; return Ok(()); } - if path.join(&srv.index).exists() { - path.push(&srv.index); + if path.join(&index).exists() { + path.push(index); meta = fs::metadata(&path).expect("Unable to read metadata"); perm = meta.permissions(); if perm.mode() & 0o0444 != 0o444 { @@ -223,15 +231,20 @@ async fn handle_connection( } // TODO add timeout - if srv.cgi.trim_end_matches("/") == path.parent().unwrap().to_str().unwrap() { - if perm.mode() & 0o0111 == 0o0111 { - cgi::cgi(con, srv, path, url).await?; - return Ok(()); - } else { - logger::logger(con.peer_addr, Status::CGIError, &request); - con.send_status(Status::CGIError, None).await?; - return Ok(()); + match &srv.server.cgi { + Some(c) => { + if c.trim_end_matches("/") == path.parent().unwrap().to_str().unwrap() { + if perm.mode() & 0o0111 == 0o0111 { + cgi::cgi(con, srv, path, url).await?; + return Ok(()); + } else { + logger::logger(con.peer_addr, Status::CGIError, &request); + con.send_status(Status::CGIError, None).await?; + return Ok(()); + } + } } + None => {} } if perm.mode() & 0o0444 != 0o0444 { @@ -300,11 +313,9 @@ fn main() -> io::Result<()> { .expect("Couldn't accept"); let srv = match stream.ssl().servername(NameType::HOST_NAME) { - Some(s) => { - match cmap.get(s) { - Some(ss) => ss, - None => cmap.get(&default).unwrap(), - } + Some(s) => match cmap.get(s) { + Some(ss) => ss, + None => cmap.get(&default).unwrap(), }, None => cmap.get(&default).unwrap(), };