1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-08 19:46:02 +01:00

feat(libstore/s3-binary-cache-store): implement uploadPart()

Implement `uploadPart()` for uploading individual parts in S3 multipart
uploads:

- Constructs URL with `?partNumber=N&uploadId=ID` query parameters
- Uploads chunk data with `application/octet-stream` mime type
- Extracts and returns `ETag` from response
This commit is contained in:
Bernardo Meurer Costa 2025-10-22 08:02:25 +00:00
parent 4b6d07d642
commit c592090fff
No known key found for this signature in database

View file

@ -37,6 +37,15 @@ private:
std::string createMultipartUpload(
std::string_view key, std::string_view mimeType, std::optional<std::string_view> contentEncoding);
/**
* Uploads a single part of a multipart upload
*
* @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html#API_UploadPart_RequestSyntax
*
* @returns the [ETag](https://en.wikipedia.org/wiki/HTTP_ETag)
*/
std::string uploadPart(std::string_view key, std::string_view uploadId, uint64_t partNumber, std::string data);
/**
* Abort a multipart upload
*
@ -88,6 +97,28 @@ std::string S3BinaryCacheStore::createMultipartUpload(
throw Error("S3 CreateMultipartUpload response missing <UploadId>");
}
std::string
S3BinaryCacheStore::uploadPart(std::string_view key, std::string_view uploadId, uint64_t partNumber, std::string data)
{
auto req = makeRequest(key);
req.setupForS3();
auto url = req.uri.parsed();
url.query["partNumber"] = std::to_string(partNumber);
url.query["uploadId"] = uploadId;
req.uri = VerbatimURL(url);
req.data = std::move(data);
req.mimeType = "application/octet-stream";
auto result = getFileTransfer()->enqueueFileTransfer(req).get();
if (result.etag.empty()) {
throw Error("S3 UploadPart response missing ETag for part %d", partNumber);
}
return std::move(result.etag);
}
void S3BinaryCacheStore::abortMultipartUpload(std::string_view key, std::string_view uploadId)
{
auto req = makeRequest(key);