Serving files is working

Right now we're not doing any streaming and this isn't ideal. I'll need
to figure it out at some point.
This commit is contained in:
Cameron Cordes
2020-07-08 21:38:21 -04:00
parent 82203d9a41
commit 536300e0a1
5 changed files with 121 additions and 8 deletions

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
/target /target
database/target database/target
*.db *.db
.env

90
Cargo.lock generated
View File

@@ -34,6 +34,27 @@ dependencies = [
"trust-dns-resolver", "trust-dns-resolver",
] ]
[[package]]
name = "actix-files"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "193b22cb1f7b4ff12a4eb2415d6d19e47e44ea93e05930b30d05375ea29d3529"
dependencies = [
"actix-http",
"actix-service",
"actix-web",
"bitflags",
"bytes",
"derive_more",
"futures-core",
"futures-util",
"log",
"mime",
"mime_guess",
"percent-encoding",
"v_htmlescape",
]
[[package]] [[package]]
name = "actix-http" name = "actix-http"
version = "1.0.1" version = "1.0.1"
@@ -809,7 +830,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac746a5f3bbfdadd6106868134545e684693d54d9d44f6e9588a7d54af0bf980" checksum = "ac746a5f3bbfdadd6106868134545e684693d54d9d44f6e9588a7d54af0bf980"
dependencies = [ dependencies = [
"typenum", "typenum",
"version_check", "version_check 0.9.2",
] ]
[[package]] [[package]]
@@ -919,6 +940,7 @@ dependencies = [
name = "image-api" name = "image-api"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"actix-files",
"actix-rt", "actix-rt",
"actix-web", "actix-web",
"bcrypt", "bcrypt",
@@ -1098,6 +1120,16 @@ version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
[[package]]
name = "mime_guess"
version = "2.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2684d4c2e97d99848d30b324b00c8fcc7e5c897b7cbb5819b09e7c90e8baf212"
dependencies = [
"mime",
"unicase",
]
[[package]] [[package]]
name = "miniz_oxide" name = "miniz_oxide"
version = "0.3.7" version = "0.3.7"
@@ -1169,6 +1201,16 @@ dependencies = [
"winapi 0.3.9", "winapi 0.3.9",
] ]
[[package]]
name = "nom"
version = "4.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6"
dependencies = [
"memchr",
"version_check 0.1.5",
]
[[package]] [[package]]
name = "num-bigint" name = "num-bigint"
version = "0.2.6" version = "0.2.6"
@@ -1754,6 +1796,15 @@ version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
[[package]]
name = "unicase"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
dependencies = [
"version_check 0.9.2",
]
[[package]] [[package]]
name = "unicode-bidi" name = "unicode-bidi"
version = "0.3.4" version = "0.3.4"
@@ -1801,12 +1852,49 @@ dependencies = [
"percent-encoding", "percent-encoding",
] ]
[[package]]
name = "v_escape"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "660b101c07b5d0863deb9e7fb3138777e858d6d2a79f9e6049a27d1cc77c6da6"
dependencies = [
"v_escape_derive",
]
[[package]]
name = "v_escape_derive"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2ca2a14bc3fc5b64d188b087a7d3a927df87b152e941ccfbc66672e20c467ae"
dependencies = [
"nom",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "v_htmlescape"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e33e939c0d8cf047514fb6ba7d5aac78bc56677a6938b2ee67000b91f2e97e41"
dependencies = [
"cfg-if",
"v_escape",
]
[[package]] [[package]]
name = "vcpkg" name = "vcpkg"
version = "0.2.10" version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6454029bf181f092ad1b853286f23e2c507d8e8194d01d92da4a55c274a5508c" checksum = "6454029bf181f092ad1b853286f23e2c507d8e8194d01d92da4a55c274a5508c"
[[package]]
name = "version_check"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
[[package]] [[package]]
name = "version_check" name = "version_check"
version = "0.9.2" version = "0.9.2"

View File

@@ -9,6 +9,7 @@ edition = "2018"
[dependencies] [dependencies]
actix-web = "2.0" actix-web = "2.0"
actix-rt = "1.0" actix-rt = "1.0"
actix-files = "0.2.2"
futures = "0.3.5" futures = "0.3.5"
jsonwebtoken = "7.2.0" jsonwebtoken = "7.2.0"
serde = "1.0" serde = "1.0"

View File

@@ -9,7 +9,7 @@ pub fn list_files(dir: PathBuf) -> io::Result<Vec<PathBuf>> {
.filter(|entry| is_image_or_video(&entry.path()) || entry.file_type().unwrap().is_dir()) .filter(|entry| is_image_or_video(&entry.path()) || entry.file_type().unwrap().is_dir())
.map(|entry| entry.path()) .map(|entry| entry.path())
.map(|path: PathBuf| { .map(|path: PathBuf| {
let relative = path.strip_prefix(std::env::current_dir().unwrap()).unwrap(); let relative = path.strip_prefix(dotenv::var("BASE_PATH").unwrap()).unwrap();
relative.to_path_buf() relative.to_path_buf()
}) })
.collect::<Vec<PathBuf>>(); .collect::<Vec<PathBuf>>();

View File

@@ -1,7 +1,8 @@
#[macro_use] #[macro_use]
extern crate diesel; extern crate diesel;
use actix_web::web::{HttpResponse, Json}; use actix_files::NamedFile;
use actix_web::web::{HttpResponse, HttpRequest, Json};
use actix_web::{get, post, App, HttpServer, Responder}; use actix_web::{get, post, App, HttpServer, Responder};
use chrono::{Duration, Utc}; use chrono::{Duration, Utc};
use data::{LoginRequest, ThumbnailRequest}; use data::{LoginRequest, ThumbnailRequest};
@@ -55,22 +56,43 @@ async fn list_photos(_claims: Claims, req: Json<ThumbnailRequest>) -> impl Respo
println!("{}", req.path); println!("{}", req.path);
let path = &req.path; let path = &req.path;
if let Some(path) = is_valid_path(path) {
match path { let files = list_files(path);
path if path.contains("..") => HttpResponse::BadRequest().finish(),
path => {
let path = PathBuf::from(path);
if path.is_relative() {
let mut full_path = std::env::current_dir().unwrap();
full_path.push(path);
let files = list_files(full_path);
HttpResponse::Ok().json(files.unwrap_or_default()) HttpResponse::Ok().json(files.unwrap_or_default())
} else { } else {
HttpResponse::BadRequest().finish() HttpResponse::BadRequest().finish()
} }
}
fn is_valid_path(path: &str) -> Option<PathBuf> {
match path {
path if path.contains("..") => None,
path => {
let path = PathBuf::from(path);
if path.is_relative() {
let mut full_path = PathBuf::from(dotenv::var("BASE_PATH").unwrap());
full_path.push(path);
Some(full_path)
} else {
None
} }
} }
}
}
#[get("/image")]
async fn image(_claims: Claims, request: HttpRequest, req: Json<ThumbnailRequest>) -> impl Responder {
if let Some(path) = is_valid_path(&req.path) {
if let Ok(file) = NamedFile::open(path) {
file.into_response(&request).unwrap()
} else {
HttpResponse::NotFound().finish()
}
} else {
HttpResponse::NotFound().finish()
}
} }
#[actix_rt::main] #[actix_rt::main]
@@ -80,6 +102,7 @@ async fn main() -> std::io::Result<()> {
.service(login) .service(login)
.service(list_photos) .service(list_photos)
.service(register) .service(register)
.service(image)
}) })
.bind("127.0.0.1:8088")? .bind("127.0.0.1:8088")?
.run() .run()