From 293ebfe7cc48fd2f2c42b9f1d254cc517d3d4c86 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Wed, 13 May 2020 00:42:23 +0100 Subject: [PATCH] ensure file responses using ranges have content-length header fixes #1384 --- actix-files/src/lib.rs | 134 +++++++++++---------------------------- actix-files/src/named.rs | 7 +- 2 files changed, 41 insertions(+), 100 deletions(-) diff --git a/actix-files/src/lib.rs b/actix-files/src/lib.rs index 6d2da6c73..490240df6 100644 --- a/actix-files/src/lib.rs +++ b/actix-files/src/lib.rs @@ -952,109 +952,58 @@ mod tests { #[actix_rt::test] async fn test_named_file_content_range_headers() { - let mut srv = test::init_service( - App::new().service(Files::new("/test", ".").index_file("tests/test.binary")), - ) - .await; + let srv = test::start(|| { + App::new().service(Files::new("/", ".").index_file("tests/test.binary")) + }); // Valid range header - let request = TestRequest::get() - .uri("/t%65st/tests/test.binary") + let response = srv + .get("/") .header(header::RANGE, "bytes=10-20") - .to_request(); - - let response = test::call_service(&mut srv, request).await; - let contentrange = response - .headers() - .get(header::CONTENT_RANGE) - .unwrap() - .to_str() + .send() + .await .unwrap(); - - assert_eq!(contentrange, "bytes 10-20/100"); + let content_range = response.headers().get(header::CONTENT_RANGE).unwrap(); + assert_eq!(content_range.to_str().unwrap(), "bytes 10-20/100"); // Invalid range header - let request = TestRequest::get() - .uri("/t%65st/tests/test.binary") + let response = srv + .get("/") .header(header::RANGE, "bytes=10-5") - .to_request(); - let response = test::call_service(&mut srv, request).await; - - let contentrange = response - .headers() - .get(header::CONTENT_RANGE) - .unwrap() - .to_str() + .send() + .await .unwrap(); - - assert_eq!(contentrange, "bytes */100"); + let content_range = response.headers().get(header::CONTENT_RANGE).unwrap(); + assert_eq!(content_range.to_str().unwrap(), "bytes */100"); } #[actix_rt::test] async fn test_named_file_content_length_headers() { - // use actix_web::body::{MessageBody, ResponseBody}; - - let mut srv = test::init_service( - App::new().service(Files::new("test", ".").index_file("tests/test.binary")), - ) - .await; + let srv = test::start(|| { + App::new().service(Files::new("/", ".").index_file("tests/test.binary")) + }); // Valid range header - let request = TestRequest::get() - .uri("/t%65st/tests/test.binary") + let response = srv + .get("/") .header(header::RANGE, "bytes=10-20") - .to_request(); - let _response = test::call_service(&mut srv, request).await; - - // let contentlength = response - // .headers() - // .get(header::CONTENT_LENGTH) - // .unwrap() - // .to_str() - // .unwrap(); - // assert_eq!(contentlength, "11"); - - // Invalid range header - let request = TestRequest::get() - .uri("/t%65st/tests/test.binary") - .header(header::RANGE, "bytes=10-8") - .to_request(); - let response = test::call_service(&mut srv, request).await; - assert_eq!(response.status(), StatusCode::RANGE_NOT_SATISFIABLE); + .send() + .await + .unwrap(); + let content_length = response.headers().get(header::CONTENT_LENGTH).unwrap(); + assert_eq!(content_length.to_str().unwrap(), "11"); // Without range header - let request = TestRequest::get() - .uri("/t%65st/tests/test.binary") - // .no_default_headers() - .to_request(); - let _response = test::call_service(&mut srv, request).await; + let mut response = srv.get("/").send().await.unwrap(); + let content_length = response.headers().get(header::CONTENT_LENGTH).unwrap(); + assert_eq!(content_length.to_str().unwrap(), "100"); - // let contentlength = response - // .headers() - // .get(header::CONTENT_LENGTH) - // .unwrap() - // .to_str() - // .unwrap(); - // assert_eq!(contentlength, "100"); + // Should be no transfer-encoding + let transfer_encoding = response.headers().get(header::TRANSFER_ENCODING); + assert!(transfer_encoding.is_none()); - // chunked - let request = TestRequest::get() - .uri("/t%65st/tests/test.binary") - .to_request(); - let response = test::call_service(&mut srv, request).await; - - // with enabled compression - // { - // let te = response - // .headers() - // .get(header::TRANSFER_ENCODING) - // .unwrap() - // .to_str() - // .unwrap(); - // assert_eq!(te, "chunked"); - // } - - let bytes = test::read_body(response).await; + // Check file contents + let bytes = response.body().await.unwrap(); let data = Bytes::from(fs::read("tests/test.binary").unwrap()); assert_eq!(bytes, data); } @@ -1062,25 +1011,16 @@ mod tests { #[actix_rt::test] async fn test_head_content_length_headers() { let mut srv = test::init_service( - App::new().service(Files::new("test", ".").index_file("tests/test.binary")), + App::new().service(Files::new("/", ".").index_file("tests/test.binary")), ) .await; - // Valid range header - let request = TestRequest::default() - .method(Method::HEAD) - .uri("/t%65st/tests/test.binary") - .to_request(); + let request = TestRequest::default().method(Method::HEAD).to_request(); let _response = test::call_service(&mut srv, request).await; // TODO: fix check - // let contentlength = response - // .headers() - // .get(header::CONTENT_LENGTH) - // .unwrap() - // .to_str() - // .unwrap(); - // assert_eq!(contentlength, "100"); + // let content_length = res.headers().get(header::CONTENT_LENGTH).unwrap(); + // assert_eq!(content_length.to_str().unwrap(), "100"); } #[actix_rt::test] diff --git a/actix-files/src/named.rs b/actix-files/src/named.rs index fdb055998..e05316904 100644 --- a/actix-files/src/named.rs +++ b/actix-files/src/named.rs @@ -388,11 +388,12 @@ impl NamedFile { fut: None, counter: 0, }; + if offset != 0 || length != self.md.len() { - Ok(resp.status(StatusCode::PARTIAL_CONTENT).streaming(reader)) - } else { - Ok(resp.body(SizedStream::new(length, reader))) + resp.status(StatusCode::PARTIAL_CONTENT); } + + Ok(resp.body(SizedStream::new(length, reader))) } }