summaryrefslogtreecommitdiff
path: root/apt-pkg/acquire-worker.cc
diff options
context:
space:
mode:
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)