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/download.cc20
-rw-r--r--src/libstore/download.hh6
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 };
 };