From a0cad136f48c14059da128fab79b2c4ad63e1b16 Mon Sep 17 00:00:00 2001 From: asonix Date: Mon, 14 Dec 2020 14:23:02 -0600 Subject: [PATCH] Minify html --- Cargo.lock | 12 ++++ Cargo.toml | 1 + src/lib.rs | 145 +++++++++++++++++++++++----------------- templates/index.rs.html | 2 +- 4 files changed, 99 insertions(+), 61 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 638e014..c51dcb5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1147,6 +1147,17 @@ version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" +[[package]] +name = "minify-html" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ac7185726f6e49b3a692680c54aeee49027351696a2db1bcebafdc33d077e3" +dependencies = [ + "aho-corasick", + "lazy_static", + "memchr", +] + [[package]] name = "miniz_oxide" version = "0.4.3" @@ -1343,6 +1354,7 @@ dependencies = [ "env_logger", "futures", "mime", + "minify-html", "ructe", "serde", "serde_json", diff --git a/Cargo.toml b/Cargo.toml index 1c47b0b..9804d8e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ bcrypt = "0.9" env_logger = "0.8.2" futures = "0.3" mime = "0.3" +minify-html = "0.3.9" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" sled = { version = "0.34.6", features = ["zstd"] } diff --git a/src/lib.rs b/src/lib.rs index 80517d3..b8519bb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,6 @@ use actix_web::{ client::Client, + dev::HttpResponseBuilder, http::{ header::{CacheControl, CacheDirective, ContentType, LastModified, LOCATION}, StatusCode, @@ -262,13 +263,11 @@ async fn static_files(filename: web::Path, state: web::Data) -> H } async fn not_found(state: web::Data) -> Result { - let mut cursor = Cursor::new(vec![]); - - self::templates::not_found(&mut cursor, &state).stateful(&state)?; - - Ok(HttpResponse::NotFound() - .content_type(mime::TEXT_HTML.essence_str()) - .body(cursor.into_inner())) + rendered( + |cursor| self::templates::not_found(cursor, &state), + HttpResponse::NotFound(), + ) + .stateful(&state) } struct StateError { @@ -296,11 +295,11 @@ impl ResponseError for StateError { } fn error_response(&self) -> HttpResponse { - let mut cursor = Cursor::new(vec![]); - match self::templates::error(&mut cursor, &self.error.to_string(), &self.state) { - Ok(_) => HttpResponse::build(self.status_code()) - .content_type(mime::TEXT_HTML.essence_str()) - .body(cursor.into_inner()), + match rendered( + |cursor| self::templates::error(cursor, &self.error.to_string(), &self.state), + HttpResponse::build(self.status_code()), + ) { + Ok(res) => res, Err(_) => HttpResponse::build(self.status_code()) .content_type(mime::TEXT_PLAIN.essence_str()) .body(self.error.to_string()), @@ -321,6 +320,15 @@ enum Error { #[error("{0}")] UploadString(String), + + #[error("Failed to minify html, {0}")] + Minify(String), +} + +impl From for Error { + fn from(e: minify_html::Error) -> Self { + Error::Minify(format!("{:?}", e)) + } } #[derive(serde::Deserialize, serde::Serialize)] @@ -479,13 +487,11 @@ async fn thumbnail( } async fn index(state: web::Data) -> Result { - let mut cursor = Cursor::new(vec![]); - - self::templates::index(&mut cursor, &state).stateful(&state)?; - - Ok(HttpResponse::Ok() - .content_type(mime::TEXT_HTML.essence_str()) - .body(cursor.into_inner())) + rendered( + |cursor| self::templates::index(cursor, &state), + HttpResponse::Ok(), + ) + .stateful(&state) } async fn collection( @@ -511,13 +517,12 @@ async fn view_collection( }; let entries = state.store.entries(path.entry_range()).await?; - let mut cursor = Cursor::new(vec![]); - - self::templates::view_collection(&mut cursor, path.collection, &collection, &entries, &state)?; - - Ok(HttpResponse::Ok() - .content_type(mime::TEXT_HTML.essence_str()) - .body(cursor.into_inner())) + rendered( + |cursor| { + self::templates::view_collection(cursor, path.collection, &collection, &entries, &state) + }, + HttpResponse::Ok(), + ) } async fn edit_collection( @@ -531,20 +536,19 @@ async fn edit_collection( }; let entries = state.store.entries(path.entry_range()).await?; - let mut cursor = Cursor::new(vec![]); - - self::templates::edit_collection( - &mut cursor, - &collection, - path.collection, - &entries, - &token, - &state, - )?; - - Ok(HttpResponse::Ok() - .content_type(mime::TEXT_HTML.essence_str()) - .body(cursor.into_inner())) + rendered( + |cursor| { + self::templates::edit_collection( + cursor, + &collection, + path.collection, + &entries, + &token, + &state, + ) + }, + HttpResponse::Ok(), + ) } async fn create_collection( @@ -629,20 +633,20 @@ async fn delete_entry( }; if !query.confirmed.unwrap_or(false) { - let mut cursor = Cursor::new(vec![]); - self::templates::confirm_entry_delete( - &mut cursor, - entry_path.collection, - entry_path.entry, - &entry, - &token, - &state, + return rendered( + |cursor| { + self::templates::confirm_entry_delete( + cursor, + entry_path.collection, + entry_path.entry, + &entry, + &token, + &state, + ) + }, + HttpResponse::Ok(), ) - .stateful(&state)?; - - return Ok(HttpResponse::Ok() - .content_type(mime::TEXT_HTML.essence_str()) - .body(cursor.into_inner())); + .stateful(&state); } conn.delete(&entry.filename, &entry.delete_token) @@ -674,13 +678,19 @@ async fn delete_collection( None => return Ok(to_404(&state)), }; - let mut cursor = Cursor::new(vec![]); - self::templates::confirm_delete(&mut cursor, path.collection, &collection, &token, &state) - .stateful(&state)?; - - return Ok(HttpResponse::Ok() - .content_type(mime::TEXT_HTML.essence_str()) - .body(cursor.into_inner())); + return rendered( + |cursor| { + self::templates::confirm_delete( + cursor, + path.collection, + &collection, + &token, + &state, + ) + }, + HttpResponse::Ok(), + ) + .stateful(&state); } let entries = state @@ -713,3 +723,18 @@ async fn delete_collection( Ok(to_home(&state)) } + +fn rendered( + f: impl FnOnce(&mut Cursor>) -> std::io::Result<()>, + mut builder: HttpResponseBuilder, +) -> Result { + let mut cursor = Cursor::new(vec![]); + (f)(&mut cursor)?; + let mut html = cursor.into_inner(); + let len = minify_html::in_place(&mut html, &minify_html::Cfg { minify_js: true })?; + html.truncate(len); + + Ok(builder + .content_type(mime::TEXT_HTML.essence_str()) + .body(html)) +} diff --git a/templates/index.rs.html b/templates/index.rs.html index c3ebfc5..9136e0a 100644 --- a/templates/index.rs.html +++ b/templates/index.rs.html @@ -17,7 +17,7 @@
@:button("Create Collection", ButtonKind::Submit) - +