diff --git a/src/server/request_context.cpp b/src/server/request_context.cpp index caa985b5b..43259d8dc 100644 --- a/src/server/request_context.cpp +++ b/src/server/request_context.cpp @@ -26,6 +26,7 @@ #include #include #include +#include namespace kiwix { @@ -64,6 +65,8 @@ fullURL2LocalURL(const std::string& full_url, const std::string& rootLocation) ByteRange parse_byte_range(std::string range) { + const int64_t int64_max = std::numeric_limits::max(); + ByteRange byteRange; const std::string byteUnitSpec("bytes="); if ( kiwix::startsWith(range, byteUnitSpec) ) { @@ -73,15 +76,21 @@ ByteRange parse_byte_range(std::string range) std::istringstream iss(range); char c; - iss >> start >> c; - if (iss.good() && c=='-') { - iss >> end; - if (iss.fail()) { - // Something went wrong while extracting - end = -1; - } - if (iss.eof()) { - byteRange = ByteRange(ByteRange::PARSED, start, end); + iss >> start; + if ( start < 0 ) { + if ( iss.eof() ) + byteRange = ByteRange(ByteRange::PARSED, start, int64_max); + } else { + iss >> c; + if (iss.good() && c=='-') { + iss >> end; + if (iss.fail()) { + // Something went wrong while extracting + end = -1; + } + if (iss.eof()) { + byteRange = ByteRange(ByteRange::PARSED, start, end); + } } } } diff --git a/src/server/response.cpp b/src/server/response.cpp index 637559bb2..77d545a53 100644 --- a/src/server/response.cpp +++ b/src/server/response.cpp @@ -46,10 +46,15 @@ ByteRange resolve_byte_range(const kiwix::Entry& entry, ByteRange range) if ( range.kind() == ByteRange::NONE ) return ByteRange(ByteRange::RESOLVED_FULL_CONTENT, 0, entrySize-1); + const int64_t resolved_first = range.first() < 0 + ? std::max(int64_t(0), entrySize + range.first()) + : range.first(); + const int64_t resolved_last = range.last() < 0 ? entrySize - 1 : std::min(entrySize-1, range.last()); - return ByteRange(ByteRange::RESOLVED_PARTIAL_CONTENT, range.first(), resolved_last); + + return ByteRange(ByteRange::RESOLVED_PARTIAL_CONTENT, resolved_first, resolved_last); } } // unnamed namespace diff --git a/test/server.cpp b/test/server.cpp index d232f4542..6031b0e65 100644 --- a/test/server.cpp +++ b/test/server.cpp @@ -436,4 +436,18 @@ TEST_F(ServerTest, ValidSingleRangeByteRangeRequestsAreHandledProperly) EXPECT_EQ(334, p->body.size()); EXPECT_EQ(full->body.substr(123, 334), p->body); } + + { + const auto p = zfs1_->GET(url, { {"Range", "bytes=20000-"} } ); + EXPECT_EQ(206, p->status); + EXPECT_EQ(full->body.substr(20000), p->body); + EXPECT_EQ("bytes 20000-20076/20077", p->get_header_value("Content-Range")); + } + + { + const auto p = zfs1_->GET(url, { {"Range", "bytes=-100"} } ); + EXPECT_EQ(206, p->status); + EXPECT_EQ(full->body.substr(19977), p->body); + EXPECT_EQ("bytes 19977-20076/20077", p->get_header_value("Content-Range")); + } }