Fix relative paths (#2615)

This commit is contained in:
Rushmore Mushambi 2023-09-05 08:38:39 +02:00 committed by GitHub
parent e9821ee09e
commit 4259e05413
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 94 additions and 76 deletions

7
Cargo.lock generated
View file

@ -3575,6 +3575,12 @@ version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
[[package]]
name = "path-clean"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17359afc20d7ab31fdb42bb844c8b3bb1dabd7dcf7e68428492da7f16966fcef"
[[package]]
name = "pbkdf2"
version = "0.12.2"
@ -5301,6 +5307,7 @@ dependencies = [
"native-tls",
"nom",
"once_cell",
"path-clean",
"pbkdf2",
"pharos",
"pin-project-lite",

View file

@ -86,6 +86,7 @@ nanoid = "0.4.0"
native-tls = { version = "0.2.11", optional = true }
nom = { version = "7.1.3", features = ["alloc"] }
once_cell = "1.18.0"
path-clean = "1.0.1"
pbkdf2 = { version = "0.12.2", features = ["simple"] }
pin-project-lite = "0.2.12"
radix_trie = { version = "0.2.1", features = ["serde"] }

View file

@ -95,7 +95,10 @@ use crate::api::opt::Endpoint;
use crate::api::Connect;
use crate::api::Result;
use crate::api::Surreal;
use crate::opt::replace_tilde;
use path_clean::PathClean;
use std::marker::PhantomData;
use std::path::Path;
use std::sync::Arc;
use std::sync::OnceLock;
use url::Url;
@ -108,12 +111,24 @@ pub trait IntoEndpoint {
impl IntoEndpoint for &str {
fn into_endpoint(self) -> Result<Endpoint> {
let url = match self {
"memory" => "mem://",
_ => self,
let (url, path) = match self {
"memory" | "mem://" => (Url::parse("mem://").unwrap(), "memory".to_owned()),
url if url.starts_with("ws") | url.starts_with("http") => {
(Url::parse(url).map_err(|_| Error::InvalidUrl(self.to_owned()))?, String::new())
}
_ => {
let (scheme, _) = self.split_once(':').unwrap_or((self, ""));
let path = replace_tilde(self);
(
Url::parse(&format!("{scheme}://"))
.map_err(|_| Error::InvalidUrl(self.to_owned()))?,
Path::new(&path).clean().display().to_string(),
)
}
};
Ok(Endpoint {
endpoint: Url::parse(url).map_err(|_| Error::InvalidUrl(self.to_owned()))?,
url,
path,
config: Default::default(),
})
}

View file

@ -61,7 +61,7 @@ impl Connection for Any {
let (conn_tx, conn_rx) = flume::bounded::<Result<()>>(1);
let mut features = HashSet::new();
match address.endpoint.scheme() {
match address.url.scheme() {
"fdb" => {
#[cfg(feature = "kv-fdb")]
{
@ -151,7 +151,7 @@ impl Connection for Any {
};
}
let client = builder.build()?;
let base_url = address.endpoint;
let base_url = address.url;
engine::remote::http::health(
client.get(base_url.join(Method::Health.as_str())?),
)
@ -169,7 +169,7 @@ impl Connection for Any {
"ws" | "wss" => {
#[cfg(feature = "protocol-ws")]
{
let url = address.endpoint.join(engine::remote::ws::PATH)?;
let url = address.url.join(engine::remote::ws::PATH)?;
#[cfg(any(feature = "native-tls", feature = "rustls"))]
let maybe_connector = address.config.tls_config.map(Connector::from);
#[cfg(not(any(feature = "native-tls", feature = "rustls")))]

View file

@ -46,7 +46,7 @@ impl Connection for Any {
let (conn_tx, conn_rx) = flume::bounded::<Result<()>>(1);
let mut features = HashSet::new();
match address.endpoint.scheme() {
match address.url.scheme() {
"fdb" => {
#[cfg(feature = "kv-fdb")]
{
@ -144,7 +144,7 @@ impl Connection for Any {
#[cfg(feature = "protocol-ws")]
{
let mut address = address;
address.endpoint = address.endpoint.join(engine::remote::ws::PATH)?;
address.url = address.url.join(engine::remote::ws::PATH)?;
engine::remote::ws::wasm::router(address, capacity, conn_tx, route_rx);
conn_rx.into_recv_async().await??;
}

View file

@ -6,7 +6,6 @@ use crate::api::conn::Route;
use crate::api::conn::Router;
use crate::api::engine::local::Db;
use crate::api::engine::local::DEFAULT_TICK_INTERVAL;
use crate::api::err::Error;
use crate::api::opt::Endpoint;
use crate::api::ExtraFeatures;
use crate::api::OnceLockExt;
@ -95,7 +94,6 @@ pub(crate) fn router(
route_rx: Receiver<Option<Route>>,
) {
tokio::spawn(async move {
let url = address.endpoint;
let configured_root = match address.config.auth {
Level::Root => Some(Root {
username: &address.config.username,
@ -104,21 +102,7 @@ pub(crate) fn router(
_ => None,
};
let kvs = {
let path = match url.scheme() {
"mem" => "memory".to_owned(),
"fdb" | "rocksdb" | "speedb" | "file" => match url.to_file_path() {
Ok(path) => format!("{}://{}", url.scheme(), path.display()),
Err(_) => {
let error = Error::InvalidUrl(url.as_str().to_owned());
let _ = conn_tx.into_send_async(Err(error.into())).await;
return;
}
},
_ => url.as_str().to_owned(),
};
match Datastore::new(&path).await {
let kvs = match Datastore::new(&address.path).await {
Ok(kvs) => {
// If a root user is specified, setup the initial datastore credentials
if let Some(root) = configured_root {
@ -134,7 +118,6 @@ pub(crate) fn router(
let _ = conn_tx.into_send_async(Err(error.into())).await;
return;
}
}
};
let kvs = kvs

View file

@ -91,7 +91,6 @@ pub(crate) fn router(
route_rx: Receiver<Option<Route>>,
) {
spawn_local(async move {
let url = address.endpoint;
let configured_root = match address.config.auth {
Level::Root => Some(Root {
username: &address.config.username,
@ -100,12 +99,7 @@ pub(crate) fn router(
_ => None,
};
let path = match url.scheme() {
"mem" => "memory",
_ => url.as_str(),
};
let kvs = match Datastore::new(path).await {
let kvs = match Datastore::new(&address.path).await {
Ok(kvs) => {
// If a root user is specified, setup the initial datastore credentials
if let Some(root) = configured_root {

View file

@ -57,7 +57,7 @@ impl Connection for Client {
let client = builder.build()?;
let base_url = address.endpoint;
let base_url = address.url;
super::health(client.get(base_url.join(Method::Health.as_str())?)).await?;

View file

@ -94,7 +94,7 @@ pub(crate) fn router(
route_rx: Receiver<Option<Route>>,
) {
spawn_local(async move {
let base_url = address.endpoint;
let base_url = address.url;
let client = match client(&base_url).await {
Ok(client) => {

View file

@ -104,7 +104,7 @@ impl Connection for Client {
capacity: usize,
) -> Pin<Box<dyn Future<Output = Result<Surreal<Self>>> + Send + Sync + 'static>> {
Box::pin(async move {
let url = address.endpoint.join(PATH)?;
let url = address.url.join(PATH)?;
#[cfg(any(feature = "native-tls", feature = "rustls"))]
let maybe_connector = address.config.tls_config.map(Connector::from);
#[cfg(not(any(feature = "native-tls", feature = "rustls")))]

View file

@ -69,7 +69,7 @@ impl Connection for Client {
capacity: usize,
) -> Pin<Box<dyn Future<Output = Result<Surreal<Self>>> + Send + Sync + 'static>> {
Box::pin(async move {
address.endpoint = address.endpoint.join(PATH)?;
address.url = address.url.join(PATH)?;
let (route_tx, route_rx) = match capacity {
0 => flume::unbounded(),
@ -118,7 +118,7 @@ pub(crate) fn router(
route_rx: Receiver<Option<Route>>,
) {
spawn_local(async move {
let (mut ws, mut socket) = match WsMeta::connect(&address.endpoint, None).await {
let (mut ws, mut socket) = match WsMeta::connect(&address.url, None).await {
Ok(pair) => pair,
Err(error) => {
let _ = conn_tx.into_send_async(Err(error.into())).await;
@ -330,7 +330,7 @@ pub(crate) fn router(
'reconnect: loop {
trace!("Reconnecting...");
match WsMeta::connect(&address.endpoint, None).await {
match WsMeta::connect(&address.url, None).await {
Ok((mut meta, stream)) => {
socket = stream;
events = {

View file

@ -30,7 +30,8 @@ impl IntoEndpoint<Test> for () {
fn into_endpoint(self) -> Result<Endpoint> {
Ok(Endpoint {
endpoint: Url::parse("test://")?,
url: Url::parse("test://")?,
path: String::new(),
config: Default::default(),
})
}

View file

@ -1,6 +1,5 @@
use crate::api::engine::local::Db;
use crate::api::engine::local::FDb;
use crate::api::err::Error;
use crate::api::opt::Config;
use crate::api::opt::Endpoint;
use crate::api::opt::IntoEndpoint;
@ -16,9 +15,10 @@ macro_rules! endpoints {
type Client = Db;
fn into_endpoint(self) -> Result<Endpoint> {
let url = super::make_url("fdb", self);
let protocol = "fdb://";
Ok(Endpoint {
endpoint: Url::parse(&url).map_err(|_| Error::InvalidUrl(url))?,
url: Url::parse(protocol).unwrap(),
path: super::path_to_string(protocol, self),
config: Default::default(),
})
}

View file

@ -18,7 +18,8 @@ macro_rules! endpoints {
fn into_endpoint(self) -> Result<Endpoint> {
let url = format!("http://{self}");
Ok(Endpoint {
endpoint: Url::parse(&url).map_err(|_| Error::InvalidUrl(url))?,
url: Url::parse(&url).map_err(|_| Error::InvalidUrl(url))?,
path: String::new(),
config: Default::default(),
})
}
@ -40,7 +41,8 @@ macro_rules! endpoints {
fn into_endpoint(self) -> Result<Endpoint> {
let url = format!("https://{self}");
Ok(Endpoint {
endpoint: Url::parse(&url).map_err(|_| Error::InvalidUrl(url))?,
url: Url::parse(&url).map_err(|_| Error::InvalidUrl(url))?,
path: String::new(),
config: Default::default(),
})
}

View file

@ -1,6 +1,5 @@
use crate::api::engine::local::Db;
use crate::api::engine::local::IndxDb;
use crate::api::err::Error;
use crate::api::opt::Config;
use crate::api::opt::Endpoint;
use crate::api::opt::IntoEndpoint;
@ -14,9 +13,10 @@ macro_rules! endpoints {
type Client = Db;
fn into_endpoint(self) -> Result<Endpoint> {
let url = format!("indxdb://{self}");
let protocol = "indxdb://";
Ok(Endpoint {
endpoint: Url::parse(&url).map_err(|_| Error::InvalidUrl(url))?,
url: Url::parse(protocol).unwrap(),
path: super::path_to_string(protocol, self),
config: Default::default(),
})
}

View file

@ -11,7 +11,8 @@ impl IntoEndpoint<Mem> for () {
fn into_endpoint(self) -> Result<Endpoint> {
Ok(Endpoint {
endpoint: Url::parse("mem://").unwrap(),
url: Url::parse("mem://").unwrap(),
path: "memory".to_owned(),
config: Default::default(),
})
}

View file

@ -26,7 +26,8 @@ use super::Config;
#[derive(Debug)]
#[allow(dead_code)] // used by the embedded and remote connections
pub struct Endpoint {
pub(crate) endpoint: Url,
pub(crate) url: Url,
pub(crate) path: String,
pub(crate) config: Config,
}
@ -38,7 +39,17 @@ pub trait IntoEndpoint<Scheme> {
fn into_endpoint(self) -> Result<Endpoint>;
}
#[cfg(any(feature = "kv-fdb", feature = "kv-rocksdb", feature = "kv-speedb"))]
fn make_url(scheme: &str, path: impl AsRef<std::path::Path>) -> String {
format!("{scheme}://{}", path.as_ref().display())
pub(crate) fn replace_tilde(path: &str) -> String {
let home = std::env::var("HOME").unwrap_or_else(|_| ".".to_owned());
path.replacen("://~", &format!("://{home}"), 1).replacen(":~", &format!(":{home}"), 1)
}
#[allow(dead_code)]
fn path_to_string(protocol: &str, path: impl AsRef<std::path::Path>) -> String {
use path_clean::PathClean;
use std::path::Path;
let path = format!("{protocol}{}", path.as_ref().display());
let expanded = replace_tilde(&path);
Path::new(&expanded).clean().display().to_string()
}

View file

@ -1,7 +1,6 @@
use crate::api::engine::local::Db;
use crate::api::engine::local::File;
use crate::api::engine::local::RocksDb;
use crate::api::err::Error;
use crate::api::opt::Config;
use crate::api::opt::Endpoint;
use crate::api::opt::IntoEndpoint;
@ -17,9 +16,10 @@ macro_rules! endpoints {
type Client = Db;
fn into_endpoint(self) -> Result<Endpoint> {
let url = super::make_url("rocksdb", self);
let protocol = "rocksdb://";
Ok(Endpoint {
endpoint: Url::parse(&url).map_err(|_| Error::InvalidUrl(url))?,
url: Url::parse(protocol).unwrap(),
path: super::path_to_string(protocol, self),
config: Default::default(),
})
}
@ -39,9 +39,10 @@ macro_rules! endpoints {
type Client = Db;
fn into_endpoint(self) -> Result<Endpoint> {
let url = super::make_url("file", self);
let protocol = "file://";
Ok(Endpoint {
endpoint: Url::parse(&url).map_err(|_| Error::InvalidUrl(url))?,
url: Url::parse(protocol).unwrap(),
path: super::path_to_string(protocol, self),
config: Default::default(),
})
}

View file

@ -1,6 +1,5 @@
use crate::api::engine::local::Db;
use crate::api::engine::local::SpeeDb;
use crate::api::err::Error;
use crate::api::opt::Config;
use crate::api::opt::Endpoint;
use crate::api::opt::IntoEndpoint;
@ -16,9 +15,10 @@ macro_rules! endpoints {
type Client = Db;
fn into_endpoint(self) -> Result<Endpoint> {
let url = super::make_url("speedb", self);
let protocol = "speedb://";
Ok(Endpoint {
endpoint: Url::parse(&url).map_err(|_| Error::InvalidUrl(url))?,
url: Url::parse(protocol).unwrap(),
path: super::path_to_string(protocol, self),
config: Default::default(),
})
}

View file

@ -1,6 +1,5 @@
use crate::api::engine::local::Db;
use crate::api::engine::local::TiKv;
use crate::api::err::Error;
use crate::api::opt::Config;
use crate::api::opt::Endpoint;
use crate::api::opt::IntoEndpoint;
@ -17,7 +16,8 @@ macro_rules! endpoints {
fn into_endpoint(self) -> Result<Endpoint> {
let url = format!("tikv://{self}");
Ok(Endpoint {
endpoint: Url::parse(&url).map_err(|_| Error::InvalidUrl(url))?,
url: Url::parse(&url).unwrap(),
path: url,
config: Default::default(),
})
}

View file

@ -18,7 +18,8 @@ macro_rules! endpoints {
fn into_endpoint(self) -> Result<Endpoint> {
let url = format!("ws://{self}");
Ok(Endpoint {
endpoint: Url::parse(&url).map_err(|_| Error::InvalidUrl(url))?,
url: Url::parse(&url).map_err(|_| Error::InvalidUrl(url))?,
path: String::new(),
config: Default::default(),
})
}
@ -40,7 +41,8 @@ macro_rules! endpoints {
fn into_endpoint(self) -> Result<Endpoint> {
let url = format!("wss://{self}");
Ok(Endpoint {
endpoint: Url::parse(&url).map_err(|_| Error::InvalidUrl(url))?,
url: Url::parse(&url).map_err(|_| Error::InvalidUrl(url))?,
path: String::new(),
config: Default::default(),
})
}