|
|
|
@ -192,7 +192,6 @@ compile_error!("Please enable only one of either the `gemini_srv` or `scgi_srv`
|
|
|
|
|
compile_error!("Please enable at least one of either the `gemini_srv` or `scgi_srv` features on the kochab crate");
|
|
|
|
|
|
|
|
|
|
use std::{
|
|
|
|
|
sync::Arc,
|
|
|
|
|
time::Duration,
|
|
|
|
|
future::Future,
|
|
|
|
|
};
|
|
|
|
@ -260,32 +259,32 @@ pub const REQUEST_URI_MAX_LEN: usize = 1024;
|
|
|
|
|
/// The default port for the gemini protocol
|
|
|
|
|
pub const GEMINI_PORT: u16 = 1965;
|
|
|
|
|
|
|
|
|
|
#[derive(Clone)]
|
|
|
|
|
struct ServerInner {
|
|
|
|
|
#[cfg(feature = "gemini_srv")]
|
|
|
|
|
tls_acceptor: TlsAcceptor,
|
|
|
|
|
routes: Arc<RoutingNode<Handler>>,
|
|
|
|
|
routes: RoutingNode<Handler>,
|
|
|
|
|
timeout: Duration,
|
|
|
|
|
complex_timeout: Option<Duration>,
|
|
|
|
|
autorewrite: bool,
|
|
|
|
|
#[cfg(feature="ratelimiting")]
|
|
|
|
|
rate_limits: Arc<RoutingNode<RateLimiter<IpAddr>>>,
|
|
|
|
|
rate_limits: RoutingNode<RateLimiter<IpAddr>>,
|
|
|
|
|
#[cfg(feature="user_management")]
|
|
|
|
|
manager: UserManager,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl ServerInner {
|
|
|
|
|
async fn serve_ip(self, listener: TcpListener) -> Result<()> {
|
|
|
|
|
let static_self: &'static Self = Box::leak(Box::new(self));
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "ratelimiting")]
|
|
|
|
|
tokio::spawn(prune_ratelimit_log(self.rate_limits.clone()));
|
|
|
|
|
tokio::spawn(prune_ratelimit_log(&static_self.rate_limits));
|
|
|
|
|
|
|
|
|
|
loop {
|
|
|
|
|
let (stream, _addr) = listener.accept().await
|
|
|
|
|
.context("Failed to accept client")?;
|
|
|
|
|
let this = self.clone();
|
|
|
|
|
|
|
|
|
|
tokio::spawn(async move {
|
|
|
|
|
if let Err(err) = this.serve_client(stream).await {
|
|
|
|
|
if let Err(err) = static_self.serve_client(stream).await {
|
|
|
|
|
error!("{:?}", err);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
@ -296,16 +295,17 @@ impl ServerInner {
|
|
|
|
|
// Yeah it's code duplication, but I can't find a way around it, so this is what we're
|
|
|
|
|
// getting for now
|
|
|
|
|
async fn serve_unix(self, listener: UnixListener) -> Result<()> {
|
|
|
|
|
let static_self: &'static Self = Box::leak(Box::new(self));
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "ratelimiting")]
|
|
|
|
|
tokio::spawn(prune_ratelimit_log(self.rate_limits.clone()));
|
|
|
|
|
tokio::spawn(prune_ratelimit_log(&static_self.rate_limits));
|
|
|
|
|
|
|
|
|
|
loop {
|
|
|
|
|
let (stream, _addr) = listener.accept().await
|
|
|
|
|
.context("Failed to accept client")?;
|
|
|
|
|
let this = self.clone();
|
|
|
|
|
|
|
|
|
|
tokio::spawn(async move {
|
|
|
|
|
if let Err(err) = this.serve_client(stream).await {
|
|
|
|
|
if let Err(err) = static_self.serve_client(stream).await {
|
|
|
|
|
error!("{:?}", err);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
@ -962,14 +962,14 @@ impl Server {
|
|
|
|
|
let data_dir = self.data_dir;
|
|
|
|
|
|
|
|
|
|
Ok(ServerInner {
|
|
|
|
|
routes: Arc::new(self.routes),
|
|
|
|
|
routes: self.routes,
|
|
|
|
|
timeout: self.timeout,
|
|
|
|
|
complex_timeout: self.complex_body_timeout_override,
|
|
|
|
|
autorewrite: self.autorewrite,
|
|
|
|
|
#[cfg(feature = "gemini_srv")]
|
|
|
|
|
tls_acceptor: TlsAcceptor::from(config),
|
|
|
|
|
#[cfg(feature="ratelimiting")]
|
|
|
|
|
rate_limits: Arc::new(self.rate_limits),
|
|
|
|
|
rate_limits: self.rate_limits,
|
|
|
|
|
#[cfg(feature="user_management")]
|
|
|
|
|
manager: UserManager::new(
|
|
|
|
|
self.database.unwrap_or_else(move|| sled::open(data_dir).unwrap())
|
|
|
|
@ -981,6 +981,11 @@ impl Server {
|
|
|
|
|
///
|
|
|
|
|
/// `addr` can be anything `tokio` can parse, including just a string like
|
|
|
|
|
/// "localhost:1965"
|
|
|
|
|
///
|
|
|
|
|
/// This will only ever exit with an error. It's important to note that even if the
|
|
|
|
|
/// function exits, the server will NOT be deallocated, since references to it in
|
|
|
|
|
/// concurrently running futures may still exist. As such, a loop that handles an
|
|
|
|
|
/// error by re-serving a new server may trigger a memory leak.
|
|
|
|
|
pub async fn serve_ip(self, addr: impl ToSocketAddrs + Send) -> Result<()> {
|
|
|
|
|
let server = self.build()?;
|
|
|
|
|
let socket = TcpListener::bind(addr).await?;
|
|
|
|
@ -992,6 +997,8 @@ impl Server {
|
|
|
|
|
///
|
|
|
|
|
/// Requires an address in the form of a path to bind to. This is only available when
|
|
|
|
|
/// in `scgi_srv` mode.
|
|
|
|
|
///
|
|
|
|
|
/// Please read the details and warnings of [`serve_ip()`] for more information
|
|
|
|
|
pub async fn serve_unix(self, addr: impl AsRef<std::path::Path>) -> Result<()> {
|
|
|
|
|
let server = self.build()?;
|
|
|
|
|
let socket = UnixListener::bind(addr)?;
|
|
|
|
|