about summary refs log tree commit diff
path: root/src/libstore
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstore')
-rw-r--r--src/libstore/http-binary-cache-store.cc76
-rw-r--r--src/libstore/local-binary-cache-store.cc14
-rw-r--r--src/libstore/store-api.hh5
3 files changed, 92 insertions, 3 deletions
diff --git a/src/libstore/http-binary-cache-store.cc b/src/libstore/http-binary-cache-store.cc
new file mode 100644
index 000000000000..78f4497e7665
--- /dev/null
+++ b/src/libstore/http-binary-cache-store.cc
@@ -0,0 +1,76 @@
+#include "binary-cache-store.hh"
+#include "download.hh"
+
+namespace nix {
+
+class HttpBinaryCacheStore : public BinaryCacheStore
+{
+private:
+
+    Path cacheUri;
+
+    ref<Downloader> downloader;
+
+public:
+
+    HttpBinaryCacheStore(std::shared_ptr<Store> localStore,
+        const Path & secretKeyFile, const Path & publicKeyFile,
+        const Path & _cacheUri)
+        : BinaryCacheStore(localStore, secretKeyFile, publicKeyFile)
+        , cacheUri(_cacheUri)
+        , downloader(makeDownloader())
+    {
+        if (cacheUri.back() == '/')
+            cacheUri.pop_back();
+    }
+
+    void init() override
+    {
+        // FIXME: do this lazily?
+        if (!fileExists("nix-cache-info"))
+            throw Error(format("‘%s’ does not appear to be a binary cache") % cacheUri);
+    }
+
+protected:
+
+    bool fileExists(const std::string & path) override
+    {
+        try {
+            DownloadOptions options;
+            options.showProgress = DownloadOptions::no;
+            options.head = true;
+            downloader->download(cacheUri + "/" + path, options);
+            return true;
+        } catch (DownloadError & e) {
+            if (e.error == Downloader::NotFound)
+                return false;
+            throw;
+        }
+    }
+
+    void upsertFile(const std::string & path, const std::string & data)
+    {
+        throw Error("uploading to an HTTP binary cache is not supported");
+    }
+
+    std::string getFile(const std::string & path) override
+    {
+        DownloadOptions options;
+        options.showProgress = DownloadOptions::no;
+        return downloader->download(cacheUri + "/" + path, options).data;
+    }
+
+};
+
+static RegisterStoreImplementation regStore([](const std::string & uri) -> std::shared_ptr<Store> {
+    if (std::string(uri, 0, 7) != "http://" &&
+        std::string(uri, 0, 8) != "https://") return 0;
+    auto store = std::make_shared<HttpBinaryCacheStore>(std::shared_ptr<Store>(0),
+        "", "", // FIXME: allow the signing key to be set
+        uri);
+    store->init();
+    return store;
+});
+
+}
+
diff --git a/src/libstore/local-binary-cache-store.cc b/src/libstore/local-binary-cache-store.cc
index a10c9d1069d5..8590aea185d4 100644
--- a/src/libstore/local-binary-cache-store.cc
+++ b/src/libstore/local-binary-cache-store.cc
@@ -65,13 +65,21 @@ std::string LocalBinaryCacheStore::getFile(const std::string & path)
     return readFile(binaryCacheDir + "/" + path);
 }
 
+ref<Store> openLocalBinaryCacheStore(std::shared_ptr<Store> localStore,
+    const Path & secretKeyFile, const Path & publicKeyFile,
+    const Path & binaryCacheDir)
+{
+    auto store = std::make_shared<LocalBinaryCacheStore>(
+        localStore, secretKeyFile, publicKeyFile, binaryCacheDir);
+    store->init();
+    return ref<Store>(std::shared_ptr<Store>(store));
+}
+
 static RegisterStoreImplementation regStore([](const std::string & uri) -> std::shared_ptr<Store> {
     if (std::string(uri, 0, 7) != "file://") return 0;
-    auto store = std::make_shared<LocalBinaryCacheStore>(std::shared_ptr<Store>(0),
+    return openLocalBinaryCacheStore(std::shared_ptr<Store>(0),
         "", "", // FIXME: allow the signing key to be set
         std::string(uri, 7));
-    store->init();
-    return store;
 });
 
 }
diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh
index 97e834ed2bd8..9825d45db102 100644
--- a/src/libstore/store-api.hh
+++ b/src/libstore/store-api.hh
@@ -453,6 +453,11 @@ ref<Store> openStoreAt(const std::string & uri);
 ref<Store> openStore();
 
 
+ref<Store> openLocalBinaryCacheStore(std::shared_ptr<Store> localStore,
+    const Path & secretKeyFile, const Path & publicKeyFile,
+    const Path & binaryCacheDir);
+
+
 /* Store implementation registration. */
 typedef std::function<std::shared_ptr<Store>(const std::string & uri)> OpenStore;