mirror of https://github.com/fafhrd91/actix-web
relative path and request head
This commit is contained in:
parent
13ff7759d3
commit
173ea9acf2
|
@ -8,7 +8,10 @@ use std::{
|
||||||
use actix_service::{boxed, IntoServiceFactory, ServiceFactory, ServiceFactoryExt};
|
use actix_service::{boxed, IntoServiceFactory, ServiceFactory, ServiceFactoryExt};
|
||||||
use actix_utils::future::ok;
|
use actix_utils::future::ok;
|
||||||
use actix_web::{
|
use actix_web::{
|
||||||
dev::{AppService, HttpServiceFactory, ResourceDef, ServiceRequest, ServiceResponse},
|
dev::{
|
||||||
|
AppService, HttpServiceFactory, RequestHead, ResourceDef, ServiceRequest,
|
||||||
|
ServiceResponse,
|
||||||
|
},
|
||||||
error::Error,
|
error::Error,
|
||||||
guard::Guard,
|
guard::Guard,
|
||||||
http::header::DispositionType,
|
http::header::DispositionType,
|
||||||
|
@ -163,7 +166,7 @@ impl Files {
|
||||||
/// `404 NotFound` is returned.
|
/// `404 NotFound` is returned.
|
||||||
pub fn path_filter<F>(mut self, f: F) -> Self
|
pub fn path_filter<F>(mut self, f: F) -> Self
|
||||||
where
|
where
|
||||||
F: Fn(&Path) -> bool + 'static,
|
F: Fn(&Path, &RequestHead) -> bool + 'static,
|
||||||
{
|
{
|
||||||
self.path_filter = Some(Rc::new(f));
|
self.path_filter = Some(Rc::new(f));
|
||||||
self
|
self
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
use actix_service::boxed::{BoxService, BoxServiceFactory};
|
use actix_service::boxed::{BoxService, BoxServiceFactory};
|
||||||
use actix_web::{
|
use actix_web::{
|
||||||
dev::{ServiceRequest, ServiceResponse},
|
dev::{RequestHead, ServiceRequest, ServiceResponse},
|
||||||
error::Error,
|
error::Error,
|
||||||
http::header::DispositionType,
|
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 MimeOverride = dyn Fn(&mime::Name<'_>) -> DispositionType;
|
||||||
|
|
||||||
type PathFilter = dyn Fn(&Path) -> bool;
|
type PathFilter = dyn Fn(&Path, &RequestHead) -> bool;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
@ -907,17 +907,18 @@ mod tests {
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn test_path_filter() {
|
async fn test_path_filter() {
|
||||||
|
// prevent searching subdirectories
|
||||||
let st = Files::new("/", ".")
|
let st = Files::new("/", ".")
|
||||||
.path_filter(|path| path.extension() == Some("png".as_ref()))
|
.path_filter(|path, _| path.components().count() == 1)
|
||||||
.new_service(())
|
.new_service(())
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.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;
|
let resp = test::call_service(&st, req).await;
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
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;
|
let resp = test::call_service(&st, req).await;
|
||||||
assert_eq!(resp.status(), StatusCode::NOT_FOUND);
|
assert_eq!(resp.status(), StatusCode::NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
@ -928,7 +929,7 @@ mod tests {
|
||||||
.default_handler(|req: ServiceRequest| {
|
.default_handler(|req: ServiceRequest| {
|
||||||
ok(req.into_response(HttpResponse::Ok().body("default content")))
|
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(())
|
.new_service(())
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
|
@ -83,14 +83,8 @@ impl Service<ServiceRequest> for FilesService {
|
||||||
Err(e) => return Box::pin(ok(req.error_response(e))),
|
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 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 {
|
if let Some(ref default) = self.default {
|
||||||
return Box::pin(default.call(req));
|
return Box::pin(default.call(req));
|
||||||
} else {
|
} else {
|
||||||
|
@ -101,6 +95,12 @@ impl Service<ServiceRequest> 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 path.is_dir() {
|
||||||
if self.redirect_to_slash
|
if self.redirect_to_slash
|
||||||
&& !req.path().ends_with('/')
|
&& !req.path().ends_with('/')
|
||||||
|
|
Loading…
Reference in New Issue