mirror of
https://github.com/tokio-rs/axum.git
synced 2026-08-28 00:00:20 +02:00
Fix integer underflow in try_range_response for empty files (#3566)
This commit is contained in:
Generated
+1
@@ -390,6 +390,7 @@ dependencies = [
|
||||
"serde_html_form",
|
||||
"serde_json",
|
||||
"serde_path_to_error",
|
||||
"tempfile",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"tokio-util",
|
||||
|
||||
@@ -120,6 +120,7 @@ hyper = "1.0.0"
|
||||
reqwest = { version = "0.12", default-features = false, features = ["json", "stream", "multipart"] }
|
||||
serde = { version = "1.0.221", features = ["derive"] }
|
||||
serde_json = "1.0.71"
|
||||
tempfile = "3.23.0"
|
||||
tokio = { version = "1.14", features = ["full"] }
|
||||
tower = { version = "0.5.2", features = ["util"] }
|
||||
tower-http = { version = "0.6.0", features = ["map-response-body", "timeout"] }
|
||||
|
||||
@@ -191,6 +191,10 @@ where
|
||||
let metadata = file.metadata().await?;
|
||||
let total_size = metadata.len();
|
||||
|
||||
if total_size == 0 {
|
||||
return Ok((StatusCode::RANGE_NOT_SATISFIABLE, "Range Not Satisfiable").into_response());
|
||||
}
|
||||
|
||||
if end == 0 {
|
||||
end = total_size - 1;
|
||||
}
|
||||
@@ -596,4 +600,52 @@ mod tests {
|
||||
}
|
||||
Some((start, end))
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn response_range_empty_file() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let file = tempfile::NamedTempFile::new()?;
|
||||
file.as_file().set_len(0)?;
|
||||
let path = file.path().to_owned();
|
||||
|
||||
let app = Router::new().route(
|
||||
"/range_empty",
|
||||
get(move |headers: HeaderMap| {
|
||||
let path = path.clone();
|
||||
async move {
|
||||
let range_header = headers
|
||||
.get(header::RANGE)
|
||||
.and_then(|value| value.to_str().ok());
|
||||
|
||||
let (start, end) = if let Some(range) = range_header {
|
||||
if let Some(range) = parse_range_header(range) {
|
||||
range
|
||||
} else {
|
||||
return (StatusCode::RANGE_NOT_SATISFIABLE, "Invalid Range")
|
||||
.into_response();
|
||||
}
|
||||
} else {
|
||||
(0, 0)
|
||||
};
|
||||
|
||||
FileStream::<ReaderStream<File>>::try_range_response(path, start, end)
|
||||
.await
|
||||
.unwrap_or_else(|_| StatusCode::INTERNAL_SERVER_ERROR.into_response())
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
let response = app
|
||||
.oneshot(
|
||||
Request::builder()
|
||||
.uri("/range_empty")
|
||||
.header(header::RANGE, "bytes=0-")
|
||||
.body(Body::empty())
|
||||
.unwrap(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(response.status(), StatusCode::RANGE_NOT_SATISFIABLE);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user