From af226cb36c565e782c863a279fa44adb8876bc7c Mon Sep 17 00:00:00 2001 From: _ <> Date: Thu, 29 Oct 2020 13:19:14 +0000 Subject: [PATCH] :construction: Working on directory indexes --- src/bin/server.rs | 133 +++++++++++++++++++++++++++++++--------------- todo.md | 1 + 2 files changed, 92 insertions(+), 42 deletions(-) diff --git a/src/bin/server.rs b/src/bin/server.rs index 7232851..0c946dc 100644 --- a/src/bin/server.rs +++ b/src/bin/server.rs @@ -11,7 +11,6 @@ use std::{ use hyper::{ StatusCode, - Uri, }; use lazy_static::*; use regex::Regex; @@ -20,7 +19,11 @@ use reqwest::{ Client, }; use tokio::{ - fs::File, + fs::{ + File, + read_dir, + ReadDir, + }, io::AsyncReadExt, sync::mpsc::{ channel, @@ -52,30 +55,69 @@ fn parse_range_header (range_str: &str) -> (Option , Option ) { const SERVER_URL: &str = "http://127.0.0.1:4000"; -async fn serve_response ( - client: &Client, - req_id: String, - resp_parts: http_serde::ResponseParts, - body: Option -) { - let mut resp_req = client - .post (&format! ("{}/http_response/{}", SERVER_URL, req_id)) - .header ("X-PTTH-2LJYXWC4", base64::encode (rmp_serde::to_vec (&resp_parts).unwrap ())); - - if let Some (body) = body { - resp_req = resp_req.body (body); - } - - //println! ("Step 6"); - if let Err (e) = resp_req.send ().await { - println! ("Err: {:?}", e); +struct ResponseHandle <'a> { + client: &'a Client, + req_id: &'a str, +} + +impl <'a> ResponseHandle <'a> { + async fn respond ( + self, + resp_parts: http_serde::ResponseParts, + body: Option + ) { + let mut resp_req = self.client + .post (&format! ("{}/http_response/{}", SERVER_URL, self.req_id)) + .header ("X-PTTH-2LJYXWC4", base64::encode (rmp_serde::to_vec (&resp_parts).unwrap ())); + + if let Some (body) = body { + resp_req = resp_req.body (body); + } + + //println! ("Step 6"); + if let Err (e) = resp_req.send ().await { + println! ("Err: {:?}", e); + } } } +async fn serve_dir ( + response_handle: ResponseHandle <'_>, + dir: ReadDir +) { + let (tx, rx) = channel (2); + + tokio::spawn (async move { + let mut tx = tx; + + tx.send (Ok::<_, Infallible> (String::from ("").into_bytes ())).await.unwrap (); + }); + + let mut headers: HashMap > = Default::default (); + + headers.insert ("content-type".into (), String::from ("text/html").into_bytes ()); + + let resp_parts = http_serde::ResponseParts { + status_code: http_serde::StatusCode::Ok, + headers, + }; + + response_handle.respond (resp_parts, Some (Body::wrap_stream (rx))).await; +} + async fn serve_file ( - client: &Client, + response_handle: ResponseHandle <'_>, mut f: File, - req_id: String, should_send_body: bool, range_start: Option , range_end: Option @@ -133,7 +175,7 @@ async fn serve_file ( //bytes_sent += bytes_read; //println! ("Sent {} bytes", bytes_sent); - delay_for (Duration::from_millis (50)).await; + //delay_for (Duration::from_millis (50)).await; } }); } @@ -157,13 +199,12 @@ async fn serve_file ( headers, }; - serve_response (client, req_id, resp_parts, body).await; + response_handle.respond (resp_parts, body).await; } async fn serve_error ( - client: &Client, - req_id: String, - status_code: ptth::http_serde::StatusCode + response_handle: ResponseHandle <'_>, + status_code: http_serde::StatusCode ) { let headers: HashMap > = Default::default (); @@ -172,11 +213,11 @@ async fn serve_error ( headers, }; - serve_response (client, req_id, resp_parts, Some ("404 Not Found".into ())).await; + response_handle.respond (resp_parts, Some ("404 Not Found".into ())).await; } async fn handle_all ( - client: Arc , + client: &Client, req_resp: reqwest::Response ) -> Result <(), Box > { //println! ("Step 1"); @@ -222,22 +263,28 @@ async fn handle_all ( let mut path = PathBuf::from ("/home/user"); path.push (&uri [1..]); - match File::open (path).await { - Ok (f) => serve_file ( - &client, - f, - req_id, + let response_handle = ResponseHandle { + client, + req_id: &req_id, + }; + + if let Ok (dir) = read_dir (&path).await { + serve_dir (response_handle, dir).await; + } + else if let Ok (file) = File::open (&path).await { + serve_file ( + response_handle, + file, should_send_body, range_start, range_end - ).await, - Err (_) => { - serve_error ( - &client, - req_id, - ptth::http_serde::StatusCode::NotFound - ).await; - }, + ).await; + } + else { + serve_error ( + response_handle, + http_serde::StatusCode::NotFound + ).await; } Ok (()) @@ -273,7 +320,9 @@ async fn main () -> Result <(), Box > { let client = client.clone (); tokio::spawn (async move { - handle_all (client, req_resp).await; + match handle_all (&client, req_resp).await { + _ => (), + } }); } } diff --git a/todo.md b/todo.md index 09d38d2..62ef3fb 100644 --- a/todo.md +++ b/todo.md @@ -1,4 +1,5 @@ - Index directories +- Handle trailing slash problem for directories - Set up tokens or something so clients can't trivially impersonate servers - Fix possible timing gap when refreshing http_listen (Just have client wait a few seconds?)