diff options
author | metamuffin <metamuffin@disroot.org> | 2024-05-29 16:37:44 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2024-05-29 16:37:44 +0200 |
commit | 886a18e0c67624d0882f04c7f6659bcfee6b4d8d (patch) | |
tree | 32a5389076b199c4e06fa10ce6b54d165d5466c5 /src/main.rs | |
parent | 6cebab912dcf01bbe225c20ec2e7656f61ba160e (diff) | |
download | gnix-886a18e0c67624d0882f04c7f6659bcfee6b4d8d.tar gnix-886a18e0c67624d0882f04c7f6659bcfee6b4d8d.tar.bz2 gnix-886a18e0c67624d0882f04c7f6659bcfee6b4d8d.tar.zst |
refactor filter system
Diffstat (limited to 'src/main.rs')
-rw-r--r-- | src/main.rs | 96 |
1 files changed, 15 insertions, 81 deletions
diff --git a/src/main.rs b/src/main.rs index 0109a62..7c74f70 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,14 +10,10 @@ pub mod helper; #[cfg(feature = "mond")] pub mod reporting; -use crate::{ - config::{Config, RouteFilter}, - filters::{files::serve_files, proxy::proxy_request}, -}; use anyhow::{anyhow, Context, Result}; -use bytes::Bytes; -use config::setup_file_watch; +use config::{setup_file_watch, Config, NODE_KINDS}; use error::ServiceError; +use filters::{NodeContext, MODULES}; use futures::future::try_join_all; use helper::TokioIo; use http_body_util::{combinators::BoxBody, BodyExt}; @@ -30,14 +26,11 @@ use hyper::{ Request, Response, StatusCode, }; use log::{debug, error, info, warn, LevelFilter}; -#[cfg(feature = "mond")] -use reporting::Reporting; use rustls::pki_types::{CertificateDer, PrivateKeyDer}; use std::{ collections::HashMap, io::BufReader, net::SocketAddr, - ops::ControlFlow, path::{Path, PathBuf}, process::exit, str::FromStr, @@ -57,14 +50,7 @@ pub struct State { pub access_logs: RwLock<HashMap<String, BufWriter<File>>>, pub l_incoming: Semaphore, pub l_outgoing: Semaphore, - #[cfg(feature = "mond")] - pub reporting: Reporting, } -pub struct HostState {} - -pub type FilterRequest = Request<Incoming>; -pub type FilterResponseOut = Option<Response<BoxBody<Bytes, ServiceError>>>; -pub type FilterResponse = Option<Response<BoxBody<Bytes, ServiceError>>>; #[tokio::main] async fn main() -> anyhow::Result<()> { @@ -73,6 +59,11 @@ async fn main() -> anyhow::Result<()> { .parse_env("LOG") .init(); + NODE_KINDS + .write() + .unwrap() + .extend(MODULES.iter().map(|m| (m.name().to_owned(), *m))); + let Some(config_path) = std::env::args().skip(1).next() else { eprintln!("error: first argument is expected to be the configuration file"); exit(1) @@ -249,70 +240,17 @@ fn load_private_key(path: &Path) -> anyhow::Result<PrivateKeyDer<'static>> { async fn service( state: Arc<State>, config: Arc<Config>, - req: Request<Incoming>, + request: Request<Incoming>, addr: SocketAddr, ) -> Result<hyper::Response<BoxBody<bytes::Bytes, ServiceError>>, ServiceError> { - debug!("{addr} ~> {:?} {}", req.headers().get(HOST), req.uri()); - #[cfg(feature = "mond")] - state.reporting.request_in.inc(); - - let host = req - .headers() - .get(HOST) - .and_then(|e| e.to_str().ok()) - .map(String::from) - .unwrap_or(String::from("")); - let host = remove_port(&host); - let route = config.hosts.get(host).ok_or(ServiceError::NoHost)?; - #[cfg(feature = "mond")] - state.reporting.hosts.get(host).unwrap().requests_in.inc(); - - // TODO this code is horrible - let mut req = Some(req); - let mut resp = None; - for filter in &route.0 { - let cf = match filter { - RouteFilter::Proxy { backend } => { - resp = Some( - proxy_request( - &state, - req.take().ok_or(ServiceError::RequestTaken)?, - addr, - backend, - ) - .await?, - ); - ControlFlow::Continue(()) - } - RouteFilter::Files { config } => { - resp = Some( - serve_files(req.as_ref().ok_or(ServiceError::RequestTaken)?, config).await?, - ); - ControlFlow::Continue(()) - } - RouteFilter::HttpBasicAuth { config } => filters::auth::http_basic( - config, - req.as_ref().ok_or(ServiceError::RequestTaken)?, - &mut resp, - )?, - RouteFilter::AccessLog { config } => { - filters::accesslog::access_log( - &state, - host, - addr, - config, - req.as_ref().ok_or(ServiceError::RequestTaken)?, - ) - .await? - } - }; - match cf { - ControlFlow::Continue(_) => continue, - ControlFlow::Break(_) => break, - } - } + debug!( + "{addr} ~> {:?} {}", + request.headers().get(HOST), + request.uri() + ); - let mut resp = resp.ok_or(ServiceError::NoResponse)?; + let mut context = NodeContext { addr, state }; + let mut resp = config.handler.handle(&mut context, request).await?; let server_header = resp.headers().get(SERVER).cloned(); resp.headers_mut().insert( @@ -327,7 +265,3 @@ async fn service( return Ok(resp); } - -pub fn remove_port(s: &str) -> &str { - s.split_once(":").map(|(s, _)| s).unwrap_or(s) -} |