aboutsummaryrefslogtreecommitdiff
path: root/zenhttp/httpserver.cpp
diff options
context:
space:
mode:
authorPer Larsson <[email protected]>2023-04-19 08:44:34 +0200
committerGitHub <[email protected]>2023-04-19 08:44:34 +0200
commit045702915c4b63d232b99d86a1ee0b16642098c8 (patch)
treeb8487d22d36b1c2a03352c45b386c209b9bb0b27 /zenhttp/httpserver.cpp
parentmake sure initialization of a new filecas dont remove the cas manifest file o... (diff)
downloadzen-045702915c4b63d232b99d86a1ee0b16642098c8.tar.xz
zen-045702915c4b63d232b99d86a1ee0b16642098c8.zip
Support for HTTP range header (#245)
* Support for HTTP range header. * Implement http range for HTTP sys. * Validate range parameters. --------- Co-authored-by: Stefan Boberg <[email protected]>
Diffstat (limited to 'zenhttp/httpserver.cpp')
-rw-r--r--zenhttp/httpserver.cpp64
1 files changed, 64 insertions, 0 deletions
diff --git a/zenhttp/httpserver.cpp b/zenhttp/httpserver.cpp
index 840b90931..952857f2c 100644
--- a/zenhttp/httpserver.cpp
+++ b/zenhttp/httpserver.cpp
@@ -185,6 +185,70 @@ ParseContentTypeInit(const std::string_view& ContentTypeString)
HttpContentType (*ParseContentType)(const std::string_view& ContentTypeString) = &ParseContentTypeInit;
+bool
+TryParseHttpRangeHeader(std::string_view RangeHeader, HttpRanges& Ranges)
+{
+ if (RangeHeader.empty())
+ {
+ return false;
+ }
+
+ const size_t Count = Ranges.size();
+
+ std::size_t UnitDelim = RangeHeader.find_first_of('=');
+ if (UnitDelim == std::string_view::npos)
+ {
+ return false;
+ }
+
+ // only bytes for now
+ std::string_view Unit = RangeHeader.substr(0, UnitDelim);
+ if (Unit != "bytes"sv)
+ {
+ return false;
+ }
+
+ std::string_view Tokens = RangeHeader.substr(UnitDelim);
+ while (!Tokens.empty())
+ {
+ // Skip =,
+ Tokens = Tokens.substr(1);
+
+ size_t Delim = Tokens.find_first_of(',');
+ if (Delim == std::string_view::npos)
+ {
+ Delim = Tokens.length();
+ }
+
+ std::string_view Token = Tokens.substr(0, Delim);
+ Tokens = Tokens.substr(Delim);
+
+ Delim = Token.find_first_of('-');
+ if (Delim == std::string_view::npos)
+ {
+ return false;
+ }
+
+ const auto Start = ParseInt<uint32_t>(Token.substr(0, Delim));
+ const auto End = ParseInt<uint32_t>(Token.substr(Delim + 1));
+
+ if (Start.has_value() && End.has_value() && End.value() > Start.value())
+ {
+ Ranges.push_back({.Start = Start.value(), .End = End.value()});
+ }
+ else if (Start)
+ {
+ Ranges.push_back({.Start = Start.value()});
+ }
+ else if (End)
+ {
+ Ranges.push_back({.End = End.value()});
+ }
+ }
+
+ return Count != Ranges.size();
+}
+
//////////////////////////////////////////////////////////////////////////
const std::string_view