1
0
mirror of https://github.com/actix/actix-extras.git synced 2025-02-08 21:06:07 +01:00

added StaticFiles::inex_file config

This commit is contained in:
Nikolay Kim 2018-01-29 03:23:45 -08:00
parent 456fd1364a
commit b6a394a113
4 changed files with 46 additions and 5 deletions

View File

@ -6,6 +6,10 @@
* Added HttpRequest::mime_type() method * Added HttpRequest::mime_type() method
* Added StaticFiles::index_file()
* Added basic websocket client
## 0.3.3 (2018-01-25) ## 0.3.3 (2018-01-25)

View File

@ -55,7 +55,8 @@ fn main() {
// websocket route // websocket route
.resource("/ws/", |r| r.method(Method::GET).f(ws_index)) .resource("/ws/", |r| r.method(Method::GET).f(ws_index))
// static files // static files
.handler("/", fs::StaticFiles::new("../static/", true))) .handler("/", fs::StaticFiles::new("../static/", true)
.index_file("index.html")))
// start http server on 127.0.0.1:8080 // start http server on 127.0.0.1:8080
.bind("127.0.0.1:8080").unwrap() .bind("127.0.0.1:8080").unwrap()
.start(); .start();

View File

@ -42,3 +42,8 @@ fn main() {
First parameter is a base directory. Second parameter is *show_index*, if it is set to *true* First parameter is a base directory. Second parameter is *show_index*, if it is set to *true*
directory listing would be returned for directories, if it is set to *false* directory listing would be returned for directories, if it is set to *false*
then *404 Not Found* would be returned instead of directory listing. then *404 Not Found* would be returned instead of directory listing.
Instead of showing files listing for directory, it is possible to redirect to specific
index file. Use
[*StaticFiles::index_file()*](../actix_web/s/struct.StaticFiles.html#method.index_file)
method to configure this redirect.

View File

@ -15,7 +15,7 @@ use handler::{Handler, Responder};
use headers::ContentEncoding; use headers::ContentEncoding;
use httprequest::HttpRequest; use httprequest::HttpRequest;
use httpresponse::HttpResponse; use httpresponse::HttpResponse;
use httpcodes::HTTPOk; use httpcodes::{HTTPOk, HTTPFound};
/// A file with an associated name; responds with the Content-Type based on the /// A file with an associated name; responds with the Content-Type based on the
/// file extension. /// file extension.
@ -177,6 +177,7 @@ impl Responder for Directory {
pub enum FilesystemElement { pub enum FilesystemElement {
File(NamedFile), File(NamedFile),
Directory(Directory), Directory(Directory),
Redirect(HttpResponse),
} }
impl Responder for FilesystemElement { impl Responder for FilesystemElement {
@ -187,6 +188,7 @@ impl Responder for FilesystemElement {
match self { match self {
FilesystemElement::File(file) => file.respond_to(req), FilesystemElement::File(file) => file.respond_to(req),
FilesystemElement::Directory(dir) => dir.respond_to(req), FilesystemElement::Directory(dir) => dir.respond_to(req),
FilesystemElement::Redirect(resp) => Ok(resp),
} }
} }
} }
@ -210,6 +212,7 @@ impl Responder for FilesystemElement {
pub struct StaticFiles { pub struct StaticFiles {
directory: PathBuf, directory: PathBuf,
accessible: bool, accessible: bool,
index: Option<String>,
show_index: bool, show_index: bool,
_chunk_size: usize, _chunk_size: usize,
_follow_symlinks: bool, _follow_symlinks: bool,
@ -221,7 +224,7 @@ impl StaticFiles {
/// `dir` - base directory /// `dir` - base directory
/// ///
/// `index` - show index for directory /// `index` - show index for directory
pub fn new<D: Into<PathBuf>>(dir: D, index: bool) -> StaticFiles { pub fn new<T: Into<PathBuf>>(dir: T, index: bool) -> StaticFiles {
let dir = dir.into(); let dir = dir.into();
let (dir, access) = match dir.canonicalize() { let (dir, access) = match dir.canonicalize() {
@ -242,12 +245,21 @@ impl StaticFiles {
StaticFiles { StaticFiles {
directory: dir, directory: dir,
accessible: access, accessible: access,
index: None,
show_index: index, show_index: index,
_chunk_size: 0, _chunk_size: 0,
_follow_symlinks: false, _follow_symlinks: false,
} }
} }
/// Set index file
///
/// Redirects to specific index file for directory "/" instead of
/// showing files listing.
pub fn index_file<T: Into<String>>(mut self, index: T) -> StaticFiles {
self.index = Some(index.into());
self
}
} }
impl<S> Handler<S> for StaticFiles { impl<S> Handler<S> for StaticFiles {
@ -270,7 +282,15 @@ impl<S> Handler<S> for StaticFiles {
let path = self.directory.join(&relpath).canonicalize()?; let path = self.directory.join(&relpath).canonicalize()?;
if path.is_dir() { if path.is_dir() {
if self.show_index { if let Some(ref redir_index) = self.index {
let mut base = Path::new(req.path()).join(relpath);
base.push(redir_index);
Ok(FilesystemElement::Redirect(
HTTPFound
.build()
.header("LOCATION", base.to_string_lossy().as_ref())
.finish().unwrap()))
} else if self.show_index {
Ok(FilesystemElement::Directory(Directory::new(self.directory.clone(), path))) Ok(FilesystemElement::Directory(Directory::new(self.directory.clone(), path)))
} else { } else {
Err(io::Error::new(io::ErrorKind::NotFound, "not found")) Err(io::Error::new(io::ErrorKind::NotFound, "not found"))
@ -285,7 +305,7 @@ impl<S> Handler<S> for StaticFiles {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use http::header; use http::{header, StatusCode};
#[test] #[test]
fn test_named_file() { fn test_named_file() {
@ -318,4 +338,15 @@ mod tests {
assert!(resp.body().is_binary()); assert!(resp.body().is_binary());
assert!(format!("{:?}", resp.body()).contains("README.md")); assert!(format!("{:?}", resp.body()).contains("README.md"));
} }
#[test]
fn test_redirec_to_index() {
let mut st = StaticFiles::new(".", false).index_file("index.html");
let mut req = HttpRequest::default();
req.match_info_mut().add("tail", "guide");
let resp = st.handle(req).respond_to(HttpRequest::default()).unwrap();
assert_eq!(resp.status(), StatusCode::FOUND);
assert_eq!(resp.headers().get(header::LOCATION).unwrap(), "/guide/index.html");
}
} }