Преглед изворни кода

Serve the whole body for a suffix range longer than it (#2615)

RFC 9110 14.1.2: if the representation is shorter than the suffix-length,
the entire representation is used. range_error computed a negative first
byte position for bytes=-8 on a 7-byte body and answered 416. Clamp it
at 0, as #711 did before the range handling was reworked.

Co-authored-by: youdie006 <youdie006@users.noreply.github.com>
KBS пре 9 часа
родитељ
комит
213029685a
2 измењених фајлова са 17 додато и 2 уклоњено
  1. 3 1
      httplib.h
  2. 14 1
      test/test.cc

+ 3 - 1
httplib.h

@@ -9910,8 +9910,10 @@ inline bool range_error(Request &req, Response &res) {
         last_pos = content_len;
       }
 
+      // RFC 9110 14.1.2: a suffix-length longer than the representation
+      // selects the entire representation.
       if (first_pos == -1) {
-        first_pos = content_len - last_pos;
+        first_pos = (std::max)(static_cast<ssize_t>(0), content_len - last_pos);
         last_pos = content_len - 1;
       }
 

+ 14 - 1
test/test.cc

@@ -7242,8 +7242,21 @@ TEST_F(ServerTest, GetStreamedWithRangeSuffix1) {
 }
 
 TEST_F(ServerTest, GetStreamedWithRangeSuffix2) {
+  // RFC 9110 14.1.2: a suffix-length longer than the representation selects
+  // the entire representation.
+  for (auto range : {"bytes=-8", "bytes=-9999"}) {
+    auto res = cli_.Get("/streamed-with-range", Headers{{"Range", range}});
+    ASSERT_TRUE(res) << "Error: " << to_string(res.error());
+    EXPECT_EQ(StatusCode::PartialContent_206, res->status) << range;
+    EXPECT_EQ("7", res->get_header_value("Content-Length")) << range;
+    EXPECT_EQ("bytes 0-6/7", res->get_header_value("Content-Range")) << range;
+    EXPECT_EQ(std::string("abcdefg"), res->body) << range;
+  }
+}
+
+TEST_F(ServerTest, GetStreamedWithRangeSuffixZero) {
   auto res =
-      cli_.Get("/streamed-with-range?error", Headers{{"Range", "bytes=-9999"}});
+      cli_.Get("/streamed-with-range?error", Headers{{"Range", "bytes=-0"}});
   ASSERT_TRUE(res) << "Error: " << to_string(res.error());
   EXPECT_EQ(StatusCode::RangeNotSatisfiable_416, res->status);
   EXPECT_EQ("0", res->get_header_value("Content-Length"));