aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/html.rs51
-rw-r--r--src/response.rs49
-rw-r--r--src/url.rs42
3 files changed, 71 insertions, 71 deletions
diff --git a/src/html.rs b/src/html.rs
index c0425df..341286c 100644
--- a/src/html.rs
+++ b/src/html.rs
@@ -1,16 +1,21 @@
use {
+ crate::url::matches_pattern,
germ::ast::Node,
std::{env::var, fmt::Write},
url::Url,
};
fn link_from_host_href(url: &Url, href: &str) -> Option<String> {
- Some(format!(
- "gemini://{}{}{}",
- url.domain()?,
- { if href.starts_with('/') { "" } else { "/" } },
- href
- ))
+ if href.starts_with("/proxy/") {
+ Some(format!("gemini://{}", href.replace("/proxy/", "")))
+ } else {
+ Some(format!(
+ "gemini://{}{}{}",
+ url.domain()?,
+ { if href.starts_with('/') { "" } else { "/" } },
+ href
+ ))
+ }
}
fn safe(text: &str) -> String {
@@ -181,30 +186,26 @@ pub fn from_gemini(
}
}
- if let Ok(keeps) = var("KEEP_GEMINI_EXACT") {
- let mut keeps = keeps.split(',');
+ if let Ok(keeps) = var("KEEP_GEMINI") {
+ let patterns = keeps.split(',').collect::<Vec<_>>();
if (href.starts_with('/') || !href.contains("://")) && !surface {
let temporary_href = link_from_host_href(url, &href)?;
+ let should_exclude = patterns
+ .iter()
+ .filter(|p| p.starts_with('!'))
+ .any(|p| matches_pattern(&p[1..], &temporary_href));
- if keeps.any(|k| k == &*temporary_href) {
- href = temporary_href;
- }
- }
- }
-
- if let Ok(keeps) = var("KEEP_GEMINI_DOMAIN") {
- let host = if let Some(host) = url.host() {
- host.to_string()
- } else {
- return None;
- };
+ if !should_exclude {
+ let should_include = patterns
+ .iter()
+ .filter(|p| !p.starts_with('!'))
+ .any(|p| matches_pattern(p, &temporary_href));
- if (href.starts_with('/')
- || !href.contains("://") && keeps.split(',').any(|k| k == &*host))
- && !surface
- {
- href = link_from_host_href(url, &href)?;
+ if should_include {
+ href = temporary_href;
+ }
+ }
}
}
diff --git a/src/response.rs b/src/response.rs
index 1a68b08..68c1690 100644
--- a/src/response.rs
+++ b/src/response.rs
@@ -1,7 +1,7 @@
pub mod configuration;
use {
- crate::url::from_path as url_from_path,
+ crate::url::{from_path as url_from_path, matches_pattern},
actix_web::{Error, HttpResponse},
std::{env::var, fmt::Write, time::Instant},
};
@@ -262,8 +262,8 @@ pub async fn default(
if let Ok(plain_texts) = var("PLAIN_TEXT_ROUTE") {
if plain_texts.split(',').any(|r| {
- path_matches_pattern(r, http_request.path())
- || path_matches_pattern(r, http_request.path().trim_end_matches('/'))
+ matches_pattern(r, http_request.path())
+ || matches_pattern(r, http_request.path().trim_end_matches('/'))
}) {
return Ok(HttpResponse::Ok().body(
response.content().as_ref().map_or_else(String::default, String::clone),
@@ -277,46 +277,3 @@ pub async fn default(
.body(html_context),
)
}
-
-fn path_matches_pattern(pattern: &str, path: &str) -> bool {
- if !pattern.contains('*') {
- return path == pattern;
- }
-
- let parts: Vec<&str> = pattern.split('*').collect();
- let mut position = if pattern.starts_with('*') {
- 0
- } else {
- let first = parts.first().unwrap();
-
- if !path.starts_with(first) {
- return false;
- }
-
- first.len()
- };
-
- let mid_end = parts.len().saturating_sub(1);
-
- for part in &parts[1..mid_end] {
- if part.is_empty() {
- continue;
- }
-
- if let Some(found) = path[position..].find(part) {
- position += found + part.len();
- } else {
- return false;
- }
- }
-
- if !pattern.ends_with('*') {
- let last = parts.last().unwrap();
-
- if !path[position..].ends_with(last) {
- return false;
- }
- }
-
- true
-}
diff --git a/src/url.rs b/src/url.rs
index 289c5cb..5289d28 100644
--- a/src/url.rs
+++ b/src/url.rs
@@ -57,3 +57,45 @@ pub fn from_path(
)
})
}
+
+pub fn matches_pattern(pattern: &str, path: &str) -> bool {
+ if !pattern.contains('*') {
+ return path == pattern;
+ }
+
+ let parts: Vec<&str> = pattern.split('*').collect();
+ let mut position = if pattern.starts_with('*') {
+ 0
+ } else {
+ let first = parts.first().unwrap();
+
+ if !path.starts_with(first) {
+ return false;
+ }
+
+ first.len()
+ };
+ let before_last = parts.len().saturating_sub(1);
+
+ for part in &parts[1..before_last] {
+ if part.is_empty() {
+ continue;
+ }
+
+ if let Some(found) = path[position..].find(part) {
+ position += found + part.len();
+ } else {
+ return false;
+ }
+ }
+
+ if !pattern.ends_with('*') {
+ let last = parts.last().unwrap();
+
+ if !path[position..].ends_with(last) {
+ return false;
+ }
+ }
+
+ true
+}