Skip to content

Commit d262f04

Browse files
refactor(psl): hoist registrable_domain to a trait default method
DafsaFilePublicSuffixList and MockPublicSuffixList had byte-identical registrable_domain impls expressed purely in terms of public_suffix. Move that body to a default method on PublicSuffixList; DatFilePublicSuffixList keeps its override (it uses the publicsuffix crate's own root()).
1 parent f2dac5a commit d262f04

2 files changed

Lines changed: 19 additions & 24 deletions

File tree

libwebauthn/src/ops/webauthn/psl/dafsa.rs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -102,16 +102,6 @@ impl PublicSuffixList for DafsaFilePublicSuffixList {
102102
}
103103
}
104104
}
105-
106-
fn registrable_domain(&self, host: &str) -> Option<String> {
107-
let suffix = self.public_suffix(host)?;
108-
if host == suffix {
109-
return None;
110-
}
111-
let prefix = host.strip_suffix(&suffix)?.strip_suffix('.')?;
112-
let last_label = prefix.rsplit('.').next()?;
113-
Some(format!("{last_label}.{suffix}"))
114-
}
115105
}
116106

117107
fn parse_header(bytes: &[u8]) -> Result<Vec<u8>, DafsaFileLoadError> {

libwebauthn/src/ops/webauthn/psl/mod.rs

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,27 @@ pub use system::{SystemLoadError, SystemPublicSuffixList};
3333
/// Implementations decide where the PSL data lives (system file, embedded
3434
/// snapshot, HTTP-cached, etc).
3535
pub trait PublicSuffixList: Send + Sync {
36-
/// Returns the registrable domain (eTLD+1) of `host`, or `None` if
37-
/// `host` has no registrable domain (e.g. it is itself a public suffix).
38-
fn registrable_domain(&self, host: &str) -> Option<String>;
39-
4036
/// Returns the public suffix of `host`, or `None` if none applies.
4137
fn public_suffix(&self, host: &str) -> Option<String>;
38+
39+
/// Returns the registrable domain (eTLD+1) of `host`, or `None` if
40+
/// `host` has no registrable domain (e.g. it is itself a public suffix).
41+
///
42+
/// The default implementation derives this from [`public_suffix`]: the
43+
/// registrable domain is the public suffix plus one more label. An
44+
/// implementation whose backing library computes it directly may override
45+
/// this.
46+
///
47+
/// [`public_suffix`]: PublicSuffixList::public_suffix
48+
fn registrable_domain(&self, host: &str) -> Option<String> {
49+
let suffix = self.public_suffix(host)?;
50+
if host == suffix {
51+
return None;
52+
}
53+
let prefix = host.strip_suffix(&suffix)?.strip_suffix('.')?;
54+
let last_label = prefix.rsplit('.').next()?;
55+
Some(format!("{last_label}.{suffix}"))
56+
}
4257
}
4358

4459
/// Test-only PSL that recognises a small fixed set of public suffixes.
@@ -63,16 +78,6 @@ impl PublicSuffixList for MockPublicSuffixList {
6378
}
6479
None
6580
}
66-
67-
fn registrable_domain(&self, host: &str) -> Option<String> {
68-
let suffix = self.public_suffix(host)?;
69-
if host == suffix {
70-
return None;
71-
}
72-
let prefix = host.strip_suffix(&suffix)?.strip_suffix('.')?;
73-
let last_label = prefix.rsplit('.').next()?;
74-
Some(format!("{last_label}.{suffix}"))
75-
}
7681
}
7782

7883
#[cfg(test)]

0 commit comments

Comments
 (0)