Skip to content
Merged
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion src/libfetchers/git-lfs-fetch.cc
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ std::vector<nlohmann::json> Fetch::fetchUrls(const std::vector<Pointer> & pointe
auto url = api.endpoint + "/objects/batch";
const auto & authHeader = api.authHeader;
FileTransferRequest request(parseURL(url));
request.post = true;
request.method = HttpMethod::POST;
Headers headers;
if (authHeader.has_value())
headers.push_back({"Authorization", *authHeader});
Expand Down
12 changes: 10 additions & 2 deletions src/libstore/filetransfer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -384,11 +384,14 @@ struct curlFileTransfer : public FileTransfer
if (settings.downloadSpeed.get() > 0)
curl_easy_setopt(req, CURLOPT_MAX_RECV_SPEED_LARGE, (curl_off_t) (settings.downloadSpeed.get() * 1024));

if (request.head)
if (request.method == HttpMethod::HEAD)
curl_easy_setopt(req, CURLOPT_NOBODY, 1);

if (request.method == HttpMethod::DELETE)
curl_easy_setopt(req, CURLOPT_CUSTOMREQUEST, "DELETE");

if (request.data) {
if (request.post) {
if (request.method == HttpMethod::POST) {
curl_easy_setopt(req, CURLOPT_POST, 1L);
curl_easy_setopt(req, CURLOPT_POSTFIELDSIZE_LARGE, (curl_off_t) request.data->length());
} else {
Expand Down Expand Up @@ -919,6 +922,11 @@ FileTransferResult FileTransfer::upload(const FileTransferRequest & request)
return enqueueFileTransfer(request).get();
}

FileTransferResult FileTransfer::deleteResource(const FileTransferRequest & request)
{
return enqueueFileTransfer(request).get();
}

void FileTransfer::download(
FileTransferRequest && request, Sink & sink, std::function<void(FileTransferResult)> resultCallback)
{
Expand Down
2 changes: 1 addition & 1 deletion src/libstore/http-binary-cache-store.cc
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ class HttpBinaryCacheStore : public virtual BinaryCacheStore

try {
FileTransferRequest request(makeRequest(path));
request.head = true;
request.method = HttpMethod::HEAD;
getFileTransfer()->download(request);
return true;
} catch (FileTransferError & e) {
Expand Down
34 changes: 31 additions & 3 deletions src/libstore/include/nix/store/filetransfer.hh
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,16 @@ extern FileTransferSettings fileTransferSettings;

extern const unsigned int RETRY_TIME_MS_DEFAULT;

/**
* HTTP methods supported by FileTransfer.
*/
enum struct HttpMethod {
GET,
HEAD,
POST,
DELETE,
};

/**
* Username and optional password for HTTP basic authentication.
* These are used with curl's CURLOPT_USERNAME and CURLOPT_PASSWORD options
Expand All @@ -99,8 +109,7 @@ struct FileTransferRequest
VerbatimURL uri;
Headers headers;
std::string expectedETag;
bool head = false;
bool post = false;
HttpMethod method = HttpMethod::GET;
size_t tries = fileTransferSettings.tries;
unsigned int baseRetryTimeMs = RETRY_TIME_MS_DEFAULT;
ActivityId parentAct;
Expand All @@ -127,9 +136,23 @@ struct FileTransferRequest
{
}

/**
* Returns the verb root for logging purposes.
* The returned string is intended to be concatenated with "ing" to form the gerund,
* e.g., "download" + "ing" -> "downloading", "upload" + "ing" -> "uploading".
*/
std::string verb() const
{
return data ? "upload" : "download";
switch (method) {
case HttpMethod::HEAD:
case HttpMethod::GET:
return "download";
case HttpMethod::POST:
return "upload";
case HttpMethod::DELETE:
return "delet";
}
unreachable();
}

private:
Expand Down Expand Up @@ -201,6 +224,11 @@ struct FileTransfer
*/
FileTransferResult upload(const FileTransferRequest & request);

/**
* Synchronously delete a resource.
*/
FileTransferResult deleteResource(const FileTransferRequest & request);

/**
* Download a file, writing its data to a sink. The sink will be
* invoked on the thread of the caller.
Expand Down
Loading