diff options
Diffstat (limited to 'src/libstore')
-rw-r--r-- | src/libstore/download.cc | 20 | ||||
-rw-r--r-- | src/libstore/download.hh | 6 |
2 files changed, 23 insertions, 3 deletions
diff --git a/src/libstore/download.cc b/src/libstore/download.cc index 5305a48950c4..5cb2b497a50a 100644 --- a/src/libstore/download.cc +++ b/src/libstore/download.cc @@ -32,7 +32,7 @@ struct CurlDownloader : public Downloader { CURL * curl; ref<std::string> data; - string etag, status, expectedETag; + string etag, status, expectedETag, effectiveUrl; struct curl_slist * requestHeaders; @@ -208,6 +208,11 @@ struct CurlDownloader : public Downloader % url % curl_easy_strerror(res) % res); } + char *effectiveUrlCStr; + curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &effectiveUrlCStr); + if (effectiveUrlCStr) + effectiveUrl = effectiveUrlCStr; + if (httpStatus == 304) return false; return true; @@ -225,6 +230,7 @@ struct CurlDownloader : public Downloader res.data = data; } else res.cached = true; + res.effectiveUrl = effectiveUrl; res.etag = etag; return res; } catch (DownloadError & e) { @@ -245,6 +251,12 @@ ref<Downloader> makeDownloader() Path Downloader::downloadCached(ref<Store> store, const string & url_, bool unpack, string name, const Hash & expectedHash) { + string ignored; + return downloadCached(store, url_, unpack, ignored, expectedHash); +} + +Path Downloader::downloadCached(ref<Store> store, const string & url_, bool unpack, string & effectiveUrl, const Hash & expectedHash) +{ auto url = resolveUri(url_); if (name == "") { @@ -281,9 +293,10 @@ Path Downloader::downloadCached(ref<Store> store, const string & url_, bool unpa auto ss = tokenizeString<vector<string>>(readFile(dataFile), "\n"); if (ss.size() >= 3 && ss[0] == url) { time_t lastChecked; - if (string2Int(ss[2], lastChecked) && lastChecked + ttl >= time(0)) + if (string2Int(ss[2], lastChecked) && lastChecked + ttl >= time(0)) { skip = true; - else if (!ss[1].empty()) { + effectiveUrl = url_; + } else if (!ss[1].empty()) { printMsg(lvlDebug, format("verifying previous ETag ‘%1%’") % ss[1]); expectedETag = ss[1]; } @@ -298,6 +311,7 @@ Path Downloader::downloadCached(ref<Store> store, const string & url_, bool unpa DownloadOptions options; options.expectedETag = expectedETag; auto res = download(url, options); + effectiveUrl = res.effectiveUrl; if (!res.cached) { ValidPathInfo info; diff --git a/src/libstore/download.hh b/src/libstore/download.hh index f22e688645b0..cb7de6ef1d99 100644 --- a/src/libstore/download.hh +++ b/src/libstore/download.hh @@ -21,6 +21,7 @@ struct DownloadResult { bool cached; string etag; + string effectiveUrl; std::shared_ptr<std::string> data; }; @@ -33,6 +34,11 @@ struct Downloader Path downloadCached(ref<Store> store, const string & url, bool unpack, string name = "", const Hash & expectedHash = Hash()); + /* Need to overload because can't have an rvalue default value for non-const reference */ + + Path downloadCached(ref<Store> store, const string & url, bool unpack, + string & effectiveUrl, const Hash & expectedHash = Hash()); + enum Error { NotFound, Forbidden, Misc, Transient }; }; |