mirror of
https://github.com/NixOS/nix.git
synced 2025-11-09 03:56:01 +01:00
feat(libstore/s3-binary-cache-store): implement createMultipartUpload()
POST to key with `?uploads` query parameter, optionally set `Content-Encoding` header, parse `uploadId` from XML response using regex
This commit is contained in:
parent
ac8b1efcf9
commit
4b6d07d642
1 changed files with 43 additions and 0 deletions
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <ranges>
|
#include <ranges>
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
@ -27,6 +28,15 @@ public:
|
||||||
private:
|
private:
|
||||||
ref<S3BinaryCacheStoreConfig> s3Config;
|
ref<S3BinaryCacheStoreConfig> s3Config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a multipart upload for large objects to S3.
|
||||||
|
*
|
||||||
|
* @see
|
||||||
|
* https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html#API_CreateMultipartUpload_RequestSyntax
|
||||||
|
*/
|
||||||
|
std::string createMultipartUpload(
|
||||||
|
std::string_view key, std::string_view mimeType, std::optional<std::string_view> contentEncoding);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abort a multipart upload
|
* Abort a multipart upload
|
||||||
*
|
*
|
||||||
|
|
@ -45,6 +55,39 @@ void S3BinaryCacheStore::upsertFile(
|
||||||
HttpBinaryCacheStore::upsertFile(path, istream, mimeType, sizeHint);
|
HttpBinaryCacheStore::upsertFile(path, istream, mimeType, sizeHint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string S3BinaryCacheStore::createMultipartUpload(
|
||||||
|
std::string_view key, std::string_view mimeType, std::optional<std::string_view> contentEncoding)
|
||||||
|
{
|
||||||
|
auto req = makeRequest(key);
|
||||||
|
|
||||||
|
// setupForS3() converts s3:// to https:// but strips query parameters
|
||||||
|
// So we call it first, then add our multipart parameters
|
||||||
|
req.setupForS3();
|
||||||
|
|
||||||
|
auto url = req.uri.parsed();
|
||||||
|
url.query["uploads"] = "";
|
||||||
|
req.uri = VerbatimURL(url);
|
||||||
|
|
||||||
|
req.method = HttpMethod::POST;
|
||||||
|
req.data = "";
|
||||||
|
req.mimeType = mimeType;
|
||||||
|
|
||||||
|
if (contentEncoding) {
|
||||||
|
req.headers.emplace_back("Content-Encoding", *contentEncoding);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto result = getFileTransfer()->enqueueFileTransfer(req).get();
|
||||||
|
|
||||||
|
std::regex uploadIdRegex("<UploadId>([^<]+)</UploadId>");
|
||||||
|
std::smatch match;
|
||||||
|
|
||||||
|
if (std::regex_search(result.data, match, uploadIdRegex)) {
|
||||||
|
return match[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
throw Error("S3 CreateMultipartUpload response missing <UploadId>");
|
||||||
|
}
|
||||||
|
|
||||||
void S3BinaryCacheStore::abortMultipartUpload(std::string_view key, std::string_view uploadId)
|
void S3BinaryCacheStore::abortMultipartUpload(std::string_view key, std::string_view uploadId)
|
||||||
{
|
{
|
||||||
auto req = makeRequest(key);
|
auto req = makeRequest(key);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue