use gdbg::dbg; use poem::{ handler, http::uri::Uri, listener::{Acceptor, BoxListener, Listener, TcpListener, UnixListener}, Route, Server, }; #[derive(clap::Parser)] pub struct Options { #[clap(long, env = "UDS")] /// Set uds path uds: Option, #[clap(long, env = "PORT")] /// Set tcp port port: Option, } impl Options { fn addr(&self, port: &str) -> String { format!("0.0.0.0:{}", port).to_string() } fn listener(&self) -> BoxListener { match (self.uds.clone(), self.port.clone()) { (Some(uds), None) => UnixListener::bind(uds).boxed(), (None, Some(port)) => TcpListener::bind(self.addr(&port)).boxed(), (Some(uds), Some(port)) => { let ln_uds = UnixListener::bind(uds); let ln_tcp = TcpListener::bind(self.addr(&port)); ln_uds.combine(ln_tcp).boxed() } _ => panic!("either uds or port must be set"), } } pub async fn run(&mut self) -> Result<(), anyhow::Error> { { let ln = { // remove old socket let _ = tokio::fs::remove_file("/tmp/abc.sock").await; let ln_uds = UnixListener::bind("/tmp/abc.sock"); let ln_tcp = TcpListener::bind("0.0.0.0:0"); ln_uds.combine(ln_tcp) }; let addrs = ln.into_acceptor().await.unwrap().local_addr(); dbg!(addrs); } let app = Route::new().at("*", hello); let ln = self.listener(); if let Some(uds) = &self.uds { // remove old socket let _ = tokio::fs::remove_file(uds).await; eprintln!("curl --unix-socket {} http://localhost/path", uds); } if let Some(port) = &self.port { eprintln!("curl http://localhost:{}/path", port); } Ok(Server::new(ln).name("hello").run(app).await?) } } #[handler] pub fn hello(uri: &Uri) -> String { let rpath = uri.path(); format!("hello, {}", rpath) }