v0.34.0_1

This commit is contained in:
Mateusz Gruszczyński committed 2026-10-17 20:34:13 +02:00
1 parent 9b3d6731cc
commit 00f29f92c8
68 files changed
+2599 -513

No files matched your search

+51
View File
@@ -2225,3 +2225,54 @@ async fn cancelled_static_and_multipart_bodies_release_files_and_count_only_emit
assert_eq!(service.web_metrics.view()["response_bytes"], accounted);
}
}
#[cfg(target_os = "linux")]
#[tokio::test]
async fn sendfile_auto_without_tcp_bridge_preserves_full_head_range_and_validators() {
let tmp = TempDir::new().unwrap();
let original = vec![0x5au8; 128 * 1024 + 3];
std::fs::write(tmp.path().join("large.bin"), &original).unwrap();
let service = Service {
id: "sendfile-fallback".into(),
name: "Sendfile fallback".into(),
document_root: tmp.path().to_path_buf(),
sendfile: SendfileMode::Auto,
..Default::default()
}.compile().unwrap();
let get = serve_request(&service, &request(Method::GET, "/large.bin"), "/large.bin").await;
assert_eq!(get.status(), StatusCode::OK);
assert_eq!(get.headers()[CONTENT_LENGTH].to_str().unwrap(), original.len().to_string());
// No transport adapter here. Even if a candidate extension was produced,
// its fallback Body must still stream the exact original representation.
let etag = get.headers()[ETAG].clone();
assert_eq!(get.into_body().collect().await.unwrap().to_bytes().to_vec(), original);
let head = serve_request(&service, &request(Method::HEAD, "/large.bin"), "/large.bin").await;
assert_eq!(head.status(), StatusCode::OK);
assert_eq!(head.headers()[CONTENT_LENGTH].to_str().unwrap(), original.len().to_string());
assert!(head.into_body().collect().await.unwrap().to_bytes().is_empty());
let mut range = request(Method::GET, "/large.bin");
range.headers_mut().insert(RANGE, HeaderValue::from_static("bytes=100-199"));
let ranged = serve_request(&service, &range, "/large.bin").await;
assert_eq!(ranged.status(), StatusCode::PARTIAL_CONTENT);
assert_eq!(ranged.headers()[CONTENT_RANGE].to_str().unwrap(), format!("bytes 100-199/{}", original.len()));
assert_eq!(ranged.into_body().collect().await.unwrap().to_bytes().to_vec(), original[100..200]);
let mut conditional = request(Method::GET, "/large.bin");
conditional.headers_mut().insert(IF_NONE_MATCH, etag);
let unchanged = serve_request(&service, &conditional, "/large.bin").await;
assert_eq!(unchanged.status(), StatusCode::NOT_MODIFIED);
assert!(unchanged.into_body().collect().await.unwrap().to_bytes().is_empty());
}
#[test]
fn sendfile_mode_is_backward_compatible_and_rejects_unknown_values() {
assert_eq!(SendfileMode::default(), SendfileMode::Off);
assert_eq!(serde_json::from_str::<SendfileMode>("\"auto\"").unwrap(), SendfileMode::Auto);
assert_eq!(serde_json::from_str::<SendfileMode>("\"off\"").unwrap(), SendfileMode::Off);
assert!(serde_json::from_str::<SendfileMode>("\"unsafe\"").is_err());
let legacy = serde_json::json!({"id":"legacy", "name":"Legacy", "document_root":"/tmp"});
assert_eq!(serde_json::from_value::<Service>(legacy).unwrap().sendfile, SendfileMode::Off);
}