diff --git a/src/libstore/filetransfer.cc b/src/libstore/filetransfer.cc index 24cc67d8a..c75e7a627 100644 --- a/src/libstore/filetransfer.cc +++ b/src/libstore/filetransfer.cc @@ -167,8 +167,19 @@ struct curlFileTransfer : public FileTransfer char * effectiveUriCStr = nullptr; curl_easy_getinfo(req, CURLINFO_EFFECTIVE_URL, &effectiveUriCStr); - if (effectiveUriCStr) + if (effectiveUriCStr) { + if (!result.effectiveUri.empty() && result.effectiveUri != effectiveUriCStr) { + throw FileTransferError( + Misc, + {}, + "uri %s changed final destination from %s to %s during transfer", + uri, + result.effectiveUri, + effectiveUriCStr + ); + } result.effectiveUri = effectiveUriCStr; + } result.cached = getHTTPStatus() == 304; @@ -307,6 +318,10 @@ struct curlFileTransfer : public FileTransfer curl_easy_setopt(req, CURLOPT_DEBUGFUNCTION, TransferItem::debugCallback); } + // use the effective URI of the previous transfer for retries. this avoids + // some silent corruption if a redirect changes between starting and retry. + const auto & uri = result.effectiveUri.empty() ? this->uri : result.effectiveUri; + curl_easy_setopt(req, CURLOPT_URL, uri.c_str()); curl_easy_setopt(req, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(req, CURLOPT_MAXREDIRS, 10);