Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions src/libstore/s3-binary-cache-store.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <cassert>
#include <ranges>
#include <regex>
#include <span>

namespace nix {

Expand Down Expand Up @@ -46,6 +47,19 @@ class S3BinaryCacheStore : public virtual HttpBinaryCacheStore
*/
std::string uploadPart(std::string_view key, std::string_view uploadId, uint64_t partNumber, std::string data);

struct UploadedPart
{
uint64_t partNumber;
std::string etag;
};

/**
* Completes a multipart upload by combining all uploaded parts.
* @see
* https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html#API_CompleteMultipartUpload_RequestSyntax
*/
void completeMultipartUpload(std::string_view key, std::string_view uploadId, std::span<const UploadedPart> parts);

/**
* Abort a multipart upload
*
Expand Down Expand Up @@ -132,6 +146,34 @@ void S3BinaryCacheStore::abortMultipartUpload(std::string_view key, std::string_
getFileTransfer()->enqueueFileTransfer(req).get();
}

void S3BinaryCacheStore::completeMultipartUpload(
std::string_view key, std::string_view uploadId, std::span<const UploadedPart> parts)
{
auto req = makeRequest(key);
req.setupForS3();

auto url = req.uri.parsed();
url.query["uploadId"] = uploadId;
req.uri = VerbatimURL(url);
req.method = HttpMethod::POST;

std::string xml = "<CompleteMultipartUpload>";
for (const auto & part : parts) {
xml += "<Part>";
xml += "<PartNumber>" + std::to_string(part.partNumber) + "</PartNumber>";
xml += "<ETag>" + part.etag + "</ETag>";
xml += "</Part>";
}
xml += "</CompleteMultipartUpload>";

debug("S3 CompleteMultipartUpload XML (%d parts): %s", parts.size(), xml);

req.data = xml;
req.mimeType = "text/xml";

getFileTransfer()->enqueueFileTransfer(req).get();
}

StringSet S3BinaryCacheStoreConfig::uriSchemes()
{
return {"s3"};
Expand Down
Loading