From 173ea9acf230161feea2953be088f5a51b0a0a28 Mon Sep 17 00:00:00 2001 From: Ali MJ Al-Nasrawy Date: Wed, 23 Jun 2021 00:59:42 +0300 Subject: [PATCH] relative path and request head --- actix-files/src/files.rs | 7 +++++-- actix-files/src/lib.rs | 13 +++++++------ actix-files/src/service.rs | 14 +++++++------- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/actix-files/src/files.rs b/actix-files/src/files.rs index 144cf1b61..b1405d0d4 100644 --- a/actix-files/src/files.rs +++ b/actix-files/src/files.rs @@ -8,7 +8,10 @@ use std::{ use actix_service::{boxed, IntoServiceFactory, ServiceFactory, ServiceFactoryExt}; use actix_utils::future::ok; use actix_web::{ - dev::{AppService, HttpServiceFactory, ResourceDef, ServiceRequest, ServiceResponse}, + dev::{ + AppService, HttpServiceFactory, RequestHead, ResourceDef, ServiceRequest, + ServiceResponse, + }, error::Error, guard::Guard, http::header::DispositionType, @@ -163,7 +166,7 @@ impl Files { /// `404 NotFound` is returned. pub fn path_filter(mut self, f: F) -> Self where - F: Fn(&Path) -> bool + 'static, + F: Fn(&Path, &RequestHead) -> bool + 'static, { self.path_filter = Some(Rc::new(f)); self diff --git a/actix-files/src/lib.rs b/actix-files/src/lib.rs index 8aa707c43..eab10ea66 100644 --- a/actix-files/src/lib.rs +++ b/actix-files/src/lib.rs @@ -16,7 +16,7 @@ use actix_service::boxed::{BoxService, BoxServiceFactory}; use actix_web::{ - dev::{ServiceRequest, ServiceResponse}, + dev::{RequestHead, ServiceRequest, ServiceResponse}, error::Error, http::header::DispositionType, }; @@ -57,7 +57,7 @@ pub fn file_extension_to_mime(ext: &str) -> mime::Mime { type MimeOverride = dyn Fn(&mime::Name<'_>) -> DispositionType; -type PathFilter = dyn Fn(&Path) -> bool; +type PathFilter = dyn Fn(&Path, &RequestHead) -> bool; #[cfg(test)] mod tests { @@ -907,17 +907,18 @@ mod tests { #[actix_rt::test] async fn test_path_filter() { + // prevent searching subdirectories let st = Files::new("/", ".") - .path_filter(|path| path.extension() == Some("png".as_ref())) + .path_filter(|path, _| path.components().count() == 1) .new_service(()) .await .unwrap(); - let req = TestRequest::with_uri("/tests/test.png").to_srv_request(); + let req = TestRequest::with_uri("/Cargo.toml").to_srv_request(); let resp = test::call_service(&st, req).await; assert_eq!(resp.status(), StatusCode::OK); - let req = TestRequest::with_uri("/Cargo.toml").to_srv_request(); + let req = TestRequest::with_uri("/tests/test.png").to_srv_request(); let resp = test::call_service(&st, req).await; assert_eq!(resp.status(), StatusCode::NOT_FOUND); } @@ -928,7 +929,7 @@ mod tests { .default_handler(|req: ServiceRequest| { ok(req.into_response(HttpResponse::Ok().body("default content"))) }) - .path_filter(|path| path.extension() == Some("png".as_ref())) + .path_filter(|path, _| path.extension() == Some("png".as_ref())) .new_service(()) .await .unwrap(); diff --git a/actix-files/src/service.rs b/actix-files/src/service.rs index d7f5b4483..09122c63e 100644 --- a/actix-files/src/service.rs +++ b/actix-files/src/service.rs @@ -83,14 +83,8 @@ impl Service for FilesService { Err(e) => return Box::pin(ok(req.error_response(e))), }; - // full file path - let path = self.directory.join(&real_path); - if let Err(err) = path.canonicalize() { - return Box::pin(self.handle_err(err, req)); - } - if let Some(filter) = &self.path_filter { - if !filter(real_path.as_ref()) { + if !filter(real_path.as_ref(), req.head()) { if let Some(ref default) = self.default { return Box::pin(default.call(req)); } else { @@ -101,6 +95,12 @@ impl Service for FilesService { } } + // full file path + let path = self.directory.join(&real_path); + if let Err(err) = path.canonicalize() { + return Box::pin(self.handle_err(err, req)); + } + if path.is_dir() { if self.redirect_to_slash && !req.path().ends_with('/')