Trailing slash normalization
This commit is contained in:
parent
85cacd8bb7
commit
1e0a6062f9
5 changed files with 50 additions and 27 deletions
36
Cargo.lock
generated
36
Cargo.lock
generated
|
@ -138,7 +138,7 @@ dependencies = [
|
||||||
"serde_urlencoded",
|
"serde_urlencoded",
|
||||||
"sync_wrapper 1.0.1",
|
"sync_wrapper 1.0.1",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tower",
|
"tower 0.4.13",
|
||||||
"tower-layer",
|
"tower-layer",
|
||||||
"tower-service",
|
"tower-service",
|
||||||
"tracing",
|
"tracing",
|
||||||
|
@ -182,7 +182,7 @@ dependencies = [
|
||||||
"mime",
|
"mime",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"serde",
|
"serde",
|
||||||
"tower",
|
"tower 0.4.13",
|
||||||
"tower-layer",
|
"tower-layer",
|
||||||
"tower-service",
|
"tower-service",
|
||||||
"tracing",
|
"tracing",
|
||||||
|
@ -205,9 +205,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "axum-test"
|
name = "axum-test"
|
||||||
version = "15.3.0"
|
version = "15.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2cd2b6c11bc5e65ec121543c5049b7e07be9e7b5a515df79d01f74a72c6a15f0"
|
checksum = "6c13fee69ea6d727350c4fcb5f9100fda3b6b73bfae33da6b4acd3b6934f6e73"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"auto-future",
|
"auto-future",
|
||||||
|
@ -227,7 +227,7 @@ dependencies = [
|
||||||
"serde_urlencoded",
|
"serde_urlencoded",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tower",
|
"tower 0.5.0",
|
||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1058,7 +1058,7 @@ dependencies = [
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"socket2",
|
"socket2",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tower",
|
"tower 0.4.13",
|
||||||
"tower-service",
|
"tower-service",
|
||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
@ -1685,6 +1685,7 @@ dependencies = [
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
"toml 0.8.19",
|
"toml 0.8.19",
|
||||||
|
"tower 0.5.0",
|
||||||
"tower-http",
|
"tower-http",
|
||||||
"trie-rs",
|
"trie-rs",
|
||||||
"unicase",
|
"unicase",
|
||||||
|
@ -2939,9 +2940,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.39.2"
|
version = "1.40.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1"
|
checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace",
|
"backtrace",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
@ -3047,6 +3048,21 @@ dependencies = [
|
||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tower"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "36b837f86b25d7c0d7988f00a54e74739be6477f2aac6201b8f429a7569991b7"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"futures-util",
|
||||||
|
"pin-project-lite",
|
||||||
|
"sync_wrapper 0.1.2",
|
||||||
|
"tokio",
|
||||||
|
"tower-layer",
|
||||||
|
"tower-service",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tower-http"
|
name = "tower-http"
|
||||||
version = "0.5.2"
|
version = "0.5.2"
|
||||||
|
@ -3076,9 +3092,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tower-layer"
|
name = "tower-layer"
|
||||||
version = "0.3.2"
|
version = "0.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0"
|
checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tower-service"
|
name = "tower-service"
|
||||||
|
|
|
@ -47,7 +47,12 @@ thiserror = "1.0.62"
|
||||||
tokio = { version = "1.39", features = ["macros", "rt-multi-thread"] }
|
tokio = { version = "1.39", features = ["macros", "rt-multi-thread"] }
|
||||||
tokio-util = { version = "0.7.11", features = ["io"] }
|
tokio-util = { version = "0.7.11", features = ["io"] }
|
||||||
toml = "0.8.19"
|
toml = "0.8.19"
|
||||||
tower-http = { version = "0.5.2", features = ["compression-gzip", "fs"] }
|
tower = { version = "0.5.0" }
|
||||||
|
tower-http = { version = "0.5.2", features = [
|
||||||
|
"compression-gzip",
|
||||||
|
"fs",
|
||||||
|
"normalize-path",
|
||||||
|
] }
|
||||||
trie-rs = { version = "0.4.2", features = ["serde"] }
|
trie-rs = { version = "0.4.2", features = ["serde"] }
|
||||||
unicase = "2.7.0"
|
unicase = "2.7.0"
|
||||||
ureq = { version = "2.10.0", default-features = false, features = ["tls"] }
|
ureq = { version = "2.10.0", default-features = false, features = ["tls"] }
|
||||||
|
@ -86,7 +91,7 @@ embed-resource = "2.4.2"
|
||||||
winres = "0.1"
|
winres = "0.1"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
axum-test = "15.3"
|
axum-test = "15.7"
|
||||||
bytes = "1.7.1"
|
bytes = "1.7.1"
|
||||||
|
|
||||||
[profile.dev.package.sqlx-macros]
|
[profile.dev.package.sqlx-macros]
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
use axum::{extract::FromRef, Router};
|
use axum::{extract::FromRef, Router, ServiceExt};
|
||||||
use tower_http::{compression::CompressionLayer, services::ServeDir};
|
use tower::Layer;
|
||||||
|
use tower_http::{
|
||||||
|
compression::CompressionLayer,
|
||||||
|
normalize_path::{NormalizePath, NormalizePathLayer},
|
||||||
|
services::ServeDir,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::app::{self, App};
|
use crate::app::{self, App};
|
||||||
|
|
||||||
|
@ -11,25 +16,28 @@ mod version;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub mod test;
|
pub mod test;
|
||||||
|
|
||||||
pub fn make_router(app: App) -> Router {
|
pub fn make_router(app: App) -> NormalizePath<Router> {
|
||||||
let swagger = ServeDir::new(&app.swagger_dir_path);
|
let swagger = ServeDir::new(&app.swagger_dir_path);
|
||||||
|
|
||||||
let static_files = Router::new()
|
let static_files = Router::new()
|
||||||
.nest_service("/", ServeDir::new(&app.web_dir_path))
|
.nest_service("/", ServeDir::new(&app.web_dir_path))
|
||||||
.layer(CompressionLayer::new());
|
.layer(CompressionLayer::new());
|
||||||
|
|
||||||
Router::new()
|
let router = Router::new()
|
||||||
.nest("/api", api::router())
|
.nest("/api", api::router())
|
||||||
.with_state(app.clone())
|
.with_state(app.clone())
|
||||||
.nest_service("/swagger", swagger)
|
.nest_service("/swagger", swagger)
|
||||||
.nest("/", static_files)
|
.nest("/", static_files);
|
||||||
|
|
||||||
|
NormalizePathLayer::trim_trailing_slash().layer(router)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn launch(app: App) -> Result<(), std::io::Error> {
|
pub async fn launch(app: App) -> Result<(), std::io::Error> {
|
||||||
let port = app.port;
|
let port = app.port;
|
||||||
let router = make_router(app);
|
let router = make_router(app);
|
||||||
|
let make_service = ServiceExt::<axum::extract::Request>::into_make_service(router);
|
||||||
let listener = tokio::net::TcpListener::bind(format!("0.0.0.0:{port}")).await?;
|
let listener = tokio::net::TcpListener::bind(format!("0.0.0.0:{port}")).await?;
|
||||||
axum::serve(listener, router).await?;
|
axum::serve(listener, make_service).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,14 +76,7 @@ pub fn router() -> Router<App> {
|
||||||
.route("/songs", post(get_songs)) // post because of https://github.com/whatwg/fetch/issues/551
|
.route("/songs", post(get_songs)) // post because of https://github.com/whatwg/fetch/issues/551
|
||||||
.route("/peaks/*path", get(get_peaks))
|
.route("/peaks/*path", get(get_peaks))
|
||||||
.route("/thumbnail/*path", get(get_thumbnail))
|
.route("/thumbnail/*path", get(get_thumbnail))
|
||||||
// Workarounds
|
// Layers
|
||||||
// TODO figure out NormalizePathLayer and remove this
|
|
||||||
// See https://github.com/tokio-rs/axum/discussions/2833
|
|
||||||
.route("/browse/", get(get_browse_root))
|
|
||||||
.route("/flatten/", get(get_flatten_root))
|
|
||||||
.route("/random/", get(get_random))
|
|
||||||
.route("/recent/", get(get_recent))
|
|
||||||
.route("/search/", get(get_search_root))
|
|
||||||
.layer(CompressionLayer::new().quality(CompressionLevel::Fastest))
|
.layer(CompressionLayer::new().quality(CompressionLevel::Fastest))
|
||||||
.layer(DefaultBodyLimit::max(10 * 1024 * 1024)) // 10MB
|
.layer(DefaultBodyLimit::max(10 * 1024 * 1024)) // 10MB
|
||||||
// Uncompressed
|
// Uncompressed
|
||||||
|
|
|
@ -34,7 +34,8 @@ impl TestService for AxumTestService {
|
||||||
|
|
||||||
let app = App::new(5050, paths).await.unwrap();
|
let app = App::new(5050, paths).await.unwrap();
|
||||||
let router = make_router(app);
|
let router = make_router(app);
|
||||||
let server = TestServer::new(router).unwrap();
|
let make_service = ServiceExt::<axum::extract::Request>::into_make_service(router);
|
||||||
|
let server = TestServer::new(make_service).unwrap();
|
||||||
|
|
||||||
AxumTestService {
|
AxumTestService {
|
||||||
authorization: None,
|
authorization: None,
|
||||||
|
|
Loading…
Add table
Reference in a new issue