diff --git a/axum/Cargo.toml b/axum/Cargo.toml index 99076ae8828..b73cf3851bd 100644 --- a/axum/Cargo.toml +++ b/axum/Cargo.toml @@ -11,11 +11,13 @@ readme = "README.md" repository = "https://github.com/tokio-rs/axum" [features] -default = ["http1", "json", "tower-log"] +default = ["http1", "json", "matched-path", "original-uri", "tower-log"] http1 = ["hyper/http1"] http2 = ["hyper/http2"] json = ["serde_json"] +matched-path = [] multipart = ["multer"] +original-uri = [] tower-log = ["tower/log"] ws = ["tokio-tungstenite", "sha-1", "base64"] @@ -84,10 +86,10 @@ rustdoc-args = ["--cfg", "docsrs"] [package.metadata.playground] features = [ - "http1", - "http2", - "json", - "multipart", - "tower", - "ws", + "http1", + "http2", + "json", + "multipart", + "tower", + "ws", ] diff --git a/axum/src/extract/mod.rs b/axum/src/extract/mod.rs index 4fdd0ba0953..68ba94e4434 100644 --- a/axum/src/extract/mod.rs +++ b/axum/src/extract/mod.rs @@ -15,7 +15,6 @@ pub mod ws; mod content_length_limit; mod extension; mod form; -mod matched_path; mod query; mod raw_query; mod request_parts; @@ -31,17 +30,23 @@ pub use self::{ extension::Extension, extractor_middleware::extractor_middleware, form::Form, - matched_path::MatchedPath, path::Path, query::Query, raw_query::RawQuery, - request_parts::OriginalUri, request_parts::{BodyStream, RawBody}, }; #[doc(no_inline)] #[cfg(feature = "json")] pub use crate::Json; +#[cfg(feature = "matched-path")] +mod matched_path; + +#[cfg(feature = "matched-path")] +#[cfg_attr(docsrs, doc(cfg(feature = "matched-path")))] +#[doc(inline)] +pub use self::matched_path::MatchedPath; + #[cfg(feature = "multipart")] #[cfg_attr(docsrs, doc(cfg(feature = "multipart")))] pub mod multipart; @@ -51,6 +56,11 @@ pub mod multipart; #[doc(inline)] pub use self::multipart::Multipart; +#[cfg(feature = "original-uri")] +#[cfg_attr(docsrs, doc(cfg(feature = "original-uri")))] +#[doc(inline)] +pub use self::request_parts::OriginalUri; + #[cfg(feature = "ws")] #[cfg_attr(docsrs, doc(cfg(feature = "ws")))] #[doc(inline)] diff --git a/axum/src/extract/request_parts.rs b/axum/src/extract/request_parts.rs index 66e63d24998..b21576b6863 100644 --- a/axum/src/extract/request_parts.rs +++ b/axum/src/extract/request_parts.rs @@ -43,9 +43,11 @@ use sync_wrapper::SyncWrapper; /// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap(); /// # }; /// ``` +#[cfg(feature = "original-uri")] #[derive(Debug, Clone)] pub struct OriginalUri(pub Uri); +#[cfg(feature = "original-uri")] #[async_trait] impl FromRequest for OriginalUri where diff --git a/axum/src/lib.rs b/axum/src/lib.rs index 364ee095e6f..c2188841169 100644 --- a/axum/src/lib.rs +++ b/axum/src/lib.rs @@ -305,12 +305,16 @@ //! `http1` | Enables hyper's `http1` feature | Yes //! `http2` | Enables hyper's `http2` feature | No //! `json` | Enables the [`Json`] type and some similar convenience functionality | Yes +//! `matched-path` | Enables capturing of every request's router path and the [`MatchedPath`] extractor | Yes //! `multipart` | Enables parsing `multipart/form-data` requests with [`Multipart`] | No +//! `original-uri` | Enables capturing of every request's original URI and the [`OriginalUri`] extractor | Yes //! `tower-log` | Enables `tower`'s `log` feature | Yes //! `ws` | Enables WebSockets support via [`extract::ws`] | No //! //! [`TypedHeader`]: crate::extract::TypedHeader +//! [`MatchedPath`]: crate::extract::MatchedPath //! [`Multipart`]: crate::extract::Multipart +//! [`OriginalUri`]: crate::extract::OriginalUri //! [`tower`]: https://crates.io/crates/tower //! [`tower-http`]: https://crates.io/crates/tower-http //! [`tokio`]: http://crates.io/crates/tokio @@ -322,7 +326,6 @@ //! [examples]: https://github.com/tokio-rs/axum/tree/main/examples //! [`Router::merge`]: crate::routing::Router::merge //! [`axum::Server`]: hyper::server::Server -//! [`OriginalUri`]: crate::extract::OriginalUri //! [`Service`]: tower::Service //! [`Service::poll_ready`]: tower::Service::poll_ready //! [`Service`'s]: tower::Service diff --git a/axum/src/routing/mod.rs b/axum/src/routing/mod.rs index 7eac8c66ed4..7640131fc44 100644 --- a/axum/src/routing/mod.rs +++ b/axum/src/routing/mod.rs @@ -3,10 +3,7 @@ use self::{future::RouterFuture, not_found::NotFound}; use crate::{ body::{boxed, Body, Bytes, HttpBody}, - extract::{ - connect_info::{Connected, IntoMakeServiceWithConnectInfo}, - MatchedPath, OriginalUri, - }, + extract::connect_info::{Connected, IntoMakeServiceWithConnectInfo}, response::Response, routing::strip_prefix::StripPrefix, util::{try_downcast, ByteStr, PercentDecodedByteStr}, @@ -400,7 +397,10 @@ where let id = *match_.value; req.extensions_mut().insert(id); + #[cfg(feature = "matched-path")] if let Some(matched_path) = self.node.route_id_to_path.get(&id) { + use crate::extract::MatchedPath; + let matched_path = if let Some(previous) = req.extensions_mut().get::() { // a previous `MatchedPath` might exist if we're inside a nested Router let previous = if let Some(previous) = @@ -468,9 +468,14 @@ where #[inline] fn call(&mut self, mut req: Request) -> Self::Future { - if req.extensions().get::().is_none() { - let original_uri = OriginalUri(req.uri().clone()); - req.extensions_mut().insert(original_uri); + #[cfg(feature = "original-uri")] + { + use crate::extract::OriginalUri; + + if req.extensions().get::().is_none() { + let original_uri = OriginalUri(req.uri().clone()); + req.extensions_mut().insert(original_uri); + } } let path = req.uri().path().to_owned();