aboutsummaryrefslogtreecommitdiff
path: root/src/zenserver/httpcidstore.cpp
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2023-05-02 13:23:42 +0200
committerGitHub <[email protected]>2023-05-02 13:23:42 +0200
commitfc53dd4bd6737f4e1c406f24cd66b4255f383e60 (patch)
tree56bf06028ddae6ed2ff445a78db6a781538949f4 /src/zenserver/httpcidstore.cpp
parentmove auth code from zenserver into zenhttp (#265) (diff)
downloadzen-fc53dd4bd6737f4e1c406f24cd66b4255f383e60.tar.xz
zen-fc53dd4bd6737f4e1c406f24cd66b4255f383e60.zip
move testing and observability code to zenhttp (#266)
Diffstat (limited to 'src/zenserver/httpcidstore.cpp')
-rw-r--r--src/zenserver/httpcidstore.cpp124
1 files changed, 124 insertions, 0 deletions
diff --git a/src/zenserver/httpcidstore.cpp b/src/zenserver/httpcidstore.cpp
new file mode 100644
index 000000000..233a45edb
--- /dev/null
+++ b/src/zenserver/httpcidstore.cpp
@@ -0,0 +1,124 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#include "httpcidstore.h"
+
+#include <zencore/compress.h>
+#include <zencore/fmtutils.h>
+#include <zencore/logging.h>
+#include <zenstore/cidstore.h>
+
+#include <gsl/gsl-lite.hpp>
+
+namespace zen {
+
+HttpCidService::HttpCidService(CidStore& Store) : m_CidStore(Store)
+{
+ m_Router.AddPattern("cid", "([0-9A-Fa-f]{40})");
+
+ m_Router.RegisterRoute(
+ "{cid}",
+ [this](HttpRouterRequest& Req) {
+ IoHash Hash = IoHash::FromHexString(Req.GetCapture(1));
+ ZEN_DEBUG("CID request for {}", Hash);
+
+ HttpServerRequest& ServerRequest = Req.ServerRequest();
+
+ switch (ServerRequest.RequestVerb())
+ {
+ case HttpVerb::kGet:
+ case HttpVerb::kHead:
+ {
+ if (IoBuffer Value = m_CidStore.FindChunkByCid(Hash))
+ {
+ return ServerRequest.WriteResponse(HttpResponseCode::OK, HttpContentType::kBinary, Value);
+ }
+
+ return ServerRequest.WriteResponse(HttpResponseCode::NotFound);
+ }
+ break;
+
+ case HttpVerb::kPut:
+ {
+ IoBuffer Payload = ServerRequest.ReadPayload();
+ IoHash RawHash;
+ uint64_t RawSize;
+ if (!CompressedBuffer::ValidateCompressedHeader(Payload, RawHash, RawSize))
+ {
+ return ServerRequest.WriteResponse(HttpResponseCode::UnsupportedMediaType);
+ }
+
+ // URI hash must match content hash
+ if (RawHash != Hash)
+ {
+ return ServerRequest.WriteResponse(HttpResponseCode::BadRequest);
+ }
+
+ m_CidStore.AddChunk(Payload, RawHash);
+
+ return ServerRequest.WriteResponse(HttpResponseCode::OK);
+ }
+ break;
+
+ default:
+ break;
+ }
+ },
+ HttpVerb::kGet | HttpVerb::kPut | HttpVerb::kHead);
+}
+
+const char*
+HttpCidService::BaseUri() const
+{
+ return "/cid/";
+}
+
+void
+HttpCidService::HandleRequest(zen::HttpServerRequest& Request)
+{
+ if (Request.RelativeUri().empty())
+ {
+ // Root URI request
+
+ switch (Request.RequestVerb())
+ {
+ case HttpVerb::kPut:
+ case HttpVerb::kPost:
+ {
+ IoBuffer Payload = Request.ReadPayload();
+ IoHash RawHash;
+ uint64_t RawSize;
+ if (!CompressedBuffer::ValidateCompressedHeader(Payload, RawHash, RawSize))
+ {
+ return Request.WriteResponse(HttpResponseCode::UnsupportedMediaType);
+ }
+
+ ZEN_DEBUG("CID POST request for {} ({} bytes)", RawHash, Payload.Size());
+
+ auto InsertResult = m_CidStore.AddChunk(Payload, RawHash);
+
+ if (InsertResult.New)
+ {
+ return Request.WriteResponse(HttpResponseCode::Created);
+ }
+ else
+ {
+ return Request.WriteResponse(HttpResponseCode::OK);
+ }
+ }
+ break;
+
+ case HttpVerb::kGet:
+ case HttpVerb::kHead:
+ break;
+
+ default:
+ break;
+ }
+ }
+ else
+ {
+ m_Router.HandleRequest(Request);
+ }
+}
+
+} // namespace zen