~ knotless Search/
↑↓ move↵ open⇧↵ all results

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
main
54 lines · 2.2 KB Raw History
// 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
        }
    }
}