From 486dab535575094060ac9d9a9780cd017408ecd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=B4=80=E1=B4=8D=E1=B4=9B=E1=B4=8F=E1=B4=80=E1=B4=87?= =?UTF-8?q?=CA=80?= Date: Thu, 10 Jul 2025 00:03:16 +0800 Subject: [PATCH] =?UTF-8?q?chore:=20=E6=B7=BB=E5=8A=A0=E5=89=8D=E7=AB=AF?= =?UTF-8?q?=E5=8E=8B=E7=BC=A9=20(#383)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 133 ++++++++++++++++++----- Cargo.toml | 3 +- crates/bili_sync/Cargo.toml | 3 +- crates/bili_sync/src/task/http_server.rs | 46 ++++++-- 4 files changed, 147 insertions(+), 38 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a1fb247..5f53458 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -43,6 +43,21 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + [[package]] name = "allocator-api2" version = "0.2.16" @@ -429,6 +444,12 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +[[package]] +name = "base85rs" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87678d33a2af71f019ed11f52db246ca6c5557edee2cccbe689676d1ad9c6b5a" + [[package]] name = "bigdecimal" version = "0.4.7" @@ -469,7 +490,6 @@ dependencies = [ "leaky-bucket", "md5", "memchr", - "mime_guess", "once_cell", "parking_lot", "prost", @@ -478,7 +498,7 @@ dependencies = [ "regex", "reqwest", "rsa", - "rust-embed", + "rust-embed-for-web", "sea-orm", "serde", "serde_json", @@ -589,6 +609,37 @@ dependencies = [ "syn_derive", ] +[[package]] +name = "brotli" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74f7971dbd9326d58187408ab83117d8ac1bb9c17b085fdacd1cf2f598719b6b" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a334ef7c9e23abf0ce748e8cd309037da93e606ad52eb372e4ce327a0dcfbdfd" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + +[[package]] +name = "bstr" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "built" version = "0.7.7" @@ -1303,6 +1354,19 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +[[package]] +name = "globset" +version = "0.4.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54a1028dfc5f5df5da8a56a73e6c153c9a9708ec57232470703592a3f18e49f5" +dependencies = [ + "aho-corasick", + "bstr", + "log", + "regex-automata 0.4.9", + "regex-syntax 0.8.5", +] + [[package]] name = "gloo-timers" version = "0.3.0" @@ -1911,16 +1975,6 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" -[[package]] -name = "mime_guess" -version = "2.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" -dependencies = [ - "mime", - "unicase", -] - [[package]] name = "miniz_oxide" version = "0.7.2" @@ -1942,6 +1996,16 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "new_mime_guess" +version = "4.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02a2dfb3559d53e90b709376af1c379462f7fb3085a0177deb73e6ea0d99eff4" +dependencies = [ + "mime", + "unicase", +] + [[package]] name = "ntapi" version = "0.4.1" @@ -2739,35 +2803,41 @@ dependencies = [ ] [[package]] -name = "rust-embed" -version = "8.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "025908b8682a26ba8d12f6f2d66b987584a4a87bc024abc5bbc12553a8cd178a" +name = "rust-embed-for-web" +version = "11.2.1" +source = "git+https://github.com/amtoaer/rust-embed-for-web?tag=v1.0.0#b6eeb475cbe1ad5cae02d5373a1bba12ea58a869" dependencies = [ - "rust-embed-impl", - "rust-embed-utils", + "rust-embed-for-web-impl", + "rust-embed-for-web-utils", "walkdir", ] [[package]] -name = "rust-embed-impl" -version = "8.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6065f1a4392b71819ec1ea1df1120673418bf386f50de1d6f54204d836d4349c" +name = "rust-embed-for-web-impl" +version = "11.2.1" +source = "git+https://github.com/amtoaer/rust-embed-for-web?tag=v1.0.0#b6eeb475cbe1ad5cae02d5373a1bba12ea58a869" dependencies = [ + "brotli", + "flate2", + "globset", "proc-macro2", "quote", - "rust-embed-utils", + "rust-embed-for-web-utils", + "shellexpand", "syn 2.0.96", "walkdir", ] [[package]] -name = "rust-embed-utils" -version = "8.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6cc0c81648b20b70c491ff8cce00c1c3b223bb8ed2b5d41f0e54c6c4c0a3594" +name = "rust-embed-for-web-utils" +version = "11.2.1" +source = "git+https://github.com/amtoaer/rust-embed-for-web?tag=v1.0.0#b6eeb475cbe1ad5cae02d5373a1bba12ea58a869" dependencies = [ + "base85rs", + "chrono", + "enum_dispatch", + "globset", + "new_mime_guess", "sha2", "walkdir", ] @@ -3140,6 +3210,15 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "shellexpand" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b1fdf65dd6331831494dd616b30351c38e96e45921a27745cf98490458b90bb" +dependencies = [ + "dirs", +] + [[package]] name = "shlex" version = "1.3.0" diff --git a/Cargo.toml b/Cargo.toml index 79b8de4..52ca798 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,7 +37,6 @@ hex = "0.4.3" leaky-bucket = "1.1.2" md5 = "0.7.0" memchr = "2.7.4" -mime_guess = "2.0.5" once_cell = "1.21.3" parking_lot = "0.12.4" prost = "0.13.5" @@ -54,7 +53,7 @@ reqwest = { version = "0.12.15", features = [ "stream", ], default-features = false } rsa = { version = "0.9.8", features = ["sha2"] } -rust-embed = "8.7.2" +rust-embed-for-web = { git = "https://github.com/amtoaer/rust-embed-for-web", tag = "v1.0.0" } sea-orm = { version = "1.1.11", features = [ "macros", "runtime-tokio-rustls", diff --git a/crates/bili_sync/Cargo.toml b/crates/bili_sync/Cargo.toml index 16b8c09..62e11d1 100644 --- a/crates/bili_sync/Cargo.toml +++ b/crates/bili_sync/Cargo.toml @@ -29,7 +29,6 @@ hex = { workspace = true } leaky-bucket = { workspace = true } md5 = { workspace = true } memchr = { workspace = true } -mime_guess = { workspace = true } once_cell = { workspace = true } parking_lot = { workspace = true } prost = { workspace = true } @@ -38,7 +37,7 @@ rand = { workspace = true } regex = { workspace = true } reqwest = { workspace = true } rsa = { workspace = true } -rust-embed = { workspace = true } +rust-embed-for-web = { workspace = true } sea-orm = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } diff --git a/crates/bili_sync/src/task/http_server.rs b/crates/bili_sync/src/task/http_server.rs index 8f92114..1929b31 100644 --- a/crates/bili_sync/src/task/http_server.rs +++ b/crates/bili_sync/src/task/http_server.rs @@ -1,20 +1,22 @@ +use std::collections::HashSet; use std::sync::Arc; use anyhow::{Context, Result}; use axum::extract::Request; -use axum::http::{Uri, header}; +use axum::http::header; use axum::response::IntoResponse; use axum::routing::get; use axum::{Extension, ServiceExt}; use reqwest::StatusCode; -use rust_embed::Embed; +use rust_embed_for_web::{EmbedableFile, RustEmbed}; use sea_orm::DatabaseConnection; use crate::api::{MpscWriter, router}; use crate::bilibili::BiliClient; use crate::config::VersionedConfig; -#[derive(Embed)] +#[derive(RustEmbed)] +#[preserve_source = false] #[folder = "../../web/build"] struct Asset; @@ -36,14 +38,44 @@ pub async fn http_server( Ok(axum::serve(listener, ServiceExt::::into_make_service(app)).await?) } -async fn frontend_files(uri: Uri) -> impl IntoResponse { - let mut path = uri.path().trim_start_matches('/'); +async fn frontend_files(request: Request) -> impl IntoResponse { + let mut path = request.uri().path().trim_start_matches('/'); if path.is_empty() || Asset::get(path).is_none() { path = "index.html"; } let Some(content) = Asset::get(path) else { return (StatusCode::NOT_FOUND, "404 Not Found").into_response(); }; - let mime = mime_guess::from_path(path).first_or_octet_stream(); - ([(header::CONTENT_TYPE, mime.as_ref())], content.data).into_response() + let mime_type = content.mime_type(); + let content_type = mime_type.as_deref().unwrap_or("application/octet-stream"); + if cfg!(debug_assertions) { + ( + [(header::CONTENT_TYPE, content_type)], + // safety: `RustEmbed` returns uncompressed files directly from the filesystem in debug mode + content.data().unwrap(), + ) + .into_response() + } else { + let accepted_encodings = request + .headers() + .get(header::ACCEPT_ENCODING) + .and_then(|v| v.to_str().ok()) + .map(|s| s.split(',').map(str::trim).collect::>()) + .unwrap_or_default(); + for (encoding, data) in [("br", content.data_br()), ("gzip", content.data_gzip())] { + if accepted_encodings.contains(encoding) { + if let Some(data) = data { + return ( + [ + (header::CONTENT_TYPE, content_type), + (header::CONTENT_ENCODING, encoding), + ], + data, + ) + .into_response(); + } + } + } + "Unsupported Encoding".into_response() + } }