Format mint URL (lowercase hostname) (#311)

This commit is contained in:
callebtc
2024-09-03 11:46:02 +02:00
committed by GitHub
parent 1cd80deaca
commit 125001211c
2 changed files with 67 additions and 21 deletions

View File

@@ -154,10 +154,8 @@ impl Mint {
}
}
let mint_url = MintUrl::from(mint_url);
Ok(Self {
mint_url,
mint_url: MintUrl::from(mint_url),
keysets: Arc::new(RwLock::new(active_keysets)),
secp_ctx,
xpriv,
@@ -1569,7 +1567,10 @@ mod tests {
#[tokio::test]
async fn mint_mod_rotate_keyset() -> Result<(), Error> {
let config: MintConfig = Default::default();
let config = MintConfig::<'_> {
mint_url: "http://example.com",
..Default::default()
};
let mint = create_mint(config).await?;
let keysets = mint.keysets().await.unwrap();

View File

@@ -16,6 +16,9 @@ pub enum Error {
/// Url error
#[error(transparent)]
Url(#[from] ParseError),
/// Invalid URL structure
#[error("Invalid URL")]
InvalidUrl,
}
/// MintUrl Url
@@ -23,13 +26,38 @@ pub enum Error {
pub struct MintUrl(String);
impl MintUrl {
/// New mint url
pub fn new<S>(url: S) -> Self
where
S: Into<String>,
{
let url: String = url.into();
Self(url.trim_end_matches('/').to_string())
fn format_url(url: &str) -> Result<String, Error> {
if url.is_empty() {
return Err(Error::InvalidUrl);
}
let url = url.trim_end_matches('/');
// https://URL.com/path/TO/resource -> https://url.com/path/TO/resource
let protocol = url
.split("://")
.nth(0)
.ok_or(Error::InvalidUrl)?
.to_lowercase();
let host = url
.split("://")
.nth(1)
.ok_or(Error::InvalidUrl)?
.split('/')
.nth(0)
.ok_or(Error::InvalidUrl)?
.to_lowercase();
let path = url
.split("://")
.nth(1)
.ok_or(Error::InvalidUrl)?
.split('/')
.skip(1)
.collect::<Vec<&str>>()
.join("/");
let mut formatted_url = format!("{}://{}", protocol, host);
if !path.is_empty() {
formatted_url.push_str(&format!("/{}", path));
}
Ok(formatted_url)
}
/// Empty mint url
@@ -42,11 +70,6 @@ impl MintUrl {
let url: Url = self.try_into()?;
Ok(url.join(path)?)
}
/// Remove trailing slashes from url
pub fn trim_trailing_slashes(&self) -> Self {
Self(self.to_string().trim_end_matches('/').to_string())
}
}
impl<'de> Deserialize<'de> for MintUrl {
@@ -65,7 +88,8 @@ where
{
fn from(url: S) -> Self {
let url: String = url.into();
Self(url.trim_end_matches('/').to_string())
let formatted_url = Self::format_url(&url).unwrap();
Self(formatted_url)
}
}
@@ -73,7 +97,11 @@ impl FromStr for MintUrl {
type Err = Error;
fn from_str(url: &str) -> Result<Self, Self::Err> {
Ok(Self::from(url))
let formatted_url = Self::format_url(url);
match formatted_url {
Ok(url) => Ok(Self(url)),
Err(_) => Err(Error::InvalidUrl),
}
}
}
@@ -111,12 +139,29 @@ mod tests {
let formatted_url = "http://url-to-check.com";
let very_trimmed_url = MintUrl::from_str(very_unformatted_url).unwrap();
assert_eq!("http://url-to-check.com", very_trimmed_url.to_string());
assert_eq!(formatted_url, very_trimmed_url.to_string());
let trimmed_url = MintUrl::from_str(unformatted_url).unwrap();
assert_eq!("http://url-to-check.com", trimmed_url.to_string());
assert_eq!(formatted_url, trimmed_url.to_string());
let unchanged_url = MintUrl::from_str(formatted_url).unwrap();
assert_eq!("http://url-to-check.com", unchanged_url.to_string());
assert_eq!(formatted_url, unchanged_url.to_string());
}
#[test]
fn test_case_insensitive() {
let wrong_cased_url = "http://URL-to-check.com";
let correct_cased_url = "http://url-to-check.com";
let cased_url_formatted = MintUrl::from_str(wrong_cased_url).unwrap();
assert_eq!(correct_cased_url, cased_url_formatted.to_string());
let wrong_cased_url_with_path = "http://URL-to-check.com/PATH/to/check";
let correct_cased_url_with_path = "http://url-to-check.com/PATH/to/check";
let cased_url_with_path_formatted = MintUrl::from_str(wrong_cased_url_with_path).unwrap();
assert_eq!(
correct_cased_url_with_path,
cased_url_with_path_formatted.to_string()
);
}
}