ByteRange::Kind

This commit is contained in:
Veloman Yunkan 2020-05-25 16:23:44 +04:00
parent d111a40ce8
commit 67294217a8
3 changed files with 36 additions and 8 deletions

View File

@ -25,15 +25,37 @@ namespace kiwix {
class ByteRange
{
public: // functions
ByteRange() : ByteRange(0, -1) {}
ByteRange(int64_t first, int64_t last) : first_(first), last_(last) {}
public: // types
enum Kind {
// No byte-range was present in the request
NONE,
// This byte-range has been parsed from request
PARSED,
// This is a response to a regular request
RESOLVED_FULL_CONTENT,
// This is a response to a range request
RESOLVED_PARTIAL_CONTENT
};
public: // functions
ByteRange() : kind_(NONE), first_(0), last_(-1) {}
ByteRange(Kind kind, int64_t first, int64_t last)
: kind_(kind)
, first_(first)
, last_(last)
{}
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_; }
private: // data
Kind kind_;
int64_t first_;
int64_t last_;
};

View File

@ -64,7 +64,7 @@ fullURL2LocalURL(const std::string& full_url, const std::string& rootLocation)
ByteRange parse_byte_range(std::string range)
{
ByteRange byteRange{0, -1};
ByteRange byteRange;
const std::string byteUnitSpec("bytes=");
if ( kiwix::startsWith(range, byteUnitSpec) ) {
range.erase(0, byteUnitSpec.size());
@ -81,7 +81,7 @@ ByteRange parse_byte_range(std::string range)
end = -1;
}
if (iss.eof()) {
byteRange = ByteRange(start, end);
byteRange = ByteRange(ByteRange::PARSED, start, end);
}
}
}
@ -197,7 +197,7 @@ bool RequestContext::is_valid_url() const {
}
bool RequestContext::has_range() const {
return byteRange_.first() <= byteRange_.last();
return byteRange_.kind() == ByteRange::PARSED;
}
ByteRange RequestContext::get_range() const {

View File

@ -42,10 +42,14 @@ bool is_compressible_mime_type(const std::string& mimeType)
ByteRange resolve_byte_range(const kiwix::Entry& entry, ByteRange range)
{
const int64_t entrySize = entry.getSize();
if ( range.kind() == ByteRange::NONE )
return ByteRange(ByteRange::RESOLVED_FULL_CONTENT, 0, entrySize-1);
const int64_t resolved_last = range.last() < 0
? entrySize - 1
: std::min(entrySize-1, range.last());
return ByteRange(range.first(), resolved_last);
return ByteRange(ByteRange::RESOLVED_PARTIAL_CONTENT, range.first(), resolved_last);
}
} // unnamed namespace
@ -288,7 +292,7 @@ int Response::send(const RequestContext& request, MHD_Connection* connection)
if ( ! etag.empty() )
MHD_add_response_header(response, MHD_HTTP_HEADER_ETAG, etag.c_str());
if (m_returnCode == MHD_HTTP_OK && request.has_range())
if (m_returnCode == MHD_HTTP_OK && m_byteRange.kind() == ByteRange::RESOLVED_PARTIAL_CONTENT)
m_returnCode = MHD_HTTP_PARTIAL_CONTENT;
if (m_verbose)
@ -322,6 +326,8 @@ void Response::set_entry(const Entry& entry, const RequestContext& request) {
set_mimeType(mimeType);
set_cacheable();
// XXX: Which of the Accept-Encoding and Range headers has precedence if both
// XXX: are present? Can partial content be compressed?
if ( is_compressible_mime_type(mimeType) ) {
zim::Blob raw_content = entry.getBlob();
const std::string content = string(raw_content.data(), raw_content.size());