tvl-depot/src/libstore/builtins.cc
Eelco Dolstra 90ad02bf62 Enable HTTP/2 support
The binary cache store can now use HTTP/2 to do lookups. This is much
more efficient than HTTP/1.1 due to multiplexing: we can issue many
requests in parallel over a single TCP connection. Thus it's no longer
necessary to use a bunch of concurrent TCP connections (25 by
default).

For example, downloading 802 .narinfo files from
https://cache.nixos.org/, using a single TCP connection, takes 11.8s
with HTTP/1.1, but only 0.61s with HTTP/2.

This did require a fairly substantial rewrite of the Downloader class
to use the curl multi interface, because otherwise curl wouldn't be
able to do multiplexing for us. As a bonus, we get connection reuse
even with HTTP/1.1. All downloads are now handled by a single worker
thread. Clients call Downloader::enqueueDownload() to tell the worker
thread to start the download, getting a std::future to the result.
2016-09-14 16:36:02 +02:00

63 lines
1.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "builtins.hh"
#include "download.hh"
#include "store-api.hh"
#include "archive.hh"
#include "compression.hh"
namespace nix {
void builtinFetchurl(const BasicDerivation & drv)
{
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. */
DownloadRequest request(url);
request.verifyTLS = false;
/* Show a progress indicator, even though stderr is not a tty. */
request.showProgress = DownloadRequest::yes;
/* Note: have to use a fresh downloader here because we're in
a forked process. */
auto data = makeDownloader()->download(request);
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());
}
if (!data) data = fetch(getAttr("url"));
Path storePath = getAttr("out");
auto unpack = drv.env.find("unpack");
if (unpack != drv.env.end() && unpack->second == "1") {
if (string(*data, 0, 6) == string("\xfd" "7zXZ\0", 6))
data = decompress("xz", *data);
StringSource source(*data);
restorePath(storePath, source);
} else
writeFile(storePath, *data);
auto executable = drv.env.find("executable");
if (executable != drv.env.end() && executable->second == "1") {
if (chmod(storePath.c_str(), 0755) == -1)
throw SysError(format("making %1% executable") % storePath);
}
}
}