diff --git a/crates/core/src/extract/metadata.rs b/crates/core/src/extract/metadata.rs index aaf1dd085..9e98128cf 100644 --- a/crates/core/src/extract/metadata.rs +++ b/crates/core/src/extract/metadata.rs @@ -186,6 +186,14 @@ impl Metadata { self.rename_all = rename_all.into(); self } + + /// Check is this type has body required. + pub(crate) fn has_body_required(&self) -> bool { + if self.default_sources.iter().any(|s| s.from == SourceFrom::Body) { + return true; + } + self.fields.iter().any(|f| f.has_body_required()) + } } /// Information about struct field. @@ -249,6 +257,11 @@ impl Field { self.rename = Some(rename); self } + + /// Check is this field has body required. + pub(crate) fn has_body_required(&self) -> bool { + self.sources.iter().any(|s| s.from == SourceFrom::Body) + } } /// Request source for extract data. diff --git a/crates/core/src/serde/request.rs b/crates/core/src/serde/request.rs index 3ae328a73..dd629542c 100644 --- a/crates/core/src/serde/request.rs +++ b/crates/core/src/serde/request.rs @@ -23,8 +23,21 @@ where T: Deserialize<'de>, { // Ensure body is parsed correctly. - req.form_data().await.ok(); - req.payload().await.ok(); + if let Some(ctype) = req.content_type() { + match ctype.subtype() { + mime::WWW_FORM_URLENCODED | mime::FORM_DATA => { + if metadata.has_body_required() { + req.form_data().await.ok(); + } + } + mime::JSON => { + if metadata.has_body_required() { + req.payload().await.ok(); + } + } + _ => {} + } + } Ok(T::deserialize(RequestDeserializer::new(req, metadata)?)?) } @@ -58,14 +71,18 @@ impl<'de> RequestDeserializer<'de> { if let Some(ctype) = request.content_type() { match ctype.subtype() { mime::WWW_FORM_URLENCODED | mime::FORM_DATA => { - payload = request.form_data.get().map(Payload::FormData); + if metadata.has_body_required() { + payload = request.form_data.get().map(Payload::FormData); + } } mime::JSON => { - if let Some(data) = request.payload.get() { - payload = match serde_json::from_slice::>(data) { - Ok(map) => Some(Payload::JsonMap(map)), - Err(_) => Some(Payload::JsonStr(std::str::from_utf8(data)?)), - }; + if metadata.has_body_required() { + if let Some(data) = request.payload.get() { + payload = match serde_json::from_slice::>(data) { + Ok(map) => Some(Payload::JsonMap(map)), + Err(_) => Some(Payload::JsonStr(std::str::from_utf8(data)?)), + }; + } } } _ => {}