mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-10 15:16:56 +00:00
fix: 优化endpoint
This commit is contained in:
+55
-30
@@ -1,17 +1,43 @@
|
||||
use crate::error::{Error, Result};
|
||||
use std::{
|
||||
collections::HashSet,
|
||||
net::{IpAddr, SocketAddr, ToSocketAddrs},
|
||||
};
|
||||
|
||||
use anyhow::{Error, Result};
|
||||
use netif;
|
||||
use url::Host;
|
||||
|
||||
// helper for validating if the provided arg is an ip address.
|
||||
/// helper for validating if the provided arg is an ip address.
|
||||
pub fn is_socket_addr(host: &str) -> bool {
|
||||
host.parse::<SocketAddr>().is_ok() || host.parse::<IpAddr>().is_ok()
|
||||
}
|
||||
|
||||
/// checks if server_addr is valid and local host.
|
||||
pub fn check_local_server_addr(server_addr: &str) -> Result<SocketAddr> {
|
||||
let addr: Vec<SocketAddr> = match server_addr.to_socket_addrs() {
|
||||
Ok(addr) => addr.collect(),
|
||||
Err(err) => return Err(Error::new(Box::new(err))),
|
||||
};
|
||||
|
||||
// 0.0.0.0 is a wildcard address and refers to local network
|
||||
// addresses. I.e, 0.0.0.0:9000 like ":9000" refers to port
|
||||
// 9000 on localhost.
|
||||
for a in addr {
|
||||
if a.ip().is_unspecified() {
|
||||
return Ok(a);
|
||||
}
|
||||
|
||||
let host = match a {
|
||||
SocketAddr::V4(a) => Host::<&str>::Ipv4(*a.ip()),
|
||||
SocketAddr::V6(a) => Host::Ipv6(*a.ip()),
|
||||
};
|
||||
|
||||
if is_local_host(host, 0, 0).is_ok() {
|
||||
return Ok(a);
|
||||
}
|
||||
}
|
||||
|
||||
return Err(Error::from_string("host in server address should be this server"));
|
||||
}
|
||||
|
||||
pub fn split_host_port(s: &str) -> Result<(String, u16)> {
|
||||
let parts: Vec<&str> = s.split(':').collect();
|
||||
if parts.len() == 2 {
|
||||
@@ -19,12 +45,12 @@ pub fn split_host_port(s: &str) -> Result<(String, u16)> {
|
||||
return Ok((parts[0].to_string(), port));
|
||||
}
|
||||
}
|
||||
Err(Error::msg("Invalid address format or port number"))
|
||||
Err(Error::from_string("Invalid address format or port number"))
|
||||
}
|
||||
|
||||
/// checks if the given parameter correspond to one of
|
||||
/// the local IP of the current machine
|
||||
pub fn is_local_host(host: Host<&str>, port: u16, local_port: u16) -> bool {
|
||||
pub fn is_local_host(host: Host<&str>, port: u16, local_port: u16) -> Result<bool> {
|
||||
let local_ips = must_get_local_ips();
|
||||
|
||||
let local_set: HashSet<IpAddr> = local_ips.into_iter().collect();
|
||||
@@ -32,7 +58,7 @@ pub fn is_local_host(host: Host<&str>, port: u16, local_port: u16) -> bool {
|
||||
Host::Domain(domain) => {
|
||||
let ips = match (domain, 0).to_socket_addrs().map(|v| v.map(|v| v.ip()).collect::<Vec<_>>()) {
|
||||
Ok(ips) => ips,
|
||||
Err(_) => return false,
|
||||
Err(err) => return Err(Error::new(Box::new(err))),
|
||||
};
|
||||
|
||||
ips.iter().any(|ip| local_set.contains(ip))
|
||||
@@ -42,14 +68,14 @@ pub fn is_local_host(host: Host<&str>, port: u16, local_port: u16) -> bool {
|
||||
};
|
||||
|
||||
if port > 0 {
|
||||
return is_local_host && port == local_port;
|
||||
return Ok(is_local_host && port == local_port);
|
||||
}
|
||||
|
||||
is_local_host
|
||||
Ok(is_local_host)
|
||||
}
|
||||
|
||||
/// returns IPs of local interface
|
||||
pub fn must_get_local_ips() -> Vec<IpAddr> {
|
||||
fn must_get_local_ips() -> Vec<IpAddr> {
|
||||
match netif::up() {
|
||||
Ok(up) => up.map(|x| x.address().to_owned()).collect(),
|
||||
Err(_) => vec![],
|
||||
@@ -58,10 +84,28 @@ pub fn must_get_local_ips() -> Vec<IpAddr> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use std::net::{Ipv4Addr, Ipv6Addr};
|
||||
use std::net::Ipv4Addr;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_is_socket_addr() {
|
||||
let test_cases = [
|
||||
("localhost", false),
|
||||
("localhost:9000", false),
|
||||
("example.com", false),
|
||||
("http://192.168.1.0", false),
|
||||
("http://192.168.1.0:9000", false),
|
||||
("192.168.1.0", true),
|
||||
("[2001:db8::1]:9000", true),
|
||||
];
|
||||
|
||||
for (addr, expected) in test_cases {
|
||||
let ret = is_socket_addr(addr);
|
||||
assert_eq!(expected, ret, "addr: {}, expected: {}, got: {}", addr, expected, ret);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_must_get_local_ips() {
|
||||
let local_ips = must_get_local_ips();
|
||||
@@ -69,23 +113,4 @@ mod test {
|
||||
|
||||
assert!(local_set.contains(&IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_local_host() {
|
||||
let host = Host::Domain("localhost");
|
||||
let is = is_local_host(host, 0, 9000);
|
||||
assert!(is);
|
||||
|
||||
let host = Host::Ipv6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));
|
||||
let is = is_local_host(host, 0, 9000);
|
||||
assert!(is);
|
||||
|
||||
let host = Host::Ipv4(Ipv4Addr::new(8, 8, 8, 8));
|
||||
let is = is_local_host(host, 0, 9000);
|
||||
assert!(!is);
|
||||
|
||||
let host = Host::Ipv4(Ipv4Addr::new(127, 0, 0, 1));
|
||||
let is = is_local_host(host, 8000, 9000);
|
||||
assert!(!is);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user