Refactor project to make it easier to test
This commit is contained in:
@ -1,2 +1,95 @@
|
||||
extern crate core;
|
||||
|
||||
use std::error::Error;
|
||||
use std::sync::Arc;
|
||||
|
||||
use futures::future::join_all;
|
||||
use reqwest::{Certificate, Identity};
|
||||
|
||||
use base::RemoteConfig;
|
||||
|
||||
use crate::client_config::ClientConfig;
|
||||
use crate::relay_client::relay_client;
|
||||
|
||||
pub mod client_config;
|
||||
pub mod relay_client;
|
||||
mod relay_client;
|
||||
|
||||
/// Get remote server config i.e. get the list of forwarded ports
|
||||
async fn get_server_config(conf: &ClientConfig) -> Result<RemoteConfig, Box<dyn Error>> {
|
||||
let url = format!("{}/config", conf.relay_url);
|
||||
log::info!("Retrieving configuration on {}", url);
|
||||
|
||||
let mut client = reqwest::Client::builder();
|
||||
|
||||
// Specify root certificate, if any was specified in the command line
|
||||
if let Some(cert) = conf.get_root_certificate() {
|
||||
client = client.add_root_certificate(Certificate::from_pem(&cert)?);
|
||||
}
|
||||
|
||||
// Specify client certificate, if any
|
||||
if let Some(kp) = conf.get_merged_client_keypair() {
|
||||
let identity = Identity::from_pem(&kp).expect("Failed to load certificates for reqwest!");
|
||||
client = client.identity(identity).use_rustls_tls();
|
||||
}
|
||||
|
||||
let client = client.build().expect("Failed to build reqwest client");
|
||||
|
||||
let req = client
|
||||
.get(url)
|
||||
.header("Authorization", format!("Bearer {}", conf.get_auth_token()))
|
||||
.send()
|
||||
.await?;
|
||||
if req.status().as_u16() != 200 {
|
||||
log::error!(
|
||||
"Could not retrieve configuration! (got status {})",
|
||||
req.status()
|
||||
);
|
||||
std::process::exit(2);
|
||||
}
|
||||
|
||||
Ok(req.json::<RemoteConfig>().await?)
|
||||
}
|
||||
|
||||
/// Core logic of the application
|
||||
pub async fn run_app(mut args: ClientConfig) -> Result<(), Box<dyn Error>> {
|
||||
args.load_certificates();
|
||||
let args = Arc::new(args);
|
||||
|
||||
// Check arguments coherence
|
||||
if args.tls_cert.is_some() != args.tls_key.is_some() {
|
||||
log::error!(
|
||||
"If you specify one of TLS certificate / key, you must then specify the other!"
|
||||
);
|
||||
panic!();
|
||||
}
|
||||
|
||||
if args.get_client_keypair().is_some() {
|
||||
log::info!("Using client-side authentication");
|
||||
}
|
||||
|
||||
// Get server relay configuration (fetch the list of port to forward)
|
||||
let remote_conf = get_server_config(&args).await?;
|
||||
|
||||
// Start to listen port
|
||||
let mut handles = vec![];
|
||||
for port in remote_conf {
|
||||
let listen_address = format!("{}:{}", args.listen_address, port.port);
|
||||
|
||||
let h = tokio::spawn(relay_client(
|
||||
format!(
|
||||
"{}/ws?id={}&token={}",
|
||||
args.relay_url,
|
||||
port.id,
|
||||
urlencoding::encode(args.get_auth_token())
|
||||
)
|
||||
.replace("http", "ws"),
|
||||
listen_address,
|
||||
args.clone(),
|
||||
));
|
||||
handles.push(h);
|
||||
}
|
||||
|
||||
join_all(handles).await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1,97 +1,11 @@
|
||||
extern crate core;
|
||||
|
||||
use std::error::Error;
|
||||
use std::sync::Arc;
|
||||
|
||||
use clap::Parser;
|
||||
use futures::future::join_all;
|
||||
use reqwest::{Certificate, Identity};
|
||||
|
||||
use base::RemoteConfig;
|
||||
use tcp_relay_client::client_config::ClientConfig;
|
||||
use tcp_relay_client::relay_client::relay_client;
|
||||
|
||||
async fn get_server_config(config: &ClientConfig) -> Result<RemoteConfig, Box<dyn Error>> {
|
||||
let url = format!("{}/config", config.relay_url);
|
||||
log::info!("Retrieving configuration on {}", url);
|
||||
|
||||
let mut client = reqwest::Client::builder();
|
||||
|
||||
// Specify root certificate, if any was specified in the command line
|
||||
if let Some(cert) = config.get_root_certificate() {
|
||||
client = client.add_root_certificate(Certificate::from_pem(&cert)?);
|
||||
}
|
||||
|
||||
// Specify client certificate, if any
|
||||
if let Some(kp) = config.get_merged_client_keypair() {
|
||||
let identity = Identity::from_pem(&kp).expect("Failed to load certificates for reqwest!");
|
||||
client = client.identity(identity).use_rustls_tls();
|
||||
}
|
||||
|
||||
let client = client.build().expect("Failed to build reqwest client");
|
||||
|
||||
let req = client
|
||||
.get(url)
|
||||
.header(
|
||||
"Authorization",
|
||||
format!("Bearer {}", config.get_auth_token()),
|
||||
)
|
||||
.send()
|
||||
.await?;
|
||||
if req.status().as_u16() != 200 {
|
||||
log::error!(
|
||||
"Could not retrieve configuration! (got status {})",
|
||||
req.status()
|
||||
);
|
||||
std::process::exit(2);
|
||||
}
|
||||
|
||||
Ok(req.json::<RemoteConfig>().await?)
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn Error>> {
|
||||
env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
|
||||
|
||||
let mut args: ClientConfig = ClientConfig::parse();
|
||||
args.load_certificates();
|
||||
let args = Arc::new(args);
|
||||
|
||||
// Check arguments coherence
|
||||
if args.tls_cert.is_some() != args.tls_key.is_some() {
|
||||
log::error!(
|
||||
"If you specify one of TLS certificate / key, you must then specify the other!"
|
||||
);
|
||||
panic!();
|
||||
}
|
||||
|
||||
if args.get_client_keypair().is_some() {
|
||||
log::info!("Using client-side authentication");
|
||||
}
|
||||
|
||||
// Get server relay configuration (fetch the list of port to forward)
|
||||
let conf = get_server_config(&args).await?;
|
||||
|
||||
// Start to listen port
|
||||
let mut handles = vec![];
|
||||
for port in conf {
|
||||
let listen_address = format!("{}:{}", args.listen_address, port.port);
|
||||
|
||||
let h = tokio::spawn(relay_client(
|
||||
format!(
|
||||
"{}/ws?id={}&token={}",
|
||||
args.relay_url,
|
||||
port.id,
|
||||
urlencoding::encode(args.get_auth_token())
|
||||
)
|
||||
.replace("http", "ws"),
|
||||
listen_address,
|
||||
args.clone(),
|
||||
));
|
||||
handles.push(h);
|
||||
}
|
||||
|
||||
join_all(handles).await;
|
||||
|
||||
Ok(())
|
||||
tcp_relay_client::run_app(ClientConfig::parse()).await
|
||||
}
|
||||
|
Reference in New Issue
Block a user