]> git.saurik.com Git - apt.git/commitdiff
a hit on Release files means the indexes will be hits too
authorDavid Kalnischkies <david@kalnischkies.de>
Sun, 12 Apr 2015 15:08:46 +0000 (17:08 +0200)
committerDavid Kalnischkies <david@kalnischkies.de>
Sat, 18 Apr 2015 23:13:10 +0000 (01:13 +0200)
If we get a IMSHit for the Transaction-Manager (= the InRelease file or
as its still supported fallback Release + Release.gpg combo) we can
assume that every file we would queue based on this manager, but already
have locally is current and hence would get an IMSHit, too. We therefore
save us and the server the trouble and skip the queuing in this case.
Beside speeding up repetative executions of 'apt-get update' this way we
also avoid hitting hashsum errors if the indexes are in fact already
updated, but the Release file isn't yet as it is the case on well
behaving mirrors as Release files is updated last.

The implementation is a bit harder than the theory makes it sound as we
still have to keep reverifying the Release files (e.g. to detect now expired
once to avoid an attacker being able to silently stale us) and have to
handle cases in which the Release file hits, but some indexes aren't
present (e.g. user added a new foreign architecture).

apt-pkg/acquire-item.cc
apt-pkg/acquire-item.h
apt-pkg/acquire.h
test/integration/framework
test/integration/test-apt-update-expected-size
test/integration/test-apt-update-ims
test/integration/test-apt-update-not-modified [new file with mode: 0755]
test/integration/test-apt-update-transactions
test/integration/test-bug-602412-dequote-redirect
test/integration/test-pdiff-usage
test/interactive-helper/aptwebserver.cc

index f3052906656255a140f3dfc9a7c2505ca0e8197c..750e7daca476ad3fa2bb65622ec2d45f0e28d174 100644 (file)
@@ -213,7 +213,7 @@ void pkgAcquire::Item::Done(string Message,unsigned long long Size,HashStringLis
    step */
 bool pkgAcquire::Item::Rename(string From,string To)
 {
-   if (rename(From.c_str(),To.c_str()) == 0)
+   if (From == To || rename(From.c_str(),To.c_str()) == 0)
       return true;
 
    std::string S;
@@ -224,9 +224,41 @@ bool pkgAcquire::Item::Rename(string From,string To)
    return false;
 }
                                                                        /*}}}*/
-void pkgAcquire::Item::QueueURI(ItemDesc &Item)                                /*{{{*/
+// Acquire::Item::QueueURI and specialisations from child classes      /*{{{*/
+/* The idea here is that an item isn't queued if it exists on disk and the
+   transition manager was a hit as this means that the files it contains
+   the checksums for can't be updated either (or they are and we are asking
+   for a hashsum mismatch to happen which helps nobody) */
+bool pkgAcquire::Item::QueueURI(ItemDesc &Item)
 {
+   std::string const FinalFile = GetFinalFilename();
+   if (TransactionManager != NULL && TransactionManager->IMSHit == true &&
+        FileExists(FinalFile) == true)
+   {
+      PartialFile = DestFile = FinalFile;
+      Status = StatDone;
+      return false;
+   }
+
    Owner->Enqueue(Item);
+   return true;
+}
+/* The transition manager InRelease itself (or its older sisters-in-law
+   Release & Release.gpg) is always queued as this allows us to rerun gpgv
+   on it to verify that we aren't stalled with old files */
+bool pkgAcqMetaBase::QueueURI(pkgAcquire::ItemDesc &Item)
+{
+   Owner->Enqueue(Item);
+   return true;
+}
+/* the Diff/Index needs to queue also the up-to-date complete index file
+   to ensure that the list cleaner isn't eating it */
+bool pkgAcqDiffIndex::QueueURI(pkgAcquire::ItemDesc &Item)
+{
+   if (pkgAcquire::Item::QueueURI(Item) == true)
+      return true;
+   QueueOnIMSHit();
+   return false;
 }
                                                                        /*}}}*/
 void pkgAcquire::Item::Dequeue()                                       /*{{{*/
@@ -408,6 +440,14 @@ string pkgAcqDiffIndex::Custom600Headers()
    return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
 }
                                                                        /*}}}*/
+void pkgAcqDiffIndex::QueueOnIMSHit() const                            /*{{{*/
+{
+   // list cleanup needs to know that this file as well as the already
+   // present index is ours, so we create an empty diff to save it for us
+   new pkgAcqIndexDiffs(Owner, TransactionManager, Target,
+        ExpectedHashes, MetaIndexParser);
+}
+                                                                       /*}}}*/
 bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile)             /*{{{*/
 {
    // failing here is fine: our caller will take care of trying to
@@ -470,11 +510,7 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile)         /*{{{*/
       // we have the same sha1 as the server so we are done here
       if(Debug)
         std::clog << "pkgAcqDiffIndex: Package file " << CurrentPackagesFile << " is up-to-date" << std::endl;
-
-      // list cleanup needs to know that this file as well as the already
-      // present index is ours, so we create an empty diff to save it for us
-      new pkgAcqIndexDiffs(Owner, TransactionManager, Target,
-                           ExpectedHashes, MetaIndexParser);
+      QueueOnIMSHit();
       return true;
    }
 
@@ -1096,6 +1132,17 @@ void pkgAcqIndexMergeDiffs::Done(string Message,unsigned long long Size,HashStri
       if(Debug)
         std::clog << "allDone: " << DestFile << "\n" << std::endl;
    }
+}
+                                                                       /*}}}*/
+// AcqBaseIndex - Constructor                                          /*{{{*/
+pkgAcqBaseIndex::pkgAcqBaseIndex(pkgAcquire *Owner,
+      pkgAcqMetaBase *TransactionManager,
+      struct IndexTarget const * const Target,
+      HashStringList const &ExpectedHashes,
+      indexRecords *MetaIndexParser)
+: Item(Owner, ExpectedHashes, TransactionManager), Target(Target),
+   MetaIndexParser(MetaIndexParser)
+{
 }
                                                                        /*}}}*/
 // AcqBaseIndex::VerifyHashByMetaKey - verify hash for the given metakey /*{{{*/
@@ -1489,6 +1536,19 @@ void pkgAcqIndex::StageDecompressDone(string Message,
    TransactionManager->TransactionStageCopy(this, DestFile, GetFinalFilename());
 
    return;
+}
+                                                                       /*}}}*/
+// AcqMetaBase - Constructor                                           /*{{{*/
+pkgAcqMetaBase::pkgAcqMetaBase(pkgAcquire *Owner,
+      const std::vector<IndexTarget*>* IndexTargets,
+      indexRecords* MetaIndexParser,
+      std::string const &RealURI,
+      HashStringList const &ExpectedHashes,
+      pkgAcqMetaBase *TransactionManager)
+: Item(Owner, ExpectedHashes, TransactionManager),
+   MetaIndexParser(MetaIndexParser), IndexTargets(IndexTargets),
+   AuthPass(false), RealURI(RealURI), IMSHit(false)
+{
 }
                                                                        /*}}}*/
 // AcqMetaBase::Add - Add a item to the current Transaction            /*{{{*/
@@ -1831,13 +1891,7 @@ bool pkgAcqMetaBase::CheckAuthDone(string Message)                       /*{{{*/
       std::cerr << "Signature verification succeeded: "
                 << DestFile << std::endl;
 
-   // Download further indexes with verification 
-   //
-   // it would be really nice if we could simply do
-   //    if (IMSHit == false) QueueIndexes(true)
-   // and skip the download if the Release file has not changed
-   // - but right now the list cleaner will needs to be tricked
-   //   to not delete all our packages/source indexes in this case
+   // Download further indexes with verification
    QueueIndexes(true);
 
    return true;
@@ -1908,7 +1962,13 @@ bool pkgAcqMetaBase::CheckDownloadDone(const std::string &Message)
    // make sure to verify against the right file on I-M-S hit
    IMSHit = StringToBool(LookupTag(Message,"IMS-Hit"),false);
    if(IMSHit)
+   {
+      // for simplicity, the transaction manager is always InRelease
+      // even if it doesn't exist.
+      if (TransactionManager != NULL)
+        TransactionManager->IMSHit = true;
       DestFile = GetFinalFilename();
+   }
 
    // set Item to complete as the remaining work is all local (verify etc)
    Complete = true;
@@ -1951,7 +2011,7 @@ void pkgAcqMetaBase::QueueIndexes(bool verify)                            /*{{{*/
                    << "Expected Hash:" << std::endl;
          for (HashStringList::const_iterator hs = ExpectedIndexHashes.begin(); hs != ExpectedIndexHashes.end(); ++hs)
             std::cerr <<  "\t- " << hs->toStr() << std::endl;
-         std::cerr << "For: " << Record->MetaKeyFilename << std::endl;
+         std::cerr << "For: " << ((Record == NULL) ? "<NULL>" : Record->MetaKeyFilename) << std::endl;
 
       }
       if (verify == true && ExpectedIndexHashes.empty() == true)
index c2759b792e291b08a791c270f6e7c69b0dcaab5d..148728b3c59914b8bd32d41b9a5eaeeb06c34140 100644 (file)
@@ -73,11 +73,16 @@ class pkgAcquire::Item : public WeakPointable
    pkgAcquire *Owner;
 
    /** \brief Insert this item into its owner's queue.
+    *
+    *  The method is designed to check if the request would end
+    *  in an IMSHit and if it determines that it would, it isn't
+    *  queueing the Item and instead sets it to completion instantly.
     *
     *  \param Item Metadata about this item (its URI and
     *  description).
+    *  \return true if the item was inserted, false if IMSHit was detected
     */
-   void QueueURI(ItemDesc &Item);
+   virtual bool QueueURI(ItemDesc &Item);
 
    /** \brief Remove this item from its owner's queue. */
    void Dequeue();
@@ -392,9 +397,6 @@ class pkgAcqMetaBase  : public pkgAcquire::Item                             /*{{{*/
     */
    bool AuthPass;
 
-   // required to deal gracefully with problems caused by incorrect ims hits
-   bool IMSHit;
-
    /** \brief The URI of the signature file.  Unlike Desc.URI, this is
     *  never modified; it is used to determine the file that is being
     *  downloaded.
@@ -457,7 +459,11 @@ class pkgAcqMetaBase  : public pkgAcquire::Item                            /*{{{*/
    virtual std::string GetFinalFilename() const;
 
  public:
+   // This refers more to the Transaction-Manager than the actual file
+   bool IMSHit;
+
    virtual std::string DescURI() {return RealURI; };
+   virtual bool QueueURI(pkgAcquire::ItemDesc &Item);
 
    // transaction code
    void Add(Item *I);
@@ -479,10 +485,7 @@ class pkgAcqMetaBase  : public pkgAcquire::Item                            /*{{{*/
                   indexRecords* MetaIndexParser,
                  std::string const &RealURI,
                   HashStringList const &ExpectedHashes=HashStringList(),
-                  pkgAcqMetaBase *TransactionManager=NULL)
-      : Item(Owner, ExpectedHashes, TransactionManager),
-        MetaIndexParser(MetaIndexParser), IndexTargets(IndexTargets),
-        AuthPass(false), IMSHit(false), RealURI(RealURI) {};
+                  pkgAcqMetaBase *TransactionManager=NULL);
 };
                                                                        /*}}}*/
 /** \brief An acquire item that downloads the detached signature       {{{
@@ -652,9 +655,7 @@ class pkgAcqBaseIndex : public pkgAcquire::Item
                    pkgAcqMetaBase *TransactionManager,
                    struct IndexTarget const * const Target,
                    HashStringList const &ExpectedHashes,
-                   indexRecords *MetaIndexParser)
-      : Item(Owner, ExpectedHashes, TransactionManager), Target(Target), 
-        MetaIndexParser(MetaIndexParser) {};
+                   indexRecords *MetaIndexParser);
 };
                                                                        /*}}}*/
 /** \brief An item that is responsible for fetching an index file of   {{{
@@ -691,6 +692,7 @@ class APT_HIDDEN pkgAcqDiffIndex : public pkgAcqBaseIndex
    /** \brief Get the full pathname of the final file for the current URI */
    virtual std::string GetFinalFilename() const;
 
+   virtual bool QueueURI(pkgAcquire::ItemDesc &Item);
  public:
    // Specialized action members
    virtual void Failed(std::string Message,pkgAcquire::MethodConfig *Cnf);
@@ -714,7 +716,6 @@ class APT_HIDDEN pkgAcqDiffIndex : public pkgAcqBaseIndex
     *  false otherwise.
     */
    bool ParseDiffIndex(std::string IndexDiffFile);
-   
 
    /** \brief Create a new pkgAcqDiffIndex.
     *
@@ -733,6 +734,8 @@ class APT_HIDDEN pkgAcqDiffIndex : public pkgAcqBaseIndex
                    struct IndexTarget const * const Target,
                    HashStringList const &ExpectedHashes,
                    indexRecords *MetaIndexParser);
+ private:
+   APT_HIDDEN void QueueOnIMSHit() const;
 };
                                                                        /*}}}*/
 /** \brief An item that is responsible for fetching client-merge patches {{{
@@ -1008,7 +1011,6 @@ class APT_HIDDEN pkgAcqIndex : public pkgAcqBaseIndex
    virtual std::string GetFinalFilename() const;
 
    public:
-   
    // Specialized action members
    virtual void Failed(std::string Message,pkgAcquire::MethodConfig *Cnf);
    virtual void Done(std::string Message,unsigned long long Size, 
index f33362922dedcd451ea1c0d8afce73066e074a50..fc90624e1e6193946094e48ee2d2e3f046c57a82 100644 (file)
@@ -111,6 +111,7 @@ class pkgAcquire
    struct MethodConfig;
    struct ItemDesc;
    friend class Item;
+   friend class pkgAcqMetaBase;
    friend class Queue;
 
    typedef std::vector<Item *>::iterator ItemIterator;
index 642c5f0d0ae77300c771a75e80eb17ac012578eb..4229ae1623e96bc1030d4e1c0b387f13efb2aa54 100644 (file)
@@ -1005,6 +1005,7 @@ signreleasefiles() {
 }
 
 webserverconfig() {
+       local WEBSERVER="${3:-http://localhost:8080}"
        local NOCHECK=false
        if [ "$1" = '--no-check' ]; then
                NOCHECK=true
@@ -1016,10 +1017,10 @@ webserverconfig() {
        local URI
        if [ -n "$2" ]; then
                msgtest "Set webserver config option '${1}' to" "$2"
-               URI="http://localhost:8080/_config/set/${1}/${2}"
+               URI="${WEBSERVER}/_config/set/${1}/${2}"
        else
                msgtest 'Clear webserver config option' "${1}"
-               URI="http://localhost:8080/_config/clear/${1}"
+               URI="${WEBSERVER}/_config/clear/${1}"
        fi
        if downloadfile "$URI" "$STATUS" > "$DOWNLOG"; then
                msgpass
@@ -1467,12 +1468,14 @@ pause() {
 }
 
 listcurrentlistsdirectory() {
-       find rootdir/var/lib/apt/lists -maxdepth 1 -type d | while read line; do
-               stat --format '%U:%G:%a:%n' "$line"
-       done
-       find rootdir/var/lib/apt/lists -maxdepth 1 \! -type d | while read line; do
-               stat --format '%U:%G:%a:%s:%y:%n' "$line"
-       done
+       {
+               find rootdir/var/lib/apt/lists -maxdepth 1 -type d | while read line; do
+                       stat --format '%U:%G:%a:%n' "$line"
+               done
+               find rootdir/var/lib/apt/lists -maxdepth 1 \! -type d | while read line; do
+                       stat --format '%U:%G:%a:%s:%y:%n' "$line"
+               done
+       } | sort
 }
 
 ### convinience hacks ###
index 22de13ea5ec704991eddc2a5bd78ded4641a32c3..9f58308aa4eda1a7ff1e8f8ad2a934f422a626c7 100755 (executable)
@@ -38,6 +38,10 @@ E: Some index files failed to download. They have been ignored, or old ones used
 }
 
 methodtest() {
+       # less complicated test setup this way
+       webserverconfig 'aptwebserver::support::modified-since' 'false' "$1"
+       webserverconfig 'aptwebserver::support::last-modified' 'false' "$1"  # curl is clever and sees hits here also
+
        msgmsg 'Test with' "$1" 'and clean start'
        rm -rf rootdir/var/lib/apt/lists rootdir/var/lib/apt/lists.good
        # normal update works fine
index 0fa882d780b0db12ecb2657d5a3ec0839d1ec8b5..f091bffaa9168b69dc47115e54efe392b1ed4a00 100755 (executable)
@@ -6,85 +6,145 @@ TESTDIR=$(readlink -f $(dirname $0))
 setupenvironment
 configarchitecture 'amd64'
 
-buildsimplenativepackage 'unrelated' 'all' '0.5~squeeze1' 'unstable'
+insertpackage 'unstable' 'unrelated' 'all' '0.5~squeeze1'
+insertsource 'unstable' 'unrelated' 'all' '0.5~squeeze1'
 
 setupaptarchive --no-update
 changetowebserver
 
 runtest() {
-    configallowinsecurerepositories "${1:-false}"
+    if [ -n "$1" ]; then
+       configallowinsecurerepositories 'true'
+    else
+       configallowinsecurerepositories 'false'
+    fi
 
-    rm -f rootdir/var/lib/apt/lists/localhost*
+    rm -rf rootdir/var/lib/apt/lists/
 
-    if [ "$1" = 'true' ]; then
-       testwarning aptget update
-    else
-       testsuccess aptget update
+    local TEST="test${1:-success}"
+    $TEST aptget update
+    if [ "$1" = 'failure' ]; then
+       # accept the outdated Release file so we can check Hit behaviour
+       "test${2:-success}" aptget update -o Acquire::Min-ValidTime=99999999999
     fi
+    listcurrentlistsdirectory > listsdir.lst
+    testsuccess grep '_Packages\(\.gz\)\?$' listsdir.lst
+    testsuccess grep '_Sources\(\.gz\)\?$' listsdir.lst
+    testsuccess grep '_Translation-en\(\.gz\)\?$' listsdir.lst
 
     # ensure no leftovers in partial
-    testfailure ls "rootdir/var/lib/apt/lists/partial/*"
+    testfailure ls 'rootdir/var/lib/apt/lists/partial/*'
 
     # check that I-M-S header is kept in redirections
-    testequal "$EXPECT" aptget update  -o Debug::pkgAcquire::Worker=0 -o Debug::Acquire::http=0
-    
-    # ensure that we still do a hash check on ims hit
-    msgtest 'Test I-M-S' 'reverify'
-    aptget update -o Debug::pkgAcquire::Auth=1 2>&1 | grep -A2 'ReceivedHash:' | grep -q -- '- SHA' && msgpass || msgfail
+    echo "$EXPECT" | sed -e 's#(invalid since [^)]\+)#(invalid since)#' > expected.output
+    $TEST aptget update  -o Debug::pkgAcquire::Worker=0 -o Debug::Acquire::http=0
+    sed -i -e 's#(invalid since [^)]\+)#(invalid since)#' rootdir/tmp/${TEST}.output
+    testequal "$(cat expected.output)" cat rootdir/tmp/${TEST}.output
+    testfileequal 'listsdir.lst' "$(listcurrentlistsdirectory)"
+
+    # ensure that we still do a hash check for other files on ims hit of Release
+    if grep -q '^Hit .* \(InRelease\|Release.gpg\)$' expected.output ; then
+           $TEST aptget update -o Debug::Acquire::gpgv=1
+           cp rootdir/tmp/${TEST}.output goodsign.output
+           testfileequal 'listsdir.lst' "$(listcurrentlistsdirectory)"
+           testsuccess grep '^Got GOODSIG, key ID:GOODSIG' goodsign.output
+    fi
 
     # ensure no leftovers in partial
-    testfailure ls "rootdir/var/lib/apt/lists/partial/*"
+    testfailure ls 'rootdir/var/lib/apt/lists/partial/*'
 }
 
-msgmsg "InRelease"
-EXPECT="Hit http://localhost:8080 unstable InRelease
-Hit http://localhost:8080 unstable/main Sources
-Hit http://localhost:8080 unstable/main amd64 Packages
-Hit http://localhost:8080 unstable/main Translation-en
-Reading package lists..."
-# with InRelease
+msgmsg 'InRelease'
+EXPECT='Hit http://localhost:8080 unstable InRelease
+Reading package lists...'
+echo 'Acquire::GzipIndexes "0";' > rootdir/etc/apt/apt.conf.d/02compressindex
 runtest
-
-# with gzip
-echo "Acquire::GzipIndexes "1";" > rootdir/etc/apt/apt.conf.d/02compressindex
+echo 'Acquire::GzipIndexes "1";' > rootdir/etc/apt/apt.conf.d/02compressindex
 runtest
 
-msgmsg "Release/Release.gpg"
-# with Release/Release.gpg
-EXPECT="Ign http://localhost:8080 unstable InRelease
+msgmsg 'Release/Release.gpg'
+EXPECT='Ign http://localhost:8080 unstable InRelease
   404  Not Found
 Hit http://localhost:8080 unstable Release
 Hit http://localhost:8080 unstable Release.gpg
-Hit http://localhost:8080 unstable/main Sources
-Hit http://localhost:8080 unstable/main amd64 Packages
-Hit http://localhost:8080 unstable/main Translation-en
-Reading package lists..."
-
+Reading package lists...'
 find aptarchive -name 'InRelease' -delete
-
-echo "Acquire::GzipIndexes "0";" > rootdir/etc/apt/apt.conf.d/02compressindex
+echo 'Acquire::GzipIndexes "0";' > rootdir/etc/apt/apt.conf.d/02compressindex
 runtest
-
-echo "Acquire::GzipIndexes "1";" > rootdir/etc/apt/apt.conf.d/02compressindex
+echo 'Acquire::GzipIndexes "1";' > rootdir/etc/apt/apt.conf.d/02compressindex
 runtest
 
-# no Release.gpg or InRelease
-msgmsg "Release only"
+msgmsg 'Release only'
 EXPECT="Ign http://localhost:8080 unstable InRelease
   404  Not Found
 Hit http://localhost:8080 unstable Release
 Ign http://localhost:8080 unstable Release.gpg
   404  Not Found
-Hit http://localhost:8080 unstable/main Sources
-Hit http://localhost:8080 unstable/main amd64 Packages
-Hit http://localhost:8080 unstable/main Translation-en
 Reading package lists...
 W: The data from 'http://localhost:8080 unstable Release.gpg' is not signed. Packages from that repository can not be authenticated."
+find aptarchive -name 'Release.gpg' -delete
+echo 'Acquire::GzipIndexes "0";' > rootdir/etc/apt/apt.conf.d/02compressindex
+runtest 'warning'
+echo 'Acquire::GzipIndexes "1";' > rootdir/etc/apt/apt.conf.d/02compressindex
+runtest 'warning'
+
+
+# make the release file old
+find aptarchive -name '*Release' -exec sed -i \
+       -e "s#^Date: .*\$#Date: $(date -d '-2 weeks' '+%a, %d %b %Y %H:%M:%S %Z')#" \
+       -e '/^Valid-Until: / d' -e "/^Date: / a\
+Valid-Until: $(date -d '-1 weeks' '+%a, %d %b %Y %H:%M:%S %Z')" '{}' \;
+signreleasefiles
+
+msgmsg 'expired InRelease'
+EXPECT='Hit http://localhost:8080 unstable InRelease
+E: Release file for http://localhost:8080/dists/unstable/InRelease is expired (invalid since). Updates for this repository will not be applied.'
+echo 'Acquire::GzipIndexes "0";' > rootdir/etc/apt/apt.conf.d/02compressindex
+runtest 'failure'
+echo 'Acquire::GzipIndexes "1";' > rootdir/etc/apt/apt.conf.d/02compressindex
+runtest 'failure'
+
+msgmsg 'expired Release/Release.gpg'
+EXPECT='Ign http://localhost:8080 unstable InRelease
+  404  Not Found
+Hit http://localhost:8080 unstable Release
+Hit http://localhost:8080 unstable Release.gpg
+E: Release file for http://localhost:8080/dists/unstable/Release.gpg is expired (invalid since). Updates for this repository will not be applied.'
+find aptarchive -name 'InRelease' -delete
+echo 'Acquire::GzipIndexes "0";' > rootdir/etc/apt/apt.conf.d/02compressindex
+runtest 'failure'
+echo 'Acquire::GzipIndexes "1";' > rootdir/etc/apt/apt.conf.d/02compressindex
+runtest 'failure'
 
+msgmsg 'expired Release only'
+EXPECT="Ign http://localhost:8080 unstable InRelease
+  404  Not Found
+Hit http://localhost:8080 unstable Release
+Ign http://localhost:8080 unstable Release.gpg
+  404  Not Found
+W: The data from 'http://localhost:8080 unstable Release.gpg' is not signed. Packages from that repository can not be authenticated.
+E: Release file for http://localhost:8080/dists/unstable/InRelease is expired (invalid since). Updates for this repository will not be applied."
 find aptarchive -name 'Release.gpg' -delete
+echo 'Acquire::GzipIndexes "0";' > rootdir/etc/apt/apt.conf.d/02compressindex
+runtest 'failure' 'warning'
+echo 'Acquire::GzipIndexes "1";' > rootdir/etc/apt/apt.conf.d/02compressindex
+runtest 'failure' 'warning'
 
-echo "Acquire::GzipIndexes "0";" > rootdir/etc/apt/apt.conf.d/02compressindex
-runtest "true"
 
-echo "Acquire::GzipIndexes "1";" > rootdir/etc/apt/apt.conf.d/02compressindex
-runtest "true"
+msgmsg 'no Release at all'
+EXPECT="Ign http://localhost:8080 unstable InRelease
+  404  Not Found
+Ign http://localhost:8080 unstable Release
+  404  Not Found
+Hit http://localhost:8080 unstable/main Sources
+Hit http://localhost:8080 unstable/main amd64 Packages
+Hit http://localhost:8080 unstable/main Translation-en
+Reading package lists...
+W: The repository 'http://localhost:8080 unstable Release' does not have a Release file. This is deprecated, please contact the owner of the repository."
+find aptarchive -name '*Release*' -delete
+echo 'Acquire::GzipIndexes "0";
+Acquire::PDiffs "0";' > rootdir/etc/apt/apt.conf.d/02compressindex
+runtest 'warning'
+echo 'Acquire::GzipIndexes "1";
+Acquire::PDiffs "0";' > rootdir/etc/apt/apt.conf.d/02compressindex
+runtest 'warning'
diff --git a/test/integration/test-apt-update-not-modified b/test/integration/test-apt-update-not-modified
new file mode 100755 (executable)
index 0000000..2dc56e7
--- /dev/null
@@ -0,0 +1,45 @@
+#!/bin/sh
+set -e
+
+TESTDIR=$(readlink -f $(dirname $0))
+. $TESTDIR/framework
+
+setupenvironment
+configarchitecture 'amd64' 'i386'
+
+insertpackage 'unstable' 'apt' 'all' '1.0'
+
+setupaptarchive --no-update
+
+methodtest() {
+       msgmsg 'Test with' "$1"
+       rm -rf rootdir/var/lib/apt/lists
+       # get our cache populated
+       testsuccess aptget update
+       listcurrentlistsdirectory > listsdir.lst
+
+       # hit again with a good cache
+       testsuccessequal "Hit $1 unstable InRelease
+Reading package lists..." aptget update
+       testfileequal 'listsdir.lst' "$(listcurrentlistsdirectory)"
+
+       # drop an architecture, which means the file should be gone now
+       configarchitecture 'i386'
+       sed '/_binary-amd64_Packages/ d' listsdir.lst > listsdir-without-amd64.lst
+       testsuccessequal "Hit $1 unstable InRelease
+Reading package lists..." aptget update
+       testfileequal 'listsdir-without-amd64.lst' "$(listcurrentlistsdirectory)"
+
+       # readd arch so its downloaded again
+       configarchitecture 'amd64' 'i386'
+       testsuccessequal "Hit $1 unstable InRelease
+Get:1 $1 unstable/main amd64 Packages [$(stat -c '%s' 'aptarchive/dists/unstable/main/binary-amd64/Packages.gz') B]
+Reading package lists..." aptget update
+       testfileequal 'listsdir.lst' "$(listcurrentlistsdirectory)"
+}
+
+changetowebserver
+methodtest 'http://localhost:8080'
+
+changetohttpswebserver
+methodtest 'https://localhost:4433'
index b325733ac460d502e182c516aebb142253ef0fa2..f028ac0c771bcdf1b3dea75f4554ff9bea2e1ef9 100755 (executable)
@@ -59,6 +59,13 @@ testsetup() {
 }
 
 testsetup 'file'
+
 changetowebserver
+webserverconfig 'aptwebserver::support::modified-since' 'false' "$1"
+webserverconfig 'aptwebserver::support::last-modified' 'false' "$1"  # curl is clever and sees hits here also
+
 testsetup 'http'
 
+changetohttpswebserver
+
+testsetup 'https'
index 384c8b1132042d584e47aca394ee8ae659eff146..ca2378c196deab1b99164ff70e37d16c46e6d9c8 100755 (executable)
@@ -22,9 +22,6 @@ testrun() {
 
        # check that I-M-S header is kept in redirections
        testsuccessequal "Hit $1 unstable InRelease
-Hit $1 unstable/main Sources
-Hit $1 unstable/main amd64 Packages
-Hit $1 unstable/main Translation-en
 Reading package lists..." aptget update
 
        msgtest 'Test redirection works in' 'package download'
index 4de07f1ad3d5c92c805cdbe1e771d840ceccd234..5e759e50e4bc477482a44147a5090a4a856fb239 100755 (executable)
@@ -14,16 +14,7 @@ changetowebserver
 PKGFILE="${TESTDIR}/$(echo "$(basename $0)" | sed 's#^test-#Packages-#')"
 
 wasmergeused() {
-       msgtest 'Test for successful execution of' "$*"
-       local OUTPUT=$(mktemp)
-       addtrap "rm $OUTPUT;"
-       if aptget update "$@" >${OUTPUT} 2>&1; then
-               msgpass
-       else
-               echo
-               cat $OUTPUT
-               msgfail
-       fi
+       testsuccess aptget update "$@"
 
        msgtest 'No intermediate patch files' 'still exist'
        local EDS="$(find rootdir/var/lib/apt/lists -name '*.ed' -o -name '*.ed.*')"
@@ -36,7 +27,7 @@ wasmergeused() {
        fi
 
        msgtest 'Check if the right pdiff merger was used'
-       if grep -q '^pkgAcqIndexMergeDiffs::Done(): rred' $OUTPUT; then
+       if grep -q '^pkgAcqIndexMergeDiffs::Done(): rred' rootdir/tmp/testsuccess.output; then
                if echo "$*" | grep -q -- '-o Acquire::PDiffs::Merge=1'; then
                        msgpass
                else
@@ -96,6 +87,8 @@ SHA256-Patches:
        msgmsg "Testcase: index is already up-to-date: $*"
        find rootdir/var/lib/apt/lists -name '*diff_Index' -type f -delete
        testsuccess aptget update "$@"
+       testequal 'Hit http://localhost:8080  InRelease
+Reading package lists...' aptget update "$@" -o Debug::Acquire::Transaction=0 -o Debug::pkgAcquire::Diffs=0
        testsuccessequal "$(cat ${PKGFILE}-new)
 " aptcache show apt newstuff
 
index 86d5c06f097c6d1e9c639b4257830601246298be..6a411e24ea1e18a5fe11bf87c4ef0698f0572f07 100644 (file)
@@ -96,9 +96,12 @@ static void addFileHeaders(std::list<std::string> &headers, FileFd &data)/*{{{*/
       contentlength << "Content-Length: " << data.FileSize();
       headers.push_back(contentlength.str());
    }
-   std::string lastmodified("Last-Modified: ");
-   lastmodified.append(TimeRFC1123(data.ModificationTime()));
-   headers.push_back(lastmodified);
+   if (_config->FindB("aptwebserver::support::last-modified", true) == true)
+   {
+      std::string lastmodified("Last-Modified: ");
+      lastmodified.append(TimeRFC1123(data.ModificationTime()));
+      headers.push_back(lastmodified);
+   }
 }
                                                                        /*}}}*/
 static void addDataHeaders(std::list<std::string> &headers, std::string &data)/*{{{*/