diff --git a/httplib.h b/httplib.h index 1a722d5203..60d6b4c014 100644 --- a/httplib.h +++ b/httplib.h @@ -5156,7 +5156,18 @@ inline bool range_error(Request &req, Response &res) { last_pos = contant_len - 1; } - if (last_pos == -1) { last_pos = contant_len - 1; } + // NOTE: RFC-9110 '14.1.2. Byte Ranges': + // A client can limit the number of bytes requested without knowing the + // size of the selected representation. If the last-pos value is absent, + // or if the value is greater than or equal to the current length of the + // representation data, the byte range is interpreted as the remainder of + // the representation (i.e., the server replaces the value of last-pos + // with a value that is one less than the current length of the selected + // representation). + // https://www.rfc-editor.org/rfc/rfc9110.html#section-14.1.2-6 + if (last_pos == -1 || last_pos >= contant_len) { + last_pos = contant_len - 1; + } // Range must be within content length if (!(0 <= first_pos && first_pos <= last_pos && diff --git a/test/test.cc b/test/test.cc index da34ea9cb7..a82912adfe 100644 --- a/test/test.cc +++ b/test/test.cc @@ -3795,11 +3795,14 @@ TEST_F(ServerTest, GetRangeWithMaxLongLength) { auto res = cli_.Get( "/with-range", {{"Range", - "bytes=0-" + std::to_string(std::numeric_limits::max())}}); - EXPECT_EQ(StatusCode::RangeNotSatisfiable_416, res->status); - EXPECT_EQ("0", res->get_header_value("Content-Length")); - EXPECT_EQ(false, res->has_header("Content-Range")); - EXPECT_EQ(0U, res->body.size()); + "bytes=0-" + std::to_string(std::numeric_limits::max())}, + {"Accept-Encoding", ""}}); + ASSERT_TRUE(res); + EXPECT_EQ(StatusCode::PartialContent_206, res->status); + EXPECT_EQ("7", res->get_header_value("Content-Length")); + EXPECT_EQ(true, res->has_header("Content-Range")); + EXPECT_EQ("bytes 0-6/7", res->get_header_value("Content-Range")); + EXPECT_EQ(std::string("abcdefg"), res->body); } TEST_F(ServerTest, GetRangeWithZeroToInfinite) {