♻️ refactor: rename file_server::State to file_server::FileServer

main
_ 2021-04-17 19:10:52 -05:00
parent ae33337156
commit fd238d8c2b
4 changed files with 99 additions and 99 deletions

View File

@ -30,12 +30,12 @@ use ptth_server::{
file_server::{ file_server::{
self, self,
metrics, metrics,
State, FileServer,
}, },
load_toml, load_toml,
}; };
async fn handle_all (req: Request <Body>, state: Arc <State>) async fn handle_all (req: Request <Body>, state: Arc <FileServer>)
-> anyhow::Result <Response <Body>> -> anyhow::Result <Response <Body>>
{ {
use std::str::FromStr; use std::str::FromStr;
@ -51,8 +51,7 @@ async fn handle_all (req: Request <Body>, state: Arc <State>)
let ptth_req = RequestParts::from_hyper (parts.method, path_and_query, parts.headers)?; let ptth_req = RequestParts::from_hyper (parts.method, path_and_query, parts.headers)?;
let ptth_resp = file_server::serve_all ( let ptth_resp = state.serve_all (
&state,
ptth_req.method, ptth_req.method,
&ptth_req.uri, &ptth_req.uri,
&ptth_req.headers &ptth_req.headers
@ -95,7 +94,7 @@ async fn main () -> anyhow::Result <()> {
file_server::metrics::Interval::monitor (interval_writer).await; file_server::metrics::Interval::monitor (interval_writer).await;
}); });
let state = Arc::new (State::new ( let state = Arc::new (FileServer::new (
config_file.file_server_root, config_file.file_server_root,
&PathBuf::new (), &PathBuf::new (),
config_file.name.unwrap_or_else (|| "PTTH File Server".to_string ()), config_file.name.unwrap_or_else (|| "PTTH File Server".to_string ()),

View File

@ -46,7 +46,7 @@ struct DirEntry {
} }
pub async fn serve_root ( pub async fn serve_root (
state: &super::State, state: &super::FileServer,
) -> Result <Response, FileServerError> ) -> Result <Response, FileServerError>
{ {
#[derive (Serialize)] #[derive (Serialize)]

View File

@ -59,7 +59,7 @@ pub struct Config {
pub file_server_root: Option <PathBuf>, pub file_server_root: Option <PathBuf>,
} }
pub struct State { pub struct FileServer {
pub config: Config, pub config: Config,
pub handlebars: handlebars::Handlebars <'static>, pub handlebars: handlebars::Handlebars <'static>,
pub metrics_startup: metrics::Startup, pub metrics_startup: metrics::Startup,
@ -67,7 +67,7 @@ pub struct State {
pub hidden_path: Option <PathBuf>, pub hidden_path: Option <PathBuf>,
} }
impl State { impl FileServer {
pub fn new ( pub fn new (
file_server_root: Option <PathBuf>, file_server_root: Option <PathBuf>,
asset_root: &Path, asset_root: &Path,
@ -332,98 +332,100 @@ async fn stream_file (
} }
} }
/// Top-level request handler for the file server module. impl FileServer {
/// /// Top-level request handler for the file server module.
/// Passes a request to the internal file server logic. ///
/// Returns an HTTP response as HTML or JSON, depending on the request. /// Passes a request to the internal file server logic.
/// Returns an HTTP response as HTML or JSON, depending on the request.
#[instrument (level = "debug", skip (state, headers))] #[instrument (level = "debug", skip (self, headers))]
pub async fn serve_all ( pub async fn serve_all (
state: &State, &self,
method: Method, method: Method,
uri: &str, uri: &str,
headers: &HashMap <String, Vec <u8>> headers: &HashMap <String, Vec <u8>>
)
-> Result <Response, FileServerError>
{
use internal::{
OutputFormat,
Response::*,
};
fn serve_error <S: Into <Vec <u8>>> (
status_code: StatusCode,
msg: S
) )
-> Response -> Result <Response, FileServerError>
{ {
let mut resp = Response::default (); use internal::{
resp.status_code (status_code); OutputFormat,
resp.body_bytes (msg.into ()); Response::*,
resp };
}
let default_root = PathBuf::from ("./");
let root: &std::path::Path = state.config.file_server_root
.as_ref ()
.unwrap_or (&default_root);
Ok (match internal::serve_all (root, method, uri, headers, state.hidden_path.as_deref ()).await? {
Favicon => serve_error (StatusCode::NotFound, "Not found\n"),
Forbidden => serve_error (StatusCode::Forbidden, "403 Forbidden\n"),
MethodNotAllowed => serve_error (StatusCode::MethodNotAllowed, "Unsupported method\n"),
NotFound => serve_error (StatusCode::NotFound, "404 Not Found\nAre you missing a trailing slash?\n"),
RangeNotSatisfiable (file_len) => {
let mut resp = Response::default ();
resp.status_code (StatusCode::RangeNotSatisfiable)
.header ("content-range".to_string (), format! ("bytes */{}", file_len).into_bytes ());
resp
},
Redirect (location) => {
let mut resp = Response::default ();
resp.status_code (StatusCode::TemporaryRedirect)
.header ("location".to_string (), location.into_bytes ());
resp.body_bytes (b"Redirecting...\n".to_vec ());
resp
},
InvalidQuery => serve_error (StatusCode::BadRequest, "Query is invalid for this object\n"),
Root => html::serve_root (state).await?, fn serve_error <S: Into <Vec <u8>>> (
ServeDir (internal::ServeDirParams { status_code: StatusCode,
path, msg: S
dir, )
format -> Response
}) => match format { {
OutputFormat::Json => serve_dir_json (dir.into_inner ()).await?, let mut resp = Response::default ();
OutputFormat::Html => html::serve_dir (&state.handlebars, &state.metrics_startup, path.to_string_lossy (), dir.into_inner ()).await?, resp.status_code (status_code);
}, resp.body_bytes (msg.into ());
ServeFile (internal::ServeFileParams { resp
file, }
send_body,
range, let default_root = PathBuf::from ("./");
}) => serve_file (file.into_inner (), send_body, range, headers.get ("if-none-match").map (|v| &v[..])).await?, let root: &std::path::Path = self.config.file_server_root
MarkdownErr (e) => { .as_ref ()
#[cfg (feature = "markdown")] .unwrap_or (&default_root);
{
use markdown::Error::*; Ok (match internal::serve_all (root, method, uri, headers, self.hidden_path.as_deref ()).await? {
let e = e.inner; Favicon => serve_error (StatusCode::NotFound, "Not found\n"),
let code = match &e { Forbidden => serve_error (StatusCode::Forbidden, "403 Forbidden\n"),
TooBig => StatusCode::InternalServerError, MethodNotAllowed => serve_error (StatusCode::MethodNotAllowed, "Unsupported method\n"),
//NotMarkdown => serve_error (StatusCode::BadRequest, "File is not Markdown"), NotFound => serve_error (StatusCode::NotFound, "404 Not Found\nAre you missing a trailing slash?\n"),
NotUtf8 => StatusCode::BadRequest, RangeNotSatisfiable (file_len) => {
}; let mut resp = Response::default ();
resp.status_code (StatusCode::RangeNotSatisfiable)
return Ok (serve_error (code, e.to_string ())); .header ("content-range".to_string (), format! ("bytes */{}", file_len).into_bytes ());
} resp
},
Redirect (location) => {
let mut resp = Response::default ();
resp.status_code (StatusCode::TemporaryRedirect)
.header ("location".to_string (), location.into_bytes ());
resp.body_bytes (b"Redirecting...\n".to_vec ());
resp
},
InvalidQuery => serve_error (StatusCode::BadRequest, "Query is invalid for this object\n"),
#[cfg (not (feature = "markdown"))] Root => html::serve_root (self).await?,
{ ServeDir (internal::ServeDirParams {
let _e = e; path,
serve_error (StatusCode::BadRequest, "Markdown feature is disabled") dir,
} format
}, }) => match format {
MarkdownPreview (s) => html::serve (s), OutputFormat::Json => serve_dir_json (dir.into_inner ()).await?,
}) OutputFormat::Html => html::serve_dir (&self.handlebars, &self.metrics_startup, path.to_string_lossy (), dir.into_inner ()).await?,
},
ServeFile (internal::ServeFileParams {
file,
send_body,
range,
}) => serve_file (file.into_inner (), send_body, range, headers.get ("if-none-match").map (|v| &v[..])).await?,
MarkdownErr (e) => {
#[cfg (feature = "markdown")]
{
use markdown::Error::*;
let e = e.inner;
let code = match &e {
TooBig => StatusCode::InternalServerError,
//NotMarkdown => serve_error (StatusCode::BadRequest, "File is not Markdown"),
NotUtf8 => StatusCode::BadRequest,
};
return Ok (serve_error (code, e.to_string ()));
}
#[cfg (not (feature = "markdown"))]
{
let _e = e;
serve_error (StatusCode::BadRequest, "Markdown feature is disabled")
}
},
MarkdownPreview (s) => html::serve (s),
})
}
} }
fn load_templates ( fn load_templates (

View File

@ -46,7 +46,7 @@ pub mod load_toml;
use errors::ServerError; use errors::ServerError;
struct State { struct State {
file_server: file_server::State, file_server: file_server::FileServer,
config: Config, config: Config,
client: Client, client: Client,
} }
@ -63,8 +63,7 @@ async fn handle_one_req (
debug! ("Handling request {}", req_id); debug! ("Handling request {}", req_id);
let response = file_server::serve_all ( let response = state.file_server.serve_all (
&state.file_server,
parts.method, parts.method,
&parts.uri, &parts.uri,
&parts.headers, &parts.headers,
@ -253,7 +252,7 @@ pub async fn run_server (
}); });
let state = Arc::new (State { let state = Arc::new (State {
file_server: file_server::State::new ( file_server: file_server::FileServer::new (
config_file.file_server_root, config_file.file_server_root,
&asset_root, &asset_root,
config_file.name, config_file.name,