2020-11-29 20:22:40 +00:00
|
|
|
#![warn (clippy::pedantic)]
|
|
|
|
|
2020-10-31 01:35:39 +00:00
|
|
|
use std::{
|
2020-11-07 01:34:58 +00:00
|
|
|
net::SocketAddr,
|
2020-10-31 01:35:39 +00:00
|
|
|
path::PathBuf,
|
|
|
|
sync::Arc,
|
|
|
|
};
|
|
|
|
|
|
|
|
use hyper::{
|
|
|
|
Body,
|
|
|
|
Request,
|
|
|
|
Response,
|
|
|
|
Server,
|
|
|
|
service::{
|
|
|
|
make_service_fn,
|
|
|
|
service_fn,
|
|
|
|
},
|
|
|
|
StatusCode,
|
|
|
|
};
|
2020-11-07 00:30:56 +00:00
|
|
|
use serde::Deserialize;
|
2020-12-18 20:43:34 +00:00
|
|
|
use tracing::debug;
|
2020-10-31 01:35:39 +00:00
|
|
|
|
2020-11-27 00:03:11 +00:00
|
|
|
use ptth_core::{
|
2020-10-31 17:56:36 +00:00
|
|
|
http_serde::RequestParts,
|
2020-11-08 16:00:31 +00:00
|
|
|
prelude::*,
|
2020-10-31 17:56:36 +00:00
|
|
|
};
|
2020-11-27 00:50:22 +00:00
|
|
|
use ptth_server::{
|
2020-12-18 20:43:34 +00:00
|
|
|
file_server::{
|
|
|
|
self,
|
|
|
|
metrics::InstanceMetrics,
|
|
|
|
},
|
2020-11-27 00:50:22 +00:00
|
|
|
load_toml,
|
|
|
|
};
|
2020-10-31 17:56:36 +00:00
|
|
|
|
2020-11-07 00:30:56 +00:00
|
|
|
#[derive (Default)]
|
|
|
|
pub struct Config {
|
|
|
|
pub file_server_root: Option <PathBuf>,
|
|
|
|
}
|
|
|
|
|
2020-10-31 02:31:03 +00:00
|
|
|
struct ServerState <'a> {
|
2020-11-07 00:30:56 +00:00
|
|
|
config: Config,
|
|
|
|
handlebars: handlebars::Handlebars <'a>,
|
2020-12-18 20:43:34 +00:00
|
|
|
instance_metrics: InstanceMetrics,
|
2020-11-08 17:58:14 +00:00
|
|
|
hidden_path: Option <PathBuf>,
|
2020-10-31 01:35:39 +00:00
|
|
|
}
|
|
|
|
|
2020-10-31 02:31:03 +00:00
|
|
|
async fn handle_all (req: Request <Body>, state: Arc <ServerState <'static>>)
|
2020-11-29 21:55:24 +00:00
|
|
|
-> Result <Response <Body>, anyhow::Error>
|
2020-10-31 01:35:39 +00:00
|
|
|
{
|
2020-11-29 19:05:28 +00:00
|
|
|
use std::str::FromStr;
|
2020-12-15 05:15:17 +00:00
|
|
|
use hyper::header::HeaderName;
|
2020-11-29 19:05:28 +00:00
|
|
|
|
2020-11-08 15:53:09 +00:00
|
|
|
debug! ("req.uri () = {:?}", req.uri ());
|
|
|
|
|
2020-11-29 20:22:40 +00:00
|
|
|
let path_and_query = req.uri ().path_and_query ().map_or_else (|| req.uri ().path (), http::uri::PathAndQuery::as_str);
|
2020-10-31 01:35:39 +00:00
|
|
|
|
2020-11-10 02:39:20 +00:00
|
|
|
let path_and_query = path_and_query.into ();
|
2020-11-08 15:53:09 +00:00
|
|
|
|
|
|
|
let (parts, _) = req.into_parts ();
|
|
|
|
|
2020-11-29 20:22:40 +00:00
|
|
|
let ptth_req = RequestParts::from_hyper (parts.method, path_and_query, parts.headers)?;
|
2020-11-08 15:53:09 +00:00
|
|
|
|
|
|
|
let default_root = PathBuf::from ("./");
|
|
|
|
let file_server_root: &std::path::Path = state.config.file_server_root
|
|
|
|
.as_ref ()
|
|
|
|
.unwrap_or (&default_root);
|
|
|
|
|
|
|
|
let ptth_resp = file_server::serve_all (
|
2020-11-10 00:44:21 +00:00
|
|
|
&state.handlebars,
|
2020-12-18 20:43:34 +00:00
|
|
|
&state.instance_metrics,
|
2020-11-08 15:53:09 +00:00
|
|
|
file_server_root,
|
|
|
|
ptth_req.method,
|
|
|
|
&ptth_req.uri,
|
|
|
|
&ptth_req.headers,
|
2020-11-25 00:16:14 +00:00
|
|
|
state.hidden_path.as_deref ()
|
2020-11-29 19:19:59 +00:00
|
|
|
).await?;
|
2020-11-08 15:53:09 +00:00
|
|
|
|
|
|
|
let mut resp = Response::builder ()
|
|
|
|
.status (StatusCode::from (ptth_resp.parts.status_code));
|
|
|
|
|
2020-11-29 20:22:40 +00:00
|
|
|
for (k, v) in ptth_resp.parts.headers {
|
2020-12-15 05:15:17 +00:00
|
|
|
resp = resp.header (HeaderName::from_str (&k)?, v);
|
2020-10-31 01:35:39 +00:00
|
|
|
}
|
2020-11-08 15:53:09 +00:00
|
|
|
|
2020-11-29 20:22:40 +00:00
|
|
|
let body = ptth_resp.body.map_or_else (Body::empty, Body::wrap_stream);
|
2020-11-08 15:53:09 +00:00
|
|
|
|
2020-11-29 19:19:59 +00:00
|
|
|
Ok (resp.body (body)?)
|
2020-10-31 01:35:39 +00:00
|
|
|
}
|
|
|
|
|
2020-11-07 00:30:56 +00:00
|
|
|
#[derive (Deserialize)]
|
|
|
|
pub struct ConfigFile {
|
|
|
|
pub file_server_root: Option <PathBuf>,
|
2020-11-10 00:44:21 +00:00
|
|
|
pub name: Option <String>,
|
2020-11-07 00:30:56 +00:00
|
|
|
}
|
|
|
|
|
2020-10-31 01:35:39 +00:00
|
|
|
#[tokio::main]
|
2020-11-29 21:38:23 +00:00
|
|
|
async fn main () -> Result <(), anyhow::Error> {
|
2020-11-07 00:30:56 +00:00
|
|
|
tracing_subscriber::fmt::init ();
|
2020-11-08 17:58:14 +00:00
|
|
|
|
|
|
|
let path = PathBuf::from ("./config/ptth_server.toml");
|
2020-11-29 21:38:23 +00:00
|
|
|
let config_file: ConfigFile = load_toml::load (&path)?;
|
2020-11-07 00:30:56 +00:00
|
|
|
info! ("file_server_root: {:?}", config_file.file_server_root);
|
|
|
|
|
2020-10-31 01:35:39 +00:00
|
|
|
let addr = SocketAddr::from(([0, 0, 0, 0], 4000));
|
|
|
|
|
2020-11-18 23:24:47 +00:00
|
|
|
let handlebars = file_server::load_templates (&PathBuf::new ())?;
|
2020-10-31 02:31:03 +00:00
|
|
|
|
2020-12-18 20:43:34 +00:00
|
|
|
let instance_metrics = InstanceMetrics::new (
|
|
|
|
config_file.name.unwrap_or_else (|| "PTTH File Server".to_string ())
|
|
|
|
);
|
|
|
|
|
|
|
|
debug! ("{:?}", instance_metrics);
|
|
|
|
|
2020-10-31 02:31:03 +00:00
|
|
|
let state = Arc::new (ServerState {
|
2020-11-07 00:30:56 +00:00
|
|
|
config: Config {
|
|
|
|
file_server_root: config_file.file_server_root,
|
|
|
|
},
|
2020-11-07 01:34:58 +00:00
|
|
|
handlebars,
|
2020-12-18 20:43:34 +00:00
|
|
|
instance_metrics,
|
2020-11-08 17:58:14 +00:00
|
|
|
hidden_path: Some (path),
|
2020-10-31 02:31:03 +00:00
|
|
|
});
|
2020-10-31 01:35:39 +00:00
|
|
|
|
|
|
|
let make_svc = make_service_fn (|_conn| {
|
|
|
|
let state = state.clone ();
|
|
|
|
|
|
|
|
async {
|
2020-11-07 01:34:58 +00:00
|
|
|
Ok::<_, String> (service_fn (move |req| {
|
2020-10-31 01:35:39 +00:00
|
|
|
let state = state.clone ();
|
|
|
|
|
|
|
|
handle_all (req, state)
|
|
|
|
}))
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2020-11-27 00:03:11 +00:00
|
|
|
let (shutdown_rx, forced_shutdown) = ptth_core::graceful_shutdown::init_with_force ();
|
2020-11-07 01:34:58 +00:00
|
|
|
|
|
|
|
let server = Server::bind (&addr)
|
|
|
|
.serve (make_svc)
|
|
|
|
.with_graceful_shutdown (async move {
|
2020-11-07 02:26:34 +00:00
|
|
|
shutdown_rx.await.ok ();
|
2020-11-07 01:34:58 +00:00
|
|
|
});
|
|
|
|
|
2020-11-07 02:26:34 +00:00
|
|
|
forced_shutdown.wrap_server (server).await??;
|
2020-10-31 01:35:39 +00:00
|
|
|
|
|
|
|
Ok (())
|
|
|
|
}
|