Skip to content

Commit f8907e3

Browse files
committed
feat: add wildcard pattern support to provider database
1 parent f1688d2 commit f8907e3

File tree

4 files changed

+366
-396
lines changed

4 files changed

+366
-396
lines changed

scripts/create-provider-data-rs.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,9 +220,9 @@ def process_dir(dir):
220220

221221
process_dir(Path(sys.argv[1]))
222222

223-
out_all += "pub(crate) static PROVIDER_DATA: Lazy<HashMap<&'static str, &'static Provider>> = Lazy::new(|| HashMap::from([\n"
223+
out_all += "pub(crate) static PROVIDER_DATA: [(&str, &Provider); " + str(len(domains_set)) + "] = [\n";
224224
out_all += out_domains
225-
out_all += "]));\n\n"
225+
out_all += "];\n\n"
226226

227227
out_all += "pub(crate) static PROVIDER_IDS: Lazy<HashMap<&'static str, &'static Provider>> = Lazy::new(|| HashMap::from([\n"
228228
out_all += out_ids

scripts/update-provider-database.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ set -euo pipefail
66
export TZ=UTC
77

88
# Provider database revision.
9-
REV=18f714cf73d0bdfb8b013fa344494ab80c92b477
9+
REV=2f3db24107e4802c2df0aa0a40f0e144006c0a9b
1010

1111
CORE_ROOT="$PWD"
1212
TMP="$(mktemp -d)"

src/provider.rs

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,18 @@ pub async fn get_provider_info(
215215

216216
/// Finds a provider in offline database based on domain.
217217
pub fn get_provider_by_domain(domain: &str) -> Option<&'static Provider> {
218-
if let Some(provider) = PROVIDER_DATA.get(domain.to_lowercase().as_str()) {
219-
return Some(*provider);
218+
let domain = domain.to_lowercase();
219+
for (pattern, provider) in PROVIDER_DATA {
220+
if let Some(suffix) = pattern.strip_prefix('*') {
221+
// Wildcard domain pattern.
222+
//
223+
// For example, `suffix` is ".hermes.radio" for "*.hermes.radio" pattern.
224+
if domain.ends_with(suffix) {
225+
return Some(provider);
226+
}
227+
} else if pattern == domain {
228+
return Some(provider);
229+
}
220230
}
221231

222232
None
@@ -226,33 +236,42 @@ pub fn get_provider_by_domain(domain: &str) -> Option<&'static Provider> {
226236
///
227237
/// For security reasons, only Gmail can be configured this way.
228238
pub async fn get_provider_by_mx(context: &Context, domain: &str) -> Option<&'static Provider> {
229-
if let Ok(resolver) = get_resolver() {
230-
let mut fqdn: String = domain.to_string();
231-
if !fqdn.ends_with('.') {
232-
fqdn.push('.');
239+
let Ok(resolver) = get_resolver() else {
240+
warn!(context, "Cannot get a resolver to check MX records.");
241+
return None;
242+
};
243+
244+
let mut fqdn: String = domain.to_string();
245+
if !fqdn.ends_with('.') {
246+
fqdn.push('.');
247+
}
248+
249+
let Ok(mx_domains) = resolver.mx_lookup(fqdn).await else {
250+
warn!(context, "Cannot resolve MX records for {domain:?}.");
251+
return None;
252+
};
253+
254+
for (provider_domain_pattern, provider) in PROVIDER_DATA {
255+
if provider.id != "gmail" {
256+
// MX lookup is limited to Gmail for security reasons
257+
continue;
233258
}
234259

235-
if let Ok(mx_domains) = resolver.mx_lookup(fqdn).await {
236-
for (provider_domain, provider) in &*PROVIDER_DATA {
237-
if provider.id != "gmail" {
238-
// MX lookup is limited to Gmail for security reasons
239-
continue;
240-
}
260+
if provider_domain_pattern.starts_with('*') {
261+
// Skip wildcard patterns.
262+
continue;
263+
}
241264

242-
let provider_fqdn = provider_domain.to_string() + ".";
243-
let provider_fqdn_dot = ".".to_string() + &provider_fqdn;
265+
let provider_fqdn = provider_domain_pattern.to_string() + ".";
266+
let provider_fqdn_dot = ".".to_string() + &provider_fqdn;
244267

245-
for mx_domain in mx_domains.iter() {
246-
let mx_domain = mx_domain.exchange().to_lowercase().to_utf8();
268+
for mx_domain in mx_domains.iter() {
269+
let mx_domain = mx_domain.exchange().to_lowercase().to_utf8();
247270

248-
if mx_domain == provider_fqdn || mx_domain.ends_with(&provider_fqdn_dot) {
249-
return Some(provider);
250-
}
251-
}
271+
if mx_domain == provider_fqdn || mx_domain.ends_with(&provider_fqdn_dot) {
272+
return Some(provider);
252273
}
253274
}
254-
} else {
255-
warn!(context, "cannot get a resolver to check MX records.");
256275
}
257276

258277
None

0 commit comments

Comments
 (0)