summaryrefslogtreecommitdiff
path: root/apt-pkg/acquire-worker.cc
diff options
context:
space:
mode:
authorDavid Kalnischkies <david@kalnischkies.de>2017-10-27 19:09:45 +0200
committerDavid Kalnischkies <david@kalnischkies.de>2017-12-13 23:56:29 +0100
commit355e1aceac1dd05c4c7daf3420b09bd860fd169d (patch)
tree6d71c3b920209bc6636893f34f6e619418bd719b /apt-pkg/acquire-worker.cc
parent9f572c0a6d13cc983a4f8880a3dee3a8e46604bb (diff)
implement fallback to alternative URIs for all items
For deb files we always supported falling back from one server to the other if one failed to download the deb, but that was hardwired in the handling of this specific item. Moving this alongside the retry infrastructure we can implement it for all items and allow methods to use this as well by providing additional URIs in a redirect.
Diffstat (limited to 'apt-pkg/acquire-worker.cc')
-rw-r--r--apt-pkg/acquire-worker.cc53
1 files changed, 46 insertions, 7 deletions
diff --git a/apt-pkg/acquire-worker.cc b/apt-pkg/acquire-worker.cc
index a763d9242..995750dea 100644
--- a/apt-pkg/acquire-worker.cc
+++ b/apt-pkg/acquire-worker.cc
@@ -211,6 +211,39 @@ static bool isDoomedItem(pkgAcquire::Item const * const Itm)
return false;
return TransItm->TransactionManager->State != pkgAcqTransactionItem::TransactionStarted;
}
+static HashStringList GetHashesFromMessage(std::string const &Prefix, std::string const &Message)
+{
+ HashStringList hsl;
+ for (char const *const *type = HashString::SupportedHashes(); *type != NULL; ++type)
+ {
+ std::string const tagname = Prefix + *type + "-Hash";
+ std::string const hashsum = LookupTag(Message, tagname.c_str());
+ if (hashsum.empty() == false)
+ hsl.push_back(HashString(*type, hashsum));
+ }
+ return hsl;
+}
+static void APT_NONNULL(3) ChangeSiteIsMirrorChange(std::string const &NewURI, pkgAcquire::ItemDesc &desc, pkgAcquire::Item *const Owner)
+{
+ if (URI::SiteOnly(NewURI) == URI::SiteOnly(desc.URI))
+ return;
+
+ auto const firstSpace = desc.Description.find(" ");
+ if (firstSpace != std::string::npos)
+ {
+ std::string const OldSite = desc.Description.substr(0, firstSpace);
+ if (likely(APT::String::Startswith(desc.URI, OldSite)))
+ {
+ std::string const OldExtra = desc.URI.substr(OldSite.length() + 1);
+ if (likely(APT::String::Endswith(NewURI, OldExtra)))
+ {
+ std::string const NewSite = NewURI.substr(0, NewURI.length() - OldExtra.length());
+ Owner->UsedMirror = URI::ArchiveOnly(NewSite);
+ desc.Description.replace(0, firstSpace, Owner->UsedMirror);
+ }
+ }
+ }
+}
bool pkgAcquire::Worker::RunMessages()
{
while (MessageQueue.empty() == false)
@@ -377,13 +410,7 @@ bool pkgAcquire::Worker::RunMessages()
std::string const givenfilename = LookupTag(Message, "Filename");
std::string const filename = givenfilename.empty() ? Itm->Owner->DestFile : givenfilename;
// see if we got hashes to verify
- for (char const * const * type = HashString::SupportedHashes(); *type != NULL; ++type)
- {
- std::string const tagname = std::string(*type) + "-Hash";
- std::string const hashsum = LookupTag(Message, tagname.c_str());
- if (hashsum.empty() == false)
- ReceivedHashes.push_back(HashString(*type, hashsum));
- }
+ ReceivedHashes = GetHashesFromMessage("", Message);
// not all methods always sent Hashes our way
if (ReceivedHashes.usable() == false)
{
@@ -525,6 +552,7 @@ bool pkgAcquire::Worker::RunMessages()
for (auto const Owner: ItmOwners)
{
+ std::string NewURI;
if (errTransient == true && Config->LocalOnly == false && Owner->ModifyRetries() != 0)
{
--Owner->ModifyRetries();
@@ -535,6 +563,17 @@ bool pkgAcquire::Worker::RunMessages()
if (isDoomedItem(Owner) == false)
OwnerQ->Owner->Enqueue(SavedDesc);
}
+ else if (Owner->PopAlternativeURI(NewURI))
+ {
+ Owner->FailMessage(Message);
+ auto &desc = Owner->GetItemDesc();
+ if (Log != nullptr)
+ Log->Fail(desc);
+ ChangeSiteIsMirrorChange(NewURI, desc, Owner);
+ desc.URI = NewURI;
+ if (isDoomedItem(Owner) == false)
+ OwnerQ->Owner->Enqueue(desc);
+ }
else
{
if (errAuthErr && Owner->GetExpectedHashes().empty() == false)