Read an address typed without a scheme as https (#101)

cnn-com was added as 'cnn.com', stored as typed, and every check failed with "relative URL
without a base" before it reached the site to look for its feed. expand_input, which both the
web page and `ipx add` pass the address through, now makes one without a scheme https, and a
protocol-relative //host/path https too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-29 19:46:10 +00:00
parent 0cc956b7c6
commit 9084b61bb6
2 changed files with 16 additions and 2 deletions

View File

@@ -50,6 +50,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed ### Fixed
- Adding a site without `https://`, such as `cnn.com`, works; it failed on every check.
- A limit on new downloads per check means a show's newest episodes: with it set to 3, ipx no longer works back through the show's history three at a time. Set to 0, it still takes the whole back catalogue. - A limit on new downloads per check means a show's newest episodes: with it set to 3, ipx no longer works back through the show's history three at a time. Set to 0, it still takes the whole back catalogue.
- With no limit on new downloads per check (`max_new_per_check = 0`), downloads work on Postgres; they failed. - With no limit on new downloads per check (`max_new_per_check = 0`), downloads work on Postgres; they failed.
- Checking a feed with a long history is much quicker: items already stored are no longer written again on every check. - Checking a feed with a long history is much quicker: items already stored are no longer written again on every check.

View File

@@ -219,11 +219,20 @@ pub fn is_patreon_creator(url: &str) -> bool {
} }
/// What was typed into Add feed, as a URL. A bare Patreon token is taken as its creator's /// What was typed into Add feed, as a URL. A bare Patreon token is taken as its creator's
/// feed, since the token alone says whose it is. /// feed, since the token alone says whose it is. An address with no scheme is https: 'cnn.com'
/// was stored as typed and every check failed with "relative URL without a base" (#101).
pub fn expand_input(input: &str) -> String { pub fn expand_input(input: &str) -> String {
let s = input.trim(); let s = input.trim();
let token = s.len() >= 20 && s.chars().all(|c| c.is_ascii_alphanumeric() || c == '-' || c == '_'); let token = s.len() >= 20 && s.chars().all(|c| c.is_ascii_alphanumeric() || c == '-' || c == '_');
if token { format!("https://www.patreon.com/rss?auth={s}") } else { s.to_owned() } if token {
format!("https://www.patreon.com/rss?auth={s}")
} else if let Some(rest) = s.strip_prefix("//") {
format!("https://{rest}")
} else if !s.contains("://") {
format!("https://{s}")
} else {
s.to_owned()
}
} }
/// Whether two URLs are the same feed. One Patreon show has several spellings -- by the /// Whether two URLs are the same feed. One Patreon show has several spellings -- by the
@@ -1226,6 +1235,10 @@ mod tests {
let tok = "AbCdEfGhIjKlMnOpQrStUvWxYz012_-9"; let tok = "AbCdEfGhIjKlMnOpQrStUvWxYz012_-9";
assert_eq!(expand_input(&format!(" {tok} ")), format!("https://www.patreon.com/rss?auth={tok}")); assert_eq!(expand_input(&format!(" {tok} ")), format!("https://www.patreon.com/rss?auth={tok}"));
assert_eq!(expand_input("https://example.com/rss"), "https://example.com/rss"); assert_eq!(expand_input("https://example.com/rss"), "https://example.com/rss");
assert_eq!(expand_input("http://example.com/rss"), "http://example.com/rss");
assert_eq!(expand_input(" cnn.com "), "https://cnn.com");
assert_eq!(expand_input("example.com/feed.xml"), "https://example.com/feed.xml");
assert_eq!(expand_input("//example.com/rss"), "https://example.com/rss");
assert!(is_patreon_creator(&format!("https://www.patreon.com/rss/glasscannon?auth={tok}"))); assert!(is_patreon_creator(&format!("https://www.patreon.com/rss/glasscannon?auth={tok}")));
assert!(is_patreon_creator(&format!("https://www.patreon.com/rss?auth={tok}"))); assert!(is_patreon_creator(&format!("https://www.patreon.com/rss?auth={tok}")));