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 <cassert>
|
||||
|
||||
namespace kiwix {
|
||||
|
||||
namespace {
|
||||
|
@ -34,7 +36,7 @@ ByteRange parseByteRange(const std::string& rangeStr)
|
|||
if (iss >> start) {
|
||||
if ( start < 0 ) {
|
||||
if ( iss.eof() )
|
||||
return ByteRange(ByteRange::PARSED, start, end);
|
||||
return ByteRange(-start);
|
||||
} else {
|
||||
char c;
|
||||
if (iss >> c && c=='-') {
|
||||
|
@ -60,7 +62,37 @@ ByteRange::ByteRange(Kind kind, int64_t first, int64_t last)
|
|||
: kind_(kind)
|
||||
, first_(first)
|
||||
, 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)
|
||||
{
|
||||
|
@ -77,16 +109,16 @@ ByteRange ByteRange::resolve(int64_t contentSize) const
|
|||
return ByteRange(RESOLVED_FULL_CONTENT, 0, contentSize-1);
|
||||
|
||||
if ( kind() == INVALID )
|
||||
return ByteRange(INVALID, 0, contentSize-1);
|
||||
return ByteRange(RESOLVED_UNSATISFIABLE, 0, contentSize-1);
|
||||
|
||||
const int64_t resolved_first = first() < 0
|
||||
? std::max(int64_t(0), contentSize + first())
|
||||
: first();
|
||||
const int64_t resolved_first = first_ < 0
|
||||
? std::max(int64_t(0), contentSize + 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 )
|
||||
return ByteRange(INVALID, 0, contentSize-1);
|
||||
return ByteRange(RESOLVED_UNSATISFIABLE, 0, contentSize-1);
|
||||
|
||||
return ByteRange(RESOLVED_PARTIAL_CONTENT, resolved_first, resolved_last);
|
||||
}
|
||||
|
|
|
@ -29,33 +29,49 @@ namespace kiwix {
|
|||
class ByteRange
|
||||
{
|
||||
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 {
|
||||
// No byte-range was present in the request
|
||||
// The request is not a range request (no Range header)
|
||||
NONE,
|
||||
|
||||
// The value of the Range header is not a valid continuous range.
|
||||
// Note that a valid (according to RFC7233) sequence of byte ranges is
|
||||
// considered invalid in this context.
|
||||
// The value of the Range header is not a valid continuous
|
||||
// range. Note that a valid (according to RFC7233) sequence of multiple
|
||||
// byte ranges is considered invalid in the current implementation
|
||||
// (i.e. only single-range partial requests are supported).
|
||||
INVALID,
|
||||
|
||||
// This byte-range has been parsed from request
|
||||
// This byte-range has been successfully parsed from the request
|
||||
PARSED,
|
||||
|
||||
// This is a response to a regular request
|
||||
// This is a response to a regular (non-range) request
|
||||
RESOLVED_FULL_CONTENT,
|
||||
|
||||
// This is a response to a range request
|
||||
RESOLVED_PARTIAL_CONTENT
|
||||
// The range request is valid but unsatisfiable
|
||||
RESOLVED_UNSATISFIABLE,
|
||||
|
||||
// This is a response to a (satisfiable) range request
|
||||
RESOLVED_PARTIAL_CONTENT,
|
||||
};
|
||||
|
||||
public: // functions
|
||||
// Constructs a ByteRange object of NONE kind
|
||||
ByteRange();
|
||||
|
||||
// Constructs a ByteRange object of the given kind (except NONE)
|
||||
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_; }
|
||||
int64_t first() const { return first_; }
|
||||
int64_t last() const { return last_; }
|
||||
int64_t length() const { return last_ + 1 - first_; }
|
||||
int64_t first() const;
|
||||
int64_t last() const;
|
||||
int64_t length() const;
|
||||
|
||||
static ByteRange parse(const std::string& rangeStr);
|
||||
ByteRange resolve(int64_t contentSize) const;
|
||||
|
|
|
@ -342,7 +342,7 @@ void Response::set_entry(const Entry& entry, const RequestContext& request) {
|
|||
|
||||
set_content(content);
|
||||
set_compress(true);
|
||||
} else if ( m_byteRange.kind() == ByteRange::INVALID ) {
|
||||
} else if ( m_byteRange.kind() == ByteRange::RESOLVED_UNSATISFIABLE ) {
|
||||
set_code(416);
|
||||
set_content("");
|
||||
m_mode = ResponseMode::ERROR_RESPONSE;
|
||||
|
|
Loading…
Reference in New Issue