mod certs; mod constants; mod error; mod globals; mod log; use crate::{error::*, log::*}; use std::sync::Arc; pub use crate::{ certs::{CertsAndKeys, CryptoSource}, globals::{AppConfig, AppConfigList, ProxyConfig, ReverseProxyConfig, TlsConfig, UpstreamUri}, }; pub mod reexports { pub use hyper::Uri; pub use rustls::{Certificate, PrivateKey}; } #[cfg(all(feature = "http3-quinn", feature = "http3-s2n"))] compile_error!("feature \"http3-quinn\" and feature \"http3-s2n\" cannot be enabled at the same time"); /// Entrypoint that creates and spawns tasks of reverse proxy services pub async fn entrypoint( proxy_config: &ProxyConfig, app_config_list: &AppConfigList, runtime_handle: &tokio::runtime::Handle, term_notify: Option>, ) -> Result<()> where T: CryptoSource + Clone + Send + Sync + 'static, { // For initial message logging if proxy_config.listen_sockets.iter().any(|addr| addr.is_ipv6()) { info!("Listen both IPv4 and IPv6") } else { info!("Listen IPv4") } if proxy_config.http_port.is_some() { info!("Listen port: {}", proxy_config.http_port.unwrap()); } if proxy_config.https_port.is_some() { info!("Listen port: {} (for TLS)", proxy_config.https_port.unwrap()); } #[cfg(any(feature = "http3-quinn", feature = "http3-s2n"))] if proxy_config.http3 { info!("Experimental HTTP/3.0 is enabled. Note it is still very unstable."); } if !proxy_config.sni_consistency { info!("Ignore consistency between TLS SNI and Host header (or Request line). Note it violates RFC."); } #[cfg(feature = "cache")] if proxy_config.cache_enabled { info!( "Cache is enabled: cache dir = {:?}", proxy_config.cache_dir.as_ref().unwrap() ); } else { info!("Cache is disabled") } // // build global // let globals = Arc::new(Globals { // proxy_config: proxy_config.clone(), // backends: app_config_list.clone().try_into()?, // request_count: Default::default(), // runtime_handle: runtime_handle.clone(), // term_notify: term_notify.clone(), // }); // // build message handler including a request forwarder // let msg_handler = Arc::new( // HttpMessageHandlerBuilder::default() // // .forwarder(Arc::new(Forwarder::new(&globals).await)) // .globals(globals.clone()) // .build()?, // ); // let http_server = Arc::new(build_http_server(&globals)); // let addresses = globals.proxy_config.listen_sockets.clone(); // let futures = select_all(addresses.into_iter().map(|addr| { // let mut tls_enabled = false; // if let Some(https_port) = globals.proxy_config.https_port { // tls_enabled = https_port == addr.port() // } // let proxy = ProxyBuilder::default() // .globals(globals.clone()) // .listening_on(addr) // .tls_enabled(tls_enabled) // .http_server(http_server.clone()) // .msg_handler(msg_handler.clone()) // .build() // .unwrap(); // globals.runtime_handle.spawn(async move { proxy.start().await }) // })); // // wait for all future // if let (Ok(Err(e)), _, _) = futures.await { // error!("Some proxy services are down: {}", e); // }; Ok(()) }