mirror of https://github.com/rapiz1/rathole.git
151 lines
3.5 KiB
Rust
151 lines
3.5 KiB
Rust
mod cli;
|
|
mod client;
|
|
mod config;
|
|
mod helper;
|
|
mod multi_map;
|
|
mod protocol;
|
|
mod server;
|
|
mod transport;
|
|
|
|
pub use cli::Cli;
|
|
pub use config::Config;
|
|
|
|
use anyhow::{anyhow, Result};
|
|
use tracing::debug;
|
|
|
|
use client::run_client;
|
|
use server::run_server;
|
|
|
|
pub async fn run(args: &Cli) -> Result<()> {
|
|
let config = Config::from_file(&args.config_path).await?;
|
|
|
|
tracing_subscriber::fmt::init();
|
|
|
|
debug!("{:?}", config);
|
|
|
|
// Raise `nofile` limit on linux and mac
|
|
fdlimit::raise_fd_limit();
|
|
|
|
match determine_run_mode(&config, args) {
|
|
RunMode::Undetermine => Err(anyhow!("Cannot determine running as a server or a client")),
|
|
RunMode::Client => run_client(&config).await,
|
|
RunMode::Server => run_server(&config).await,
|
|
}
|
|
}
|
|
|
|
#[derive(PartialEq, Eq, Debug)]
|
|
enum RunMode {
|
|
Server,
|
|
Client,
|
|
Undetermine,
|
|
}
|
|
|
|
fn determine_run_mode(config: &Config, args: &Cli) -> RunMode {
|
|
use RunMode::*;
|
|
if args.client && args.server {
|
|
Undetermine
|
|
} else if args.client {
|
|
Client
|
|
} else if args.server {
|
|
Server
|
|
} else if config.client.is_some() && config.server.is_none() {
|
|
Client
|
|
} else if config.server.is_some() && config.client.is_none() {
|
|
Server
|
|
} else {
|
|
Undetermine
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_determine_run_mode() {
|
|
use config::*;
|
|
use RunMode::*;
|
|
|
|
struct T {
|
|
cfg_s: bool,
|
|
cfg_c: bool,
|
|
arg_s: bool,
|
|
arg_c: bool,
|
|
run_mode: RunMode,
|
|
}
|
|
|
|
let tests = [
|
|
T {
|
|
cfg_s: false,
|
|
cfg_c: false,
|
|
arg_s: false,
|
|
arg_c: false,
|
|
run_mode: Undetermine,
|
|
},
|
|
T {
|
|
cfg_s: true,
|
|
cfg_c: false,
|
|
arg_s: false,
|
|
arg_c: false,
|
|
run_mode: Server,
|
|
},
|
|
T {
|
|
cfg_s: false,
|
|
cfg_c: true,
|
|
arg_s: false,
|
|
arg_c: false,
|
|
run_mode: Client,
|
|
},
|
|
T {
|
|
cfg_s: true,
|
|
cfg_c: true,
|
|
arg_s: false,
|
|
arg_c: false,
|
|
run_mode: Undetermine,
|
|
},
|
|
T {
|
|
cfg_s: true,
|
|
cfg_c: true,
|
|
arg_s: true,
|
|
arg_c: false,
|
|
run_mode: Server,
|
|
},
|
|
T {
|
|
cfg_s: true,
|
|
cfg_c: true,
|
|
arg_s: false,
|
|
arg_c: true,
|
|
run_mode: Client,
|
|
},
|
|
T {
|
|
cfg_s: true,
|
|
cfg_c: true,
|
|
arg_s: true,
|
|
arg_c: true,
|
|
run_mode: Undetermine,
|
|
},
|
|
];
|
|
|
|
for t in tests {
|
|
let config = Config {
|
|
server: match t.cfg_s {
|
|
true => Some(ServerConfig::default()),
|
|
false => None,
|
|
},
|
|
client: match t.cfg_c {
|
|
true => Some(ClientConfig::default()),
|
|
false => None,
|
|
},
|
|
};
|
|
|
|
let args = Cli {
|
|
config_path: std::path::PathBuf::new(),
|
|
server: t.arg_s,
|
|
client: t.arg_c,
|
|
};
|
|
|
|
assert_eq!(determine_run_mode(&config, &args), t.run_mode);
|
|
}
|
|
}
|
|
}
|