Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optional extractors #685

Merged
merged 2 commits into from
Jan 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions axum/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"]

Expand Down Expand Up @@ -84,10 +86,10 @@ rustdoc-args = ["--cfg", "docsrs"]

[package.metadata.playground]
features = [
"http1",
"http2",
"json",
"multipart",
"tower",
"ws",
"http1",
"http2",
"json",
"multipart",
"tower",
"ws",
]
16 changes: 13 additions & 3 deletions axum/src/extract/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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)]
Expand Down
2 changes: 2 additions & 0 deletions axum/src/extract/request_parts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<B> FromRequest<B> for OriginalUri
where
Expand Down
5 changes: 4 additions & 1 deletion axum/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
19 changes: 12 additions & 7 deletions axum/src/routing/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down Expand Up @@ -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::<MatchedPath>() {
// a previous `MatchedPath` might exist if we're inside a nested Router
let previous = if let Some(previous) =
Expand Down Expand Up @@ -468,9 +468,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();
Expand Down