summaryrefslogtreecommitdiffstats
path: root/xbmc/utils/HttpRangeUtils.h
diff options
context:
space:
mode:
Diffstat (limited to 'xbmc/utils/HttpRangeUtils.h')
-rw-r--r--xbmc/utils/HttpRangeUtils.h187
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
+};