implement a CachedResponse Responder struct

this adds a Cache-Control header to existing responses so they can be
cached in the browser. cache busting means this cache can be immutable
as if the file changes, the filename changes, so the browser will get
new files.
This commit is contained in:
Fries 2023-07-11 02:37:31 -07:00
parent 53193d84b8
commit 70bb0691d3

View file

@ -1,5 +1,9 @@
use super::{files::get_file_wrapper, templates::ErrorTemplate}; use super::{files::get_file_wrapper, templates::ErrorTemplate};
use rocket::{http::Status, response::content::RawCss}; use rocket::{
http::{Header, Status},
response::{self, content::RawCss, Responder},
Response,
};
use std::borrow::Cow; use std::borrow::Cow;
#[derive(Responder)] #[derive(Responder)]
@ -15,8 +19,32 @@ pub struct ErrorTemplateResponder<'a> {
template: ErrorTemplate<'a>, template: ErrorTemplate<'a>,
} }
pub struct CachedResponse<T> {
inner: T,
}
impl<'r, T> Responder<'r, 'static> for CachedResponse<T>
where
T: Responder<'r, 'static>,
{
fn respond_to(self, request: &'r rocket::Request<'_>) -> response::Result<'static> {
Response::build_from(self.inner.respond_to(request)?)
.header(Header::new("Cache-Control", "max-age=31536000, immutable"))
.ok()
}
}
impl<'r, T> From<T> for CachedResponse<T>
where
T: Responder<'r, 'static>,
{
fn from(value: T) -> Self {
CachedResponse { inner: value }
}
}
#[get("/css/<style>")] #[get("/css/<style>")]
pub fn style(style: &str) -> Result<RawCss<String>, Status> { pub fn style(style: &str) -> Result<CachedResponse<RawCss<String>>, Status> {
let style_file = &get_file_wrapper()?.style; let style_file = &get_file_wrapper()?.style;
let hyperlegible_file = &get_file_wrapper()?.hyperlegible; let hyperlegible_file = &get_file_wrapper()?.hyperlegible;
@ -24,16 +52,20 @@ pub fn style(style: &str) -> Result<RawCss<String>, Status> {
let hyperlegible_name = hyperlegible_file.metadata.get_hash_filename(); let hyperlegible_name = hyperlegible_file.metadata.get_hash_filename();
if style == style_name { if style == style_name {
Ok(RawCss::<String>(style_file.text.clone())) Ok(CachedResponse::from(RawCss::<String>(
style_file.text.clone(),
)))
} else if style == hyperlegible_name { } else if style == hyperlegible_name {
Ok(RawCss::<String>(hyperlegible_file.text.clone())) Ok(CachedResponse::from(RawCss::<String>(
hyperlegible_file.text.clone(),
)))
} else { } else {
Err(Status::NotFound) Err(Status::NotFound)
} }
} }
#[get("/woff2/<font>")] #[get("/woff2/<font>")]
pub fn woff2_font(font: &str) -> Result<RawWoff2Font, Status> { pub fn woff2_font(font: &str) -> Result<CachedResponse<RawWoff2Font>, Status> {
let latin_file = &get_file_wrapper()?.atkinson_latin_woff2; let latin_file = &get_file_wrapper()?.atkinson_latin_woff2;
let latin_ext_file = &get_file_wrapper()?.atkinson_latin_ext_woff2; let latin_ext_file = &get_file_wrapper()?.atkinson_latin_ext_woff2;
@ -41,21 +73,23 @@ pub fn woff2_font(font: &str) -> Result<RawWoff2Font, Status> {
let latin_ext = latin_file.metadata.get_hash_filename(); let latin_ext = latin_file.metadata.get_hash_filename();
if font == latin { if font == latin {
Ok(RawWoff2Font(latin_file.data.clone())) Ok(CachedResponse::from(RawWoff2Font(latin_file.data.clone())))
} else if font == latin_ext { } else if font == latin_ext {
Ok(RawWoff2Font(latin_ext_file.data.clone())) Ok(CachedResponse::from(RawWoff2Font(
latin_ext_file.data.clone(),
)))
} else { } else {
Err(Status::NotFound) Err(Status::NotFound)
} }
} }
#[get("/woff/<font>")] #[get("/woff/<font>")]
pub fn woff_font(font: &str) -> Result<RawWoffFont, Status> { pub fn woff_font(font: &str) -> Result<CachedResponse<RawWoffFont>, Status> {
let all_file = &get_file_wrapper()?.atkinson_all_woff; let all_file = &get_file_wrapper()?.atkinson_all_woff;
let all = all_file.metadata.get_hash_filename(); let all = all_file.metadata.get_hash_filename();
if font == all { if font == all {
Ok(RawWoffFont(all_file.data.clone())) Ok(CachedResponse::from(RawWoffFont(all_file.data.clone())))
} else { } else {
Err(Status::NotFound) Err(Status::NotFound)
} }