Skip to content

Commit

Permalink
feat: Add support for listening on Unix domain sockets
Browse files Browse the repository at this point in the history
Add a new command line option `--listen-unix` for binding
the HTTP server to socket file paths.

Resolves #5
  • Loading branch information
ravenexp committed Sep 2, 2024
1 parent ee786a1 commit b144ff5
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 6 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ Options:
-h, --help print help and exit
-V, --version print version and exit
-L, --listen ADDRESS:PORT address and port to listen at (0.0.0.0:3080)
--listen-unix PATH Unix domain socket path to listen at
-U, --upstream-url URL upstream download URL (https://crates.io/)
-I, --index-url URL upstream index URL (https://index.crates.io/)
-S, --proxy-url URL this proxy server URL (http://localhost:3080/)
Expand Down
40 changes: 34 additions & 6 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ mod metadata_cache;
use std::env;
use std::fmt::Display;
use std::io::Read;
use std::path::PathBuf;
use std::path::{Path, PathBuf};
use std::sync::OnceLock;
use std::time::Duration;

Expand Down Expand Up @@ -538,11 +538,29 @@ fn handle_get_request(request: Request, config: &ProxyConfig) {
};
}

/// Runs HTTP proxy server forever.
fn main_loop(listen_addr: &str, config: &ProxyConfig) -> ! {
info!("proxy: starting HTTP server at: {listen_addr}");
/// Server listening address
enum ListenAddress {
/// IP address + port
SocketAddr(String),
/// Unix domain socket path
UnixPath(String),
}

let server = Server::http(listen_addr).expect("failed to start the HTTP server");
/// Runs HTTP proxy server forever.
fn main_loop(listen_addr: &ListenAddress, config: &ProxyConfig) -> ! {
let server = match listen_addr {
ListenAddress::SocketAddr(addr) => {
info!("proxy: starting HTTP server at: {addr}");
Server::http(addr).expect("failed to start the HTTP server")
}
ListenAddress::UnixPath(path) => {
info!("proxy: starting HTTP server at Unix socket {path}");
let path = Path::new(path);
// Reap stale socket files before binding.
std::fs::remove_file(path).ok();
Server::http_unix(path).expect("failed to start the HTTP server")
}
};

// Main HTTP request accept loop.
loop {
Expand Down Expand Up @@ -583,6 +601,7 @@ fn usage() {
println!(" -h, --help print help and exit");
println!(" -V, --version print version and exit");
println!(" -L, --listen ADDRESS:PORT address and port to listen at (0.0.0.0:3080)");
println!(" --listen-unix PATH Unix domain socket path to listen at");
println!(" -U, --upstream-url URL upstream download URL (https://crates.io/)");
println!(" -I, --index-url URL upstream index URL (https://index.crates.io/)");
println!(" -S, --proxy-url URL this proxy server URL (http://localhost:3080/)");
Expand Down Expand Up @@ -626,7 +645,11 @@ fn main() {
verbose += 1;
}

let listen_addr = args
let listen_addr_unix = args
.opt_value_from_str("--listen-unix")
.expect("bad listen socket path");

let listen_addr_ip = args
.opt_value_from_str(["-L", "--listen"])
.expect("bad listen address argument")
.unwrap_or_else(|| LISTEN_ADDRESS.to_string());
Expand Down Expand Up @@ -703,6 +726,11 @@ fn main() {
cache_ttl,
};

let listen_addr = match listen_addr_unix {
Some(unix_path) => ListenAddress::UnixPath(unix_path),
None => ListenAddress::SocketAddr(listen_addr_ip),
};

// Start the main HTTP server.
main_loop(&listen_addr, &config)
}

0 comments on commit b144ff5

Please sign in to comment.