mirror of https://github.com/ospab/ostp.git
feat: implement native public IP autodetection via ip r and interactive cached prompt fallback for server links
This commit is contained in:
parent
5d590f7d59
commit
85d3e28c85
|
|
@ -191,6 +191,79 @@ async fn main() -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
fn is_private_ip(ip: &str) -> bool {
|
||||||
|
ip.starts_with("10.")
|
||||||
|
|| ip.starts_with("192.168.")
|
||||||
|
|| ip.starts_with("127.")
|
||||||
|
|| (ip.starts_with("172.") && {
|
||||||
|
let parts: Vec<&str> = ip.split('.').collect();
|
||||||
|
if parts.len() >= 2 {
|
||||||
|
if let Ok(second) = parts[1].parse::<u8>() {
|
||||||
|
(16..=31).contains(&second)
|
||||||
|
} else { false }
|
||||||
|
} else { false }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn detect_local_public_ip() -> Option<String> {
|
||||||
|
#[cfg(not(target_os = "windows"))]
|
||||||
|
{
|
||||||
|
let out = std::process::Command::new("ip")
|
||||||
|
.args(["-4", "addr", "show", "scope", "global"])
|
||||||
|
.output()
|
||||||
|
.ok()?;
|
||||||
|
|
||||||
|
let text = String::from_utf8_lossy(&out.stdout);
|
||||||
|
for line in text.lines() {
|
||||||
|
if let Some(idx) = line.find("inet ") {
|
||||||
|
let substr = &line[idx + 5..];
|
||||||
|
let ip = substr.split(|c: char| c == '/' || c.is_whitespace()).next().unwrap_or("");
|
||||||
|
if !ip.is_empty() && !is_private_ip(ip) {
|
||||||
|
return Some(ip.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_or_ask_public_ip(config_path: &std::path::Path) -> String {
|
||||||
|
let config_dir = config_path.parent().unwrap_or_else(|| std::path::Path::new("."));
|
||||||
|
let cache_path = config_dir.join(".ostp_public_ip");
|
||||||
|
|
||||||
|
if cache_path.exists() {
|
||||||
|
if let Ok(cached) = std::fs::read_to_string(&cache_path) {
|
||||||
|
let ip = cached.trim().to_string();
|
||||||
|
if !ip.is_empty() {
|
||||||
|
return ip;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(detected) = detect_local_public_ip() {
|
||||||
|
println!("[OSTP Core] Auto-detected public network IP: {}", detected);
|
||||||
|
let _ = std::fs::write(&cache_path, &detected);
|
||||||
|
return detected;
|
||||||
|
}
|
||||||
|
|
||||||
|
print!("\n[OSTP Core] Could not automatically detect your Server's Public IP.\n");
|
||||||
|
print!(">>> Please enter your Public IP or Domain Name for user links: ");
|
||||||
|
use std::io::Write;
|
||||||
|
let _ = std::io::stdout().flush();
|
||||||
|
|
||||||
|
let mut input = String::new();
|
||||||
|
if std::io::stdin().read_line(&mut input).is_ok() {
|
||||||
|
let ip = input.trim().to_string();
|
||||||
|
if !ip.is_empty() {
|
||||||
|
let _ = std::fs::write(&cache_path, &ip);
|
||||||
|
return ip;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"<YOUR_SERVER_PUBLIC_IP>".to_string()
|
||||||
|
}
|
||||||
|
|
||||||
async fn run_app() -> Result<()> {
|
async fn run_app() -> Result<()> {
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
|
|
||||||
|
|
@ -262,8 +335,9 @@ async fn run_app() -> Result<()> {
|
||||||
if is_server {
|
if is_server {
|
||||||
if let AppMode::Server(s) = dummy.mode {
|
if let AppMode::Server(s) = dummy.mode {
|
||||||
let key = &s.access_keys[0];
|
let key = &s.access_keys[0];
|
||||||
|
let host = get_or_ask_public_ip(&args.config);
|
||||||
println!("\n>>> Handy Client Share Link for your users:");
|
println!("\n>>> Handy Client Share Link for your users:");
|
||||||
println!(" ostp://{}@<YOUR_SERVER_PUBLIC_IP>:50000", key);
|
println!(" ostp://{}@{}:50000", key, host);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
|
@ -293,7 +367,11 @@ async fn run_app() -> Result<()> {
|
||||||
let listen = server_cfg.listen.clone();
|
let listen = server_cfg.listen.clone();
|
||||||
let parts: Vec<&str> = listen.split(':').collect();
|
let parts: Vec<&str> = listen.split(':').collect();
|
||||||
let port = parts.get(1).unwrap_or(&"50000");
|
let port = parts.get(1).unwrap_or(&"50000");
|
||||||
let host = if parts[0] == "0.0.0.0" { "<YOUR_SERVER_PUBLIC_IP>" } else { parts[0] };
|
let host = if parts[0] == "0.0.0.0" {
|
||||||
|
get_or_ask_public_ip(&args.config)
|
||||||
|
} else {
|
||||||
|
parts[0].to_string()
|
||||||
|
};
|
||||||
|
|
||||||
println!("\n>>> Ready-to-use OSTP client share links from {:?}:", args.config);
|
println!("\n>>> Ready-to-use OSTP client share links from {:?}:", args.config);
|
||||||
for (idx, key) in server_cfg.access_keys.iter().enumerate() {
|
for (idx, key) in server_cfg.access_keys.iter().enumerate() {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue