diff --git a/source/Main/config.rs b/source/Main/config.rs index 7e41102..6a26ea6 100644 --- a/source/Main/config.rs +++ b/source/Main/config.rs @@ -253,6 +253,8 @@ pub(crate) struct Lifetimes { #[serde(default = "c_cache_lifetime_external")] #[serde(alias = "external")] pub(crate) forwarded: u64, + #[serde(default = "c_cache_lifetime_external")] + pub(crate) assets: u64, #[serde(default = "c_cache_lifetime_served")] pub(crate) served: u64, } @@ -263,6 +265,7 @@ impl Default for Lifetimes { javascript: c_cache_lifetime_js(), forwarded: c_cache_lifetime_external(), served: c_cache_lifetime_served(), + assets: c_cache_lifetime_external(), } } } diff --git a/source/Main/main.rs b/source/Main/main.rs index 90631eb..86788bd 100644 --- a/source/Main/main.rs +++ b/source/Main/main.rs @@ -12,6 +12,7 @@ use futures::join; use log::info; use log::LevelFilter; use log::{debug, error}; +use requestresponse::assets_with_cache; use simplelog::{ColorChoice, CombinedLogger, TermLogger, TerminalMode, WriteLogger}; use std::fs::File; use std::path::PathBuf; @@ -314,10 +315,7 @@ async fn start() { use requestresponse::serve; let main_server = match HttpServer::new(move || { App::new() - .route( - "/assets/{filename:.*}", - actix_web::web::get().to(requestresponse::assets), - ) + .service(assets_with_cache) .service(serve) .app_data(server_context_data.clone()) }) diff --git a/source/Main/requestresponse.rs b/source/Main/requestresponse.rs index b3c991c..5cf1a85 100644 --- a/source/Main/requestresponse.rs +++ b/source/Main/requestresponse.rs @@ -8,6 +8,7 @@ use actix_web::web::Data; use actix_web::{get, HttpRequest, HttpResponse, Responder}; use colored::Colorize; use log::{debug, trace, warn}; +use std::io::Read; use std::path::PathBuf; use std::sync::Arc; use tokio::sync::Mutex; @@ -139,42 +140,80 @@ pub(crate) async fn serve( } } -pub(crate) async fn assets( +#[get("/assets/{reqfile:.*}")] +pub(crate) async fn assets_with_cache( server_context_mutex: Data>>, req: HttpRequest, -) -> actix_web::Result { - let config_clone = server_context_mutex - .lock_callback(|a| { - a.request_count += 1; - a.config.clone() - }) +) -> impl Responder { + let path = req.match_info().get("reqfile").unwrap(); + let cacheresulr = server_context_mutex + .lock_callback(|servercontext| servercontext.get_cache(path, 0)) .await; - let coninfo = req.connection_info(); - let ip = coninfo.realip_remote_addr().unwrap_or(""); - - let file = req.match_info().query("filename"); - let path: PathBuf = std::env::current_dir()? - .canonicalize()? - .join("cynthiaFiles/assets/") - .join(file); - debug!("Requested asset: {:?}", path); - if path.exists() { - config_clone.tell(format!( - "{}\t{:>25.27}\t\t{}\t{}", - "Request/200".bright_green(), - req.path().blue(), - ip, - "filesystem".blue() - )); - } else { - config_clone.tell(format!( - "{}\t{:>25.27}\t\t{}\t{}", - "Request/404".bright_red(), - req.path().blue(), - ip, - "not found".red() - )); - return Err(actix_web::error::ErrorNotFound("File not found")); + match cacheresulr { + None => { + let config_clone = server_context_mutex + .lock_callback(|a| { + a.request_count += 1; + a.config.clone() + }) + .await; + let filepath: PathBuf = std::env::current_dir() + .unwrap() + .canonicalize() + .unwrap() + .join("cynthiaFiles/assets/") + .join(path); + debug!("Requested asset: {:?}", filepath); + if filepath.exists() { + let contents: Vec = std::fs::read(filepath).unwrap(); + let mut server_context = server_context_mutex.lock().await; + server_context + .store_cache(path, &contents, config_clone.cache.lifetimes.assets) + .unwrap(); + let coninfo = req.connection_info(); + let ip = coninfo.realip_remote_addr().unwrap_or(""); + server_context.tell(format!( + "{}\t{:>25.27}\t\t{}\t{}", + "Request/200".bright_green(), + req.path().blue(), + ip, + "filesystem".blue() + )); + HttpResponse::Ok() + .append_header(("Content-Type", "text/html; charset=utf-8")) + .body(contents) + } else { + let coninfo = req.connection_info(); + let ip = coninfo.realip_remote_addr().unwrap_or(""); + config_clone.tell(format!( + "{}\t{:>25.27}\t\t{}\t{}", + "Request/404".bright_red(), + req.path().blue(), + ip, + "not found".red() + )); + HttpResponse::NotFound().body("404 Not Found") + } + } + Some(c) => { + let config_clone = server_context_mutex + .lock_callback(|a| { + a.request_count += 1; + a.config.clone() + }) + .await; + let coninfo = req.connection_info(); + let ip = coninfo.realip_remote_addr().unwrap_or(""); + config_clone.tell(format!( + "{}\t{:>25.27}\t\t{}\t{}", + "Request/200".bright_green(), + req.path().blue(), + ip, + "from cache".green() + )); + HttpResponse::Ok() + .append_header(("Content-Type", "text/html; charset=utf-8")) + .body(c.0) + } } - Ok(NamedFile::open(path)?) }