minify html

This commit is contained in:
asonix 2021-01-05 11:03:18 -06:00
parent cc744eafa1
commit a168ddf9ec
4 changed files with 71 additions and 62 deletions

12
Cargo.lock generated
View file

@ -1033,6 +1033,17 @@ version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
[[package]]
name = "minify-html"
version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dedb5736b6b92db14a164678219f6738bc1104bf66d915d7143efc825f551323"
dependencies = [
"aho-corasick",
"lazy_static",
"memchr",
]
[[package]] [[package]]
name = "miniz_oxide" name = "miniz_oxide"
version = "0.4.3" version = "0.4.3"
@ -1231,6 +1242,7 @@ dependencies = [
"env_logger", "env_logger",
"futures", "futures",
"mime", "mime",
"minify-html",
"once_cell", "once_cell",
"ructe", "ructe",
"serde", "serde",

View file

@ -20,6 +20,7 @@ dotenv = "0.15.0"
env_logger = "0.8" env_logger = "0.8"
futures = "0.3" futures = "0.3"
mime = "0.3" mime = "0.3"
minify-html = "0.3.9"
once_cell = "1.4" once_cell = "1.4"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
structopt = "0.3.14" structopt = "0.3.14"

View file

@ -1,6 +1,7 @@
use actix_web::{ use actix_web::{
body::BodyStream, body::BodyStream,
client::Client, client::Client,
dev::HttpResponseBuilder,
http::{ http::{
header::{CacheControl, CacheDirective, ContentType, LastModified, LOCATION}, header::{CacheControl, CacheDirective, ContentType, LastModified, LOCATION},
StatusCode, StatusCode,
@ -250,6 +251,9 @@ enum Error {
#[error("{0}")] #[error("{0}")]
JsonPayload(#[from] awc::error::JsonPayloadError), JsonPayload(#[from] awc::error::JsonPayloadError),
#[error("Failed to minify html: {0}")]
Minify(String),
} }
impl ResponseError for Error { impl ResponseError for Error {
@ -258,27 +262,21 @@ impl ResponseError for Error {
} }
fn error_response(&self) -> HttpResponse { fn error_response(&self) -> HttpResponse {
let mut builder = HttpResponse::build(self.status_code()); match render(HttpResponse::build(self.status_code()), |cursor| {
self::templates::error(cursor, &self.to_string())
let mut cursor = Cursor::new(vec![]); }) {
if let Err(e) = self::templates::error(&mut cursor, &self.to_string()) { Ok(res) => res,
return builder Err(_) => HttpResponse::build(self.status_code())
.content_type(mime::TEXT_PLAIN.essence_str()) .content_type(mime::TEXT_PLAIN.essence_str())
.body(e.to_string()); .body(self.to_string()),
} }
builder
.content_type(mime::TEXT_HTML.essence_str())
.body(cursor.into_inner())
} }
} }
async fn index() -> Result<HttpResponse, Error> { async fn index() -> Result<HttpResponse, Error> {
let mut cursor = Cursor::new(vec![]); render(HttpResponse::Ok(), |cursor| {
self::templates::index(&mut cursor, "/upload", "images[]")?; self::templates::index(cursor, "/upload", "images[]")
Ok(HttpResponse::Ok() })
.content_type(mime::TEXT_HTML.essence_str())
.body(cursor.into_inner()))
} }
async fn upload( async fn upload(
@ -298,12 +296,9 @@ async fn upload(
let images = res.json::<Images>().await?; let images = res.json::<Images>().await?;
let mut cursor = Cursor::new(vec![]); render(HttpResponse::build(res.status()), |cursor| {
self::templates::images(&mut cursor, images)?; self::templates::images(cursor, images)
})
Ok(HttpResponse::build(res.status())
.content_type(mime::TEXT_HTML.essence_str())
.body(cursor.into_inner()))
} }
const THUMBNAIL_SIZES: &[u64] = &[40, 50, 80, 100, 200, 400, 800, 1200]; const THUMBNAIL_SIZES: &[u64] = &[40, 50, 80, 100, 200, 400, 800, 1200];
@ -334,12 +329,9 @@ async fn thumbs(
details, details,
}; };
let mut cursor = Cursor::new(vec![]); render(HttpResponse::Ok(), |cursor| {
self::templates::thumbnails(&mut cursor, image, THUMBNAIL_SIZES)?; self::templates::thumbnails(cursor, image, THUMBNAIL_SIZES)
})
Ok(HttpResponse::Ok()
.content_type(mime::TEXT_HTML.essence_str())
.body(cursor.into_inner()))
} }
async fn image( async fn image(
@ -390,12 +382,9 @@ async fn view_original(
details, details,
}; };
let mut cursor = Cursor::new(vec![]); render(HttpResponse::Ok(), |cursor| {
self::templates::view(&mut cursor, image, None)?; self::templates::view(cursor, image, None)
})
Ok(HttpResponse::Ok()
.content_type(mime::TEXT_HTML.essence_str())
.body(cursor.into_inner()))
} }
async fn view( async fn view(
@ -423,12 +412,9 @@ async fn view(
details, details,
}; };
let mut cursor = Cursor::new(vec![]); render(HttpResponse::Ok(), |cursor| {
self::templates::view(&mut cursor, image, Some(size))?; self::templates::view(cursor, image, Some(size))
})
Ok(HttpResponse::Ok()
.content_type(mime::TEXT_HTML.essence_str())
.body(cursor.into_inner()))
} }
async fn thumbnail( async fn thumbnail(
@ -505,28 +491,27 @@ async fn delete(
return Ok(to_404()); return Ok(to_404());
} }
let mut cursor = Cursor::new(vec![]);
if confirm { if confirm {
let url = CONFIG.upstream_delete_url(&token, &file); let url = CONFIG.upstream_delete_url(&token, &file);
client.delete(url).send().await?; client.delete(url).send().await?;
self::templates::deleted(&mut cursor, &file)?; render(HttpResponse::Ok(), |cursor| {
self::templates::deleted(cursor, &file)
})
} else { } else {
let details: Details = res.json().await?; let details: Details = res.json().await?;
self::templates::confirm_delete( render(HttpResponse::Ok(), move |cursor| {
&mut cursor, self::templates::confirm_delete(
&Image { cursor,
file, &Image {
delete_token: token, file,
details, delete_token: token,
}, details,
)?; },
)
})
} }
Ok(HttpResponse::Ok()
.content_type(mime::TEXT_HTML.essence_str())
.body(cursor.into_inner()))
} }
fn to_404() -> HttpResponse { fn to_404() -> HttpResponse {
@ -536,13 +521,9 @@ fn to_404() -> HttpResponse {
} }
async fn not_found() -> Result<HttpResponse, Error> { async fn not_found() -> Result<HttpResponse, Error> {
let mut cursor = Cursor::new(vec![]); render(HttpResponse::NotFound(), |cursor| {
self::templates::not_found(cursor)
self::templates::not_found(&mut cursor)?; })
Ok(HttpResponse::NotFound()
.content_type(mime::TEXT_HTML.essence_str())
.body(cursor.into_inner()))
} }
async fn go_home() -> HttpResponse { async fn go_home() -> HttpResponse {
@ -551,6 +532,21 @@ async fn go_home() -> HttpResponse {
.finish() .finish()
} }
fn render(
mut builder: HttpResponseBuilder,
f: impl FnOnce(&mut Cursor<&mut Vec<u8>>) -> Result<(), std::io::Error>,
) -> Result<HttpResponse, Error> {
let mut bytes = vec![];
(f)(&mut Cursor::new(&mut bytes))?;
minify_html::truncate(&mut bytes, &minify_html::Cfg { minify_js: false })
.map_err(|e| Error::Minify(format!("{:?}", e)))?;
Ok(builder
.content_type(mime::TEXT_HTML.essence_str())
.body(bytes))
}
#[actix_rt::main] #[actix_rt::main]
async fn main() -> Result<(), anyhow::Error> { async fn main() -> Result<(), anyhow::Error> {
dotenv::dotenv().ok(); dotenv::dotenv().ok();

View file

@ -33,7 +33,7 @@
<span>Upload</span> <span>Upload</span>
<button>Upload</button> <button>Upload</button>
</div> </div>
</form> </article>
</article> </form>
</section> </section>
}) })