Support for single-ended byte ranges

This commit is contained in:
Veloman Yunkan 2020-05-25 16:37:01 +04:00
parent 67294217a8
commit 52f207eaa6
3 changed files with 38 additions and 10 deletions

View File

@ -26,6 +26,7 @@
#include <sstream> #include <sstream>
#include <cstdio> #include <cstdio>
#include <atomic> #include <atomic>
#include <limits>
namespace kiwix { namespace kiwix {
@ -64,6 +65,8 @@ fullURL2LocalURL(const std::string& full_url, const std::string& rootLocation)
ByteRange parse_byte_range(std::string range) ByteRange parse_byte_range(std::string range)
{ {
const int64_t int64_max = std::numeric_limits<int64_t>::max();
ByteRange byteRange; ByteRange byteRange;
const std::string byteUnitSpec("bytes="); const std::string byteUnitSpec("bytes=");
if ( kiwix::startsWith(range, byteUnitSpec) ) { if ( kiwix::startsWith(range, byteUnitSpec) ) {
@ -73,7 +76,12 @@ ByteRange parse_byte_range(std::string range)
std::istringstream iss(range); std::istringstream iss(range);
char c; char c;
iss >> start >> c; iss >> start;
if ( start < 0 ) {
if ( iss.eof() )
byteRange = ByteRange(ByteRange::PARSED, start, int64_max);
} else {
iss >> c;
if (iss.good() && c=='-') { if (iss.good() && c=='-') {
iss >> end; iss >> end;
if (iss.fail()) { if (iss.fail()) {
@ -85,6 +93,7 @@ ByteRange parse_byte_range(std::string range)
} }
} }
} }
}
return byteRange; return byteRange;
} }

View File

@ -46,10 +46,15 @@ ByteRange resolve_byte_range(const kiwix::Entry& entry, ByteRange range)
if ( range.kind() == ByteRange::NONE ) if ( range.kind() == ByteRange::NONE )
return ByteRange(ByteRange::RESOLVED_FULL_CONTENT, 0, entrySize-1); 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 const int64_t resolved_last = range.last() < 0
? entrySize - 1 ? entrySize - 1
: std::min(entrySize-1, range.last()); : 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 } // unnamed namespace

View File

@ -436,4 +436,18 @@ TEST_F(ServerTest, ValidSingleRangeByteRangeRequestsAreHandledProperly)
EXPECT_EQ(334, p->body.size()); EXPECT_EQ(334, p->body.size());
EXPECT_EQ(full->body.substr(123, 334), p->body); 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"));
}
} }