➕ add ptth_file_server to ptth_multi_call_server.
Even with all 3 servers it's only 18 MB - Most of the big code is shared.main
parent
4911a37887
commit
b8d07c526a
|
@ -0,0 +1,127 @@
|
||||||
|
#![warn (clippy::pedantic)]
|
||||||
|
|
||||||
|
use std::{
|
||||||
|
ffi::OsString,
|
||||||
|
net::SocketAddr,
|
||||||
|
path::PathBuf,
|
||||||
|
sync::Arc,
|
||||||
|
};
|
||||||
|
|
||||||
|
use arc_swap::ArcSwap;
|
||||||
|
use hyper::{
|
||||||
|
Body,
|
||||||
|
Request,
|
||||||
|
Response,
|
||||||
|
Server,
|
||||||
|
service::{
|
||||||
|
make_service_fn,
|
||||||
|
service_fn,
|
||||||
|
},
|
||||||
|
StatusCode,
|
||||||
|
};
|
||||||
|
use serde::Deserialize;
|
||||||
|
use tokio_stream::wrappers::ReceiverStream;
|
||||||
|
use tracing::debug;
|
||||||
|
|
||||||
|
use ptth_core::{
|
||||||
|
http_serde::RequestParts,
|
||||||
|
prelude::*,
|
||||||
|
};
|
||||||
|
use ptth_server::{
|
||||||
|
file_server::{
|
||||||
|
self,
|
||||||
|
metrics,
|
||||||
|
FileServer,
|
||||||
|
},
|
||||||
|
load_toml,
|
||||||
|
};
|
||||||
|
|
||||||
|
async fn handle_all (req: Request <Body>, state: Arc <FileServer>)
|
||||||
|
-> anyhow::Result <Response <Body>>
|
||||||
|
{
|
||||||
|
use std::str::FromStr;
|
||||||
|
use hyper::header::HeaderName;
|
||||||
|
|
||||||
|
debug! ("req.uri () = {:?}", req.uri ());
|
||||||
|
|
||||||
|
let path_and_query = req.uri ().path_and_query ().map_or_else (|| req.uri ().path (), http::uri::PathAndQuery::as_str);
|
||||||
|
|
||||||
|
let path_and_query = path_and_query.into ();
|
||||||
|
|
||||||
|
let (parts, _) = req.into_parts ();
|
||||||
|
|
||||||
|
let ptth_req = RequestParts::from_hyper (parts.method, path_and_query, parts.headers)?;
|
||||||
|
|
||||||
|
let ptth_resp = state.serve_all (
|
||||||
|
ptth_req.method,
|
||||||
|
&ptth_req.uri,
|
||||||
|
&ptth_req.headers
|
||||||
|
).await?;
|
||||||
|
|
||||||
|
let mut resp = Response::builder ()
|
||||||
|
.status (StatusCode::from (ptth_resp.parts.status_code));
|
||||||
|
|
||||||
|
for (k, v) in ptth_resp.parts.headers {
|
||||||
|
resp = resp.header (HeaderName::from_str (&k)?, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
let body = ptth_resp.body.map_or_else (Body::empty, |body| {
|
||||||
|
Body::wrap_stream (ReceiverStream::new (body))
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok (resp.body (body)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive (Deserialize)]
|
||||||
|
struct ConfigFile {
|
||||||
|
file_server_root: Option <PathBuf>,
|
||||||
|
name: Option <String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn main (_args: &[OsString]) -> anyhow::Result <()> {
|
||||||
|
let path = PathBuf::from ("./config/ptth_server.toml");
|
||||||
|
let config_file: ConfigFile = load_toml::load (&path)?;
|
||||||
|
info! ("file_server_root: {:?}", config_file.file_server_root);
|
||||||
|
|
||||||
|
let addr = SocketAddr::from(([0, 0, 0, 0], 4000));
|
||||||
|
|
||||||
|
let metrics_interval = Arc::new (ArcSwap::default ());
|
||||||
|
|
||||||
|
let interval_writer = Arc::clone (&metrics_interval);
|
||||||
|
tokio::spawn (async move {
|
||||||
|
file_server::metrics::Interval::monitor (interval_writer).await;
|
||||||
|
});
|
||||||
|
|
||||||
|
let state = Arc::new (FileServer::new (
|
||||||
|
config_file.file_server_root,
|
||||||
|
&PathBuf::new (),
|
||||||
|
config_file.name.unwrap_or_else (|| "PTTH File Server".to_string ()),
|
||||||
|
metrics_interval,
|
||||||
|
Some (path),
|
||||||
|
)?);
|
||||||
|
|
||||||
|
let make_svc = make_service_fn (|_conn| {
|
||||||
|
let state = state.clone ();
|
||||||
|
|
||||||
|
async {
|
||||||
|
Ok::<_, String> (service_fn (move |req| {
|
||||||
|
let state = state.clone ();
|
||||||
|
|
||||||
|
handle_all (req, state)
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let (shutdown_rx, forced_shutdown) = ptth_core::graceful_shutdown::init_with_force ();
|
||||||
|
|
||||||
|
let server = Server::bind (&addr)
|
||||||
|
.serve (make_svc)
|
||||||
|
.with_graceful_shutdown (async move {
|
||||||
|
shutdown_rx.await.ok ();
|
||||||
|
});
|
||||||
|
|
||||||
|
forced_shutdown.wrap_server (server).await??;
|
||||||
|
|
||||||
|
Ok (())
|
||||||
|
}
|
||||||
|
|
|
@ -1,128 +1,12 @@
|
||||||
#![warn (clippy::pedantic)]
|
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
net::SocketAddr,
|
iter::FromIterator,
|
||||||
path::PathBuf,
|
|
||||||
sync::Arc,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use arc_swap::ArcSwap;
|
|
||||||
use hyper::{
|
|
||||||
Body,
|
|
||||||
Request,
|
|
||||||
Response,
|
|
||||||
Server,
|
|
||||||
service::{
|
|
||||||
make_service_fn,
|
|
||||||
service_fn,
|
|
||||||
},
|
|
||||||
StatusCode,
|
|
||||||
};
|
|
||||||
use serde::Deserialize;
|
|
||||||
use tokio_stream::wrappers::ReceiverStream;
|
|
||||||
use tracing::debug;
|
|
||||||
|
|
||||||
use ptth_core::{
|
|
||||||
http_serde::RequestParts,
|
|
||||||
prelude::*,
|
|
||||||
};
|
|
||||||
use ptth_server::{
|
|
||||||
file_server::{
|
|
||||||
self,
|
|
||||||
metrics,
|
|
||||||
FileServer,
|
|
||||||
},
|
|
||||||
load_toml,
|
|
||||||
};
|
|
||||||
|
|
||||||
async fn handle_all (req: Request <Body>, state: Arc <FileServer>)
|
|
||||||
-> anyhow::Result <Response <Body>>
|
|
||||||
{
|
|
||||||
use std::str::FromStr;
|
|
||||||
use hyper::header::HeaderName;
|
|
||||||
|
|
||||||
debug! ("req.uri () = {:?}", req.uri ());
|
|
||||||
|
|
||||||
let path_and_query = req.uri ().path_and_query ().map_or_else (|| req.uri ().path (), http::uri::PathAndQuery::as_str);
|
|
||||||
|
|
||||||
let path_and_query = path_and_query.into ();
|
|
||||||
|
|
||||||
let (parts, _) = req.into_parts ();
|
|
||||||
|
|
||||||
let ptth_req = RequestParts::from_hyper (parts.method, path_and_query, parts.headers)?;
|
|
||||||
|
|
||||||
let ptth_resp = state.serve_all (
|
|
||||||
ptth_req.method,
|
|
||||||
&ptth_req.uri,
|
|
||||||
&ptth_req.headers
|
|
||||||
).await?;
|
|
||||||
|
|
||||||
let mut resp = Response::builder ()
|
|
||||||
.status (StatusCode::from (ptth_resp.parts.status_code));
|
|
||||||
|
|
||||||
for (k, v) in ptth_resp.parts.headers {
|
|
||||||
resp = resp.header (HeaderName::from_str (&k)?, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
let body = ptth_resp.body.map_or_else (Body::empty, |body| {
|
|
||||||
Body::wrap_stream (ReceiverStream::new (body))
|
|
||||||
});
|
|
||||||
|
|
||||||
Ok (resp.body (body)?)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive (Deserialize)]
|
|
||||||
pub struct ConfigFile {
|
|
||||||
pub file_server_root: Option <PathBuf>,
|
|
||||||
pub name: Option <String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main () -> anyhow::Result <()> {
|
async fn main () -> anyhow::Result <()> {
|
||||||
tracing_subscriber::fmt::init ();
|
tracing_subscriber::fmt::init ();
|
||||||
|
|
||||||
let path = PathBuf::from ("./config/ptth_server.toml");
|
let args = Vec::from_iter (std::env::args_os ());
|
||||||
let config_file: ConfigFile = load_toml::load (&path)?;
|
|
||||||
info! ("file_server_root: {:?}", config_file.file_server_root);
|
|
||||||
|
|
||||||
let addr = SocketAddr::from(([0, 0, 0, 0], 4000));
|
ptth_file_server::main (&args).await
|
||||||
|
|
||||||
let metrics_interval = Arc::new (ArcSwap::default ());
|
|
||||||
|
|
||||||
let interval_writer = Arc::clone (&metrics_interval);
|
|
||||||
tokio::spawn (async move {
|
|
||||||
file_server::metrics::Interval::monitor (interval_writer).await;
|
|
||||||
});
|
|
||||||
|
|
||||||
let state = Arc::new (FileServer::new (
|
|
||||||
config_file.file_server_root,
|
|
||||||
&PathBuf::new (),
|
|
||||||
config_file.name.unwrap_or_else (|| "PTTH File Server".to_string ()),
|
|
||||||
metrics_interval,
|
|
||||||
Some (path),
|
|
||||||
)?);
|
|
||||||
|
|
||||||
let make_svc = make_service_fn (|_conn| {
|
|
||||||
let state = state.clone ();
|
|
||||||
|
|
||||||
async {
|
|
||||||
Ok::<_, String> (service_fn (move |req| {
|
|
||||||
let state = state.clone ();
|
|
||||||
|
|
||||||
handle_all (req, state)
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let (shutdown_rx, forced_shutdown) = ptth_core::graceful_shutdown::init_with_force ();
|
|
||||||
|
|
||||||
let server = Server::bind (&addr)
|
|
||||||
.serve (make_svc)
|
|
||||||
.with_graceful_shutdown (async move {
|
|
||||||
shutdown_rx.await.ok ();
|
|
||||||
});
|
|
||||||
|
|
||||||
forced_shutdown.wrap_server (server).await??;
|
|
||||||
|
|
||||||
Ok (())
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,7 @@ async fn main () -> anyhow::Result <()> {
|
||||||
let (subcommand, args) = parse_args (&args)?;
|
let (subcommand, args) = parse_args (&args)?;
|
||||||
match subcommand {
|
match subcommand {
|
||||||
Subcommand::PtthServer => ptth_server::executable::main (&args).await,
|
Subcommand::PtthServer => ptth_server::executable::main (&args).await,
|
||||||
Subcommand::PtthFileServer => unimplemented! (),
|
Subcommand::PtthFileServer => ptth_file_server::main (&args).await,
|
||||||
Subcommand::PtthQuicEndServer => quic_demo::executable_end_server::main (&args).await,
|
Subcommand::PtthQuicEndServer => quic_demo::executable_end_server::main (&args).await,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue