agate

Simple gemini server for static files
git clone https://github.com/mbrubeck/agate.git
Log | Files | Refs | README

commit 675309f4aa55b8b797db4c0eda3af74f13d969d9
parent 01597a1d2c09c3ac3ed907079a4023831621c336
Author: Johann150 <johann.galle@protonmail.com>
Date:   Tue, 23 Nov 2021 09:56:28 +0100

normalize hostnames before comparing

Diffstat:
Msrc/main.rs | 18+++++++++++++++---
Mtests/tests.rs | 4+++-
2 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/src/main.rs b/src/main.rs @@ -226,6 +226,7 @@ fn args() -> Result<Args> { let mut hostnames = vec![]; for s in matches.opt_strs("hostname") { + // normalize hostname, add punycoding if necessary let hostname = Host::parse(&s)?; // 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) 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: // correct scheme @@ -448,14 +449,25 @@ impl RequestHandle { } // 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 // 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) { return Err((53, "Proxy request refused")); } } else { - return Err((59, "URL does not contain a host")); + return Err((59, "URL does not contain a domain")); } // correct port diff --git a/tests/tests.rs b/tests/tests.rs @@ -509,6 +509,8 @@ mod vhosts { #[test] /// - simple vhosts are enabled when multiple hostnames are supplied /// - 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() { let page = get( &[ @@ -520,7 +522,7 @@ mod vhosts { "example.org", ], addr(1984), - "gemini://example.com/", + "gemini://Example.com/", ) .expect("could not get page");