mirror of
https://github.com/YGGverse/ggemini.git
synced 2026-04-02 18:15:37 +00:00
add support for uri starts with double slash
This commit is contained in:
parent
e3abd89c9d
commit
0523f67850
2 changed files with 82 additions and 45 deletions
|
|
@ -54,8 +54,32 @@ impl Redirect {
|
||||||
// > it is up to the client which fragment to apply.
|
// > it is up to the client which fragment to apply.
|
||||||
None, // @TODO
|
None, // @TODO
|
||||||
)
|
)
|
||||||
.parse_relative(self.target(), UriFlags::NONE)
|
.parse_relative(
|
||||||
{
|
&{
|
||||||
|
// URI started with double slash yet not supported by Glib function
|
||||||
|
// https://datatracker.ietf.org/doc/html/rfc3986#section-4.2
|
||||||
|
let t = self.target();
|
||||||
|
match t.strip_prefix("//") {
|
||||||
|
Some(p) => {
|
||||||
|
let postfix = p.trim_start_matches(":");
|
||||||
|
format!(
|
||||||
|
"{}://{}",
|
||||||
|
base.scheme(),
|
||||||
|
if postfix.is_empty() {
|
||||||
|
match base.host() {
|
||||||
|
Some(h) => format!("{h}/"),
|
||||||
|
None => return Err(Error::BaseHost),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
postfix.to_string()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
None => t.to_string(),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
UriFlags::NONE,
|
||||||
|
) {
|
||||||
Ok(absolute) => Ok(absolute),
|
Ok(absolute) => Ok(absolute),
|
||||||
Err(e) => Err(Error::Uri(e)),
|
Err(e) => Err(Error::Uri(e)),
|
||||||
}
|
}
|
||||||
|
|
@ -127,9 +151,9 @@ fn target(value: Option<&GStringPtr>) -> Result<String, Error> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_from_str() {
|
fn test() {
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
{
|
||||||
let temporary = Redirect::from_str("30 /uri\r\n").unwrap();
|
let temporary = Redirect::from_str("30 /uri\r\n").unwrap();
|
||||||
assert_eq!(temporary.target(), "/uri");
|
assert_eq!(temporary.target(), "/uri");
|
||||||
assert_eq!(temporary.to_code(), TEMPORARY.0);
|
assert_eq!(temporary.to_code(), TEMPORARY.0);
|
||||||
|
|
@ -140,12 +164,8 @@ fn test_from_str() {
|
||||||
assert_eq!(permanent.to_code(), PERMANENT.0);
|
assert_eq!(permanent.to_code(), PERMANENT.0);
|
||||||
assert_eq!(permanent.to_string(), PERMANENT.1);
|
assert_eq!(permanent.to_string(), PERMANENT.1);
|
||||||
}
|
}
|
||||||
|
{
|
||||||
#[test]
|
let base = Uri::build(
|
||||||
fn test_to_uri() {
|
|
||||||
use std::str::FromStr;
|
|
||||||
|
|
||||||
let request = Uri::build(
|
|
||||||
UriFlags::NONE,
|
UriFlags::NONE,
|
||||||
"gemini",
|
"gemini",
|
||||||
None,
|
None,
|
||||||
|
|
@ -158,19 +178,32 @@ fn test_to_uri() {
|
||||||
|
|
||||||
let resolve = Redirect::from_str("30 /uri\r\n").unwrap();
|
let resolve = Redirect::from_str("30 /uri\r\n").unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
resolve.to_uri(&request).unwrap().to_string(),
|
resolve.to_uri(&base).unwrap().to_string(),
|
||||||
"gemini://geminiprotocol.net/uri"
|
"gemini://geminiprotocol.net/uri"
|
||||||
);
|
);
|
||||||
|
|
||||||
let resolve = Redirect::from_str("30 uri\r\n").unwrap();
|
let resolve = Redirect::from_str("30 uri\r\n").unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
resolve.to_uri(&request).unwrap().to_string(),
|
resolve.to_uri(&base).unwrap().to_string(),
|
||||||
"gemini://geminiprotocol.net/path/uri"
|
"gemini://geminiprotocol.net/path/uri"
|
||||||
);
|
);
|
||||||
|
|
||||||
let resolve = Redirect::from_str("30 gemini://test.host/uri\r\n").unwrap();
|
let resolve = Redirect::from_str("30 gemini://test.host/uri\r\n").unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
resolve.to_uri(&request).unwrap().to_string(),
|
resolve.to_uri(&base).unwrap().to_string(),
|
||||||
"gemini://test.host/uri"
|
"gemini://test.host/uri"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let resolve = Redirect::from_str("30 //\r\n").unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
resolve.to_uri(&base).unwrap().to_string(),
|
||||||
|
"gemini://geminiprotocol.net/"
|
||||||
|
);
|
||||||
|
|
||||||
|
let resolve = Redirect::from_str("30 //:\r\n").unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
resolve.to_uri(&base).unwrap().to_string(),
|
||||||
|
"gemini://geminiprotocol.net/"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ use std::{
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
BaseHost,
|
||||||
Uri(glib::Error),
|
Uri(glib::Error),
|
||||||
Protocol,
|
Protocol,
|
||||||
Target,
|
Target,
|
||||||
|
|
@ -14,6 +15,9 @@ pub enum Error {
|
||||||
impl Display for Error {
|
impl Display for Error {
|
||||||
fn fmt(&self, f: &mut Formatter) -> Result {
|
fn fmt(&self, f: &mut Formatter) -> Result {
|
||||||
match self {
|
match self {
|
||||||
|
Self::BaseHost => {
|
||||||
|
write!(f, "Base host required")
|
||||||
|
}
|
||||||
Self::Uri(e) => {
|
Self::Uri(e) => {
|
||||||
write!(f, "URI error: {e}")
|
write!(f, "URI error: {e}")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue