Browse Source

Support content-range from non-compliant server

See GH-509
Tatsuhiro Tsujikawa 9 years ago
parent
commit
8512fe992e
2 changed files with 23 additions and 5 deletions
  1. 12 5
      src/HttpHeader.cc
  2. 11 0
      test/HttpHeaderTest.cc

+ 12 - 5
src/HttpHeader.cc

@@ -113,13 +113,20 @@ Range HttpHeader::getRange() const
       }
     }
   }
-  // we expect that rangeStr looks like 'bytes 100-199/100'
-  // but some server returns '100-199/100', omitting bytes-unit specifier
-  // 'bytes'.
+  // we expect that rangeStr looks like 'bytes 100-199/200' but some
+  // server returns '100-199/200', omitting bytes-unit specifier
+  // 'bytes'.  Moreover, some server may return like
+  // 'bytes=100-199/200'.
   auto byteRangeSpec = std::find(rangeStr.begin(), rangeStr.end(), ' ');
   if(byteRangeSpec == rangeStr.end()) {
-    // we assume bytes-unit specifier omitted.
-    byteRangeSpec = rangeStr.begin();
+    // check for 'bytes=100-199/200' case
+    byteRangeSpec = std::find(rangeStr.begin(), rangeStr.end(), '=');
+    if (byteRangeSpec == rangeStr.end()) {
+      // we assume bytes-unit specifier omitted.
+      byteRangeSpec = rangeStr.begin();
+    } else {
+      ++byteRangeSpec;
+    }
   } else {
     while(byteRangeSpec != rangeStr.end() &&
           (*byteRangeSpec == ' ' || *byteRangeSpec == '\t')) {

+ 11 - 0
test/HttpHeaderTest.cc

@@ -101,6 +101,17 @@ void HttpHeaderTest::testGetRange()
     CPPUNIT_ASSERT_EQUAL((int64_t)0, range.endByte);
     CPPUNIT_ASSERT_EQUAL((int64_t)0, range.entityLength);
   }
+  {
+    // Support for non-compliant server
+    HttpHeader httpHeader;
+    httpHeader.put(HttpHeader::CONTENT_RANGE, "bytes=0-1023/1024");
+
+    Range range = httpHeader.getRange();
+
+    CPPUNIT_ASSERT_EQUAL((int64_t)0, range.startByte);
+    CPPUNIT_ASSERT_EQUAL((int64_t)1023, range.endByte);
+    CPPUNIT_ASSERT_EQUAL((int64_t)1024, range.entityLength);
+  }
   {
     HttpHeader httpHeader;
     httpHeader.put(HttpHeader::CONTENT_RANGE, "bytes 0-/3");