Skip to content

Commit 92c1593

Browse files
fix!: ignore unparseable Range headers instead of returning 400
Per RFC 9110 Section 14.2, a server that receives a Range header it cannot parse or does not support (unknown range unit, multiple ranges, malformed values) must ignore the header and serve the full representation. The axum extractor was previously propagating all parse errors as rejections, which mapped to 400 Bad Request responses. Change the extractor to return Ok(None) for any unparseable Range header, so the server falls back to serving the complete resource.
1 parent 21a3c12 commit 92c1593

1 file changed

Lines changed: 18 additions & 9 deletions

File tree

src/headers/range.rs

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#[cfg(feature = "axum")]
2+
use std::convert::Infallible;
13
use std::{
24
fmt::{self, Display},
35
str::FromStr,
@@ -84,19 +86,26 @@ impl<S> axum_core::extract::OptionalFromRequestParts<S> for HttpRange
8486
where
8587
S: Send + Sync,
8688
{
87-
type Rejection = ParseHttpRangeOrContentRangeError;
88-
89+
type Rejection = Infallible;
90+
91+
/// Extracts an optional [`HttpRange`] from the request's `Range` header.
92+
///
93+
/// Per [RFC 9110 Section 14.2], a server that receives a `Range` header it
94+
/// cannot parse or does not support (unknown range unit, multiple ranges,
95+
/// malformed values) **must** ignore the header and serve the full
96+
/// representation. This extractor returns `Ok(None)` in all such cases
97+
/// instead of rejecting the request.
98+
///
99+
/// [RFC 9110 Section 14.2]: https://www.rfc-editor.org/rfc/rfc9110#section-14.2
89100
async fn from_request_parts(
90101
parts: &mut http::request::Parts,
91102
_state: &S,
92103
) -> Result<Option<Self>, Self::Rejection> {
93-
match parts.headers.get(http::header::RANGE) {
94-
Some(range) => {
95-
let range = HttpRange::try_from(range)?;
96-
Ok(Some(range))
97-
}
98-
None => Ok(None),
99-
}
104+
let range = parts
105+
.headers
106+
.get(http::header::RANGE)
107+
.and_then(|range| HttpRange::try_from(range).ok());
108+
Ok(range)
100109
}
101110
}
102111

0 commit comments

Comments
 (0)