From 62d219284cac70f0b4e44750b8fc46c82b465ab3 Mon Sep 17 00:00:00 2001 From: projectmoon Date: Mon, 1 Apr 2024 12:21:33 +0200 Subject: [PATCH] Normalize target URL and gemention links to handle port numbers etc from incoming connection URL --- src/verification/mod.rs | 44 +++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/src/verification/mod.rs b/src/verification/mod.rs index ec69855..4ee8ca5 100644 --- a/src/verification/mod.rs +++ b/src/verification/mod.rs @@ -7,6 +7,15 @@ use crate::error::GementionError; use crate::models::mentions::Mention; 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 { gemtext_link.starts_with(endpoint.as_str()) } @@ -16,6 +25,7 @@ fn scan_for_gemention_endpoints( meta: GeminiMetadata, ast: GeminiAst, ) -> (VerificationSource, Vec) { + // TODO remove this in favor of checking for /gemention.txt // Check metadata of the page for a gemention endpoint. if let Some(endpoint) = meta.parameters().get("gemention") { let endpoint = endpoint.trim_start_matches("="); @@ -42,10 +52,8 @@ fn verify_mentions( source_and_endpoints: (VerificationSource, Vec), ) -> Result { let (verification_source, mentions) = source_and_endpoints; - // TODO need to normalize url from page as well as ours, to make - // sure things like ports being in url or not are handled. - let expected_link = mention.receiving_endpoint().join(mention.target())?; - let expected_link = expected_link.as_ref(); + let mut expected_link = mention.receiving_endpoint().join(mention.target())?; + normalize_url(&mut expected_link); let verification_status = if mentions.len() > 0 { // We have links that go to our endpoint. Scan links for the @@ -53,15 +61,21 @@ fn verify_mentions( // incorrect link. mentions .into_iter() - .find_map(|link| { - if link == expected_link { - Some(VerificationStatus::Verified { - endpoint: link, - source: verification_source, - }) - } else { - None - } + .find_map(|mention_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 { + endpoint: gemention_link.to_string(), + source: verification_source, + }) + } else { + None + } + }) }) .unwrap_or(VerificationStatus::Invalid( VerificationFailureReason::MentionLinkIncorrect( @@ -76,9 +90,9 @@ fn verify_mentions( } 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 content = resp