fix relative scheme resolve

This commit is contained in:
yggverse 2025-03-14 22:45:35 +02:00
parent 7c2051acaf
commit ffcf8f9627
3 changed files with 36 additions and 13 deletions

View file

@ -29,17 +29,25 @@ impl Link {
// Detect address required to continue // Detect address required to continue
let mut unresolved_address = regex.get(1)?.to_string(); let mut unresolved_address = regex.get(1)?.to_string();
// Seems that [Uri resolver](https://docs.gtk.org/glib/type_func.Uri.resolve_relative.html) // Relative scheme patch
// does not support [protocol-relative URI](https://datatracker.ietf.org/doc/html/rfc3986#section-4.2) // https://datatracker.ietf.org/doc/html/rfc3986#section-4.2
// resolve manually if let Some(p) = unresolved_address.strip_prefix("//") {
if unresolved_address.starts_with("//:") { let postfix = p.trim_start_matches(":");
let scheme = match base { match base {
Some(base) => base.scheme(), Some(b) => {
None => return None, unresolved_address = format!(
}; "{}://{}",
unresolved_address = unresolved_address.replace("//:", &format!("{scheme}://")); b.scheme(),
if postfix.is_empty() {
b.host()?
} else {
postfix.into()
}
)
}
None => return None,
}
} }
// Convert address to the valid URI // Convert address to the valid URI
let uri = match base { let uri = match base {
// Base conversion requested // Base conversion requested
@ -54,10 +62,7 @@ impl Link {
// Try convert string to the valid URI // Try convert string to the valid URI
match Uri::parse(&resolved_str, UriFlags::NONE) { match Uri::parse(&resolved_str, UriFlags::NONE) {
Ok(resolved_uri) => { Ok(resolved_uri) => {
// Change external status
is_external = Some(resolved_uri.scheme() != base_uri.scheme()); is_external = Some(resolved_uri.scheme() != base_uri.scheme());
// Result
resolved_uri resolved_uri
} }
Err(_) => return None, Err(_) => return None,

View file

@ -8,6 +8,8 @@
=> gemini://geminiprotocol.net 1965-01-19 Gemini => gemini://geminiprotocol.net 1965-01-19 Gemini
=> /docs/gemtext.gmi 1965-01-19 Gemini => /docs/gemtext.gmi 1965-01-19 Gemini
=> //:geminiprotocol.net => //:geminiprotocol.net
=> //geminiprotocol.net
=> //
* Listing item 1 * Listing item 1
* Listing item 2 * Listing item 2

View file

@ -146,7 +146,7 @@ fn gemtext() {
} // #3 } // #3
// Validate links // Validate links
assert_eq!(link.len(), 6); assert_eq!(link.len(), 8);
{ {
let item = link.first().unwrap(); let item = link.first().unwrap();
@ -214,6 +214,22 @@ fn gemtext() {
assert_eq!(item.uri.to_str(), "gemini://geminiprotocol.net"); assert_eq!(item.uri.to_str(), "gemini://geminiprotocol.net");
} // #6 } // #6
{
let item = link.get(6).unwrap();
assert_eq!(item.alt, None);
assert_eq!(item.timestamp, None);
assert_eq!(item.uri.to_str(), "gemini://geminiprotocol.net");
} // #7
{
let item = link.get(7).unwrap();
assert_eq!(item.alt, None);
assert_eq!(item.timestamp, None);
assert_eq!(item.uri.to_str(), "gemini://geminiprotocol.net");
} // #8
// Validate lists // Validate lists
assert_eq!(list.len(), 2); assert_eq!(list.len(), 2);
assert_eq!(list.first().unwrap().value, "Listing item 1"); assert_eq!(list.first().unwrap().value, "Listing item 1");