-
Notifications
You must be signed in to change notification settings - Fork 321
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This depends on #414 Add serve_dir method to Route Update serve_dir.rs Adjust methods so body can correctly be sent along tweak static file serving simplify internals cargo fmt & fix tests fix all tests cargo fmt Fix merge conflicts with master undo bonus changes Fix static path prefix stripping err
- Loading branch information
1 parent
1b7fceb
commit f3af561
Showing
9 changed files
with
195 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
use async_std::task; | ||
|
||
fn main() -> Result<(), std::io::Error> { | ||
femme::start(log::LevelFilter::Info).unwrap(); | ||
task::block_on(async { | ||
let mut app = tide::new(); | ||
app.at("/").get(|_| async move { Ok("visit /src/*") }); | ||
app.at("/src").serve_dir("src/")?; | ||
app.listen("127.0.0.1:8080").await?; | ||
Ok(()) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
use async_std::fs::File; | ||
use async_std::io::BufReader; | ||
use http_types::{Body, StatusCode}; | ||
|
||
use crate::{Endpoint, Request, Response, Result}; | ||
|
||
use std::path::{Path, PathBuf}; | ||
|
||
type BoxFuture<'a, T> = std::pin::Pin<Box<dyn std::future::Future<Output = T> + 'a + Send>>; | ||
pub struct ServeDir { | ||
prefix: String, | ||
dir: PathBuf, | ||
} | ||
|
||
impl ServeDir { | ||
/// Create a new instance of `ServeDir`. | ||
pub(crate) fn new(prefix: String, dir: PathBuf) -> Self { | ||
Self { prefix, dir } | ||
} | ||
} | ||
|
||
impl<State> Endpoint<State> for ServeDir { | ||
fn call<'a>(&'a self, req: Request<State>) -> BoxFuture<'a, Result<Response>> { | ||
let path = req.uri().path(); | ||
let path = path.replacen(&self.prefix, "", 1); | ||
let path = path.trim_start_matches('/'); | ||
let mut dir = self.dir.clone(); | ||
for p in Path::new(path) { | ||
dir.push(&p); | ||
} | ||
log::info!("Requested file: {:?}", dir); | ||
|
||
Box::pin(async move { | ||
let file = match async_std::fs::canonicalize(&dir).await { | ||
Err(_) => { | ||
// This needs to return the same status code as the | ||
// unauthorized case below to ensure we don't leak | ||
// information of which files exist to adversaries. | ||
log::warn!("File not found: {:?}", dir); | ||
return Ok(Response::new(StatusCode::NotFound)); | ||
} | ||
Ok(mut file_path) => { | ||
// Verify this is a sub-path of the original dir. | ||
let mut file_iter = (&mut file_path).iter(); | ||
if !dir.iter().all(|lhs| Some(lhs) == file_iter.next()) { | ||
// This needs to return the same status code as the | ||
// 404 case above to ensure we don't leak | ||
// information about the local fs to adversaries. | ||
log::warn!("Unauthorized attempt to read: {:?}", file_path); | ||
return Ok(Response::new(StatusCode::NotFound)); | ||
} | ||
|
||
// Open the file and send back the contents. | ||
match File::open(&file_path).await { | ||
Ok(file) => file, | ||
Err(_) => { | ||
log::warn!("Could not open {:?}", file_path); | ||
return Ok(Response::new(StatusCode::InternalServerError)); | ||
} | ||
} | ||
} | ||
}; | ||
|
||
let len = match file.metadata().await { | ||
Ok(metadata) => metadata.len() as usize, | ||
Err(_) => { | ||
log::warn!("Could not retrieve metadata"); | ||
return Ok(Response::new(StatusCode::InternalServerError)); | ||
} | ||
}; | ||
|
||
let body = Body::from_reader(BufReader::new(file), Some(len)); | ||
// TODO: fix related bug where async-h1 crashes on large files | ||
let mut res = Response::new(StatusCode::Ok); | ||
res.set_body(body); | ||
Ok(res) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters