Skip to content

Commit d1980a7

Browse files
committed
Port to cap-async-std.
1 parent 4be9062 commit d1980a7

File tree

3 files changed

+20
-33
lines changed

3 files changed

+20
-33
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ async-session = { version = "3.0", optional = true }
3838
async-sse = "4.0.1"
3939
async-std = { version = "1.6.5", features = ["unstable"] }
4040
async-trait = "0.1.41"
41+
cap-async-std = "0.21.1"
4142
femme = { version = "2.1.1", optional = true }
4243
futures-util = "0.3.6"
4344
http-client = { version = "6.1.0", default-features = false }

src/fs/serve_dir.rs

Lines changed: 12 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
11
use crate::log;
22
use crate::{Body, Endpoint, Request, Response, Result, StatusCode};
33

4-
use async_std::path::PathBuf as AsyncPathBuf;
4+
use async_std::io::BufReader;
55

6-
use std::path::{Path, PathBuf};
7-
use std::{ffi::OsStr, io};
6+
use cap_async_std::fs;
87

98
pub(crate) struct ServeDir {
109
prefix: String,
11-
dir: PathBuf,
10+
dir: fs::Dir,
1211
}
1312

1413
impl ServeDir {
1514
/// Create a new instance of `ServeDir`.
16-
pub(crate) fn new(prefix: String, dir: PathBuf) -> Self {
15+
pub(crate) fn new(prefix: String, dir: fs::Dir) -> Self {
1716
Self { prefix, dir }
1817
}
1918
}
@@ -29,33 +28,14 @@ where
2928
.strip_prefix(&self.prefix.trim_end_matches('*'))
3029
.unwrap();
3130
let path = path.trim_start_matches('/');
32-
let mut file_path = self.dir.clone();
33-
for p in Path::new(path) {
34-
if p == OsStr::new(".") {
35-
continue;
36-
} else if p == OsStr::new("..") {
37-
file_path.pop();
38-
} else {
39-
file_path.push(&p);
40-
}
41-
}
42-
43-
log::info!("Requested file: {:?}", file_path);
44-
45-
let file_path = AsyncPathBuf::from(file_path);
46-
if !file_path.starts_with(&self.dir) {
47-
log::warn!("Unauthorized attempt to read: {:?}", file_path);
48-
Ok(Response::new(StatusCode::Forbidden))
49-
} else {
50-
match Body::from_file(&file_path).await {
51-
Ok(body) => Ok(Response::builder(StatusCode::Ok).body(body).build()),
52-
Err(e) if e.kind() == io::ErrorKind::NotFound => {
53-
log::warn!("File not found: {:?}", &file_path);
54-
Ok(Response::new(StatusCode::NotFound))
55-
}
56-
Err(e) => Err(e.into()),
57-
}
58-
}
31+
32+
log::info!("Requested file: {:?}", path);
33+
34+
let file = self.dir.open(path).await?;
35+
// TODO: This always uses `mime::BYTE_STREAM`; with http-types 3.0
36+
// we'll be able to use `Body::from_open_file` which fixes this.
37+
let body = Body::from_reader(BufReader::new(file), None);
38+
Ok(Response::builder(StatusCode::Ok).body(body).build())
5939
}
6040
}
6141

src/route.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ use std::fmt::Debug;
22
use std::io;
33
use std::path::Path;
44
use std::sync::Arc;
5+
use async_std::task;
6+
use cap_async_std::ambient_authority;
7+
use cap_async_std::fs::Dir;
58

69
use crate::endpoint::MiddlewareEndpoint;
710
use crate::fs::{ServeDir, ServeFile};
@@ -165,7 +168,10 @@ impl<'a, State: Clone + Send + Sync + 'static> Route<'a, State> {
165168
/// ```
166169
pub fn serve_dir(&mut self, dir: impl AsRef<Path>) -> io::Result<()> {
167170
// Verify path exists, return error if it doesn't.
168-
let dir = dir.as_ref().to_owned().canonicalize()?;
171+
let path = dir.as_ref().to_owned().canonicalize()?;
172+
let dir = task::block_on(async {
173+
Dir::open_ambient_dir(path, ambient_authority()).await
174+
})?;
169175
let prefix = self.path().to_string();
170176
self.get(ServeDir::new(prefix, dir));
171177
Ok(())

0 commit comments

Comments
 (0)