mirror of https://github.com/fafhrd91/actix-web
merge master into branch tokio0.3
This commit is contained in:
commit
d42490d5a0
|
@ -4,12 +4,14 @@
|
||||||
### Changed
|
### Changed
|
||||||
* Bumped `rand` to `0.8`
|
* Bumped `rand` to `0.8`
|
||||||
* Update `rust-tls` to `0.19.0`
|
* Update `rust-tls` to `0.19.0`
|
||||||
|
* Rename `Handler` to `HandlerService` and rename `Factory` to `Handler`. [#1852]
|
||||||
|
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
* added the actual parsing error to `test::read_body_json` [#1812]
|
* added the actual parsing error to `test::read_body_json` [#1812]
|
||||||
|
|
||||||
[#1812]: https://github.com/actix/actix-web/pull/1812
|
[#1812]: https://github.com/actix/actix-web/pull/1812
|
||||||
|
[#1852]: https://github.com/actix/actix-web/pull/1852
|
||||||
|
|
||||||
## 3.3.2 - 2020-12-01
|
## 3.3.2 - 2020-12-01
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
|
@ -4,6 +4,12 @@
|
||||||
* Update `bytes` to `1`.
|
* Update `bytes` to `1`.
|
||||||
|
|
||||||
|
|
||||||
|
## 0.5.0 - 2020-12-26
|
||||||
|
* Optionally support hidden files/directories. [#1811]
|
||||||
|
|
||||||
|
[#1811]: https://github.com/actix/actix-web/pull/1811
|
||||||
|
|
||||||
|
|
||||||
## 0.4.1 - 2020-11-24
|
## 0.4.1 - 2020-11-24
|
||||||
* Clarify order of parameters in `Files::new` and improve docs.
|
* Clarify order of parameters in `Files::new` and improve docs.
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "actix-files"
|
name = "actix-files"
|
||||||
version = "0.4.1"
|
version = "0.5.0"
|
||||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||||
description = "Static file serving for Actix Web"
|
description = "Static file serving for Actix Web"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
@ -23,13 +23,13 @@ bitflags = "1"
|
||||||
bytes = "1"
|
bytes = "1"
|
||||||
futures-core = { version = "0.3.7", default-features = false }
|
futures-core = { version = "0.3.7", default-features = false }
|
||||||
futures-util = { version = "0.3.7", default-features = false, features = ["sink"] }
|
futures-util = { version = "0.3.7", default-features = false, features = ["sink"] }
|
||||||
derive_more = "0.99.2"
|
derive_more = "0.99.5"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
mime = "0.3"
|
mime = "0.3"
|
||||||
mime_guess = "2.0.1"
|
mime_guess = "2.0.1"
|
||||||
percent-encoding = "2.1"
|
percent-encoding = "2.1"
|
||||||
v_htmlescape = "0.11"
|
v_htmlescape = "0.12"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
actix-rt = "1.0.0"
|
actix-rt = "1.0.0"
|
||||||
actix-web = { version = "3.0.0", features = ["openssl"] }
|
actix-web = "3.0.0"
|
||||||
|
|
|
@ -3,11 +3,11 @@
|
||||||
> Static file serving for Actix Web
|
> Static file serving for Actix Web
|
||||||
|
|
||||||
[](https://crates.io/crates/actix-files)
|
[](https://crates.io/crates/actix-files)
|
||||||
[](https://docs.rs/actix-files/0.4.1)
|
[](https://docs.rs/actix-files/0.5.0)
|
||||||
[](https://blog.rust-lang.org/2020/03/12/Rust-1.42.html)
|
[](https://blog.rust-lang.org/2020/03/12/Rust-1.42.html)
|
||||||

|

|
||||||
<br />
|
<br />
|
||||||
[](https://deps.rs/crate/actix-files/0.4.1)
|
[](https://deps.rs/crate/actix-files/0.5.0)
|
||||||
[](https://crates.io/crates/actix-files)
|
[](https://crates.io/crates/actix-files)
|
||||||
[](https://gitter.im/actix/actix?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
[](https://gitter.im/actix/actix?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ pub struct Files {
|
||||||
mime_override: Option<Rc<MimeOverride>>,
|
mime_override: Option<Rc<MimeOverride>>,
|
||||||
file_flags: named::Flags,
|
file_flags: named::Flags,
|
||||||
guards: Option<Rc<dyn Guard>>,
|
guards: Option<Rc<dyn Guard>>,
|
||||||
|
hidden_files: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for Files {
|
impl fmt::Debug for Files {
|
||||||
|
@ -60,6 +61,7 @@ impl Clone for Files {
|
||||||
path: self.path.clone(),
|
path: self.path.clone(),
|
||||||
mime_override: self.mime_override.clone(),
|
mime_override: self.mime_override.clone(),
|
||||||
guards: self.guards.clone(),
|
guards: self.guards.clone(),
|
||||||
|
hidden_files: self.hidden_files,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,6 +105,7 @@ impl Files {
|
||||||
mime_override: None,
|
mime_override: None,
|
||||||
file_flags: named::Flags::default(),
|
file_flags: named::Flags::default(),
|
||||||
guards: None,
|
guards: None,
|
||||||
|
hidden_files: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,6 +216,13 @@ impl Files {
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Enables serving hidden files and directories, allowing a leading dots in url fragments.
|
||||||
|
#[inline]
|
||||||
|
pub fn use_hidden_files(mut self) -> Self {
|
||||||
|
self.hidden_files = true;
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HttpServiceFactory for Files {
|
impl HttpServiceFactory for Files {
|
||||||
|
@ -251,6 +261,7 @@ impl ServiceFactory for Files {
|
||||||
mime_override: self.mime_override.clone(),
|
mime_override: self.mime_override.clone(),
|
||||||
file_flags: self.file_flags,
|
file_flags: self.file_flags,
|
||||||
guards: self.guards.clone(),
|
guards: self.guards.clone(),
|
||||||
|
hidden_files: self.hidden_files,
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(ref default) = *self.default.borrow() {
|
if let Some(ref default) = *self.default.borrow() {
|
||||||
|
|
|
@ -15,12 +15,19 @@ impl FromStr for PathBufWrap {
|
||||||
type Err = UriSegmentError;
|
type Err = UriSegmentError;
|
||||||
|
|
||||||
fn from_str(path: &str) -> Result<Self, Self::Err> {
|
fn from_str(path: &str) -> Result<Self, Self::Err> {
|
||||||
|
Self::parse_path(path, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PathBufWrap {
|
||||||
|
/// Parse a path, giving the choice of allowing hidden files to be considered valid segments.
|
||||||
|
pub fn parse_path(path: &str, hidden_files: bool) -> Result<Self, UriSegmentError> {
|
||||||
let mut buf = PathBuf::new();
|
let mut buf = PathBuf::new();
|
||||||
|
|
||||||
for segment in path.split('/') {
|
for segment in path.split('/') {
|
||||||
if segment == ".." {
|
if segment == ".." {
|
||||||
buf.pop();
|
buf.pop();
|
||||||
} else if segment.starts_with('.') {
|
} else if !hidden_files && segment.starts_with('.') {
|
||||||
return Err(UriSegmentError::BadStart('.'));
|
return Err(UriSegmentError::BadStart('.'));
|
||||||
} else if segment.starts_with('*') {
|
} else if segment.starts_with('*') {
|
||||||
return Err(UriSegmentError::BadStart('*'));
|
return Err(UriSegmentError::BadStart('*'));
|
||||||
|
@ -96,4 +103,17 @@ mod tests {
|
||||||
PathBuf::from_iter(vec!["seg2"])
|
PathBuf::from_iter(vec!["seg2"])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_parse_path() {
|
||||||
|
assert_eq!(
|
||||||
|
PathBufWrap::parse_path("/test/.tt", false).map(|t| t.0),
|
||||||
|
Err(UriSegmentError::BadStart('.'))
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
PathBufWrap::parse_path("/test/.tt", true).unwrap().0,
|
||||||
|
PathBuf::from_iter(vec!["test", ".tt"])
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ pub struct FilesService {
|
||||||
pub(crate) mime_override: Option<Rc<MimeOverride>>,
|
pub(crate) mime_override: Option<Rc<MimeOverride>>,
|
||||||
pub(crate) file_flags: named::Flags,
|
pub(crate) file_flags: named::Flags,
|
||||||
pub(crate) guards: Option<Rc<dyn Guard>>,
|
pub(crate) guards: Option<Rc<dyn Guard>>,
|
||||||
|
pub(crate) hidden_files: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
type FilesServiceFuture = Either<
|
type FilesServiceFuture = Either<
|
||||||
|
@ -83,10 +84,11 @@ impl Service for FilesService {
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
let real_path: PathBufWrap = match req.match_info().path().parse() {
|
let real_path =
|
||||||
Ok(item) => item,
|
match PathBufWrap::parse_path(req.match_info().path(), self.hidden_files) {
|
||||||
Err(e) => return Either::Left(ok(req.error_response(e))),
|
Ok(item) => item,
|
||||||
};
|
Err(e) => return Either::Left(ok(req.error_response(e))),
|
||||||
|
};
|
||||||
|
|
||||||
// full file path
|
// full file path
|
||||||
let path = match self.directory.join(&real_path).canonicalize() {
|
let path = match self.directory.join(&real_path).canonicalize() {
|
||||||
|
|
|
@ -14,7 +14,12 @@ use crate::request::HttpRequest;
|
||||||
use crate::responder::Responder;
|
use crate::responder::Responder;
|
||||||
use crate::service::{ServiceRequest, ServiceResponse};
|
use crate::service::{ServiceRequest, ServiceResponse};
|
||||||
|
|
||||||
/// Async handler converter factory
|
/// A request handler is an async function that accepts zero or more parameters that can be
|
||||||
|
/// extracted from a request (ie, [`impl FromRequest`](crate::FromRequest)) and returns a type that can be converted into
|
||||||
|
/// an [`HttpResponse`](crate::HttpResponse) (ie, [`impl Responder`](crate::Responder)).
|
||||||
|
///
|
||||||
|
/// If you got the error `the trait Handler<_, _, _> is not implemented`, then your function is not
|
||||||
|
/// a valid handler. See [Request Handlers](https://actix.rs/docs/handlers/) for more information.
|
||||||
pub trait Handler<T, R>: Clone + 'static
|
pub trait Handler<T, R>: Clone + 'static
|
||||||
where
|
where
|
||||||
R: Future,
|
R: Future,
|
||||||
|
@ -55,7 +60,7 @@ where
|
||||||
R::Output: Responder,
|
R::Output: Responder,
|
||||||
{
|
{
|
||||||
pub fn new(hnd: F) -> Self {
|
pub fn new(hnd: F) -> Self {
|
||||||
HandlerService {
|
Self {
|
||||||
hnd,
|
hnd,
|
||||||
_t: PhantomData,
|
_t: PhantomData,
|
||||||
}
|
}
|
||||||
|
@ -70,7 +75,7 @@ where
|
||||||
R::Output: Responder,
|
R::Output: Responder,
|
||||||
{
|
{
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
HandlerService {
|
Self {
|
||||||
hnd: self.hnd.clone(),
|
hnd: self.hnd.clone(),
|
||||||
_t: PhantomData,
|
_t: PhantomData,
|
||||||
}
|
}
|
||||||
|
@ -97,7 +102,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handler is both it's ServiceFactory and Service Type.
|
// HandlerService is both it's ServiceFactory and Service Type.
|
||||||
impl<F, T, R> Service for HandlerService<F, T, R>
|
impl<F, T, R> Service for HandlerService<F, T, R>
|
||||||
where
|
where
|
||||||
F: Handler<T, R>,
|
F: Handler<T, R>,
|
||||||
|
|
Loading…
Reference in New Issue