Skip to content

Commit 3c2dcf4

Browse files
authored
Merge pull request #14477 from lovesegfault/http-upload-headers
refactor(libstore): pass headers into upload methods
2 parents 5a97c00 + a0d4714 commit 3c2dcf4

File tree

3 files changed

+26
-40
lines changed

3 files changed

+26
-40
lines changed

src/libstore/http-binary-cache-store.cc

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
#include "nix/store/nar-info-disk-cache.hh"
55
#include "nix/util/callback.hh"
66
#include "nix/store/store-registration.hh"
7-
#include "nix/util/compression.hh"
87

98
namespace nix {
109

@@ -139,13 +138,14 @@ void HttpBinaryCacheStore::upload(
139138
RestartableSource & source,
140139
uint64_t sizeHint,
141140
std::string_view mimeType,
142-
std::optional<std::string_view> contentEncoding)
141+
std::optional<Headers> headers)
143142
{
144143
auto req = makeRequest(path);
145144
req.method = HttpMethod::PUT;
146145

147-
if (contentEncoding) {
148-
req.headers.emplace_back("Content-Encoding", *contentEncoding);
146+
if (headers) {
147+
req.headers.reserve(req.headers.size() + headers->size());
148+
std::ranges::move(std::move(*headers), std::back_inserter(req.headers));
149149
}
150150

151151
req.data = {sizeHint, source};
@@ -154,18 +154,14 @@ void HttpBinaryCacheStore::upload(
154154
getFileTransfer()->upload(req);
155155
}
156156

157-
void HttpBinaryCacheStore::upload(std::string_view path, CompressedSource & source, std::string_view mimeType)
158-
{
159-
upload(path, static_cast<RestartableSource &>(source), source.size(), mimeType, source.getCompressionMethod());
160-
}
161-
162157
void HttpBinaryCacheStore::upsertFile(
163158
const std::string & path, RestartableSource & source, const std::string & mimeType, uint64_t sizeHint)
164159
{
165160
try {
166161
if (auto compressionMethod = getCompressionMethod(path)) {
167162
CompressedSource compressed(source, *compressionMethod);
168-
upload(path, compressed, mimeType);
163+
Headers headers = {{"Content-Encoding", *compressionMethod}};
164+
upload(path, compressed, compressed.size(), mimeType, std::move(headers));
169165
} else {
170166
upload(path, source, sizeHint, mimeType, std::nullopt);
171167
}

src/libstore/include/nix/store/http-binary-cache-store.hh

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -103,18 +103,7 @@ protected:
103103
RestartableSource & source,
104104
uint64_t sizeHint,
105105
std::string_view mimeType,
106-
std::optional<std::string_view> contentEncoding);
107-
108-
/**
109-
* Uploads data to the binary cache (CompressedSource overload).
110-
*
111-
* This overload infers both the size and compression method from the CompressedSource.
112-
*
113-
* @param path The path in the binary cache to upload to
114-
* @param source The compressed source (knows size and compression method)
115-
* @param mimeType The MIME type of the content
116-
*/
117-
void upload(std::string_view path, CompressedSource & source, std::string_view mimeType);
106+
std::optional<Headers> headers);
118107

119108
void getFile(const std::string & path, Sink & sink) override;
120109

src/libstore/s3-binary-cache-store.cc

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class S3BinaryCacheStore : public virtual HttpBinaryCacheStore
5050
RestartableSource & source,
5151
uint64_t sizeHint,
5252
std::string_view mimeType,
53-
std::optional<std::string_view> contentEncoding);
53+
std::optional<Headers> headers);
5454

5555
/**
5656
* Uploads a file to S3 using multipart upload.
@@ -67,7 +67,7 @@ class S3BinaryCacheStore : public virtual HttpBinaryCacheStore
6767
RestartableSource & source,
6868
uint64_t sizeHint,
6969
std::string_view mimeType,
70-
std::optional<std::string_view> contentEncoding);
70+
std::optional<Headers> headers);
7171

7272
/**
7373
* A Sink that manages a complete S3 multipart upload lifecycle.
@@ -89,7 +89,7 @@ class S3BinaryCacheStore : public virtual HttpBinaryCacheStore
8989
std::string_view path,
9090
uint64_t sizeHint,
9191
std::string_view mimeType,
92-
std::optional<std::string_view> contentEncoding);
92+
std::optional<Headers> headers);
9393

9494
void operator()(std::string_view data) override;
9595
void finish();
@@ -102,8 +102,7 @@ class S3BinaryCacheStore : public virtual HttpBinaryCacheStore
102102
* @see
103103
* https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html#API_CreateMultipartUpload_RequestSyntax
104104
*/
105-
std::string createMultipartUpload(
106-
std::string_view key, std::string_view mimeType, std::optional<std::string_view> contentEncoding);
105+
std::string createMultipartUpload(std::string_view key, std::string_view mimeType, std::optional<Headers> headers);
107106

108107
/**
109108
* Uploads a single part of a multipart upload
@@ -134,18 +133,19 @@ class S3BinaryCacheStore : public virtual HttpBinaryCacheStore
134133
void S3BinaryCacheStore::upsertFile(
135134
const std::string & path, RestartableSource & source, const std::string & mimeType, uint64_t sizeHint)
136135
{
137-
auto doUpload = [&](RestartableSource & src, uint64_t size, std::optional<std::string_view> encoding) {
136+
auto doUpload = [&](RestartableSource & src, uint64_t size, std::optional<Headers> headers) {
138137
if (s3Config->multipartUpload && size > s3Config->multipartThreshold) {
139-
uploadMultipart(path, src, size, mimeType, encoding);
138+
uploadMultipart(path, src, size, mimeType, std::move(headers));
140139
} else {
141-
upload(path, src, size, mimeType, encoding);
140+
upload(path, src, size, mimeType, std::move(headers));
142141
}
143142
};
144143

145144
try {
146145
if (auto compressionMethod = getCompressionMethod(path)) {
147146
CompressedSource compressed(source, *compressionMethod);
148-
doUpload(compressed, compressed.size(), compressed.getCompressionMethod());
147+
Headers headers = {{"Content-Encoding", *compressionMethod}};
148+
doUpload(compressed, compressed.size(), std::move(headers));
149149
} else {
150150
doUpload(source, sizeHint, std::nullopt);
151151
}
@@ -161,7 +161,7 @@ void S3BinaryCacheStore::upload(
161161
RestartableSource & source,
162162
uint64_t sizeHint,
163163
std::string_view mimeType,
164-
std::optional<std::string_view> contentEncoding)
164+
std::optional<Headers> headers)
165165
{
166166
debug("using S3 regular upload for '%s' (%d bytes)", path, sizeHint);
167167
if (sizeHint > AWS_MAX_PART_SIZE)
@@ -170,18 +170,18 @@ void S3BinaryCacheStore::upload(
170170
renderSize(sizeHint),
171171
renderSize(AWS_MAX_PART_SIZE));
172172

173-
HttpBinaryCacheStore::upload(path, source, sizeHint, mimeType, contentEncoding);
173+
HttpBinaryCacheStore::upload(path, source, sizeHint, mimeType, std::move(headers));
174174
}
175175

176176
void S3BinaryCacheStore::uploadMultipart(
177177
std::string_view path,
178178
RestartableSource & source,
179179
uint64_t sizeHint,
180180
std::string_view mimeType,
181-
std::optional<std::string_view> contentEncoding)
181+
std::optional<Headers> headers)
182182
{
183183
debug("using S3 multipart upload for '%s' (%d bytes)", path, sizeHint);
184-
MultipartSink sink(*this, path, sizeHint, mimeType, contentEncoding);
184+
MultipartSink sink(*this, path, sizeHint, mimeType, std::move(headers));
185185
source.drainInto(sink);
186186
sink.finish();
187187
}
@@ -191,7 +191,7 @@ S3BinaryCacheStore::MultipartSink::MultipartSink(
191191
std::string_view path,
192192
uint64_t sizeHint,
193193
std::string_view mimeType,
194-
std::optional<std::string_view> contentEncoding)
194+
std::optional<Headers> headers)
195195
: store(store)
196196
, path(path)
197197
{
@@ -227,7 +227,7 @@ S3BinaryCacheStore::MultipartSink::MultipartSink(
227227

228228
buffer.reserve(chunkSize);
229229
partEtags.reserve(estimatedParts);
230-
uploadId = store.createMultipartUpload(path, mimeType, contentEncoding);
230+
uploadId = store.createMultipartUpload(path, mimeType, std::move(headers));
231231
}
232232

233233
void S3BinaryCacheStore::MultipartSink::operator()(std::string_view data)
@@ -279,7 +279,7 @@ void S3BinaryCacheStore::MultipartSink::uploadChunk(std::string chunk)
279279
}
280280

281281
std::string S3BinaryCacheStore::createMultipartUpload(
282-
std::string_view key, std::string_view mimeType, std::optional<std::string_view> contentEncoding)
282+
std::string_view key, std::string_view mimeType, std::optional<Headers> headers)
283283
{
284284
auto req = makeRequest(key);
285285

@@ -296,8 +296,9 @@ std::string S3BinaryCacheStore::createMultipartUpload(
296296
req.data = {payload};
297297
req.mimeType = mimeType;
298298

299-
if (contentEncoding) {
300-
req.headers.emplace_back("Content-Encoding", *contentEncoding);
299+
if (headers) {
300+
req.headers.reserve(req.headers.size() + headers->size());
301+
std::move(headers->begin(), headers->end(), std::back_inserter(req.headers));
301302
}
302303

303304
auto result = getFileTransfer()->enqueueFileTransfer(req).get();

0 commit comments

Comments
 (0)