about summary refs log tree commit diff
path: root/corgi/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'corgi/src/main.rs')
-rw-r--r--corgi/src/main.rs28
1 files changed, 25 insertions, 3 deletions
diff --git a/corgi/src/main.rs b/corgi/src/main.rs
index cd3b67c..6a3c528 100644
--- a/corgi/src/main.rs
+++ b/corgi/src/main.rs
@@ -1,7 +1,9 @@
 use std::{
 	net::{IpAddr, SocketAddr},
+	path::PathBuf,
 	pin::Pin,
 	process::Stdio,
+	sync::Arc,
 	time::Instant,
 };
 
@@ -17,9 +19,11 @@ use hyper::{
 };
 use hyper_util::rt::TokioIo;
 use regex_lite::Regex;
+use stats::Stats;
 use tokio::{io::AsyncWriteExt, net::TcpListener, process::Command, runtime::Runtime};
 
 mod caller;
+mod stats;
 
 #[derive(Clone, Debug)]
 pub struct Settings {
@@ -64,8 +68,13 @@ fn main() {
 		}
 	}
 
+	let stats = Stats::new(PathBuf::from(
+		conf.get("Server/StatsDb").unwrap().to_owned(),
+	));
+	stats.create_tables();
+
 	let rt = Runtime::new().unwrap();
-	rt.block_on(async { run(settings).await });
+	rt.block_on(async { run(settings, stats).await });
 }
 
 fn parse_script_conf(conf: &Value) -> Script {
@@ -106,12 +115,13 @@ fn parse_script_conf(conf: &Value) -> Script {
 }
 
 // We have tokio::main at home :)
-async fn run(settings: Settings) {
+async fn run(settings: Settings, stats: Stats) {
 	let addr = SocketAddr::from(([0, 0, 0, 0], settings.port));
 	let listen = TcpListener::bind(addr).await.unwrap();
 
 	let svc = Svc {
 		settings,
+		stats: Arc::new(stats),
 		client_addr: addr,
 	};
 
@@ -129,6 +139,7 @@ async fn run(settings: Settings) {
 #[derive(Clone, Debug)]
 struct Svc {
 	settings: Settings,
+	stats: Arc<Stats>,
 	client_addr: SocketAddr,
 }
 
@@ -140,14 +151,16 @@ impl Service<Request<Incoming>> for Svc {
 	fn call(&self, req: Request<Incoming>) -> Self::Future {
 		let settings = self.settings.clone();
 		let caddr = self.client_addr;
+		let stats = self.stats.clone();
 
-		Box::pin(async move { Ok(Self::handle(settings, caddr, req).await) })
+		Box::pin(async move { Ok(Self::handle(settings, stats, caddr, req).await) })
 	}
 }
 
 impl Svc {
 	async fn handle(
 		settings: Settings,
+		stats: Arc<Stats>,
 		caddr: SocketAddr,
 		req: Request<Incoming>,
 	) -> Response<Full<Bytes>> {
@@ -242,6 +255,13 @@ impl Svc {
 			response = response.header(key, value);
 		}
 
+		let db_req = stats::Request {
+			agent: &uagent,
+			ip_address: &client_addr,
+			script: &script.name,
+			path: &path,
+		};
+
 		println!(
 			"served to [{client_addr}]\n\tscript: {}\n\tpath: {path}\n\tcgi took {}ms. total time {}ms\n\tUA: {uagent}",
 			&script.name,
@@ -249,6 +269,8 @@ impl Svc {
 			start.elapsed().as_millis()
 		);
 
+		stats.log_request(db_req);
+
 		let response_body = cgi_response.body.map(|v| Bytes::from(v)).unwrap_or(Bytes::new());
 		response.body(Full::new(response_body)).unwrap()
 	}