minify: minify html on the fly in release mode

This commit is contained in:
Philippe Loctaux 2023-05-06 13:15:43 +02:00
parent 895d3ad117
commit 3dfcd542bf
4 changed files with 136 additions and 0 deletions

81
Cargo.lock generated
View file

@ -354,6 +354,12 @@ version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13418e745008f7349ec7e449155f419a61b92b58a99cc3616942b926825ec76b" checksum = "13418e745008f7349ec7e449155f419a61b92b58a99cc3616942b926825ec76b"
[[package]]
name = "convert_case"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
[[package]] [[package]]
name = "cookie" name = "cookie"
version = "0.17.0" version = "0.17.0"
@ -455,6 +461,17 @@ dependencies = [
"typenum", "typenum",
] ]
[[package]]
name = "css-minify"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "874c6e2d19f8d4a285083b11a3241bfbe01ac3ed85f26e1e6b34888d960552bd"
dependencies = [
"derive_more",
"indexmap",
"nom",
]
[[package]] [[package]]
name = "cxx" name = "cxx"
version = "1.0.93" version = "1.0.93"
@ -595,6 +612,19 @@ dependencies = [
"zeroize", "zeroize",
] ]
[[package]]
name = "derive_more"
version = "0.99.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321"
dependencies = [
"convert_case",
"proc-macro2",
"quote",
"rustc_version",
"syn 1.0.109",
]
[[package]] [[package]]
name = "deunicode" name = "deunicode"
version = "0.4.3" version = "0.4.3"
@ -791,6 +821,7 @@ dependencies = [
"id", "id",
"infer", "infer",
"jwt", "jwt",
"minify-html",
"openid", "openid",
"refresh_tokens", "refresh_tokens",
"rocket", "rocket",
@ -1634,6 +1665,30 @@ version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
[[package]]
name = "minify-html"
version = "0.10.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7754d4669873379ea6a8a5b56e406eb83de713af8a791517ef35a0c832b1e7d5"
dependencies = [
"aho-corasick",
"css-minify",
"lazy_static",
"memchr",
"minify-js",
"rustc-hash",
]
[[package]]
name = "minify-js"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c300f90ba1138b5c5daf5d9441dc9bdc67b808aac22cf638362a2647bc213be4"
dependencies = [
"lazy_static",
"parse-js",
]
[[package]] [[package]]
name = "minimal-lexical" name = "minimal-lexical"
version = "0.2.1" version = "0.2.1"
@ -2053,6 +2108,17 @@ dependencies = [
"windows-sys 0.45.0", "windows-sys 0.45.0",
] ]
[[package]]
name = "parse-js"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30534759e6ad87aa144c396544747e1c25b1020bd133356fd758c8facec764e5"
dependencies = [
"aho-corasick",
"lazy_static",
"memchr",
]
[[package]] [[package]]
name = "parse-zoneinfo" name = "parse-zoneinfo"
version = "0.3.0" version = "0.3.0"
@ -2661,6 +2727,15 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rustc_version"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
dependencies = [
"semver",
]
[[package]] [[package]]
name = "rustix" name = "rustix"
version = "0.36.11" version = "0.36.11"
@ -2781,6 +2856,12 @@ dependencies = [
"zeroize", "zeroize",
] ]
[[package]]
name = "semver"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.158" version = "1.0.158"

View file

@ -16,6 +16,7 @@ rocket_cors = "0.6.0-alpha2"
email_address = { workspace = true } email_address = { workspace = true }
chrono-tz = "0.8.2" chrono-tz = "0.8.2"
chrono-humanize = "0.2.2" chrono-humanize = "0.2.2"
minify-html = "0.10.8"
# local crates # local crates
database_pool = { path = "../database_pool" } database_pool = { path = "../database_pool" }

View file

@ -10,6 +10,7 @@ mod guards;
mod icons; mod icons;
mod id; mod id;
mod menu; mod menu;
mod minify;
mod oauth; mod oauth;
mod page; mod page;
mod response_timer; mod response_timer;
@ -18,6 +19,7 @@ mod shutdown;
mod tokens; mod tokens;
pub use crate::email::init as email_init; pub use crate::email::init as email_init;
use crate::minify::Minify;
pub fn rocket_setup(rocket_builder: Rocket<Build>) -> Rocket<Build> { pub fn rocket_setup(rocket_builder: Rocket<Build>) -> Rocket<Build> {
use cache::CacheControl; use cache::CacheControl;
@ -46,6 +48,9 @@ pub fn rocket_setup(rocket_builder: Rocket<Build>) -> Rocket<Build> {
// Static assets // Static assets
let rocket_builder = rocket_builder.mount("/", FileServer::from("static")); let rocket_builder = rocket_builder.mount("/", FileServer::from("static"));
// Minify content
let rocket_builder = Minify::rocket(rocket_builder);
// Routes // Routes
let rocket_builder = routes::routes(rocket_builder); let rocket_builder = routes::routes(rocket_builder);

View file

@ -0,0 +1,49 @@
use rocket::fairing::{self, Fairing, Kind};
use rocket::http::ContentType;
use rocket::{Build, Request, Response, Rocket};
pub struct Minify {}
impl Minify {
pub fn rocket(rocket_builder: Rocket<Build>) -> Rocket<Build> {
if cfg!(debug_assertions) {
rocket_builder
} else {
rocket_builder.attach(Self {})
}
}
}
#[rocket::async_trait]
impl Fairing for Minify {
fn info(&self) -> fairing::Info {
fairing::Info {
name: "Minify HTML",
kind: Kind::Response,
}
}
async fn on_response<'r>(&self, _request: &'r Request<'_>, response: &mut Response<'r>) {
if response.content_type() == Some(ContentType::HTML) {
let body = response.body_mut();
if let Ok(original) = body.to_bytes().await {
let cfg = minify_html::Cfg {
// Be HTML spec compliant
do_not_minify_doctype: true,
ensure_spec_compliant_unquoted_attribute_values: true,
keep_spaces_between_attributes: true,
// The rest
keep_closing_tags: true,
keep_html_and_head_opening_tags: true,
minify_css: true,
minify_js: true,
..Default::default()
};
let minified = minify_html::minify(&original, &cfg);
response.set_sized_body(minified.len(), std::io::Cursor::new(minified));
}
}
}
}