From 6560a2285faa11a5416f1207e15dac95055775f0 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 26 May 2020 17:13:35 +0900 Subject: [PATCH 1/5] Suppress warning --- actix-files/src/error.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/actix-files/src/error.rs b/actix-files/src/error.rs index 49a46e58d..9b30cbaa2 100644 --- a/actix-files/src/error.rs +++ b/actix-files/src/error.rs @@ -5,6 +5,7 @@ use derive_more::Display; #[derive(Display, Debug, PartialEq)] pub enum FilesError { /// Path is not a directory + #[allow(dead_code)] #[display(fmt = "Path is not a directory. Unable to serve static files")] IsNotDirectory, From 7870165da2953ca5896fc8ab3b19bd2f688bd69a Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 26 May 2020 17:14:33 +0900 Subject: [PATCH 2/5] Fix spelling error --- actix-files/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actix-files/src/lib.rs b/actix-files/src/lib.rs index d910b7d5f..6d2da6c73 100644 --- a/actix-files/src/lib.rs +++ b/actix-files/src/lib.rs @@ -521,7 +521,7 @@ impl Service for FilesService { Err(e) => return Either::Left(ok(req.error_response(e))), }; - // full filepath + // full file path let path = match self.directory.join(&real_path.0).canonicalize() { Ok(path) => path, Err(e) => return self.handle_err(e, req), From 60dcfd1affa13c0f710df3d7303e2b0db426543c Mon Sep 17 00:00:00 2001 From: Omid Rad Date: Sun, 17 May 2020 23:54:42 +0200 Subject: [PATCH 3/5] Actix-files will always send SizedStream (#1496) * Fixes #1384 * There is no need to set no_chunking * Test content-length for static files * Update the tests * Add Changelog * Try to simply fix Windows test issues! Co-authored-by: Rob Ede --- actix-files/CHANGES.md | 3 + actix-files/src/lib.rs | 159 ++++++++++++++------------------------- actix-files/src/named.rs | 7 +- 3 files changed, 65 insertions(+), 104 deletions(-) diff --git a/actix-files/CHANGES.md b/actix-files/CHANGES.md index c4918b56d..263776dab 100644 --- a/actix-files/CHANGES.md +++ b/actix-files/CHANGES.md @@ -3,6 +3,9 @@ ## [0.2.1] - 2019-12-22 * Use the same format for file URLs regardless of platforms +* Support sending Content-Length when Content-Range is specified [#1384] + +[#1384]: https://github.com/actix/actix-web/pull/1384 ## [0.2.0] - 2019-12-20 diff --git a/actix-files/src/lib.rs b/actix-files/src/lib.rs index 6d2da6c73..27ec6c583 100644 --- a/actix-files/src/lib.rs +++ b/actix-files/src/lib.rs @@ -952,135 +952,92 @@ 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("/", ".")) + }); // Valid range header - let request = TestRequest::get() - .uri("/t%65st/tests/test.binary") + let response = srv + .get("/tests/test.binary") .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("/tests/test.binary") .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("/", ".")) + }); // Valid range header - let request = TestRequest::get() - .uri("/t%65st/tests/test.binary") + let response = srv + .get("/tests/test.binary") .header(header::RANGE, "bytes=10-20") - .to_request(); - let _response = test::call_service(&mut srv, request).await; + .send() + .await + .unwrap(); + let content_length = response.headers().get(header::CONTENT_LENGTH).unwrap(); + assert_eq!(content_length.to_str().unwrap(), "11"); - // 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); + // Valid range header, starting from 0 + let response = srv + .get("/tests/test.binary") + .header(header::RANGE, "bytes=0-20") + .send() + .await + .unwrap(); + let content_length = response.headers().get(header::CONTENT_LENGTH).unwrap(); + assert_eq!(content_length.to_str().unwrap(), "21"); // 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("/tests/test.binary").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); } #[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")), - ) - .await; + let srv = test::start(|| { + App::new().service(Files::new("/", ".")) + }); - // Valid range header - let request = TestRequest::default() - .method(Method::HEAD) - .uri("/t%65st/tests/test.binary") - .to_request(); - let _response = test::call_service(&mut srv, request).await; + let response = srv + .head("/tests/test.binary") + .send() + .await + .unwrap(); - // TODO: fix check - // let contentlength = response - // .headers() - // .get(header::CONTENT_LENGTH) - // .unwrap() - // .to_str() - // .unwrap(); - // assert_eq!(contentlength, "100"); + let content_length = response + .headers() + .get(header::CONTENT_LENGTH) + .unwrap() + .to_str() + .unwrap(); + + assert_eq!(content_length, "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))) } } From a8117183bb6916ba83f3f9f131c68c5706bea1dc Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Mon, 18 May 2020 11:41:07 +0900 Subject: [PATCH 4/5] files: Minimize `futures` dependencies --- actix-files/Cargo.toml | 3 ++- actix-files/src/lib.rs | 4 ++-- actix-files/src/named.rs | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/actix-files/Cargo.toml b/actix-files/Cargo.toml index 104eb3dfa..f2e6c1f70 100644 --- a/actix-files/Cargo.toml +++ b/actix-files/Cargo.toml @@ -23,7 +23,8 @@ actix-http = "1.0.1" actix-service = "1.0.1" bitflags = "1" bytes = "0.5.3" -futures = "0.3.1" +futures-core = { version = "0.3.5", default-features = false } +futures-util = { version = "0.3.5", default-features = false } derive_more = "0.99.2" log = "0.4" mime = "0.3" diff --git a/actix-files/src/lib.rs b/actix-files/src/lib.rs index 27ec6c583..76c68ce25 100644 --- a/actix-files/src/lib.rs +++ b/actix-files/src/lib.rs @@ -24,8 +24,8 @@ use actix_web::http::header::{self, DispositionType}; use actix_web::http::Method; use actix_web::{web, FromRequest, HttpRequest, HttpResponse}; use bytes::Bytes; -use futures::future::{ok, ready, Either, FutureExt, LocalBoxFuture, Ready}; -use futures::Stream; +use futures_core::Stream; +use futures_util::future::{ok, ready, Either, FutureExt, LocalBoxFuture, Ready}; use mime; use mime_guess::from_ext; use percent_encoding::{utf8_percent_encode, CONTROLS}; diff --git a/actix-files/src/named.rs b/actix-files/src/named.rs index e05316904..6ee561a4b 100644 --- a/actix-files/src/named.rs +++ b/actix-files/src/named.rs @@ -18,7 +18,7 @@ use actix_web::http::header::{ }; use actix_web::http::{ContentEncoding, StatusCode}; use actix_web::{Error, HttpMessage, HttpRequest, HttpResponse, Responder}; -use futures::future::{ready, Ready}; +use futures_util::future::{ready, Ready}; use crate::range::HttpRange; use crate::ChunkedReadFile; From 55d79cc1b23bc07471fdac4c6d84d288141d09d3 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 26 May 2020 17:22:16 +0900 Subject: [PATCH 5/5] files: Bump up to 0.2.2 --- actix-files/CHANGES.md | 11 ++++++++--- actix-files/Cargo.toml | 6 +++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/actix-files/CHANGES.md b/actix-files/CHANGES.md index 263776dab..c6b6e722b 100644 --- a/actix-files/CHANGES.md +++ b/actix-files/CHANGES.md @@ -1,11 +1,16 @@ # Changes +## [0.2.2] - 2020-05-26 + +* Minimize `futures` dependency +* Support sending Content-Length when Content-Range is specified [#1496] +* Update `actix-web` to 2.0.0 + +[#1496]: https://github.com/actix/actix-web/issues/1496 + ## [0.2.1] - 2019-12-22 * Use the same format for file URLs regardless of platforms -* Support sending Content-Length when Content-Range is specified [#1384] - -[#1384]: https://github.com/actix/actix-web/pull/1384 ## [0.2.0] - 2019-12-20 diff --git a/actix-files/Cargo.toml b/actix-files/Cargo.toml index f2e6c1f70..d7ccaa989 100644 --- a/actix-files/Cargo.toml +++ b/actix-files/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-files" -version = "0.2.1" +version = "0.2.2" authors = ["Nikolay Kim "] description = "Static files support for actix web." readme = "README.md" @@ -18,7 +18,7 @@ name = "actix_files" path = "src/lib.rs" [dependencies] -actix-web = { version = "2.0.0-rc", default-features = false } +actix-web = { version = "2.0.0", default-features = false } actix-http = "1.0.1" actix-service = "1.0.1" bitflags = "1" @@ -34,4 +34,4 @@ v_htmlescape = "0.4" [dev-dependencies] actix-rt = "1.0.0" -actix-web = { version = "2.0.0-rc", features=["openssl"] } +actix-web = { version = "2.0.0", features = ["openssl"] }