1 #![doc = include_str!("../docs/extract.md")]
2 
3 use http::header::{self, HeaderMap};
4 
5 #[cfg(feature = "tokio")]
6 pub mod connect_info;
7 pub mod path;
8 pub mod rejection;
9 
10 #[cfg(feature = "ws")]
11 pub mod ws;
12 
13 mod host;
14 mod raw_form;
15 mod raw_query;
16 mod request_parts;
17 mod state;
18 
19 #[doc(inline)]
20 pub use axum_core::extract::{DefaultBodyLimit, FromRef, FromRequest, FromRequestParts};
21 
22 #[cfg(feature = "macros")]
23 pub use axum_macros::{FromRef, FromRequest, FromRequestParts};
24 
25 #[doc(inline)]
26 #[allow(deprecated)]
27 pub use self::{
28     host::Host,
29     path::{Path, RawPathParams},
30     raw_form::RawForm,
31     raw_query::RawQuery,
32     request_parts::{BodyStream, RawBody},
33     state::State,
34 };
35 
36 #[doc(inline)]
37 #[cfg(feature = "tokio")]
38 pub use self::connect_info::ConnectInfo;
39 
40 #[doc(no_inline)]
41 #[cfg(feature = "json")]
42 pub use crate::Json;
43 
44 #[doc(no_inline)]
45 pub use crate::Extension;
46 
47 #[cfg(feature = "form")]
48 #[doc(no_inline)]
49 pub use crate::form::Form;
50 
51 #[cfg(feature = "matched-path")]
52 pub(crate) mod matched_path;
53 
54 #[cfg(feature = "matched-path")]
55 #[doc(inline)]
56 pub use self::matched_path::MatchedPath;
57 
58 #[cfg(feature = "multipart")]
59 pub mod multipart;
60 
61 #[cfg(feature = "multipart")]
62 #[doc(inline)]
63 pub use self::multipart::Multipart;
64 
65 #[cfg(feature = "query")]
66 mod query;
67 
68 #[cfg(feature = "query")]
69 #[doc(inline)]
70 pub use self::query::Query;
71 
72 #[cfg(feature = "original-uri")]
73 #[doc(inline)]
74 pub use self::request_parts::OriginalUri;
75 
76 #[cfg(feature = "ws")]
77 #[doc(inline)]
78 pub use self::ws::WebSocketUpgrade;
79 
80 #[cfg(feature = "headers")]
81 #[doc(no_inline)]
82 pub use crate::TypedHeader;
83 
84 // this is duplicated in `axum-extra/src/extract/form.rs`
has_content_type(headers: &HeaderMap, expected_content_type: &mime::Mime) -> bool85 pub(super) fn has_content_type(headers: &HeaderMap, expected_content_type: &mime::Mime) -> bool {
86     let content_type = if let Some(content_type) = headers.get(header::CONTENT_TYPE) {
87         content_type
88     } else {
89         return false;
90     };
91 
92     let content_type = if let Ok(content_type) = content_type.to_str() {
93         content_type
94     } else {
95         return false;
96     };
97 
98     content_type.starts_with(expected_content_type.as_ref())
99 }
100 
101 #[cfg(test)]
102 mod tests {
103     use crate::{routing::get, test_helpers::*, Router};
104 
105     #[crate::test]
consume_body()106     async fn consume_body() {
107         let app = Router::new().route("/", get(|body: String| async { body }));
108 
109         let client = TestClient::new(app);
110         let res = client.get("/").body("foo").send().await;
111         let body = res.text().await;
112 
113         assert_eq!(body, "foo");
114     }
115 }
116