Merge branch 'http-binary-cache-put-upsert' of https://github.com/adelbertc/nix

This commit is contained in:
Eelco Dolstra 2018-01-31 15:10:12 +01:00
commit 6270b2e50f
No known key found for this signature in database
GPG key ID: 8170B4726D7198DE
3 changed files with 38 additions and 4 deletions

View file

@ -22,6 +22,7 @@
#include <thread> #include <thread>
#include <cmath> #include <cmath>
#include <random> #include <random>
#include <algorithm>
using namespace std::string_literals; using namespace std::string_literals;
@ -91,6 +92,8 @@ struct CurlDownloader : public Downloader
{ {
if (!request.expectedETag.empty()) if (!request.expectedETag.empty())
requestHeaders = curl_slist_append(requestHeaders, ("If-None-Match: " + request.expectedETag).c_str()); requestHeaders = curl_slist_append(requestHeaders, ("If-None-Match: " + request.expectedETag).c_str());
if (!request.mimeType.empty())
requestHeaders = curl_slist_append(requestHeaders, ("Content-Type: " + request.mimeType).c_str());
} }
~DownloadItem() ~DownloadItem()
@ -185,6 +188,22 @@ struct CurlDownloader : public Downloader
return 0; return 0;
} }
size_t readOffset = 0;
int readCallback(char *buffer, size_t size, size_t nitems)
{
if (readOffset == request.data->length())
return 0;
auto count = std::min(size * nitems, request.data->length() - readOffset);
memcpy(buffer, request.data->data() + readOffset, count);
readOffset += count;
return count;
}
static int readCallbackWrapper(char *buffer, size_t size, size_t nitems, void * userp)
{
return ((DownloadItem *) userp)->readCallback(buffer, size, nitems);
}
long lowSpeedTimeout = 300; long lowSpeedTimeout = 300;
void init() void init()
@ -225,6 +244,13 @@ struct CurlDownloader : public Downloader
if (request.head) if (request.head)
curl_easy_setopt(req, CURLOPT_NOBODY, 1); curl_easy_setopt(req, CURLOPT_NOBODY, 1);
if (request.data) {
curl_easy_setopt(req, CURLOPT_UPLOAD, 1L);
curl_easy_setopt(req, CURLOPT_READFUNCTION, readCallbackWrapper);
curl_easy_setopt(req, CURLOPT_READDATA, this);
curl_easy_setopt(req, CURLOPT_INFILESIZE_LARGE, (curl_off_t) request.data->length());
}
if (request.verifyTLS) { if (request.verifyTLS) {
if (settings.caFile != "") if (settings.caFile != "")
curl_easy_setopt(req, CURLOPT_CAINFO, settings.caFile.c_str()); curl_easy_setopt(req, CURLOPT_CAINFO, settings.caFile.c_str());
@ -265,7 +291,7 @@ struct CurlDownloader : public Downloader
} }
if (code == CURLE_OK && if (code == CURLE_OK &&
(httpStatus == 200 || httpStatus == 304 || httpStatus == 226 /* FTP */ || httpStatus == 0 /* other protocol */)) (httpStatus == 200 || httpStatus == 201 || httpStatus == 204 || httpStatus == 304 || httpStatus == 226 /* FTP */ || httpStatus == 0 /* other protocol */))
{ {
result.cached = httpStatus == 304; result.cached = httpStatus == 304;
done = true; done = true;

View file

@ -18,9 +18,11 @@ struct DownloadRequest
unsigned int baseRetryTimeMs = 250; unsigned int baseRetryTimeMs = 250;
ActivityId parentAct; ActivityId parentAct;
bool decompress = true; bool decompress = true;
std::shared_ptr<std::string> data;
std::string mimeType;
DownloadRequest(const std::string & uri) DownloadRequest(const std::string & uri, std::shared_ptr<std::string> data = nullptr, std::string mimeType = "")
: uri(uri), parentAct(curActivity) { } : uri(uri), parentAct(curActivity), data(std::move(data)), mimeType(std::move(mimeType)) { }
}; };
struct DownloadResult struct DownloadResult

View file

@ -67,7 +67,13 @@ protected:
const std::string & data, const std::string & data,
const std::string & mimeType) override const std::string & mimeType) override
{ {
throw UploadToHTTP("uploading to an HTTP binary cache is not supported"); auto data_ = std::make_shared<string>(data);
auto req = DownloadRequest(cacheUri + "/" + path, data_, mimeType);
try {
getDownloader()->download(req);
} catch (DownloadError & e) {
throw UploadToHTTP(format("uploading to HTTP binary cache at %1% not supported: %2%") % cacheUri % e.msg());
}
} }
void getFile(const std::string & path, void getFile(const std::string & path,