indexRecords::checkSum *Record = MetaIndexParser->Lookup(MetaKey);
if(Record)
FileSize = Record->Size;
+
+ InitByHashIfNeeded(MetaKey);
}
Desc.Description = URIDesc;
QueueURI(Desc);
}
/*}}}*/
+// AcqIndex::AdjustForByHash - modify URI for by-hash support /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void pkgAcqIndex::InitByHashIfNeeded(const std::string MetaKey)
+{
+ // TODO:
+ // - (maybe?) add support for by-hash into the sources.list as flag
+ // - make apt-ftparchive generate the hashes (and expire?)
+ std::string HostKnob = "APT::Acquire::" + ::URI(Desc.URI).Host + "::By-Hash";
+ if(_config->FindB("APT::Acquire::By-Hash", false) == true ||
+ _config->FindB(HostKnob, false) == true ||
+ MetaIndexParser->GetSupportsAcquireByHash())
+ {
+ indexRecords::checkSum *Record = MetaIndexParser->Lookup(MetaKey);
+ if(Record)
+ {
+ // FIXME: should we really use the best hash here? or a fixed one?
+ const HashString *TargetHash = Record->Hashes.find("");
+ std::string ByHash = "/by-hash/" + TargetHash->HashType() + "/" + TargetHash->HashValue();
+ size_t trailing_slash = Desc.URI.find_last_of("/");
+ Desc.URI = Desc.URI.replace(
+ trailing_slash,
+ Desc.URI.substr(trailing_slash+1).size()+1,
+ ByHash);
+ } else {
+ _error->Warning(
+ "Fetching ByHash requested but can not find record for %s",
+ MetaKey.c_str());
+ }
+ }
+}
+ /*}}}*/
// AcqIndex::Custom600Headers - Insert custom request headers /*{{{*/
// ---------------------------------------------------------------------
/* The only header we use is the last-modified header. */
*/
std::string CompressionExtension;
+ /** \brief Do the changes needed to fetch via AptByHash (if needed) */
+ void InitByHashIfNeeded(const std::string MetaKey);
+
public:
// Specialized action members
return this->Suite;
}
+APT_PURE bool indexRecords::GetSupportsAcquireByHash() const
+{
+ return this->SupportsAcquireByHash;
+}
+
APT_PURE bool indexRecords::CheckDist(const string MaybeDist) const
{
return (this->Dist == MaybeDist
strprintf(ErrorText, _("No sections in Release file %s"), Filename.c_str());
return false;
}
+ // FIXME: find better tag name
+ SupportsAcquireByHash = Section.FindB("Acquire-By-Hash", false);
Suite = Section.FindS("Suite");
Dist = Section.FindS("Codename");
- int i;
- for (i=0;HashString::SupportedHashes()[i] != NULL; i++)
+ bool FoundHashSum = false;
+ for (int i=0;HashString::SupportedHashes()[i] != NULL; i++)
{
if (!Section.Find(HashString::SupportedHashes()[i], Start, End))
continue;
{
if (!parseSumData(Start, End, Name, Hash, Size))
return false;
- indexRecords::checkSum *Sum = new indexRecords::checkSum;
- Sum->MetaKeyFilename = Name;
- Sum->Hashes.push_back(HashString(HashString::SupportedHashes()[i],Hash));
- Sum->Size = Size;
- Entries[Name] = Sum;
+
+ if (Entries.find(Name) == Entries.end())
+ {
+ indexRecords::checkSum *Sum = new indexRecords::checkSum;
+ Sum->MetaKeyFilename = Name;
+ Sum->Size = Size;
+ Entries[Name] = Sum;
+ }
+ Entries[Name]->Hashes.push_back(HashString(HashString::SupportedHashes()[i],Hash));
+ FoundHashSum = true;
}
- break;
}
- if(HashString::SupportedHashes()[i] == NULL)
+ if(FoundHashSum == false)
{
strprintf(ErrorText, _("No Hash entry in Release file %s"), Filename.c_str());
return false;
}
indexRecords::indexRecords(const string ExpectedDist) :
- ExpectedDist(ExpectedDist), ValidUntil(0)
+ ExpectedDist(ExpectedDist), ValidUntil(0), SupportsAcquireByHash(false)
{
}
public:
struct checkSum;
std::string ErrorText;
+ // dpointer (for later9
+ void * d;
protected:
std::string Dist;
std::string Suite;
std::string ExpectedDist;
time_t ValidUntil;
+ bool SupportsAcquireByHash;
std::map<std::string,checkSum *> Entries;
virtual bool Load(std::string Filename);
std::string GetDist() const;
std::string GetSuite() const;
+ bool GetSupportsAcquireByHash() const;
time_t GetValidUntil() const;
virtual bool CheckDist(const std::string MaybeDist) const;
std::string GetExpectedDist() const;
return Result;
}
/*}}}*/
+// TagSection::FindB - Find boolean value /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool pkgTagSection::FindB(const char *Tag, bool const &Default) const
+{
+ const char *Start, *Stop;
+ if (Find(Tag, Start, Stop) == false)
+ return Default;
+ return StringToBool(string(Start, Stop));
+}
+ /*}}}*/
// TagSection::FindFlag - Locate a yes/no type flag /*{{{*/
// ---------------------------------------------------------------------
/* The bits marked in Flag are masked on/off in Flags */
bool Find(const char *Tag,const char *&Start, const char *&End) const;
bool Find(const char *Tag,unsigned int &Pos) const;
std::string FindS(const char *Tag) const;
- signed int FindI(const char *Tag,signed long Default = 0) const ;
+ signed int FindI(const char *Tag,signed long Default = 0) const;
+ bool FindB(const char *Tag, bool const &Default = false) const;
unsigned long long FindULL(const char *Tag, unsigned long long const &Default = 0) const;
bool FindFlag(const char *Tag,unsigned long &Flags,
unsigned long Flag) const;
--- /dev/null
+#!/bin/sh
+set -e
+
+TESTDIR=$(readlink -f $(dirname $0))
+. $TESTDIR/framework
+
+setupenvironment
+configarchitecture "i386"
+
+insertpackage 'unstable' 'foo' 'all' '1.0'
+
+setupaptarchive --no-update
+
+APTARCHIVE=$(readlink -f ./aptarchive)
+
+# make Packages *only* accessable by-hash for this test
+mkdir -p aptarchive/dists/unstable/main/binary-i386/by-hash/SHA512
+(cd aptarchive/dists/unstable/main/binary-i386/by-hash/SHA512 &&
+ mv ../../Packages* . &&
+ ln -s Packages.gz $(sha512sum Packages.gz|cut -f1 -d' ') )
+
+# add sources
+mkdir -p aptarchive/dists/unstable/main/source/by-hash/SHA512
+(cd aptarchive/dists/unstable/main/source/by-hash/SHA512 &&
+ ln -s ../../Sources.gz $(sha512sum ../../Sources.gz|cut -f1 -d' ')
+)
+
+# we moved the Packages file away, normal update won't work
+testfailure aptget upate
+
+# ensure we do not know about "foo"
+testequal "Reading package lists...
+Building dependency tree...
+E: Unable to locate package foo" aptget install -q -s foo
+
+# ensure we can apt-get update by hash
+testsuccess aptget update -o APT::Acquire::By-Hash=1
+
+# ensure it works
+testequal "Inst foo (1.0 unstable [all])
+Conf foo (1.0 unstable [all])" aptget install -qq -s foo
+
+# add magic string to Release file ...
+MAGIC="Acquire-By-Hash: true"
+sed -i "s#Suite: unstable#Suite: unstable\n$MAGIC#" aptarchive/dists/unstable/Release
+signreleasefiles
+# ... and verify that it fetches by hash now
+testsuccess aptget update
+