commit dd4be5b9f6f56902f244638dfe41c4810dc9b9f7
parent 4e7d09204fd9a8e4ea0ea0f8ebc244bcbd780c89
Author: Matt Brubeck <mbrubeck@limpet.net>
Date: Sat, 16 Jan 2021 10:16:52 -0800
Take port as a separate command-line argument
Diffstat:
2 files changed, 23 insertions(+), 7 deletions(-)
diff --git a/README.md b/README.md
@@ -33,7 +33,9 @@ openssl req -x509 -newkey rsa:4096 -keyout key.rsa -out cert.pem \
agate --content path/to/content/ \
--key key.rsa \
--cert cert.pem \
- --addr [::]:1965 \
+ --addr :: \
+ --addr 0.0.0.0 \
+ --port 1965 \
--hostname example.com \
--lang en-US
```
diff --git a/src/main.rs b/src/main.rs
@@ -11,6 +11,7 @@ use {
ffi::OsStr,
fs::File,
io::BufReader,
+ net::{IpAddr, SocketAddr},
path::Path,
sync::Arc,
},
@@ -28,8 +29,11 @@ fn main() -> Result {
env_logger::Builder::new().parse_filters("info").init();
}
Runtime::new()?.block_on(async {
- let listener = TcpListener::bind(&ARGS.sock_addr).await?;
- log::info!("Listening on {}...", ARGS.sock_addr);
+ let port = ARGS.port;
+ let sock_addrs: Vec<_> = ARGS.addrs.iter().map(|addr| SocketAddr::new(*addr, port)).collect();
+
+ let listener = TcpListener::bind(&sock_addrs[..]).await?;
+ log::info!("Listening on {:?}...", sock_addrs);
loop {
let (stream, _) = listener.accept().await?;
tokio::spawn(async {
@@ -51,7 +55,8 @@ static ARGS: Lazy<Args> = Lazy::new(|| {
});
struct Args {
- sock_addr: String,
+ addrs: Vec<IpAddr>,
+ port: u16,
content_dir: String,
cert_file: String,
key_file: String,
@@ -67,7 +72,8 @@ fn args() -> Result<Args> {
opts.optopt("", "content", "Root of the content directory (default ./content)", "DIR");
opts.optopt("", "cert", "TLS certificate PEM file (default ./cert.pem)", "FILE");
opts.optopt("", "key", "PKCS8 private key file (default ./key.rsa)", "FILE");
- opts.optopt("", "addr", "Address to listen on (default 0.0.0.0:1965)", "IP:PORT");
+ opts.optmulti("", "addr", "Address to listen on (default 0.0.0.0 and [::])", "IP");
+ opts.optopt("", "port", "Port to listen on (default 1965)", "PORT");
opts.optopt("", "hostname", "Domain name of this Gemini server (optional)", "NAME");
opts.optopt("", "lang", "RFC 4646 Language code(s) for text/gemini documents", "LANG");
opts.optflag("s", "silent", "Disable logging output");
@@ -83,8 +89,16 @@ fn args() -> Result<Args> {
Some(s) => Some(Host::parse(&s)?),
None => None,
};
+ let mut addrs = vec![];
+ for i in matches.opt_strs("addr") {
+ addrs.push(i.parse()?);
+ }
+ if addrs.is_empty() {
+ addrs = vec![ "::".parse().unwrap(), "0.0.0.0".parse().unwrap()];
+ }
Ok(Args {
- sock_addr: matches.opt_get_default("addr", "0.0.0.0:1965".into())?,
+ addrs,
+ port: matches.opt_get_default("port", 1965)?,
content_dir: check_path(matches.opt_get_default("content", "content".into())?)?,
cert_file: check_path(matches.opt_get_default("cert", "cert.pem".into())?)?,
key_file: check_path(matches.opt_get_default("key", "key.rsa".into())?)?,
@@ -166,7 +180,7 @@ async fn parse_request(stream: &mut TlsStream<TcpStream>) -> std::result::Result
}
}
if let Some(port) = url.port() {
- if !ARGS.sock_addr.ends_with(&format!(":{}", port)) {
+ if port != ARGS.port {
return Err((53, "proxy request refused"));
}
}