From 57e370b52ce93f1d17abf4fc853ea9de33e21094 Mon Sep 17 00:00:00 2001 From: int 80h Date: Tue, 12 May 2020 21:17:29 -0400 Subject: [PATCH] Added logger.rs --- Cargo.toml | 2 ++ src/cgi.rs | 7 +++++-- src/logger.rs | 17 +++++++++++++++++ src/main.rs | 46 +++++++++++++++++++++++++++------------------- src/revproxy.rs | 17 ++++++++++------- 5 files changed, 61 insertions(+), 28 deletions(-) create mode 100644 src/logger.rs diff --git a/Cargo.toml b/Cargo.toml index d12635d..8426a53 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,8 @@ url = "*" chrono = "0.4" mime_guess = "2.0.3" mime = "0.3.16" +log = "0.4" +simple_logger = "1" [workspace] members = [ "cgi-scripts/agena-cgi" ] diff --git a/src/cgi.rs b/src/cgi.rs index cb874bd..af6a872 100644 --- a/src/cgi.rs +++ b/src/cgi.rs @@ -8,8 +8,9 @@ use tokio_openssl::SslStream; use url::Url; use crate::config; -use crate::status; +use crate::status::Status; use crate::conn; +use crate::logger; pub async fn cgi(mut con: conn::Connection, path: PathBuf, url: Url) -> Result<(), io::Error> { let mut envs = HashMap::new(); @@ -33,10 +34,12 @@ pub async fn cgi(mut con: conn::Connection, path: PathBuf, url: Url) -> Result<( .output() .unwrap(); if !cmd.status.success() { - con.send_status(status::Status::CGIError, None).await?; + logger::logger(con.peer_addr, Status::CGIError, url.as_str()); + con.send_status(Status::CGIError, None).await?; return Ok(()); } let cmd = String::from_utf8(cmd.stdout).unwrap(); + logger::logger(con.peer_addr, Status::Success, url.as_str()); con.send_raw(cmd.as_bytes()).await?; return Ok(()); } diff --git a/src/logger.rs b/src/logger.rs new file mode 100644 index 0000000..97d37e8 --- /dev/null +++ b/src/logger.rs @@ -0,0 +1,17 @@ +use std::net::SocketAddr; +use log::{info, warn}; +use crate::conn; +use crate::status; + +pub fn logger(addr: SocketAddr, stat: status::Status, req: &str) { + match stat as u8 { + 20..=29 => info!( + "remote={} status={} request={}", + addr, stat as u8, req + ), + _ => warn!( + "remote={} status={} request={}", + addr, stat as u8, req + ), + } +} diff --git a/src/main.rs b/src/main.rs index 5826138..43318cb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -28,13 +28,16 @@ use url::Url; use chrono::{DateTime, Utc}; use mime_guess; use mime; +use log::{info, warn}; mod cgi; mod config; mod status; +use status::Status; mod tls; mod conn; mod revproxy; +mod logger; fn get_mime(path: &PathBuf) -> String { let mut mime = "text/gemini"; @@ -97,49 +100,49 @@ fn get_content(path: PathBuf, u: url::Url) -> Result { return Ok(list); } + // TODO Rewrite this monster. async fn handle_connection(mut con: conn::Connection, srv: &config::ServerCfg) -> Result<(), io::Error> { - let now: DateTime = Utc::now(); - println!("{} New Connection: {}", now, con.peer_addr); let mut buffer = [0; 1024]; con.stream.read(&mut buffer).await?; let mut request = match String::from_utf8(buffer[..].to_vec()) { Ok(request) => request, Err(_) => { - println!("Bad Request"); - con.send_status(status::Status::BadRequest, None).await?; + logger::logger(con.peer_addr, Status::BadRequest, ""); + con.send_status(Status::BadRequest, None).await?; return Ok(()) } }; if request.starts_with("//") { request = request.replacen("//", "gemini://", 1); } - println!("Request: {}", request); let url = match Url::parse(&request) { Ok(url) => url, - Err(_) => { con.send_status(status::Status::BadRequest, None).await?; - return Ok(()) + Err(_) => { + logger::logger(con.peer_addr, Status::BadRequest, &request); + con.send_status(Status::BadRequest, None).await?; + return Ok(()) } }; if Some(srv.hostname.as_str()) != url.host_str() { - con.send_status(status::Status::ProxyRequestRefused, None).await?; + logger::logger(con.peer_addr, Status::ProxyRequestRefused, &request); + con.send_status(Status::ProxyRequestRefused, None).await?; return Ok(()); } match url.port() { Some(p) => { if p != srv.port { + logger::logger(con.peer_addr, Status::ProxyRequestRefused, &request); con.send_status(status::Status::ProxyRequestRefused, None).await?; }}, None => {} } if url.scheme() != "gemini" { - con.send_status( - status::Status::ProxyRequestRefused, - None, - ) + logger::logger(con.peer_addr, Status::ProxyRequestRefused, &request); + con.send_status(Status::ProxyRequestRefused, None) .await?; return Ok(()); } @@ -179,7 +182,8 @@ async fn handle_connection(mut con: conn::Connection, srv: &config::ServerCfg) - } if !path.exists() { - con.send_status(status::Status::NotFound, None).await?; + logger::logger(con.peer_addr, Status::NotFound, &request); + con.send_status(Status::NotFound, None).await?; return Ok(()); } @@ -190,9 +194,9 @@ async fn handle_connection(mut con: conn::Connection, srv: &config::ServerCfg) - // This block is terrible if meta.is_dir() { if !url.path().ends_with("/") { - println!("{}", url); + logger::logger(con.peer_addr, Status::RedirectPermanent, &request); con.send_status( - status::Status::RedirectPermanent, + Status::RedirectPermanent, Some(format!("{}/", url).as_str()), ) .await?; @@ -218,20 +222,21 @@ async fn handle_connection(mut con: conn::Connection, srv: &config::ServerCfg) - cgi::cgi(con, path, url).await?; return Ok(()); } else { - con.send_status( - status::Status::CGIError, None).await?; + logger::logger(con.peer_addr, Status::CGIError, &request); + con.send_status(Status::CGIError, None).await?; return Ok(()); } } if perm.mode() & 0o0444 != 0o0444 { - con.send_status( - status::Status::NotFound, None).await?; + logger::logger(con.peer_addr, Status::NotFound, &request); + con.send_status(Status::NotFound, None).await?; return Ok(()); } let mime = get_mime(&path); if !mime.starts_with("text/") { + logger::logger(con.peer_addr, Status::Success, &request); get_binary(con, path, mime).await?; return Ok(()); } @@ -242,11 +247,13 @@ async fn handle_connection(mut con: conn::Connection, srv: &config::ServerCfg) - Some(content), ) .await?; + logger::logger(con.peer_addr, Status::Success, &request); Ok(()) } fn main() -> io::Result<()> { + simple_logger::init_with_level(log::Level::Info).unwrap(); let args: Vec = env::args().collect(); if args.len() != 2 { println!("Please run with the path to the config file."); @@ -257,6 +264,7 @@ fn main() -> io::Result<()> { println!("Config file doesn't exist"); return Ok(()); } + let cfg = config::Config::new(&p)?; let cmap = cfg.to_map(); println!("Serving {} vhosts", cfg.server.len()); diff --git a/src/revproxy.rs b/src/revproxy.rs index e7ebc71..2de7e8b 100644 --- a/src/revproxy.rs +++ b/src/revproxy.rs @@ -11,16 +11,19 @@ use openssl::ssl::{SslConnector, SslMethod}; use url::Url; use crate::conn; -use crate::status; +use crate::status::Status; +use crate::logger; pub async fn proxy(addr: String, u: url::Url, mut con: conn::Connection) -> Result<(), io::Error> { let p: Vec<&str> = u.path().trim_start_matches("/").splitn(2, "/").collect(); if p.len() == 1 { - con.send_status(status::Status::NotFound, None).await?; + logger::logger(con.peer_addr, Status::NotFound, u.as_str()); + con.send_status(Status::NotFound, None).await?; return Ok(()); } if p[1] == "" || p[1] == "/" { - con.send_status(status::Status::NotFound, None).await?; + logger::logger(con.peer_addr, Status::NotFound, u.as_str()); + con.send_status(Status::NotFound, None).await?; return Ok(()) } let addr = addr @@ -35,16 +38,16 @@ pub async fn proxy(addr: String, u: url::Url, mut con: conn::Connection) -> Resu let stream = match TcpStream::connect(&addr).await { Ok(s) => s, Err(_) => { - eprintln!("Error connecting to proxy"); - con.send_status(status::Status::ProxyError, None).await?; + logger::logger(con.peer_addr, Status::ProxyError, u.as_str()); + con.send_status(Status::ProxyError, None).await?; return Ok(()) }, }; let mut stream = match tokio_openssl::connect(config, "localhost", stream).await { Ok(s) => s, Err(_) => { - eprintln!("Error connecting to proxy"); - con.send_status(status::Status::ProxyError, None).await?; + logger::logger(con.peer_addr, Status::ProxyError, u.as_str()); + con.send_status(Status::ProxyError, None).await?; return Ok(()) }, };