➕ 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::{ | ||||
| 	net::SocketAddr, | ||||
| 	path::PathBuf, | ||||
| 	sync::Arc, | ||||
| 	iter::FromIterator, | ||||
| }; | ||||
| 
 | ||||
| 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] | ||||
| async fn main () -> anyhow::Result <()> { | ||||
| 	tracing_subscriber::fmt::init (); | ||||
| 	
 | ||||
| 	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 args = Vec::from_iter (std::env::args_os ()); | ||||
| 	
 | ||||
| 	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 (()) | ||||
| 	ptth_file_server::main (&args).await | ||||
| } | ||||
|  |  | |||
|  | @ -67,7 +67,7 @@ async fn main () -> anyhow::Result <()> { | |||
| 	let (subcommand, args) = parse_args (&args)?; | ||||
| 	match subcommand { | ||||
| 		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, | ||||
| 	} | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 _
						_