From 325f68b56614aff64ef01804992978b2527c4940 Mon Sep 17 00:00:00 2001 From: _ <_@_> Date: Fri, 30 Oct 2020 17:11:35 -0500 Subject: [PATCH] :recycle: Make the server's inner handlers look more like a regular Hyper server --- src/bin/server.rs | 95 ++++++++++++++++++++--------------------------- todo.md | 1 + 2 files changed, 42 insertions(+), 54 deletions(-) diff --git a/src/bin/server.rs b/src/bin/server.rs index 39c4862..a461df7 100644 --- a/src/bin/server.rs +++ b/src/bin/server.rs @@ -1,6 +1,5 @@ use std::{ cmp::{min, max}, - collections::*, convert::{Infallible, TryInto}, error::Error, io::SeekFrom, @@ -88,10 +87,7 @@ impl <'a> ResponseHandle <'a> { } } -async fn serve_dir ( - response_handle: ResponseHandle <'_>, - mut dir: ReadDir -) { +async fn serve_dir (mut dir: ReadDir) -> http_serde::Response { let (tx, rx) = channel (2); tokio::spawn (async move { @@ -142,25 +138,20 @@ async fn serve_dir ( tx.send (Ok::<_, Infallible> (String::from ("").into_bytes ())).await.unwrap (); }); - let mut headers: HashMap > = Default::default (); + let mut response = http_serde::Response::default (); - headers.insert ("content-type".into (), String::from ("text/html").into_bytes ()); + response.header ("content-type".into (), String::from ("text/html").into_bytes ()); + response.body (Body::wrap_stream (rx)); - let resp_parts = http_serde::ResponseParts { - status_code: http_serde::StatusCode::Ok, - headers, - }; - - response_handle.respond (resp_parts, Some (Body::wrap_stream (rx))).await; + response } async fn serve_file ( - response_handle: ResponseHandle <'_>, mut f: File, should_send_body: bool, range_start: Option , range_end: Option -) { +) -> http_serde::Response { let (tx, rx) = channel (2); let body = if should_send_body { Some (Body::wrap_stream (rx)) @@ -219,40 +210,38 @@ async fn serve_file ( }); } - let mut headers: HashMap > = Default::default (); - headers.insert (String::from ("accept-ranges"), b"bytes".to_vec ()); + let mut response = http_serde::Response::default (); - let status_code; + response.header (String::from ("accept-ranges"), b"bytes".to_vec ()); if range_start.is_none () && range_end.is_none () { - headers.insert (String::from ("content-length"), end.to_string ().into_bytes ()); - status_code = http_serde::StatusCode::Ok; + response.status_code (http_serde::StatusCode::Ok); + response.header (String::from ("content-length"), end.to_string ().into_bytes ()); } else { - headers.insert (String::from ("content-range"), format! ("bytes {}-{}/{}", start, end - 1, end).into_bytes ()); - status_code = http_serde::StatusCode::PartialContent; + response.status_code (http_serde::StatusCode::PartialContent); + response.header (String::from ("content-range"), format! ("bytes {}-{}/{}", start, end - 1, end).into_bytes ()); } - let resp_parts = http_serde::ResponseParts { - status_code, - headers, - }; + if let Some (body) = body { + response.body (body); + } - response_handle.respond (resp_parts, body).await; + response } async fn serve_error ( - response_handle: ResponseHandle <'_>, - status_code: http_serde::StatusCode -) { - let headers: HashMap > = Default::default (); + status_code: http_serde::StatusCode, + msg: String +) +-> http_serde::Response +{ + let mut response = http_serde::Response::default (); - let resp_parts = http_serde::ResponseParts { - status_code, - headers, - }; + response.status_code (status_code); + response.body (msg.into ()); - response_handle.respond (resp_parts, Some ("404 Not Found".into ())).await; + response } async fn handle_all ( @@ -307,29 +296,27 @@ async fn handle_all ( let mut full_path = PathBuf::from ("/home/user"); full_path.push (&*path); + let response = if let Ok (dir) = read_dir (&full_path).await { + serve_dir (dir).await + } + else if let Ok (file) = File::open (&full_path).await { + serve_file ( + file, + should_send_body, + range_start, + range_end + ).await + } + else { + serve_error (http_serde::StatusCode::NotFound, "404 Not Found".into ()).await + }; + let response_handle = ResponseHandle { client, req_id: &req_id, }; - if let Ok (dir) = read_dir (&full_path).await { - serve_dir (response_handle, dir).await; - } - else if let Ok (file) = File::open (&full_path).await { - serve_file ( - response_handle, - file, - should_send_body, - range_start, - range_end - ).await; - } - else { - serve_error ( - response_handle, - http_serde::StatusCode::NotFound - ).await; - } + response_handle.respond_2 (response).await; Ok (()) } diff --git a/todo.md b/todo.md index 7d9e5df..ce39f7c 100644 --- a/todo.md +++ b/todo.md @@ -1,3 +1,4 @@ +- Add ".." for parent directory - Set up tokens or something so clients can't trivially impersonate servers - Offer list of clients at server root