about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libstore/builtins.cc55
1 files changed, 35 insertions, 20 deletions
diff --git a/src/libstore/builtins.cc b/src/libstore/builtins.cc
index 6383ab59ea02..d3194a905733 100644
--- a/src/libstore/builtins.cc
+++ b/src/libstore/builtins.cc
@@ -8,33 +8,48 @@ namespace nix {
 
 void builtinFetchurl(const BasicDerivation & drv)
 {
-    auto url = drv.env.find("url");
-    if (url == drv.env.end()) throw Error("attribute ‘url’ missing");
-
-    /* No need to do TLS verification, because we check the hash of
-       the result anyway. */
-    DownloadOptions options;
-    options.verifyTLS = false;
-
-    /* Show a progress indicator, even though stderr is not a tty. */
-    options.showProgress = DownloadOptions::yes;
-
-    auto data = makeDownloader()->download(url->second, options);
-    assert(data.data);
+    auto getAttr = [&](const string & name) {
+        auto i = drv.env.find(name);
+        if (i == drv.env.end()) throw Error(format("attribute ‘%s’ missing") % name);
+        return i->second;
+    };
+
+    auto fetch = [&](const string & url) {
+        /* No need to do TLS verification, because we check the hash of
+           the result anyway. */
+        DownloadOptions options;
+        options.verifyTLS = false;
+
+        /* Show a progress indicator, even though stderr is not a tty. */
+        options.showProgress = DownloadOptions::yes;
+
+        auto data = makeDownloader()->download(url, options);
+        assert(data.data);
+
+        return data.data;
+    };
+
+    std::shared_ptr<std::string> data;
+
+    try {
+        if (getAttr("outputHashMode") == "flat")
+            data = fetch("http://tarballs.nixos.org/" + getAttr("outputHashAlgo") + "/" + getAttr("outputHash"));
+    } catch (Error & e) {
+        debug(e.what());
+    }
 
-    auto out = drv.env.find("out");
-    if (out == drv.env.end()) throw Error("attribute ‘out’ missing");
+    if (!data) data = fetch(getAttr("url"));
 
-    Path storePath = out->second;
+    Path storePath = getAttr("out");
 
     auto unpack = drv.env.find("unpack");
     if (unpack != drv.env.end() && unpack->second == "1") {
-        if (string(*data.data, 0, 6) == string("\xfd" "7zXZ\0", 6))
-            data.data = decompress("xz", *data.data);
-        StringSource source(*data.data);
+        if (string(*data, 0, 6) == string("\xfd" "7zXZ\0", 6))
+            data = decompress("xz", *data);
+        StringSource source(*data);
         restorePath(storePath, source);
     } else
-        writeFile(storePath, *data.data);
+        writeFile(storePath, *data);
 
     auto executable = drv.env.find("executable");
     if (executable != drv.env.end() && executable->second == "1") {