mirror of
https://github.com/rustfs/rustfs.git
synced 2026-07-26 08:18:18 +00:00
fix: Optimize the issue of obtaining path errors on Windows.
This commit is contained in:
@@ -29,7 +29,7 @@ pub struct Endpoint {
|
||||
impl Display for Endpoint {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
if self.url.scheme() == "file" {
|
||||
write!(f, "{}", self.url.path())
|
||||
write!(f, "{}", self.get_file_path())
|
||||
} else {
|
||||
write!(f, "{}", self.url)
|
||||
}
|
||||
@@ -42,13 +42,9 @@ impl TryFrom<&str> for Endpoint {
|
||||
|
||||
/// Performs the conversion.
|
||||
fn try_from(value: &str) -> Result<Self, Self::Error> {
|
||||
/// check whether given path is not empty.
|
||||
fn is_empty_path(path: impl AsRef<Path>) -> bool {
|
||||
["", "/", "\\"].iter().any(|&v| Path::new(v).eq(path.as_ref()))
|
||||
}
|
||||
|
||||
if is_empty_path(value) {
|
||||
return Err(Error::from_string("empty or root endpoint is not supported"));
|
||||
// check whether given path is not empty.
|
||||
if ["", "/", "\\"].iter().any(|&v| v.eq(value)) {
|
||||
return Err(ErrorCode::EmptyPath().with_message("empty or root endpoint is not supported"));
|
||||
}
|
||||
|
||||
let mut is_local = false;
|
||||
@@ -67,35 +63,26 @@ impl TryFrom<&str> for Endpoint {
|
||||
return Err(Error::from_string("invalid URL endpoint format"));
|
||||
}
|
||||
|
||||
let path = Path::new(url.path()).clean();
|
||||
if is_empty_path(&path) {
|
||||
return Err(Error::from_string("empty or root path is not supported in URL endpoint"));
|
||||
}
|
||||
let path = url.path().to_string();
|
||||
|
||||
if let Some(v) = path.to_str() {
|
||||
url.set_path(v)
|
||||
}
|
||||
#[cfg(not(windows))]
|
||||
let path = Path::new(&path).absolutize()?;
|
||||
|
||||
// On windows having a preceding SlashSeparator will cause problems, if the
|
||||
// command line already has C:/<export-folder/ in it. Final resulting
|
||||
// path on windows might become C:/C:/ this will cause problems
|
||||
// of starting rustfs server properly in distributed mode on windows.
|
||||
// As a special case make sure to trim the separator.
|
||||
|
||||
// NOTE: It is also perfectly fine for windows users to have a path
|
||||
// without C:/ since at that point we treat it as relative path
|
||||
// and obtain the full filesystem path as well. Providing C:/
|
||||
// style is necessary to provide paths other than C:/,
|
||||
// such as F:/, D:/ etc.
|
||||
//
|
||||
// Another additional benefit here is that this style also
|
||||
// supports providing \\host\share support as well.
|
||||
#[cfg(windows)]
|
||||
{
|
||||
let path = url.path().to_owned();
|
||||
if Path::new(&path[1..]).is_absolute() {
|
||||
url.set_path(&path[1..]);
|
||||
}
|
||||
let path = Path::new(&path[1..]).absolutize()?;
|
||||
|
||||
if path.parent().is_none() || Path::new("").eq(&path) {
|
||||
return Err(Error::from_string("empty or root path is not supported in URL endpoint"));
|
||||
}
|
||||
|
||||
match path.to_str() {
|
||||
Some(v) => url.set_path(v),
|
||||
None => return Err(Error::from_string("invalid path")),
|
||||
}
|
||||
|
||||
url
|
||||
@@ -182,6 +169,15 @@ impl Endpoint {
|
||||
_ => String::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_file_path(&self) -> &str {
|
||||
let path = self.url.path();
|
||||
|
||||
#[cfg(windows)]
|
||||
let path = &path[1..];
|
||||
|
||||
path
|
||||
}
|
||||
}
|
||||
|
||||
/// parse a file path into an URL.
|
||||
|
||||
@@ -114,7 +114,7 @@ impl Debug for LocalDisk {
|
||||
|
||||
impl LocalDisk {
|
||||
pub async fn new(ep: &Endpoint, cleanup: bool) -> Result<Self> {
|
||||
let root = fs::canonicalize(ep.url.path()).await?;
|
||||
let root = fs::canonicalize(ep.get_file_path()).await?;
|
||||
|
||||
if cleanup {
|
||||
// TODO: 删除tmp数据
|
||||
|
||||
@@ -52,7 +52,7 @@ pub struct RemoteDisk {
|
||||
impl RemoteDisk {
|
||||
pub async fn new(ep: &Endpoint, _opt: &DiskOption) -> Result<Self> {
|
||||
// let root = fs::canonicalize(ep.url.path()).await?;
|
||||
let root = PathBuf::from(ep.url.path());
|
||||
let root = PathBuf::from(ep.get_file_path());
|
||||
let addr = format!("{}://{}:{}", ep.url.scheme(), ep.url.host_str().unwrap(), ep.url.port().unwrap());
|
||||
Ok(Self {
|
||||
id: Mutex::new(None),
|
||||
|
||||
@@ -231,7 +231,7 @@ impl PoolEndpointList {
|
||||
.map_err(|e| Error::from_string(format!("host '{}' cannot resolve: {}", host, e)))?
|
||||
});
|
||||
|
||||
let path = ep.url.path();
|
||||
let path = ep.get_file_path();
|
||||
match path_ip_map.entry(path) {
|
||||
Entry::Occupied(mut e) => {
|
||||
if e.get().intersection(host_ip_set).count() > 0 {
|
||||
@@ -255,7 +255,7 @@ impl PoolEndpointList {
|
||||
continue;
|
||||
}
|
||||
|
||||
let path = ep.url.path();
|
||||
let path = ep.get_file_path();
|
||||
if local_path_set.contains(path) {
|
||||
return Err(Error::from_string(format!(
|
||||
"path '{}' cannot be served by different address on same server",
|
||||
@@ -272,7 +272,7 @@ impl PoolEndpointList {
|
||||
let mut local_endpoint_count = 0;
|
||||
|
||||
for ep in endpoints.as_ref() {
|
||||
ep_path_set.insert(ep.url.path());
|
||||
ep_path_set.insert(ep.get_file_path());
|
||||
if ep.is_local && ep.url.has_host() {
|
||||
local_server_host_set.insert(ep.url.host());
|
||||
local_port_set.insert(ep.url.port());
|
||||
|
||||
Reference in New Issue
Block a user