mirror of
https://github.com/tokio-rs/axum.git
synced 2025-01-16 14:33:02 +01:00
Optional extractor extensions (#685)
* Fix inconsistent indentation in axum/Cargo.toml * Make MatchedPath and OriginalUri extractors and logic for them optional … they add some runtime cost to handling any request that goes through a Router, which only makes sense if they actually get used. Enable both features by default for convenience.
This commit is contained in:
parent
d97f2aeae6
commit
e0a463b463
5 changed files with 41 additions and 21 deletions
|
@ -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",
|
||||
]
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -80,9 +80,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<B> FromRequest<B> for OriginalUri
|
||||
where
|
||||
|
|
|
@ -375,12 +375,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
|
||||
|
@ -392,7 +396,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
|
||||
|
|
|
@ -3,13 +3,8 @@
|
|||
use self::{future::RouterFuture, not_found::NotFound};
|
||||
use crate::{
|
||||
body::{boxed, Body, Bytes, HttpBody},
|
||||
extract::{
|
||||
connect_info::{Connected, IntoMakeServiceWithConnectInfo},
|
||||
MatchedPath, OriginalUri,
|
||||
},
|
||||
response::IntoResponse,
|
||||
response::Redirect,
|
||||
response::Response,
|
||||
extract::connect_info::{Connected, IntoMakeServiceWithConnectInfo},
|
||||
response::{Response, Redirect, IntoResponse},
|
||||
routing::strip_prefix::StripPrefix,
|
||||
util::{try_downcast, ByteStr, PercentDecodedByteStr},
|
||||
BoxError,
|
||||
|
@ -405,7 +400,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::<MatchedPath>() {
|
||||
// a previous `MatchedPath` might exist if we're inside a nested Router
|
||||
let previous = if let Some(previous) =
|
||||
|
@ -476,9 +474,14 @@ where
|
|||
|
||||
#[inline]
|
||||
fn call(&mut self, mut req: Request<B>) -> Self::Future {
|
||||
if req.extensions().get::<OriginalUri>().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::<OriginalUri>().is_none() {
|
||||
let original_uri = OriginalUri(req.uri().clone());
|
||||
req.extensions_mut().insert(original_uri);
|
||||
}
|
||||
}
|
||||
|
||||
let path = req.uri().path().to_owned();
|
||||
|
|
Loading…
Reference in a new issue