diff options
Diffstat (limited to 'xbmc/utils/HttpRangeUtils.h')
-rw-r--r-- | xbmc/utils/HttpRangeUtils.h | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/xbmc/utils/HttpRangeUtils.h b/xbmc/utils/HttpRangeUtils.h new file mode 100644 index 0000000..7e0b66d --- /dev/null +++ b/xbmc/utils/HttpRangeUtils.h @@ -0,0 +1,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 +}; |