From 33d84a12b63b35ab4e90a9c2bfebc821349505ee Mon Sep 17 00:00:00 2001 From: yhirose Date: Mon, 12 Oct 2026 19:37:07 -0400 Subject: [PATCH] Compare the Range unit case-insensitively MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RFC 9110 ยง14.1 makes range unit names case-insensitive, but parse_range_header() matched "bytes=" exactly, so a request with Range: Bytes=1-3 was answered with 416. --- httplib.h | 2 +- test/test.cc | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/httplib.h b/httplib.h index b261b80a..526cb3fc 100644 --- a/httplib.h +++ b/httplib.h @@ -9189,7 +9189,7 @@ inline bool parse_range_header(const std::string &s, Ranges &ranges) try { return std::all_of(str.cbegin(), str.cend(), is_ascii_digit); }; - if (s.size() > 7 && s.compare(0, 6, "bytes=") == 0) { + if (s.size() > 7 && case_ignore::equal(s.substr(0, 6), "bytes=")) { const auto pos = static_cast(6); const auto len = static_cast(s.size() - 6); auto all_valid_ranges = true; diff --git a/test/test.cc b/test/test.cc index 0e1afb18..38385f74 100644 --- a/test/test.cc +++ b/test/test.cc @@ -2033,6 +2033,13 @@ TEST(ParseHeaderValueTest, Range) { EXPECT_EQ(0, ranges[0].first); EXPECT_EQ(-1, ranges[0].second); } + + // RFC 9110 14.1: range unit names are case-insensitive. + for (const auto &s : {"Bytes=1-10", "BYTES=1-10", "bYtEs=1-10"}) { + Ranges ranges; + EXPECT_TRUE(detail::parse_range_header(s, ranges)) << s; + EXPECT_EQ((Ranges{{1, 10}}), ranges) << s; + } } TEST(ParseAcceptEncoding1, AcceptEncoding) {