diff --git a/httplib.h b/httplib.h index abe73a1..b556c83 100644 --- a/httplib.h +++ b/httplib.h @@ -13342,7 +13342,11 @@ inline bool SSLClient::verify_host_with_common_name(X509 *server_cert) const { inline bool SSLClient::check_host_name(const char *pattern, size_t pattern_len) const { - if (host_.size() == pattern_len && host_ == pattern) { return true; } + // Exact match (case-insensitive) + if (host_.size() == pattern_len && + detail::case_ignore::equal(host_, std::string(pattern, pattern_len))) { + return true; + } // Wildcard match // https://bugs.launchpad.net/ubuntu/+source/firefox-3.0/+bug/376484 @@ -13357,9 +13361,21 @@ inline bool SSLClient::check_host_name(const char *pattern, auto itr = pattern_components.begin(); for (const auto &h : host_components_) { auto &p = *itr; - if (p != h && p != "*") { - auto partial_match = (p.size() > 0 && p[p.size() - 1] == '*' && - !p.compare(0, p.size() - 1, h)); + if (!httplib::detail::case_ignore::equal(p, h) && p != "*") { + bool partial_match = false; + if (!p.empty() && p[p.size() - 1] == '*') { + const auto prefix_length = p.size() - 1; + if (prefix_length == 0) { + partial_match = true; + } else if (h.size() >= prefix_length) { + partial_match = + std::equal(p.begin(), p.begin() + prefix_length, h.begin(), + [](const char ca, const char cb) { + return httplib::detail::case_ignore::to_lower(ca) == + httplib::detail::case_ignore::to_lower(cb); + }); + } + } if (!partial_match) { return false; } } ++itr; diff --git a/test/test.cc b/test/test.cc index 5964096..6f9511e 100644 --- a/test/test.cc +++ b/test/test.cc @@ -8717,6 +8717,31 @@ TEST(SSLClientTest, WildcardHostNameMatch_Online) { ASSERT_EQ(StatusCode::OK_200, res->status); } +TEST(SSLClientTest, WildcardHostNameMatchCase_Online) { + SSLClient cli("wWw.YouTube.Com"); + + cli.set_ca_cert_path(CA_CERT_FILE); + cli.enable_server_certificate_verification(true); + cli.enable_server_hostname_verification(true); + cli.set_follow_location(true); + + auto res = cli.Get("/"); + ASSERT_TRUE(res); + ASSERT_EQ(StatusCode::OK_200, res->status); +} + +TEST(SSLClientTest, HostNameMatchCase_Online) { + SSLClient cli("gOoGlE.COm"); + + cli.enable_server_certificate_verification(true); + cli.enable_server_hostname_verification(true); + cli.set_follow_location(true); + + auto res = cli.Get("/"); + ASSERT_TRUE(res); + ASSERT_EQ(StatusCode::OK_200, res->status); +} + TEST(SSLClientTest, Issue2004_Online) { Client client("https://google.com"); client.set_follow_location(true);