Normalize target URL and gemention links to handle port numbers etc from incoming connection URL

This commit is contained in:
projectmoon 2024-04-01 12:21:33 +02:00
parent c5eeb147a5
commit 62d219284c
1 changed files with 29 additions and 15 deletions

View File

@ -7,6 +7,15 @@ use crate::error::GementionError;
use crate::models::mentions::Mention; use crate::models::mentions::Mention;
use crate::models::verification::*; use crate::models::verification::*;
/// Normalize URL by making sure it starts with the right protocol and
/// has a port number.
fn normalize_url(url: &mut Url) {
if url.port().is_none() {
// Weird line because the error is Unit type.
let _ = url.set_port(Some(1965));
}
}
fn is_mention_link(endpoint: &Url, gemtext_link: &str) -> bool { fn is_mention_link(endpoint: &Url, gemtext_link: &str) -> bool {
gemtext_link.starts_with(endpoint.as_str()) gemtext_link.starts_with(endpoint.as_str())
} }
@ -16,6 +25,7 @@ fn scan_for_gemention_endpoints(
meta: GeminiMetadata, meta: GeminiMetadata,
ast: GeminiAst, ast: GeminiAst,
) -> (VerificationSource, Vec<String>) { ) -> (VerificationSource, Vec<String>) {
// TODO remove this in favor of checking for <domain>/gemention.txt
// Check metadata of the page for a gemention endpoint. // Check metadata of the page for a gemention endpoint.
if let Some(endpoint) = meta.parameters().get("gemention") { if let Some(endpoint) = meta.parameters().get("gemention") {
let endpoint = endpoint.trim_start_matches("="); let endpoint = endpoint.trim_start_matches("=");
@ -42,10 +52,8 @@ fn verify_mentions(
source_and_endpoints: (VerificationSource, Vec<String>), source_and_endpoints: (VerificationSource, Vec<String>),
) -> Result<VerificationStatus, GementionError> { ) -> Result<VerificationStatus, GementionError> {
let (verification_source, mentions) = source_and_endpoints; let (verification_source, mentions) = source_and_endpoints;
// TODO need to normalize url from page as well as ours, to make let mut expected_link = mention.receiving_endpoint().join(mention.target())?;
// sure things like ports being in url or not are handled. normalize_url(&mut expected_link);
let expected_link = mention.receiving_endpoint().join(mention.target())?;
let expected_link = expected_link.as_ref();
let verification_status = if mentions.len() > 0 { let verification_status = if mentions.len() > 0 {
// We have links that go to our endpoint. Scan links for the // We have links that go to our endpoint. Scan links for the
@ -53,16 +61,22 @@ fn verify_mentions(
// incorrect link. // incorrect link.
mentions mentions
.into_iter() .into_iter()
.find_map(|link| { .find_map(|mention_link| {
if link == expected_link { let mut parsed = Url::parse(&mention_link).ok();
let parsed = parsed.as_mut();
parsed.and_then(|gemention_link| {
normalize_url(gemention_link);
if gemention_link == &expected_link {
Some(VerificationStatus::Verified { Some(VerificationStatus::Verified {
endpoint: link, endpoint: gemention_link.to_string(),
source: verification_source, source: verification_source,
}) })
} else { } else {
None None
} }
}) })
})
.unwrap_or(VerificationStatus::Invalid( .unwrap_or(VerificationStatus::Invalid(
VerificationFailureReason::MentionLinkIncorrect( VerificationFailureReason::MentionLinkIncorrect(
mention.receiving_endpoint().to_string(), mention.receiving_endpoint().to_string(),
@ -76,9 +90,9 @@ fn verify_mentions(
} }
async fn verify_mention(mention: &mut Mention) -> Result<(), GementionError> { async fn verify_mention(mention: &mut Mention) -> Result<(), GementionError> {
let url = Url::parse(&format!("gemini://{}", mention.target()))?; let target_url = Url::parse(&format!("gemini://{}", mention.target()))?;
let resp = germ_request(&url).await?; let resp = germ_request(&target_url).await?;
let meta = GeminiMetadata::from_string(resp.meta()); let meta = GeminiMetadata::from_string(resp.meta());
let content = resp let content = resp