From c7ba963a17ee4139f3d8d8a31c727da494d2ac65 Mon Sep 17 00:00:00 2001 From: Florian Fischer <60611027+florianfischerx@users.noreply.github.com> Date: Fri, 5 Jun 2026 02:15:21 +0200 Subject: [PATCH] Ignore ranges for unknown-length streams (#2465) --- httplib.h | 8 ++++++++ test/test.cc | 27 +++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/httplib.h b/httplib.h index cc54ff85..667520a2 100644 --- a/httplib.h +++ b/httplib.h @@ -8443,6 +8443,14 @@ inline void coalesce_ranges(Ranges &ranges, size_t content_length) { inline bool range_error(Request &req, Response &res) { if (!req.ranges.empty() && 200 <= res.status && res.status < 300) { + if (res.body.empty() && res.content_provider_ && res.content_length_ == 0) { + req.ranges.clear(); + if (res.status == StatusCode::PartialContent_206) { + res.status = StatusCode::OK_200; + } + return false; + } + ssize_t content_len = static_cast( res.content_length_ ? res.content_length_ : res.body.size()); diff --git a/test/test.cc b/test/test.cc index 03ac2546..8e2eb01e 100644 --- a/test/test.cc +++ b/test/test.cc @@ -3718,6 +3718,23 @@ protected: return true; }); }) + .Get("/streamed-without-length", + [&](const Request & /*req*/, Response &res) { + auto data = new std::string("abcdefg"); + res.set_content_provider( + "text/plain", + [data](size_t offset, DataSink &sink) { + if (offset < data->size()) { + sink.os << data->substr(offset); + } + sink.done(); + return true; + }, + [data](bool success) { + EXPECT_TRUE(success); + delete data; + }); + }) .Get("/streamed-with-range", [&](const Request &req, Response &res) { auto data = new std::string("abcdefg"); @@ -5197,6 +5214,16 @@ TEST_F(ServerTest, GetStreamed) { EXPECT_EQ(std::string("aaabbb"), res->body); } +TEST_F(ServerTest, GetStreamedWithoutLengthWithRange) { + auto res = + cli_.Get("/streamed-without-length", {make_range_header({{0, -1}})}); + ASSERT_TRUE(res); + EXPECT_EQ(StatusCode::OK_200, res->status); + EXPECT_EQ(false, res->has_header("Content-Length")); + EXPECT_EQ(false, res->has_header("Content-Range")); + EXPECT_EQ(std::string("abcdefg"), res->body); +} + TEST_F(ServerTest, GetStreamedWithRange1) { auto res = cli_.Get("/streamed-with-range", {{make_range_header({{3, 5}})}}); ASSERT_TRUE(res);