aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/filetransfer.hh
diff options
context:
space:
mode:
authorJohn Ericson <John.Ericson@Obsidian.Systems>2020-06-17 03:51:02 +0000
committerJohn Ericson <John.Ericson@Obsidian.Systems>2020-06-17 03:51:02 +0000
commit02928f76fdf8ab991da404d4216e97d54af19976 (patch)
treed3b05632fbad02a2019d69eee8db445fc95557a0 /src/libstore/filetransfer.hh
parente3173242362c8421429633c0e9f64ab0211760bd (diff)
parent29542865cee37ab22efe1bd142900b69f6c59f0d (diff)
Merge remote-tracking branch 'upstream/master' into multi-output-hashDerivationModulo
Diffstat (limited to 'src/libstore/filetransfer.hh')
-rw-r--r--src/libstore/filetransfer.hh117
1 files changed, 117 insertions, 0 deletions
diff --git a/src/libstore/filetransfer.hh b/src/libstore/filetransfer.hh
new file mode 100644
index 000000000..11dca2fe0
--- /dev/null
+++ b/src/libstore/filetransfer.hh
@@ -0,0 +1,117 @@
+#pragma once
+
+#include "types.hh"
+#include "hash.hh"
+#include "config.hh"
+
+#include <string>
+#include <future>
+
+namespace nix {
+
+struct FileTransferSettings : Config
+{
+ Setting<bool> enableHttp2{this, true, "http2",
+ "Whether to enable HTTP/2 support."};
+
+ Setting<std::string> userAgentSuffix{this, "", "user-agent-suffix",
+ "String appended to the user agent in HTTP requests."};
+
+ Setting<size_t> httpConnections{this, 25, "http-connections",
+ "Number of parallel HTTP connections.",
+ {"binary-caches-parallel-connections"}};
+
+ Setting<unsigned long> connectTimeout{this, 0, "connect-timeout",
+ "Timeout for connecting to servers during downloads. 0 means use curl's builtin default."};
+
+ Setting<unsigned long> stalledDownloadTimeout{this, 300, "stalled-download-timeout",
+ "Timeout (in seconds) for receiving data from servers during download. Nix cancels idle downloads after this timeout's duration."};
+
+ Setting<unsigned int> tries{this, 5, "download-attempts",
+ "How often Nix will attempt to download a file before giving up."};
+};
+
+extern FileTransferSettings fileTransferSettings;
+
+struct FileTransferRequest
+{
+ std::string uri;
+ std::string expectedETag;
+ bool verifyTLS = true;
+ bool head = false;
+ size_t tries = fileTransferSettings.tries;
+ unsigned int baseRetryTimeMs = 250;
+ ActivityId parentAct;
+ bool decompress = true;
+ std::shared_ptr<std::string> data;
+ std::string mimeType;
+ std::function<void(char *, size_t)> dataCallback;
+
+ FileTransferRequest(const std::string & uri)
+ : uri(uri), parentAct(getCurActivity()) { }
+
+ std::string verb()
+ {
+ return data ? "upload" : "download";
+ }
+};
+
+struct FileTransferResult
+{
+ bool cached = false;
+ std::string etag;
+ std::string effectiveUri;
+ std::shared_ptr<std::string> data;
+ uint64_t bodySize = 0;
+};
+
+class Store;
+
+struct FileTransfer
+{
+ virtual ~FileTransfer() { }
+
+ /* Enqueue a data transfer request, returning a future to the result of
+ the download. The future may throw a FileTransferError
+ exception. */
+ virtual void enqueueFileTransfer(const FileTransferRequest & request,
+ Callback<FileTransferResult> callback) = 0;
+
+ std::future<FileTransferResult> enqueueFileTransfer(const FileTransferRequest & request);
+
+ /* Synchronously download a file. */
+ FileTransferResult download(const FileTransferRequest & request);
+
+ /* Synchronously upload a file. */
+ FileTransferResult upload(const FileTransferRequest & request);
+
+ /* Download a file, writing its data to a sink. The sink will be
+ invoked on the thread of the caller. */
+ void download(FileTransferRequest && request, Sink & sink);
+
+ enum Error { NotFound, Forbidden, Misc, Transient, Interrupted };
+};
+
+/* Return a shared FileTransfer object. Using this object is preferred
+ because it enables connection reuse and HTTP/2 multiplexing. */
+ref<FileTransfer> getFileTransfer();
+
+/* Return a new FileTransfer object. */
+ref<FileTransfer> makeFileTransfer();
+
+class FileTransferError : public Error
+{
+public:
+ FileTransfer::Error error;
+ template<typename... Args>
+ FileTransferError(FileTransfer::Error error, const Args & ... args)
+ : Error(args...), error(error)
+ { }
+};
+
+bool isUri(const string & s);
+
+/* Resolve deprecated 'channel:<foo>' URLs. */
+std::string resolveUri(const std::string & uri);
+
+}