axum: support RawForm extraction from HEAD query strings (#3772)

Co-authored-by: Mira Sato <[email protected]>
This commit is contained in:
oab24413gmai
2026-07-23 22:12:25 +00:00
committed by GitHub
co-authored by Mira Sato
parent 502aa875b7
commit 8ef714c12b
+21 -4
View File
@@ -9,8 +9,8 @@ use super::{
/// Extractor that extracts raw form requests. /// Extractor that extracts raw form requests.
/// ///
/// For `GET` requests it will extract the raw query. For other methods it extracts the raw /// For `GET` and `HEAD` requests it will extract the raw query. For other methods it extracts the
/// `application/x-www-form-urlencoded` encoded request body. /// raw `application/x-www-form-urlencoded` encoded request body.
/// ///
/// # Example /// # Example
/// ///
@@ -36,7 +36,7 @@ where
type Rejection = RawFormRejection; type Rejection = RawFormRejection;
async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> { async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {
if req.method() == Method::GET { if req.method() == Method::GET || req.method() == Method::HEAD {
if let Some(query) = req.uri().query() { if let Some(query) = req.uri().query() {
return Ok(Self(Bytes::copy_from_slice(query.as_bytes()))); return Ok(Self(Bytes::copy_from_slice(query.as_bytes())));
} }
@@ -55,7 +55,7 @@ where
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use axum_core::body::Body; use axum_core::body::Body;
use http::{header::CONTENT_TYPE, Request}; use http::{header::CONTENT_TYPE, Method, Request};
use super::{InvalidFormContentType, RawForm, RawFormRejection}; use super::{InvalidFormContentType, RawForm, RawFormRejection};
@@ -67,6 +67,16 @@ mod tests {
assert_eq!(RawForm::from_request(req, &()).await.unwrap().0, value); assert_eq!(RawForm::from_request(req, &()).await.unwrap().0, value);
} }
async fn check_head_query(uri: &str, value: &[u8]) {
let req = Request::builder()
.method(Method::HEAD)
.uri(uri)
.body(Body::empty())
.unwrap();
assert_eq!(RawForm::from_request(req, &()).await.unwrap().0, value);
}
async fn check_body(body: &'static [u8]) { async fn check_body(body: &'static [u8]) {
let req = Request::post("http://example.com/test") let req = Request::post("http://example.com/test")
.header(CONTENT_TYPE, mime::APPLICATION_WWW_FORM_URLENCODED.as_ref()) .header(CONTENT_TYPE, mime::APPLICATION_WWW_FORM_URLENCODED.as_ref())
@@ -83,6 +93,13 @@ mod tests {
check_query("http://example.com/test?page=0&size=10", b"page=0&size=10").await; check_query("http://example.com/test?page=0&size=10", b"page=0&size=10").await;
} }
#[crate::test]
async fn test_from_head_query() {
check_head_query("http://example.com/test", b"").await;
check_head_query("http://example.com/test?page=0&size=10", b"page=0&size=10").await;
}
#[crate::test] #[crate::test]
async fn test_from_body() { async fn test_from_body() {
check_body(b"").await; check_body(b"").await;