aboutsummaryrefslogtreecommitdiff
path: root/zenserver/objectstore/objectstore.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 /zenserver/objectstore/objectstore.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 'zenserver/objectstore/objectstore.cpp')
-rw-r--r--zenserver/objectstore/objectstore.cpp53
1 files changed, 45 insertions, 8 deletions
diff --git a/zenserver/objectstore/objectstore.cpp b/zenserver/objectstore/objectstore.cpp
index 950505bcb..e5739418e 100644
--- a/zenserver/objectstore/objectstore.cpp
+++ b/zenserver/objectstore/objectstore.cpp
@@ -8,6 +8,7 @@
#include <zencore/string.h>
#include "zencore/compactbinarybuilder.h"
#include "zenhttp/httpcommon.h"
+#include "zenhttp/httpserver.h"
#include <thread>
@@ -130,6 +131,13 @@ HttpObjectStoreService::GetBlob(zen::HttpRouterRequest& Request)
return Request.ServerRequest().WriteResponse(HttpResponseCode::NotFound);
}
+ zen::HttpRanges Ranges;
+ if (Request.ServerRequest().TryGetRanges(Ranges); Ranges.size() > 1)
+ {
+ // Only a single range is supported
+ return Request.ServerRequest().WriteResponse(HttpResponseCode::BadRequest);
+ }
+
FileContents File = ReadFile(FilePath);
if (File.ErrorCode)
{
@@ -144,16 +152,45 @@ HttpObjectStoreService::GetBlob(zen::HttpRouterRequest& Request)
}
const IoBuffer& FileBuf = File.Data[0];
- const uint64_t Total = TotalBytesServed.fetch_add(FileBuf.Size()) + FileBuf.Size();
- ZEN_LOG_DEBUG(LogObj,
- "GET - '{}/{}' ({}) [OK] (Total: {})",
- BucketName,
- RelativeBucketPath,
- NiceBytes(FileBuf.Size()),
- NiceBytes(Total));
+ if (Ranges.empty())
+ {
+ const uint64_t TotalServed = TotalBytesServed.fetch_add(FileBuf.Size()) + FileBuf.Size();
- Request.ServerRequest().WriteResponse(HttpResponseCode::OK, HttpContentType::kUnknownContentType, FileBuf);
+ ZEN_LOG_DEBUG(LogObj,
+ "GET - '{}/{}' ({}) [OK] (Served: {})",
+ BucketName,
+ RelativeBucketPath,
+ NiceBytes(FileBuf.Size()),
+ NiceBytes(TotalServed));
+
+ Request.ServerRequest().WriteResponse(HttpResponseCode::OK, HttpContentType::kBinary, FileBuf);
+ }
+ else
+ {
+ const auto Range = Ranges[0];
+ const uint64_t RangeSize = Range.End - Range.Start;
+ const uint64_t TotalServed = TotalBytesServed.fetch_add(RangeSize) + RangeSize;
+
+ ZEN_LOG_DEBUG(LogObj,
+ "GET - '{}/{}' (Range: {}-{}) ({}/{}) [OK] (Served: {})",
+ BucketName,
+ RelativeBucketPath,
+ Range.Start,
+ Range.End,
+ NiceBytes(RangeSize),
+ NiceBytes(FileBuf.Size()),
+ NiceBytes(TotalServed));
+
+ MemoryView RangeView = FileBuf.GetView().Mid(Range.Start, RangeSize);
+ if (RangeView.GetSize() != RangeSize)
+ {
+ return Request.ServerRequest().WriteResponse(HttpResponseCode::BadRequest);
+ }
+
+ IoBuffer RangeBuf = IoBuffer(IoBuffer::Wrap, RangeView.GetData(), RangeView.GetSize());
+ Request.ServerRequest().WriteResponse(HttpResponseCode::PartialContent, HttpContentType::kBinary, RangeBuf);
+ }
}
void