minify html
This commit is contained in:
parent
cc744eafa1
commit
a168ddf9ec
12
Cargo.lock
generated
12
Cargo.lock
generated
|
@ -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",
|
||||||
|
|
|
@ -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"
|
||||||
|
|
116
src/main.rs
116
src/main.rs
|
@ -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();
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
<span>Upload</span>
|
<span>Upload</span>
|
||||||
<button>Upload</button>
|
<button>Upload</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</article>
|
||||||
</article>
|
</form>
|
||||||
</section>
|
</section>
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue