Added logger.rs

This commit is contained in:
int 80h
2020-05-12 21:17:29 -04:00
parent ea2c67c72f
commit 57e370b52c
5 changed files with 61 additions and 28 deletions

View File

@@ -18,6 +18,8 @@ url = "*"
chrono = "0.4" chrono = "0.4"
mime_guess = "2.0.3" mime_guess = "2.0.3"
mime = "0.3.16" mime = "0.3.16"
log = "0.4"
simple_logger = "1"
[workspace] [workspace]
members = [ "cgi-scripts/agena-cgi" ] members = [ "cgi-scripts/agena-cgi" ]

View File

@@ -8,8 +8,9 @@ use tokio_openssl::SslStream;
use url::Url; use url::Url;
use crate::config; use crate::config;
use crate::status; use crate::status::Status;
use crate::conn; use crate::conn;
use crate::logger;
pub async fn cgi(mut con: conn::Connection, path: PathBuf, url: Url) -> Result<(), io::Error> { pub async fn cgi(mut con: conn::Connection, path: PathBuf, url: Url) -> Result<(), io::Error> {
let mut envs = HashMap::new(); let mut envs = HashMap::new();
@@ -33,10 +34,12 @@ pub async fn cgi(mut con: conn::Connection, path: PathBuf, url: Url) -> Result<(
.output() .output()
.unwrap(); .unwrap();
if !cmd.status.success() { 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(()); return Ok(());
} }
let cmd = String::from_utf8(cmd.stdout).unwrap(); 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?; con.send_raw(cmd.as_bytes()).await?;
return Ok(()); return Ok(());
} }

17
src/logger.rs Normal file
View File

@@ -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
),
}
}

View File

@@ -28,13 +28,16 @@ use url::Url;
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
use mime_guess; use mime_guess;
use mime; use mime;
use log::{info, warn};
mod cgi; mod cgi;
mod config; mod config;
mod status; mod status;
use status::Status;
mod tls; mod tls;
mod conn; mod conn;
mod revproxy; mod revproxy;
mod logger;
fn get_mime(path: &PathBuf) -> String { fn get_mime(path: &PathBuf) -> String {
let mut mime = "text/gemini"; let mut mime = "text/gemini";
@@ -97,49 +100,49 @@ fn get_content(path: PathBuf, u: url::Url) -> Result<String, io::Error> {
return Ok(list); return Ok(list);
} }
// TODO Rewrite this monster. // TODO Rewrite this monster.
async fn handle_connection(mut con: conn::Connection, srv: &config::ServerCfg) -> Result<(), io::Error> { async fn handle_connection(mut con: conn::Connection, srv: &config::ServerCfg) -> Result<(), io::Error> {
let now: DateTime<Utc> = Utc::now();
println!("{} New Connection: {}", now, con.peer_addr);
let mut buffer = [0; 1024]; let mut buffer = [0; 1024];
con.stream.read(&mut buffer).await?; con.stream.read(&mut buffer).await?;
let mut request = match String::from_utf8(buffer[..].to_vec()) { let mut request = match String::from_utf8(buffer[..].to_vec()) {
Ok(request) => request, Ok(request) => request,
Err(_) => { Err(_) => {
println!("Bad Request"); logger::logger(con.peer_addr, Status::BadRequest, "");
con.send_status(status::Status::BadRequest, None).await?; con.send_status(Status::BadRequest, None).await?;
return Ok(()) return Ok(())
} }
}; };
if request.starts_with("//") { if request.starts_with("//") {
request = request.replacen("//", "gemini://", 1); request = request.replacen("//", "gemini://", 1);
} }
println!("Request: {}", request);
let url = match Url::parse(&request) { let url = match Url::parse(&request) {
Ok(url) => url, Ok(url) => url,
Err(_) => { con.send_status(status::Status::BadRequest, None).await?; Err(_) => {
return Ok(()) 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() { 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(()); return Ok(());
} }
match url.port() { match url.port() {
Some(p) => { if p != srv.port { Some(p) => { if p != srv.port {
logger::logger(con.peer_addr, Status::ProxyRequestRefused, &request);
con.send_status(status::Status::ProxyRequestRefused, None).await?; con.send_status(status::Status::ProxyRequestRefused, None).await?;
}}, }},
None => {} None => {}
} }
if url.scheme() != "gemini" { if url.scheme() != "gemini" {
con.send_status( logger::logger(con.peer_addr, Status::ProxyRequestRefused, &request);
status::Status::ProxyRequestRefused, con.send_status(Status::ProxyRequestRefused, None)
None,
)
.await?; .await?;
return Ok(()); return Ok(());
} }
@@ -179,7 +182,8 @@ async fn handle_connection(mut con: conn::Connection, srv: &config::ServerCfg) -
} }
if !path.exists() { 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(()); return Ok(());
} }
@@ -190,9 +194,9 @@ async fn handle_connection(mut con: conn::Connection, srv: &config::ServerCfg) -
// This block is terrible // This block is terrible
if meta.is_dir() { if meta.is_dir() {
if !url.path().ends_with("/") { if !url.path().ends_with("/") {
println!("{}", url); logger::logger(con.peer_addr, Status::RedirectPermanent, &request);
con.send_status( con.send_status(
status::Status::RedirectPermanent, Status::RedirectPermanent,
Some(format!("{}/", url).as_str()), Some(format!("{}/", url).as_str()),
) )
.await?; .await?;
@@ -218,20 +222,21 @@ async fn handle_connection(mut con: conn::Connection, srv: &config::ServerCfg) -
cgi::cgi(con, path, url).await?; cgi::cgi(con, path, url).await?;
return Ok(()); return Ok(());
} else { } else {
con.send_status( logger::logger(con.peer_addr, Status::CGIError, &request);
status::Status::CGIError, None).await?; con.send_status(Status::CGIError, None).await?;
return Ok(()); return Ok(());
} }
} }
if perm.mode() & 0o0444 != 0o0444 { if perm.mode() & 0o0444 != 0o0444 {
con.send_status( logger::logger(con.peer_addr, Status::NotFound, &request);
status::Status::NotFound, None).await?; con.send_status(Status::NotFound, None).await?;
return Ok(()); return Ok(());
} }
let mime = get_mime(&path); let mime = get_mime(&path);
if !mime.starts_with("text/") { if !mime.starts_with("text/") {
logger::logger(con.peer_addr, Status::Success, &request);
get_binary(con, path, mime).await?; get_binary(con, path, mime).await?;
return Ok(()); return Ok(());
} }
@@ -242,11 +247,13 @@ async fn handle_connection(mut con: conn::Connection, srv: &config::ServerCfg) -
Some(content), Some(content),
) )
.await?; .await?;
logger::logger(con.peer_addr, Status::Success, &request);
Ok(()) Ok(())
} }
fn main() -> io::Result<()> { fn main() -> io::Result<()> {
simple_logger::init_with_level(log::Level::Info).unwrap();
let args: Vec<String> = env::args().collect(); let args: Vec<String> = env::args().collect();
if args.len() != 2 { if args.len() != 2 {
println!("Please run with the path to the config file."); println!("Please run with the path to the config file.");
@@ -257,6 +264,7 @@ fn main() -> io::Result<()> {
println!("Config file doesn't exist"); println!("Config file doesn't exist");
return Ok(()); return Ok(());
} }
let cfg = config::Config::new(&p)?; let cfg = config::Config::new(&p)?;
let cmap = cfg.to_map(); let cmap = cfg.to_map();
println!("Serving {} vhosts", cfg.server.len()); println!("Serving {} vhosts", cfg.server.len());

View File

@@ -11,16 +11,19 @@ use openssl::ssl::{SslConnector, SslMethod};
use url::Url; use url::Url;
use crate::conn; 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> { 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(); let p: Vec<&str> = u.path().trim_start_matches("/").splitn(2, "/").collect();
if p.len() == 1 { 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(()); return Ok(());
} }
if p[1] == "" || p[1] == "/" { 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(()) return Ok(())
} }
let addr = addr 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 { let stream = match TcpStream::connect(&addr).await {
Ok(s) => s, Ok(s) => s,
Err(_) => { Err(_) => {
eprintln!("Error connecting to proxy"); logger::logger(con.peer_addr, Status::ProxyError, u.as_str());
con.send_status(status::Status::ProxyError, None).await?; con.send_status(Status::ProxyError, None).await?;
return Ok(()) return Ok(())
}, },
}; };
let mut stream = match tokio_openssl::connect(config, "localhost", stream).await { let mut stream = match tokio_openssl::connect(config, "localhost", stream).await {
Ok(s) => s, Ok(s) => s,
Err(_) => { Err(_) => {
eprintln!("Error connecting to proxy"); logger::logger(con.peer_addr, Status::ProxyError, u.as_str());
con.send_status(status::Status::ProxyError, None).await?; con.send_status(Status::ProxyError, None).await?;
return Ok(()) return Ok(())
}, },
}; };