builtins.{fetchurl,fetchTarball}: Support a sha256 attribute

Also, allow builtins.{fetchurl,fetchTarball} in restricted mode if a
hash is specified.
This commit is contained in:
Eelco Dolstra 2016-07-26 21:16:52 +02:00
parent ee3032e4de
commit 06bbfb6004
3 changed files with 37 additions and 12 deletions

View file

@ -3,6 +3,7 @@
#include "globals.hh"
#include "hash.hh"
#include "store-api.hh"
#include "archive.hh"
#include <curl/curl.h>
@ -221,10 +222,21 @@ ref<Downloader> makeDownloader()
return make_ref<CurlDownloader>();
}
Path Downloader::downloadCached(ref<Store> store, const string & url_, bool unpack)
Path Downloader::downloadCached(ref<Store> store, const string & url_, bool unpack, const Hash & expectedHash)
{
auto url = resolveUri(url_);
string name;
auto p = url.rfind('/');
if (p != string::npos) name = string(url, p + 1);
Path expectedStorePath;
if (expectedHash) {
expectedStorePath = store->makeFixedOutputPath(unpack, expectedHash.type, expectedHash, name);
if (store->isValidPath(expectedStorePath))
return expectedStorePath;
}
Path cacheDir = getCacheDir() + "/nix/tarballs";
createDirs(cacheDir);
@ -258,10 +270,6 @@ Path Downloader::downloadCached(ref<Store> store, const string & url_, bool unpa
storePath = "";
}
string name;
auto p = url.rfind('/');
if (p != string::npos) name = string(url, p + 1);
if (!skip) {
try {
@ -269,8 +277,16 @@ Path Downloader::downloadCached(ref<Store> store, const string & url_, bool unpa
options.expectedETag = expectedETag;
auto res = download(url, options);
if (!res.cached)
storePath = store->addTextToStore(name, *res.data, PathSet(), false);
if (!res.cached) {
ValidPathInfo info;
StringSink sink;
dumpString(*res.data, sink);
Hash hash = hashString(expectedHash ? expectedHash.type : htSHA256, *res.data);
info.path = store->makeFixedOutputPath(false, hash.type, hash, name);
info.narHash = hashString(htSHA256, *sink.s);
store->addToStore(info, *sink.s, false, true);
storePath = info.path;
}
assert(!storePath.empty());
replaceSymlink(storePath, fileLink);
@ -300,9 +316,12 @@ Path Downloader::downloadCached(ref<Store> store, const string & url_, bool unpa
unpackedStorePath = store->addToStore(name, tmpDir, true, htSHA256, defaultPathFilter, false);
}
replaceSymlink(unpackedStorePath, unpackedLink);
return unpackedStorePath;
storePath = unpackedStorePath;
}
if (expectedStorePath != "" && storePath != expectedStorePath)
throw nix::Error(format("hash mismatch in file downloaded from %s") % url);
return storePath;
}