Added logger.rs
This commit is contained in:
@@ -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" ]
|
||||||
|
|||||||
@@ -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
17
src/logger.rs
Normal 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
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
44
src/main.rs
44
src/main.rs
@@ -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(_) => {
|
||||||
|
logger::logger(con.peer_addr, Status::BadRequest, &request);
|
||||||
|
con.send_status(Status::BadRequest, None).await?;
|
||||||
return Ok(())
|
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());
|
||||||
|
|||||||
@@ -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(())
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user