♻️ refactor: rename file_server::State to file_server::FileServer
parent
ae33337156
commit
fd238d8c2b
|
@ -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 ()),
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
|
@ -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 (
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue