From 52dc0a787c03b6ad95c693b1a25100a7013e4b15 Mon Sep 17 00:00:00 2001 From: patrick-immometrica Date: Thu, 5 Nov 2026 11:52:03 +0100 Subject: [PATCH] fix(uri): parse uppercase http/https as standard schemes Scheme::from_str("HTTP") produced Scheme2::Other, which is not equal to Scheme::HTTP and hashes differently, while parsing a full Uri lowercases the scheme and gets Scheme::HTTP. Match the two standard schemes case-insensitively so both paths agree. --- src/uri/scheme.rs | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/uri/scheme.rs b/src/uri/scheme.rs index bf4d59c32..0cfe31665 100644 --- a/src/uri/scheme.rs +++ b/src/uri/scheme.rs @@ -236,8 +236,8 @@ impl Scheme2 { // Postcondition: On all Ok() returns, s is valid UTF-8 fn parse_exact(s: &[u8]) -> Result, InvalidUri> { match s { - b"http" => Ok(Protocol::Http.into()), - b"https" => Ok(Protocol::Https.into()), + _ if s.eq_ignore_ascii_case(b"http") => Ok(Protocol::Http.into()), + _ if s.eq_ignore_ascii_case(b"https") => Ok(Protocol::Https.into()), _ => { if s.len() > MAX_SCHEME_LEN { return Err(ErrorKind::SchemeTooLong.into()); @@ -347,6 +347,22 @@ mod test { assert_eq!(&scheme("my+funky+scheme"), "my+funky+scheme"); } + #[test] + fn standard_scheme_is_case_insensitive() { + use std::collections::HashSet; + + for (s, expected) in [ + ("HTTP", Scheme::HTTP), + ("hTtP", Scheme::HTTP), + ("HTTPS", Scheme::HTTPS), + ] { + let parsed = scheme(s); + assert_eq!(parsed, expected); + assert_eq!(parsed.as_str(), expected.as_str()); + assert!(HashSet::from([expected]).contains(&parsed)); + } + } + #[test] fn invalid_scheme_is_error() { Scheme::try_from("my_funky_scheme").expect_err("Unexpectedly valid Scheme");