diff --git a/Cargo.lock b/Cargo.lock index 1df6b2c..0347172 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -367,9 +367,9 @@ dependencies = [ [[package]] name = "axum" -version = "0.6.12" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349f8ccfd9221ee7d1f3d4b33e1f8319b3a81ed8f61f2ea40b37b859794b4491" +checksum = "f8175979259124331c1d7bf6586ee7e0da434155e4b2d48ec2c8386281d8df39" dependencies = [ "async-trait", "axum-core", @@ -1607,6 +1607,7 @@ dependencies = [ "tokio-stream", "tower", "tower-http", + "tower-service", "tracing", "tracing-subscriber", "url", diff --git a/Cargo.toml b/Cargo.toml index b90a5bc..e69b9d7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ name = "s3-active-storage" version = "0.1.0" edition = "2021" # Due to AWS SDK. -rust-version = "1.62.1" +rust-version = "1.66.1" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -14,8 +14,7 @@ aws-sdk-s3 = "0.27" aws-smithy-http = "0.55" aws-smithy-types = "0.55" aws-types = "0.55" -# Axum 0.6.13 introduced a change in behaviour around trimming trailing paths. -axum = { version = "=0.6.12", features = ["headers"] } +axum = { version = "0.6", features = ["headers"] } axum-server = { version = "0.4.7", features = ["tls-rustls"] } clap = { version = "4.2", features = ["derive", "env"] } expanduser = "1.2.2" @@ -33,6 +32,7 @@ thiserror = "1.0" tokio = { version = "1.28", features = ["full"] } tower = "0.4" tower-http = { version = "0.4", features = ["normalize-path", "trace", "validate-request"] } +tower-service = "0.3" tokio-stream = "0.1" tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } diff --git a/src/app.rs b/src/app.rs index d88c147..9f85492 100644 --- a/src/app.rs +++ b/src/app.rs @@ -19,6 +19,7 @@ use axum::{ Router, TypedHeader, }; +use tower::Layer; use tower::ServiceBuilder; use tower_http::normalize_path::NormalizePathLayer; use tower_http::trace::TraceLayer; @@ -54,9 +55,7 @@ impl IntoResponse for models::Response { /// * a [tower_http::trace::TraceLayer] for tracing requests and responses /// * a [tower_http::validate_request::ValidateRequestHeaderLayer] for validating authorisation /// headers -/// * a [tower_http::normalize_path::NormalizePathLayer] for trimming trailing slashes from -/// requests -pub fn router() -> Router { +fn router() -> Router { fn v1() -> Router { Router::new() .route("/count", post(operation_handler::)) @@ -85,7 +84,25 @@ pub fn router() -> Router { Router::new() .route("/.well-known/s3-active-storage-schema", get(schema)) .nest("/v1", v1()) - .layer(NormalizePathLayer::trim_trailing_slash()) +} + +/// Returns a [tower_service::Service] for the Active Storage server API +/// +/// The service is populated with all routes as well as the following middleware: +/// +/// * a [tower_http::trace::TraceLayer] for tracing requests and responses +/// * a [tower_http::validate_request::ValidateRequestHeaderLayer] for validating authorisation +/// headers +/// * a [tower_http::normalize_path::NormalizePathLayer] for trimming trailing slashes from +/// requests +pub fn service() -> tower_http::normalize_path::NormalizePath { + // FIXME: The return type should be some form of tower_service::Service, but couldn't find the + // necessary trait bounds. + + // Note that any middleware that should affect routing must wrap the router. + // See + // https://docs.rs/axum/0.6.18/axum/middleware/index.html#rewriting-request-uri-in-middleware. + NormalizePathLayer::trim_trailing_slash().layer(router()) } /// TODO: Return an OpenAPI schema diff --git a/src/main.rs b/src/main.rs index 564dfa2..26bc0bc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,6 +24,7 @@ use std::{net::SocketAddr, process::exit, str::FromStr, time::Duration}; +use axum::ServiceExt; use axum_server::{tls_rustls::RustlsConfig, Handle}; use clap::Parser; use expanduser::expanduser; @@ -77,7 +78,7 @@ async fn main() { init_tracing(); - let router = app::router(); + let service = app::service(); let addr = SocketAddr::from_str(&format!("{}:{}", args.host, args.port)) .expect("invalid host name, IP address or port number"); @@ -120,14 +121,14 @@ async fn main() { // run HTTPS server with hyper axum_server::bind_rustls(addr, tls_config) .handle(handle) - .serve(router.into_make_service()) + .serve(service.into_make_service()) .await .unwrap(); } else { // run HTTP server with hyper axum_server::bind(addr) .handle(handle) - .serve(router.into_make_service()) + .serve(service.into_make_service()) .await .unwrap(); }