johnandersen777.bsky.social/atlibs-webrtc
WebRTC transport for atlibs: com.fedfork.exec.webrtc.connect in the browser, and webrtc-peer, its guest side
0
0
// webrtc-peer --tunnel <tag>=<port> ... [--origin <page origin>] [--port 0] [--host 127.0.0.1]
// The loopback check's WebRTC guest (src/lib.rs): `cargo build --release` builds it.
use std::collections::HashMap;
use atlibs_host::Signal;
const USAGE: &str = "usage: webrtc-peer --tunnel <tag>=<port> ... [--origin <page origin>] [--port 0] [--host 127.0.0.1]";
fn parse(argv: &[String]) -> Result<(HashMap<String, u16>, std::net::IpAddr, u16, Option<String>), String> {
let (mut tunnels, mut host, mut port, mut origin) = (HashMap::new(), "127.0.0.1".to_string(), "0".to_string(), None);
let mut it = argv.iter();
while let Some(flag) = it.next() {
let mut value = || it.next().cloned().ok_or(format!("{flag} needs a value\n{USAGE}"));
match flag.as_str() {
"--tunnel" => {
let t = value()?;
let (tag, p) = t.split_once('=').ok_or(format!("--tunnel {t}: want <tag>=<port>"))?;
tunnels.insert(tag.to_string(), p.parse::<u16>().map_err(|e| format!("--tunnel {t}: {e}"))?);
}
"--host" => host = value()?,
"--port" => port = value()?,
"--origin" => origin = Some(value()?.trim_end_matches('/').to_string()),
_ => return Err(USAGE.into()),
}
}
if tunnels.is_empty() {
return Err(USAGE.into());
}
Ok((tunnels, host.parse().map_err(|e| format!("--host: {e}"))?, port.parse().map_err(|e| format!("--port: {e}"))?, origin))
}
#[tokio::main(flavor = "current_thread")]
async fn main() -> std::process::ExitCode {
let argv: Vec<String> = std::env::args().skip(1).collect();
let signal = Signal::new();
let stop = signal.clone();
tokio::spawn(async move {
if tokio::signal::ctrl_c().await.is_ok() {
stop.abort("aborted");
}
});
let ran = match parse(&argv) {
Ok((tunnels, host, port, origin)) => atlibs_webrtc::main(tunnels, host, port, origin, signal).await,
Err(e) => Err(e),
};
match ran {
Ok(()) => std::process::ExitCode::SUCCESS,
Err(e) => {
eprintln!("{e}");
std::process::ExitCode::FAILURE
}
}
}