Skip to content

Commit 8a716e1

Browse files
test(downloads): check if an error is thrown if the server does not honor range
1 parent 9c16c78 commit 8a716e1

1 file changed

Lines changed: 41 additions & 7 deletions

File tree

src/download/tests.rs

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ mod curl {
5757
let target_path = tmpdir.path().join("downloaded");
5858
write_file(&target_path, "123");
5959

60-
let addr = serve_file(b"xxx45".to_vec());
60+
let addr = serve_file(b"xxx45".to_vec(), true);
6161

6262
let from_url = format!("http://{addr}").parse().unwrap();
6363

@@ -213,7 +213,7 @@ mod reqwest {
213213
let target_path = tmpdir.path().join("downloaded");
214214
write_file(&target_path, "123");
215215

216-
let addr = serve_file(b"xxx45".to_vec());
216+
let addr = serve_file(b"xxx45".to_vec(), true);
217217

218218
let from_url = format!("http://{addr}").parse().unwrap();
219219

@@ -258,6 +258,33 @@ mod reqwest {
258258
assert_eq!(std::fs::read_to_string(&target_path).unwrap(), "12345");
259259
}
260260

261+
#[tokio::test]
262+
async fn resume_partial_fails_if_server_ignores_range() {
263+
let _guard = scrub_env().await;
264+
let tmpdir = tmp_dir();
265+
let target_path = tmpdir.path().join("downloaded");
266+
write_file(&target_path, "123");
267+
268+
let addr = serve_file(b"xxx45".to_vec(), false);
269+
let from_url = format!("http://{addr}").parse().unwrap();
270+
271+
Backend::Reqwest(TlsBackend::NativeTls)
272+
.download_to_path(
273+
&from_url,
274+
&target_path,
275+
true,
276+
None,
277+
Duration::from_secs(180),
278+
)
279+
.await
280+
.expect_err("download should fail if server ignores range");
281+
282+
assert!(
283+
!target_path.exists(),
284+
"partial file should have been deleted"
285+
);
286+
}
287+
261288
#[tokio::test]
262289
async fn network_failure_does_not_delete_partial_file() {
263290
let _guard = scrub_env().await;
@@ -299,11 +326,16 @@ pub fn write_file(path: &Path, contents: &str) {
299326
// A dead simple hyper server implementation.
300327
// For more info, see:
301328
// https://hyper.rs/guides/1/server/hello-world/
302-
async fn run_server(addr_tx: Sender<SocketAddr>, addr: SocketAddr, contents: Vec<u8>) {
329+
async fn run_server(
330+
addr_tx: Sender<SocketAddr>,
331+
addr: SocketAddr,
332+
contents: Vec<u8>,
333+
honor_range: bool,
334+
) {
303335
let svc = service_fn(move |req: Request<hyper::body::Incoming>| {
304336
let contents = contents.clone();
305337
async move {
306-
let res = serve_contents(req, contents);
338+
let res = serve_contents(req, contents, honor_range);
307339
Ok::<_, Infallible>(res)
308340
}
309341
});
@@ -331,12 +363,12 @@ async fn run_server(addr_tx: Sender<SocketAddr>, addr: SocketAddr, contents: Vec
331363
}
332364
}
333365

334-
pub fn serve_file(contents: Vec<u8>) -> SocketAddr {
366+
pub fn serve_file(contents: Vec<u8>, honor_range: bool) -> SocketAddr {
335367
let addr = ([127, 0, 0, 1], 0).into();
336368
let (addr_tx, addr_rx) = channel();
337369

338370
thread::spawn(move || {
339-
let server = run_server(addr_tx, addr, contents);
371+
let server = run_server(addr_tx, addr, contents, honor_range);
340372
let rt = tokio::runtime::Runtime::new().expect("could not creating Runtime");
341373
rt.block_on(server);
342374
});
@@ -348,9 +380,11 @@ pub fn serve_file(contents: Vec<u8>) -> SocketAddr {
348380
fn serve_contents(
349381
req: Request<hyper::body::Incoming>,
350382
contents: Vec<u8>,
383+
honor_range: bool,
351384
) -> hyper::Response<Full<Bytes>> {
352385
let mut range_header = None;
353-
let (status, body) = if let Some(range) = req.headers().get(hyper::header::RANGE) {
386+
let (status, body) = if honor_range && let Some(range) = req.headers().get(hyper::header::RANGE)
387+
{
354388
// extract range "bytes={start}-"
355389
let range = range.to_str().expect("unexpected Range header");
356390
assert!(range.starts_with("bytes="));

0 commit comments

Comments
 (0)