1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
|
/*
* Copyright (C) 2015-2018 Team Kodi
* This file is part of Kodi - https://kodi.tv
*
* SPDX-License-Identifier: GPL-2.0-or-later
* See LICENSES/README.md for more information.
*/
#pragma once
#include <stdint.h>
#include <string>
#include <vector>
class CHttpRange
{
public:
CHttpRange() = default;
CHttpRange(uint64_t firstPosition, uint64_t lastPosition);
virtual ~CHttpRange() = default;
bool operator<(const CHttpRange &other) const;
bool operator==(const CHttpRange &other) const;
bool operator!=(const CHttpRange &other) const;
virtual uint64_t GetFirstPosition() const { return m_first; }
virtual void SetFirstPosition(uint64_t firstPosition) { m_first = firstPosition; }
virtual uint64_t GetLastPosition() const { return m_last; }
virtual void SetLastPosition(uint64_t lastPosition) { m_last = lastPosition; }
virtual uint64_t GetLength() const;
virtual void SetLength(uint64_t length);
virtual bool IsValid() const;
protected:
uint64_t m_first = 1;
uint64_t m_last = 0;
};
typedef std::vector<CHttpRange> HttpRanges;
class CHttpResponseRange : public CHttpRange
{
public:
CHttpResponseRange();
CHttpResponseRange(uint64_t firstPosition, uint64_t lastPosition);
CHttpResponseRange(const void* data, uint64_t firstPosition, uint64_t lastPosition);
CHttpResponseRange(const void* data, uint64_t length);
~CHttpResponseRange() override = default;
bool operator==(const CHttpResponseRange &other) const;
bool operator!=(const CHttpResponseRange &other) const;
const void* GetData() const { return m_data; }
void SetData(const void* data) { m_data = data; }
void SetData(const void* data, uint64_t length);
void SetData(const void* data, uint64_t firstPosition, uint64_t lastPosition);
bool IsValid() const override;
protected:
const void* m_data;
};
typedef std::vector<CHttpResponseRange> HttpResponseRanges;
class CHttpRanges final
{
public:
CHttpRanges();
explicit CHttpRanges(const HttpRanges& httpRanges);
const HttpRanges& Get() const { return m_ranges; }
bool Get(size_t index, CHttpRange& range) const;
bool GetFirst(CHttpRange& range) const;
bool GetLast(CHttpRange& range) const;
size_t Size() const { return m_ranges.size(); }
bool IsEmpty() const { return m_ranges.empty(); }
bool GetFirstPosition(uint64_t& position) const;
bool GetLastPosition(uint64_t& position) const;
uint64_t GetLength() const;
bool GetTotalRange(CHttpRange& range) const;
void Add(const CHttpRange& range);
void Remove(size_t index);
void Clear();
HttpRanges::const_iterator Begin() const { return m_ranges.begin(); }
HttpRanges::const_iterator End() const { return m_ranges.end(); }
bool Parse(const std::string& header);
bool Parse(const std::string& header, uint64_t totalLength);
protected:
void SortAndCleanup();
HttpRanges m_ranges;
};
class HttpRangeUtils
{
public:
/*!
* \brief Generates a valid Content-Range HTTP header value for the given HTTP
* range definition.
*
* \param range HTTP range definition used to generate the Content-Range HTTP header
* \return Content-Range HTTP header value
*/
static std::string GenerateContentRangeHeaderValue(const CHttpRange* range);
/*!
* \brief Generates a valid Content-Range HTTP header value for the given HTTP
* range properties.
*
* \param start Start position of the HTTP range
* \param end Last/End position of the HTTP range
* \param total Total length of original content (not just the range)
* \return Content-Range HTTP header value
*/
static std::string GenerateContentRangeHeaderValue(uint64_t start, uint64_t end, uint64_t total);
#ifdef HAS_WEB_SERVER
/*!
* \brief Generates a multipart boundary that can be used in ranged HTTP
* responses.
*
* \return Multipart boundary that can be used in ranged HTTP responses
*/
static std::string GenerateMultipartBoundary();
/*!
* \brief Generates the multipart/byteranges Content-Type HTTP header value
* containing the given multipart boundary for a ranged HTTP response.
*
* \param multipartBoundary Multipart boundary to be used in the ranged HTTP response
* \return multipart/byteranges Content-Type HTTP header value
*/
static std::string GenerateMultipartBoundaryContentType(const std::string& multipartBoundary);
/*!
* \brief Generates a multipart boundary including the Content-Type HTTP
* header value with the (actual) given content type of the original
* content.
*
* \param multipartBoundary Multipart boundary to be used in the ranged HTTP response
* \param contentType (Actual) Content type of the original content
* \return Multipart boundary (including the Content-Type HTTP header) value that can be used in ranged HTTP responses
*/
static std::string GenerateMultipartBoundaryWithHeader(const std::string& multipartBoundary, const std::string& contentType);
/*!
* \brief Generates a multipart boundary including the Content-Type HTTP
* header value with the (actual) given content type of the original
* content and the Content-Range HTTP header value for the given range.
*
* \param multipartBoundary Multipart boundary to be used in the ranged HTTP response
* \param contentType (Actual) Content type of the original content
* \param range HTTP range definition used to generate the Content-Range HTTP header
* \return Multipart boundary (including the Content-Type and Content-Range HTTP headers) value that can be used in ranged HTTP responses
*/
static std::string GenerateMultipartBoundaryWithHeader(const std::string& multipartBoundary, const std::string& contentType, const CHttpRange* range);
/*!
* \brief Generates a multipart boundary including the Content-Type HTTP
* header value with the (actual) given content type of the original
* content and the Content-Range HTTP header value for the given range.
*
* \param multipartBoundaryWithContentType Multipart boundary (already including the Content-Type HTTP header value) to be used in the ranged HTTP response
* \param range HTTP range definition used to generate the Content-Range HTTP header
* \return Multipart boundary (including the Content-Type and Content-Range HTTP headers) value that can be used in ranged HTTP responses
*/
static std::string GenerateMultipartBoundaryWithHeader(const std::string& multipartBoundaryWithContentType, const CHttpRange* range);
/*!
* \brief Generates a multipart boundary end that can be used in ranged HTTP
* responses.
*
* \param multipartBoundary Multipart boundary to be used in the ranged HTTP response
* \return Multipart boundary end that can be used in a ranged HTTP response
*/
static std::string GenerateMultipartBoundaryEnd(const std::string& multipartBoundary);
#endif // HAS_WEB_SERVER
};
|