diff --git a/src/main.rs b/src/main.rs index d42dcef..14043ec 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -// mod threaded_archiver; +mod threaded_archiver; mod listing; mod web; diff --git a/src/web.rs b/src/web.rs index 6d5e8de..0dba5d2 100644 --- a/src/web.rs +++ b/src/web.rs @@ -1,8 +1,7 @@ -use actix_files::Files; -use actix_web::{get, middleware, web, App, HttpServer, HttpResponse, Responder}; - - -// use crate::threaded_archiver; +use actix_web::{get, error, middleware, web, App, Error, HttpServer, HttpRequest, HttpResponse, Responder}; +use actix_web::http::StatusCode; +use actix_files::{Files, NamedFile}; +use futures::StreamExt; use std::path::PathBuf; @@ -12,12 +11,12 @@ pub async fn run(bind_addr: &str, root: &PathBuf) -> std::io::Result<()> { let s = HttpServer::new(move || { let static_files = Files::new("/", &root_) - .show_files_listing() - .redirect_to_slash_directory() - .files_listing_renderer(crate::listing::directory_listing); + .show_files_listing() + .redirect_to_slash_directory() + .files_listing_renderer(crate::listing::directory_listing); App::new() - .app_data(root_.clone()) + .data(root_.clone()) .wrap(middleware::Logger::default()) .service(favicon_ico) .service(handle_tar) @@ -31,20 +30,28 @@ pub async fn run(bind_addr: &str, root: &PathBuf) -> std::io::Result<()> { } #[get("/{tail:.*}.tar")] -async fn handle_tar(_root: web::Data, web::Path(_tail): web::Path) -> impl Responder { -// let relpath = PathBuf::from(tail.trim_end_matches('/')); -// let fullpath = root.join(&relpath).canonicalize()?; +async fn handle_tar(req: HttpRequest, root: web::Data, web::Path(tail): web::Path) -> impl Responder { + let relpath = PathBuf::from(tail.trim_end_matches('/')); + let fullpath = root.join(&relpath).canonicalize() + .map_err(|err| error::InternalError::new(err, StatusCode::INTERNAL_SERVER_ERROR))?; -// if !(fullpath.is_dir()) { -// return Err(error::ErrorBadRequest("not a directory")); -// } + if fullpath.is_file() { + return NamedFile::open(fullpath) + .map_err(|err| error::InternalError::new(err, StatusCode::INTERNAL_SERVER_ERROR))? + .into_response(&req); + } -// let stream = threaded_archiver::stream_tar_in_thread(fullpath); -// let resp = HttpResponse::Ok() -// .content_type("application/x-tar") -// .streaming(stream.map_err(|_e| error::ErrorBadRequest("stream error"))); -// Ok(resp) - HttpResponse::Ok() + if !(fullpath.is_dir()) { + return Ok(HttpResponse::NotFound().body("Directory not found")); + } + + let stream = crate::threaded_archiver::stream_tar_in_thread(fullpath) + .map(|item| Ok::<_, Error>(item)); + let res = HttpResponse::Ok() + .content_type("application/x-tar") + .streaming(stream); + + Ok(res) } const FAVICON_ICO: &'static [u8] = include_bytes!("favicon.png");