diff --git a/httplib.h b/httplib.h index 3118c568..b23bfa0a 100644 --- a/httplib.h +++ b/httplib.h @@ -15202,7 +15202,9 @@ Server::process_request(Stream &strm, const std::string &remote_addr, } } - if (req.has_header("Range")) { + // RFC 9110 14.2: range handling is defined only for GET (and so for HEAD) + if ((req.method == "GET" || req.method == "HEAD") && + req.has_header("Range")) { const auto &range_header_value = req.get_header_value("Range"); if (!detail::parse_range_header(range_header_value, req.ranges)) { connection_closed = true; diff --git a/test/test.cc b/test/test.cc index 755e05cb..32c2089c 100644 --- a/test/test.cc +++ b/test/test.cc @@ -2742,6 +2742,31 @@ TEST(RangeTest, FromHTTPBin_Online) { } } +TEST(RangeTest, IgnoredForPost) { + Server svr; + svr.Post("/", [](const Request &, Response &res) { + res.set_content("abcdefg", "text/plain"); + }); + + auto port = svr.bind_to_any_port(HOST); + ASSERT_GT(port, 0); + thread t = thread([&] { svr.listen_after_bind(); }); + auto se = detail::scope_exit([&] { + svr.stop(); + t.join(); + ASSERT_FALSE(svr.is_running()); + }); + svr.wait_until_ready(); + + Client cli(HOST, port); + for (auto range : {"bytes=1-2", "bytes=x"}) { + auto res = cli.Post("/", Headers{{"Range", range}}); + ASSERT_TRUE(res) << range << ": " << to_string(res.error()); + EXPECT_EQ(StatusCode::OK_200, res->status) << range; + EXPECT_EQ("abcdefg", res->body) << range; + } +} + TEST(GetAddrInfoDanglingRefTest, LongTimeout) { auto host = "unresolvableaddress.local"; auto path = std::string{"/"};