Просмотр исходного кода

Ignore ranges for unknown-length streams (#2465)

Florian Fischer 2 месяцев назад
Родитель
Сommit
c7ba963a17
2 измененных файлов с 35 добавлено и 0 удалено
  1. 8 0
      httplib.h
  2. 27 0
      test/test.cc

+ 8 - 0
httplib.h

@@ -8443,6 +8443,14 @@ inline void coalesce_ranges(Ranges &ranges, size_t content_length) {
 
 
 inline bool range_error(Request &req, Response &res) {
 inline bool range_error(Request &req, Response &res) {
   if (!req.ranges.empty() && 200 <= res.status && res.status < 300) {
   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<ssize_t>(
     ssize_t content_len = static_cast<ssize_t>(
         res.content_length_ ? res.content_length_ : res.body.size());
         res.content_length_ ? res.content_length_ : res.body.size());
 
 

+ 27 - 0
test/test.cc

@@ -3718,6 +3718,23 @@ protected:
                      return true;
                      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",
         .Get("/streamed-with-range",
              [&](const Request &req, Response &res) {
              [&](const Request &req, Response &res) {
                auto data = new std::string("abcdefg");
                auto data = new std::string("abcdefg");
@@ -5197,6 +5214,16 @@ TEST_F(ServerTest, GetStreamed) {
   EXPECT_EQ(std::string("aaabbb"), res->body);
   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) {
 TEST_F(ServerTest, GetStreamedWithRange1) {
   auto res = cli_.Get("/streamed-with-range", {{make_range_header({{3, 5}})}});
   auto res = cli_.Get("/streamed-with-range", {{make_range_header({{3, 5}})}});
   ASSERT_TRUE(res);
   ASSERT_TRUE(res);