about summary refs log tree commit diff
path: root/src/libstore
diff options
context:
space:
mode:
authorShea Levy <shea@shealevy.com>2016-08-11T15·34-0400
committerShea Levy <shea@shealevy.com>2016-08-11T15·34-0400
commit59124228b3ac6120e73bc6a88b2c633a70bdf0fc (patch)
tree7c1c780875b29a86acbf667513376751655af46b /src/libstore
parenta6eed133c5a3602037bc48675ca783185cca5454 (diff)
nix-channel: implement in c++
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 cf3929cadd65..9cc433228141 100644
--- a/src/libstore/download.cc
+++ b/src/libstore/download.cc
@@ -31,7 +31,7 @@ struct CurlDownloader : public Downloader
 {
     CURL * curl;
     ref<std::string> data;
-    string etag, status, expectedETag;
+    string etag, status, expectedETag, effectiveUrl;
 
     struct curl_slist * requestHeaders;
 
@@ -199,6 +199,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;
@@ -212,6 +217,7 @@ struct CurlDownloader : public Downloader
             res.data = data;
         } else
             res.cached = true;
+        res.effectiveUrl = effectiveUrl;
         res.etag = etag;
         return res;
     }
@@ -224,6 +230,12 @@ ref<Downloader> makeDownloader()
 
 Path Downloader::downloadCached(ref<Store> store, const string & url_, bool unpack, 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_);
 
     string name;
@@ -259,9 +271,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];
                 }
@@ -276,6 +289,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 efddc55281fe..d17e14400f1a 100644
--- a/src/libstore/download.hh
+++ b/src/libstore/download.hh
@@ -19,6 +19,7 @@ struct DownloadResult
 {
     bool cached;
     string etag;
+    string effectiveUrl;
     std::shared_ptr<std::string> data;
 };
 
@@ -31,6 +32,11 @@ struct Downloader
     Path downloadCached(ref<Store> store, const string & url, bool unpack,
         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 };
 };