Skip to content

Commit 93e6426

Browse files
authored
Merge pull request #47 from UMEssen/trim-trailing-slashes
Trim trailing slashes
2 parents 0739fe7 + cc39f83 commit 93e6426

3 files changed

Lines changed: 14 additions & 3 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1111

1212
- QIDO-RS and MWL services now support `uid-list-matching` syntax for match query parameters.
1313

14+
### Changed
15+
16+
- Trailing slashes in URLs are now trimmed for all endpoints before processing (`/studies/` and `/studies` are equivalent).
17+
1418
## [0.3.0]
1519

1620
### Added

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ axum-extra = { version = "0.10.3", features = ["query"] }
4242
axum-streams = { version = "0.23.1", features = ["json"] }
4343
futures = "0.3.31"
4444
mime = "0.3.17"
45-
tower-http = { version = "0.6.6", features = ["trace", "cors", "timeout"] }
45+
tower-http = { version = "0.6.6", features = ["trace", "cors", "timeout", "normalize-path"] }
4646
tower = { version = "0.5.2", features = ["limit"] }
4747
url = "2.5.7"
4848
async-trait = "0.1.89"

src/main.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,15 @@ use crate::types::AE;
1313
use association::pool::AssociationPools;
1414
use axum::extract::{DefaultBodyLimit, Request};
1515
use axum::response::Response;
16+
use axum::routing::IntoMakeService;
17+
use axum::ServiceExt;
1618
use std::net::SocketAddr;
1719
use std::time::Duration;
1820
use tokio::net::TcpListener;
1921
use tokio::signal;
22+
use tower::Layer;
2023
use tower_http::cors::CorsLayer;
24+
use tower_http::normalize_path::NormalizePathLayer;
2125
use tower_http::timeout::TimeoutLayer;
2226
use tower_http::trace;
2327
use tracing::{error, info, level_filters::LevelFilter, Level};
@@ -144,6 +148,9 @@ async fn run(config: AppConfig) -> anyhow::Result<()> {
144148
)))
145149
.with_state(app_state);
146150

151+
let app = NormalizePathLayer::trim_trailing_slash().layer(app);
152+
let service = ServiceExt::<Request>::into_make_service(app);
153+
147154
let HttpServerConfig {
148155
interface: host,
149156
port,
@@ -159,11 +166,11 @@ async fn run(config: AppConfig) -> anyhow::Result<()> {
159166
"Started DICOMweb server"
160167
);
161168
if config.server.http.graceful_shutdown {
162-
axum::serve(listener, app)
169+
axum::serve(listener, service)
163170
.with_graceful_shutdown(shutdown_signal())
164171
.await?;
165172
} else {
166-
axum::serve(listener, app).await?;
173+
axum::serve(listener, service).await?;
167174
}
168175

169176
Ok(())

0 commit comments

Comments
 (0)