♻️ Make the server's inner handlers look more like a regular Hyper server

main
_ 2020-10-30 17:11:35 -05:00
parent 1615f0d075
commit 325f68b566
2 changed files with 42 additions and 54 deletions

View File

@ -1,6 +1,5 @@
use std::{ use std::{
cmp::{min, max}, cmp::{min, max},
collections::*,
convert::{Infallible, TryInto}, convert::{Infallible, TryInto},
error::Error, error::Error,
io::SeekFrom, io::SeekFrom,
@ -88,10 +87,7 @@ impl <'a> ResponseHandle <'a> {
} }
} }
async fn serve_dir ( async fn serve_dir (mut dir: ReadDir) -> http_serde::Response {
response_handle: ResponseHandle <'_>,
mut dir: ReadDir
) {
let (tx, rx) = channel (2); let (tx, rx) = channel (2);
tokio::spawn (async move { tokio::spawn (async move {
@ -142,25 +138,20 @@ async fn serve_dir (
tx.send (Ok::<_, Infallible> (String::from ("</ul>").into_bytes ())).await.unwrap (); tx.send (Ok::<_, Infallible> (String::from ("</ul>").into_bytes ())).await.unwrap ();
}); });
let mut headers: HashMap <String, Vec <u8>> = 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 { response
status_code: http_serde::StatusCode::Ok,
headers,
};
response_handle.respond (resp_parts, Some (Body::wrap_stream (rx))).await;
} }
async fn serve_file ( async fn serve_file (
response_handle: ResponseHandle <'_>,
mut f: File, mut f: File,
should_send_body: bool, should_send_body: bool,
range_start: Option <u64>, range_start: Option <u64>,
range_end: Option <u64> range_end: Option <u64>
) { ) -> http_serde::Response {
let (tx, rx) = channel (2); let (tx, rx) = channel (2);
let body = if should_send_body { let body = if should_send_body {
Some (Body::wrap_stream (rx)) Some (Body::wrap_stream (rx))
@ -219,40 +210,38 @@ async fn serve_file (
}); });
} }
let mut headers: HashMap <String, Vec <u8>> = Default::default (); let mut response = http_serde::Response::default ();
headers.insert (String::from ("accept-ranges"), b"bytes".to_vec ());
let status_code; response.header (String::from ("accept-ranges"), b"bytes".to_vec ());
if range_start.is_none () && range_end.is_none () { if range_start.is_none () && range_end.is_none () {
headers.insert (String::from ("content-length"), end.to_string ().into_bytes ()); response.status_code (http_serde::StatusCode::Ok);
status_code = http_serde::StatusCode::Ok; response.header (String::from ("content-length"), end.to_string ().into_bytes ());
} }
else { else {
headers.insert (String::from ("content-range"), format! ("bytes {}-{}/{}", start, end - 1, end).into_bytes ()); response.status_code (http_serde::StatusCode::PartialContent);
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 { if let Some (body) = body {
status_code, response.body (body);
headers, }
};
response_handle.respond (resp_parts, body).await; response
} }
async fn serve_error ( async fn serve_error (
response_handle: ResponseHandle <'_>, status_code: http_serde::StatusCode,
status_code: http_serde::StatusCode msg: String
) { )
let headers: HashMap <String, Vec <u8>> = Default::default (); -> http_serde::Response
{
let mut response = http_serde::Response::default ();
let resp_parts = http_serde::ResponseParts { response.status_code (status_code);
status_code, response.body (msg.into ());
headers,
};
response_handle.respond (resp_parts, Some ("404 Not Found".into ())).await; response
} }
async fn handle_all ( async fn handle_all (
@ -307,29 +296,27 @@ async fn handle_all (
let mut full_path = PathBuf::from ("/home/user"); let mut full_path = PathBuf::from ("/home/user");
full_path.push (&*path); 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 { let response_handle = ResponseHandle {
client, client,
req_id: &req_id, req_id: &req_id,
}; };
if let Ok (dir) = read_dir (&full_path).await { response_handle.respond_2 (response).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;
}
Ok (()) Ok (())
} }

View File

@ -1,3 +1,4 @@
- Add ".." for parent directory
- Set up tokens or something so clients can't trivially - Set up tokens or something so clients can't trivially
impersonate servers impersonate servers
- Offer list of clients at server root - Offer list of clients at server root