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"
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]]
name = "miniz_oxide"
version = "0.4.3"
@ -1231,6 +1242,7 @@ dependencies = [
"env_logger",
"futures",
"mime",
"minify-html",
"once_cell",
"ructe",
"serde",

View file

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

View file

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

View file

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