mirror of https://github.com/kiwix/libkiwix.git
Final clean-up of byte_range.{h,cpp}
This commit is contained in:
parent
c2ebdefe8d
commit
16bd79fa1b
|
@ -22,6 +22,8 @@
|
||||||
|
|
||||||
#include "tools/stringTools.h"
|
#include "tools/stringTools.h"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
namespace kiwix {
|
namespace kiwix {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -34,7 +36,7 @@ ByteRange parseByteRange(const std::string& rangeStr)
|
||||||
if (iss >> start) {
|
if (iss >> start) {
|
||||||
if ( start < 0 ) {
|
if ( start < 0 ) {
|
||||||
if ( iss.eof() )
|
if ( iss.eof() )
|
||||||
return ByteRange(ByteRange::PARSED, start, end);
|
return ByteRange(-start);
|
||||||
} else {
|
} else {
|
||||||
char c;
|
char c;
|
||||||
if (iss >> c && c=='-') {
|
if (iss >> c && c=='-') {
|
||||||
|
@ -60,7 +62,37 @@ ByteRange::ByteRange(Kind kind, int64_t first, int64_t last)
|
||||||
: kind_(kind)
|
: kind_(kind)
|
||||||
, first_(first)
|
, first_(first)
|
||||||
, last_(last)
|
, last_(last)
|
||||||
{}
|
{
|
||||||
|
assert(kind != NONE);
|
||||||
|
assert(first >= 0);
|
||||||
|
assert(last >= first);
|
||||||
|
}
|
||||||
|
|
||||||
|
ByteRange::ByteRange(int64_t suffix_length)
|
||||||
|
: kind_(PARSED)
|
||||||
|
, first_(-suffix_length)
|
||||||
|
, last_(INT64_MAX)
|
||||||
|
{
|
||||||
|
assert(suffix_length > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t ByteRange::first() const
|
||||||
|
{
|
||||||
|
assert(kind_ > PARSED);
|
||||||
|
return first_;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t ByteRange::last() const
|
||||||
|
{
|
||||||
|
assert(kind_ > PARSED);
|
||||||
|
return last_;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t ByteRange::length() const
|
||||||
|
{
|
||||||
|
assert(kind_ > PARSED);
|
||||||
|
return last_ + 1 - first_;
|
||||||
|
}
|
||||||
|
|
||||||
ByteRange ByteRange::parse(const std::string& rangeStr)
|
ByteRange ByteRange::parse(const std::string& rangeStr)
|
||||||
{
|
{
|
||||||
|
@ -77,16 +109,16 @@ ByteRange ByteRange::resolve(int64_t contentSize) const
|
||||||
return ByteRange(RESOLVED_FULL_CONTENT, 0, contentSize-1);
|
return ByteRange(RESOLVED_FULL_CONTENT, 0, contentSize-1);
|
||||||
|
|
||||||
if ( kind() == INVALID )
|
if ( kind() == INVALID )
|
||||||
return ByteRange(INVALID, 0, contentSize-1);
|
return ByteRange(RESOLVED_UNSATISFIABLE, 0, contentSize-1);
|
||||||
|
|
||||||
const int64_t resolved_first = first() < 0
|
const int64_t resolved_first = first_ < 0
|
||||||
? std::max(int64_t(0), contentSize + first())
|
? std::max(int64_t(0), contentSize + first_)
|
||||||
: first();
|
: first_;
|
||||||
|
|
||||||
const int64_t resolved_last = std::min(contentSize-1, last());
|
const int64_t resolved_last = std::min(contentSize-1, last_);
|
||||||
|
|
||||||
if ( resolved_first > resolved_last )
|
if ( resolved_first > resolved_last )
|
||||||
return ByteRange(INVALID, 0, contentSize-1);
|
return ByteRange(RESOLVED_UNSATISFIABLE, 0, contentSize-1);
|
||||||
|
|
||||||
return ByteRange(RESOLVED_PARTIAL_CONTENT, resolved_first, resolved_last);
|
return ByteRange(RESOLVED_PARTIAL_CONTENT, resolved_first, resolved_last);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,33 +29,49 @@ namespace kiwix {
|
||||||
class ByteRange
|
class ByteRange
|
||||||
{
|
{
|
||||||
public: // types
|
public: // types
|
||||||
|
|
||||||
|
// ByteRange is parsed in a request, then it must be resolved (taking
|
||||||
|
// into account the actual size of the requested resource) before
|
||||||
|
// being applied in the response.
|
||||||
|
// The Kind enum represents possible states in such a lifecycle.
|
||||||
enum Kind {
|
enum Kind {
|
||||||
// No byte-range was present in the request
|
// The request is not a range request (no Range header)
|
||||||
NONE,
|
NONE,
|
||||||
|
|
||||||
// The value of the Range header is not a valid continuous range.
|
// The value of the Range header is not a valid continuous
|
||||||
// Note that a valid (according to RFC7233) sequence of byte ranges is
|
// range. Note that a valid (according to RFC7233) sequence of multiple
|
||||||
// considered invalid in this context.
|
// byte ranges is considered invalid in the current implementation
|
||||||
|
// (i.e. only single-range partial requests are supported).
|
||||||
INVALID,
|
INVALID,
|
||||||
|
|
||||||
// This byte-range has been parsed from request
|
// This byte-range has been successfully parsed from the request
|
||||||
PARSED,
|
PARSED,
|
||||||
|
|
||||||
// This is a response to a regular request
|
// This is a response to a regular (non-range) request
|
||||||
RESOLVED_FULL_CONTENT,
|
RESOLVED_FULL_CONTENT,
|
||||||
|
|
||||||
// This is a response to a range request
|
// The range request is valid but unsatisfiable
|
||||||
RESOLVED_PARTIAL_CONTENT
|
RESOLVED_UNSATISFIABLE,
|
||||||
|
|
||||||
|
// This is a response to a (satisfiable) range request
|
||||||
|
RESOLVED_PARTIAL_CONTENT,
|
||||||
};
|
};
|
||||||
|
|
||||||
public: // functions
|
public: // functions
|
||||||
|
// Constructs a ByteRange object of NONE kind
|
||||||
ByteRange();
|
ByteRange();
|
||||||
|
|
||||||
|
// Constructs a ByteRange object of the given kind (except NONE)
|
||||||
ByteRange(Kind kind, int64_t first, int64_t last);
|
ByteRange(Kind kind, int64_t first, int64_t last);
|
||||||
|
|
||||||
|
// Constructs a ByteRange object of PARSED kind corresponding to a
|
||||||
|
// range request of the form "Range: bytes=-suffix_length"
|
||||||
|
explicit ByteRange(int64_t suffix_length);
|
||||||
|
|
||||||
Kind kind() const { return kind_; }
|
Kind kind() const { return kind_; }
|
||||||
int64_t first() const { return first_; }
|
int64_t first() const;
|
||||||
int64_t last() const { return last_; }
|
int64_t last() const;
|
||||||
int64_t length() const { return last_ + 1 - first_; }
|
int64_t length() const;
|
||||||
|
|
||||||
static ByteRange parse(const std::string& rangeStr);
|
static ByteRange parse(const std::string& rangeStr);
|
||||||
ByteRange resolve(int64_t contentSize) const;
|
ByteRange resolve(int64_t contentSize) const;
|
||||||
|
|
|
@ -342,7 +342,7 @@ void Response::set_entry(const Entry& entry, const RequestContext& request) {
|
||||||
|
|
||||||
set_content(content);
|
set_content(content);
|
||||||
set_compress(true);
|
set_compress(true);
|
||||||
} else if ( m_byteRange.kind() == ByteRange::INVALID ) {
|
} else if ( m_byteRange.kind() == ByteRange::RESOLVED_UNSATISFIABLE ) {
|
||||||
set_code(416);
|
set_code(416);
|
||||||
set_content("");
|
set_content("");
|
||||||
m_mode = ResponseMode::ERROR_RESPONSE;
|
m_mode = ResponseMode::ERROR_RESPONSE;
|
||||||
|
|
Loading…
Reference in New Issue