Allow binding to unix sockets

This commit is contained in:
Emi Simpson 2021-11-05 16:24:31 -04:00
parent 3a4afbcaea
commit adcbae08ca
Signed by: Emi
GPG key ID: A12F2C2FFDC3D847
2 changed files with 43 additions and 27 deletions

View file

@ -1,5 +1,3 @@
use std::net::Ipv4Addr;
use std::net::IpAddr;
use std::path::PathBuf; use std::path::PathBuf;
use pronouns_today::PronounList; use pronouns_today::PronounList;
use pronouns_today::UserPreferences; use pronouns_today::UserPreferences;
@ -64,13 +62,10 @@ pub struct Run {
/// options will be filled in using sane defaults /// options will be filled in using sane defaults
pub no_read_cfg: bool, pub no_read_cfg: bool,
#[argh(option, short = 'p')]
/// the port to listen on
pub port: Option<u16>,
#[argh(option)] #[argh(option)]
/// the address to bind to /// the address to bind to. can be an ip address and a port, like 0.0.0.0:1312, or a
pub address: Option<IpAddr>, /// unix socket like /run/programming.sock. defaults to 0.0.0.0:1312
pub bind: Option<String>,
#[argh(option)] #[argh(option)]
/// default pronoun probabilites (formatted as a prefstring, like the ones in the /// default pronoun probabilites (formatted as a prefstring, like the ones in the
@ -134,8 +129,9 @@ pub struct Conf {
/// The port for the server to bind to. Defaults to 1312 /// The port for the server to bind to. Defaults to 1312
pub port: u16, pub port: u16,
/// The address to bind to. Defaults to 0.0.0.0 /// The address to bind to. Can be an ip address and a port, like 0.0.0.0:1312, or a
pub address: IpAddr, /// unix socket like /run/programming.sock. Defaults to 0.0.0.0:1312
pub bind: String,
/// The base url the server will be running under, with no trailing slash /// The base url the server will be running under, with no trailing slash
pub base_url: String, pub base_url: String,
@ -143,8 +139,7 @@ pub struct Conf {
impl Conf { impl Conf {
fn update_with(mut self, args: Run) -> Conf { fn update_with(mut self, args: Run) -> Conf {
self.port = args.port.unwrap_or(self.port); self.bind = args.bind.unwrap_or(self.bind);
self.address = args.address.unwrap_or(self.address);
self.instance_settings.pronoun_list = args.pronouns.map(Into::into).unwrap_or(self.instance_settings.pronoun_list); self.instance_settings.pronoun_list = args.pronouns.map(Into::into).unwrap_or(self.instance_settings.pronoun_list);
self.base_url = args.base_url.unwrap_or(self.base_url); self.base_url = args.base_url.unwrap_or(self.base_url);
self self
@ -156,7 +151,7 @@ impl Default for Conf {
Conf { Conf {
instance_settings: InstanceSettings::default(), instance_settings: InstanceSettings::default(),
port: 1312, port: 1312,
address: IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), bind: "0.0.0.0:1312".into(),
base_url: "https://pronouns.today".into(), base_url: "https://pronouns.today".into(),
} }
} }

View file

@ -4,6 +4,7 @@ pub mod statics;
pub mod configuration; pub mod configuration;
mod write_vectored_all; mod write_vectored_all;
use async_net::unix::UnixListener;
use crate::configuration::Conf; use crate::configuration::Conf;
use std::io::IoSlice; use std::io::IoSlice;
use crate::statics::StaticAsset; use crate::statics::StaticAsset;
@ -80,17 +81,18 @@ fn main() {
/// requests is delegated to the [`handle_request()`], which is the actual task that is /// requests is delegated to the [`handle_request()`], which is the actual task that is
/// spawned into the Executor. /// spawned into the Executor.
async fn start_server(config: configuration::Conf, executor: &LocalExecutor<'_>) -> std::io::Result<()> { async fn start_server(config: configuration::Conf, executor: &LocalExecutor<'_>) -> std::io::Result<()> {
// Make the configuration immortal
let config = Box::leak(Box::new(config));
// Where we binding bois // Where we binding bois
let socket_addr = SocketAddr::new(config.address, config.port); if let Ok(socket_addr) = config.bind.parse() as Result<SocketAddr, _> {
println!("Starting pronouns-today-web on {}", &socket_addr); println!("Starting pronouns-today-web on {}", &socket_addr);
let connection = TcpListener::bind(socket_addr).await?; let connection = TcpListener::bind(socket_addr).await?;
let mut incoming = connection.incoming(); let mut incoming = connection.incoming();
// Make the configuration immortal
let config = Box::leak(Box::new(config));
while let Some(stream) = incoming.next().await { while let Some(stream) = incoming.next().await {
match stream { match stream {
Ok(stream) => { Ok(stream) => {
@ -102,6 +104,25 @@ async fn start_server(config: configuration::Conf, executor: &LocalExecutor<'_>)
} }
} }
} else {
let bind = config.bind.trim_start_matches("unix:");
let listener = UnixListener::bind(bind)?;
println!("Listening for connections on unix:{}", bind);
let mut incoming = listener.incoming();
while let Some(stream) = incoming.next().await {
match stream {
Ok(stream) => {
executor.spawn(handle_request(stream, config)).detach();
},
Err(e) => {
log::error!("IO Error with client/server connection: {}", e);
}
}
}
}
Ok(()) Ok(())
} }