normalize hostnames before comparing

This commit is contained in:
Johann150 2021-11-23 09:56:28 +01:00
parent 01597a1d2c
commit 675309f4aa
No known key found for this signature in database
GPG key ID: 9EE6577A2A06F8F1
2 changed files with 18 additions and 4 deletions

View file

@ -226,6 +226,7 @@ fn args() -> Result<Args> {
let mut hostnames = vec![]; let mut hostnames = vec![];
for s in matches.opt_strs("hostname") { for s in matches.opt_strs("hostname") {
// normalize hostname, add punycoding if necessary
let hostname = Host::parse(&s)?; let hostname = Host::parse(&s)?;
// check if we have a certificate for that domain // check if we have a certificate for that domain
@ -434,7 +435,7 @@ impl RequestHandle {
// log literal request (might be different from or not an actual URL) // log literal request (might be different from or not an actual URL)
write!(self.log_line, " \"{}\"", request).unwrap(); write!(self.log_line, " \"{}\"", request).unwrap();
let url = Url::parse(request).or(Err((59, "Invalid URL")))?; let mut url = Url::parse(request).or(Err((59, "Invalid URL")))?;
// Validate the URL: // Validate the URL:
// correct scheme // correct scheme
@ -448,14 +449,25 @@ impl RequestHandle {
} }
// correct host // correct host
if let Some(host) = url.host() { if let Some(domain) = url.domain() {
// because the gemini scheme is not special enough for WHATWG, normalize
// it ourselves
let host = Host::parse(
&percent_decode_str(domain)
.decode_utf8()
.expect("invalid domain?"),
)
.expect("invalid domain?");
// TODO: simplify when <https://github.com/servo/rust-url/issues/586> resolved
url.set_host(Some(&host.to_string()))
.expect("invalid domain?");
// do not use "contains" here since it requires the same type and does // do not use "contains" here since it requires the same type and does
// not allow to check for Host<&str> if the vec contains Hostname<String> // not allow to check for Host<&str> if the vec contains Hostname<String>
if !ARGS.hostnames.is_empty() && !ARGS.hostnames.iter().any(|h| h == &host) { if !ARGS.hostnames.is_empty() && !ARGS.hostnames.iter().any(|h| h == &host) {
return Err((53, "Proxy request refused")); return Err((53, "Proxy request refused"));
} }
} else { } else {
return Err((59, "URL does not contain a host")); return Err((59, "URL does not contain a domain"));
} }
// correct port // correct port

View file

@ -509,6 +509,8 @@ mod vhosts {
#[test] #[test]
/// - simple vhosts are enabled when multiple hostnames are supplied /// - simple vhosts are enabled when multiple hostnames are supplied
/// - the vhosts access the correct files /// - the vhosts access the correct files
/// - the hostname comparison is case insensitive
/// - the hostname is converted to lower case to access certificates
fn example_com() { fn example_com() {
let page = get( let page = get(
&[ &[
@ -520,7 +522,7 @@ mod vhosts {
"example.org", "example.org",
], ],
addr(1984), addr(1984),
"gemini://example.com/", "gemini://Example.com/",
) )
.expect("could not get page"); .expect("could not get page");