]> git.saurik.com Git - apt.git/commitdiff
* apt-pkg/acquire-item.cc:
authorMichael Vogt <michael.vogt@ubuntu.com>
Fri, 3 Aug 2007 08:22:24 +0000 (10:22 +0200)
committerMichael Vogt <michael.vogt@ubuntu.com>
Fri, 3 Aug 2007 08:22:24 +0000 (10:22 +0200)
  - remove zero size files on I-M-S hit
* methods/https.cc:
  - only send LastModified if we actually have one
  - send range request with if-range
  - delete failed downloads

1  2 
apt-pkg/acquire-item.cc
debian/changelog
methods/https.cc

diff --combined apt-pkg/acquire-item.cc
index 6d71b6ea34187ce1822b2076191d74a522260c51,bc6d8cead6e1416644df03b401cd7ddc11ae8e1d..4f5d644ab216bbd0523044b072a4122ec9aca842
@@@ -13,6 -13,9 +13,6 @@@
     ##################################################################### */
                                                                        /*}}}*/
  // Include Files                                                      /*{{{*/
 -#ifdef __GNUG__
 -#pragma implementation "apt-pkg/acquire-item.h"
 -#endif
  #include <apt-pkg/acquire-item.h>
  #include <apt-pkg/configuration.h>
  #include <apt-pkg/sourcelist.h>
@@@ -21,8 -24,6 +21,8 @@@
  #include <apt-pkg/strutl.h>
  #include <apt-pkg/fileutl.h>
  #include <apt-pkg/md5.h>
 +#include <apt-pkg/sha1.h>
 +#include <apt-pkg/tagfile.h>
  
  #include <apti18n.h>
      
@@@ -30,7 -31,6 +30,7 @@@
  #include <unistd.h>
  #include <errno.h>
  #include <string>
 +#include <sstream>
  #include <stdio.h>
                                                                        /*}}}*/
  
@@@ -100,8 -100,7 +100,8 @@@ void pkgAcquire::Item::Done(string Mess
  {
     // We just downloaded something..
     string FileName = LookupTag(Message,"Filename");
 -   if (Complete == false && FileName == DestFile)
 +   // we only inform the Log class if it was actually not a local thing
 +   if (Complete == false && !Local && FileName == DestFile)
     {
        if (Owner->Log != 0)
         Owner->Log->Fetched(Size,atoi(LookupTag(Message,"Resume-Point","0").c_str()));
@@@ -132,432 -131,14 +132,432 @@@ void pkgAcquire::Item::Rename(string Fr
  }
                                                                        /*}}}*/
  
 +
 +// AcqDiffIndex::AcqDiffIndex - Constructor                   
 +// ---------------------------------------------------------------------
 +/* Get the DiffIndex file first and see if there are patches availabe 
 + * If so, create a pkgAcqIndexDiffs fetcher that will get and apply the
 + * patches. If anything goes wrong in that process, it will fall back to
 + * the original packages file
 + */
 +pkgAcqDiffIndex::pkgAcqDiffIndex(pkgAcquire *Owner,
 +                               string URI,string URIDesc,string ShortDesc,
 +                               string ExpectedMD5)
 +   : Item(Owner), RealURI(URI), ExpectedMD5(ExpectedMD5), Description(URIDesc)
 +{
 +   
 +   Debug = _config->FindB("Debug::pkgAcquire::Diffs",false);
 +
 +   Desc.Description = URIDesc + "/DiffIndex";
 +   Desc.Owner = this;
 +   Desc.ShortDesc = ShortDesc;
 +   Desc.URI = URI + ".diff/Index";
 +
 +   DestFile = _config->FindDir("Dir::State::lists") + "partial/";
 +   DestFile += URItoFileName(URI) + string(".DiffIndex");
 +
 +   if(Debug)
 +      std::clog << "pkgAcqDiffIndex: " << Desc.URI << std::endl;
 +
 +   // look for the current package file
 +   CurrentPackagesFile = _config->FindDir("Dir::State::lists");
 +   CurrentPackagesFile += URItoFileName(RealURI);
 +
 +   // FIXME: this file:/ check is a hack to prevent fetching
 +   //        from local sources. this is really silly, and
 +   //        should be fixed cleanly as soon as possible
 +   if(!FileExists(CurrentPackagesFile) || 
 +      Desc.URI.substr(0,strlen("file:/")) == "file:/")
 +   {
 +      // we don't have a pkg file or we don't want to queue
 +      if(Debug)
 +       std::clog << "No index file, local or canceld by user" << std::endl;
 +      Failed("", NULL);
 +      return;
 +   }
 +
 +   if(Debug) 
 +      std::clog << "pkgAcqIndexDiffs::pkgAcqIndexDiffs(): " 
 +              << CurrentPackagesFile << std::endl;
 +   
 +   QueueURI(Desc);
 +
 +}
 +
 +// AcqIndex::Custom600Headers - Insert custom request headers         /*{{{*/
 +// ---------------------------------------------------------------------
 +/* The only header we use is the last-modified header. */
 +string pkgAcqDiffIndex::Custom600Headers()
 +{
 +   string Final = _config->FindDir("Dir::State::lists");
 +   Final += URItoFileName(RealURI) + string(".IndexDiff");
 +   
 +   if(Debug)
 +      std::clog << "Custom600Header-IMS: " << Final << std::endl;
 +
 +   struct stat Buf;
 +   if (stat(Final.c_str(),&Buf) != 0)
 +      return "\nIndex-File: true";
 +   
 +   return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
 +}
 +
 +
 +bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile)
 +{
 +   if(Debug)
 +      std::clog << "pkgAcqIndexDiffs::ParseIndexDiff() " << IndexDiffFile 
 +              << std::endl;
 +
 +   pkgTagSection Tags;
 +   string ServerSha1;
 +   vector<DiffInfo> available_patches;
 +   
 +   FileFd Fd(IndexDiffFile,FileFd::ReadOnly);
 +   pkgTagFile TF(&Fd);
 +   if (_error->PendingError() == true)
 +      return false;
 +
 +   if(TF.Step(Tags) == true)
 +   {
 +      string local_sha1;
 +      bool found = false;
 +      DiffInfo d;
 +      string size;
 +
 +      string tmp = Tags.FindS("SHA1-Current");
 +      std::stringstream ss(tmp);
 +      ss >> ServerSha1;
 +
 +      FileFd fd(CurrentPackagesFile, FileFd::ReadOnly);
 +      SHA1Summation SHA1;
 +      SHA1.AddFD(fd.Fd(), fd.Size());
 +      local_sha1 = string(SHA1.Result());
 +
 +      if(local_sha1 == ServerSha1) 
 +      {
 +       // we have the same sha1 as the server
 +       if(Debug)
 +          std::clog << "Package file is up-to-date" << std::endl;
 +       // set found to true, this will queue a pkgAcqIndexDiffs with
 +       // a empty availabe_patches
 +       found = true;
 +      } 
 +      else 
 +      {
 +       if(Debug)
 +          std::clog << "SHA1-Current: " << ServerSha1 << std::endl;
 +
 +       // check the historie and see what patches we need
 +       string history = Tags.FindS("SHA1-History");     
 +       std::stringstream hist(history);
 +       while(hist >> d.sha1 >> size >> d.file) 
 +       {
 +          d.size = atoi(size.c_str());
 +          // read until the first match is found
 +          if(d.sha1 == local_sha1) 
 +             found=true;
 +          // from that point on, we probably need all diffs
 +          if(found) 
 +          {
 +             if(Debug)
 +                std::clog << "Need to get diff: " << d.file << std::endl;
 +             available_patches.push_back(d);
 +          }
 +       }
 +      }
 +
 +      // we have something, queue the next diff
 +      if(found) 
 +      {
 +       // queue the diffs
 +       unsigned int last_space = Description.rfind(" ");
 +       if(last_space != string::npos)
 +          Description.erase(last_space, Description.size()-last_space);
 +       new pkgAcqIndexDiffs(Owner, RealURI, Description, Desc.ShortDesc,
 +                            ExpectedMD5, available_patches);
 +       Complete = false;
 +       Status = StatDone;
 +       Dequeue();
 +       return true;
 +      }
 +   }
 +   
 +   // Nothing found, report and return false
 +   // Failing here is ok, if we return false later, the full
 +   // IndexFile is queued
 +   if(Debug)
 +      std::clog << "Can't find a patch in the index file" << std::endl;
 +   return false;
 +}
 +
 +void pkgAcqDiffIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
 +{
 +   if(Debug)
 +      std::clog << "pkgAcqDiffIndex failed: " << Desc.URI << std::endl
 +              << "Falling back to normal index file aquire" << std::endl;
 +
 +   new pkgAcqIndex(Owner, RealURI, Description, Desc.ShortDesc, 
 +                 ExpectedMD5);
 +
 +   Complete = false;
 +   Status = StatDone;
 +   Dequeue();
 +}
 +
 +void pkgAcqDiffIndex::Done(string Message,unsigned long Size,string Md5Hash,
 +                         pkgAcquire::MethodConfig *Cnf)
 +{
 +   if(Debug)
 +      std::clog << "pkgAcqDiffIndex::Done(): " << Desc.URI << std::endl;
 +
 +   Item::Done(Message,Size,Md5Hash,Cnf);
 +
 +   string FinalFile;
 +   FinalFile = _config->FindDir("Dir::State::lists")+URItoFileName(RealURI);
 +
 +   // sucess in downloading the index
 +   // rename the index
 +   FinalFile += string(".IndexDiff");
 +   if(Debug)
 +      std::clog << "Renaming: " << DestFile << " -> " << FinalFile 
 +              << std::endl;
 +   Rename(DestFile,FinalFile);
 +   chmod(FinalFile.c_str(),0644);
 +   DestFile = FinalFile;
 +
 +   if(!ParseDiffIndex(DestFile))
 +      return Failed("", NULL);
 +
 +   Complete = true;
 +   Status = StatDone;
 +   Dequeue();
 +   return;
 +}
 +
 +
 +
 +// AcqIndexDiffs::AcqIndexDiffs - Constructor                 
 +// ---------------------------------------------------------------------
 +/* The package diff is added to the queue. one object is constructed
 + * for each diff and the index
 + */
 +pkgAcqIndexDiffs::pkgAcqIndexDiffs(pkgAcquire *Owner,
 +                                 string URI,string URIDesc,string ShortDesc,
 +                                 string ExpectedMD5, vector<DiffInfo> diffs)
 +   : Item(Owner), RealURI(URI), ExpectedMD5(ExpectedMD5), 
 +     available_patches(diffs)
 +{
 +   
 +   DestFile = _config->FindDir("Dir::State::lists") + "partial/";
 +   DestFile += URItoFileName(URI);
 +
 +   Debug = _config->FindB("Debug::pkgAcquire::Diffs",false);
 +
 +   Description = URIDesc;
 +   Desc.Owner = this;
 +   Desc.ShortDesc = ShortDesc;
 +
 +   if(available_patches.size() == 0) 
 +   {
 +      // we are done (yeah!)
 +      Finish(true);
 +   }
 +   else
 +   {
 +      // get the next diff
 +      State = StateFetchDiff;
 +      QueueNextDiff();
 +   }
 +}
 +
 +
 +void pkgAcqIndexDiffs::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
 +{
 +   if(Debug)
 +      std::clog << "pkgAcqIndexDiffs failed: " << Desc.URI << std::endl
 +              << "Falling back to normal index file aquire" << std::endl;
 +   new pkgAcqIndex(Owner, RealURI, Description,Desc.ShortDesc, 
 +                 ExpectedMD5);
 +   Finish();
 +}
 +
 +
 +// helper that cleans the item out of the fetcher queue
 +void pkgAcqIndexDiffs::Finish(bool allDone)
 +{
 +   // we restore the original name, this is required, otherwise
 +   // the file will be cleaned
 +   if(allDone) 
 +   {
 +      DestFile = _config->FindDir("Dir::State::lists");
 +      DestFile += URItoFileName(RealURI);
 +
 +      // do the final md5sum checking
 +      MD5Summation sum;
 +      FileFd Fd(DestFile, FileFd::ReadOnly);
 +      sum.AddFD(Fd.Fd(), Fd.Size());
 +      Fd.Close();
 +      string MD5 = (string)sum.Result();
 +
 +      if (!ExpectedMD5.empty() && MD5 != ExpectedMD5)
 +      {
 +       Status = StatAuthError;
 +       ErrorText = _("MD5Sum mismatch");
 +       Rename(DestFile,DestFile + ".FAILED");
 +       Dequeue();
 +       return;
 +      }
 +
 +      // this is for the "real" finish
 +      Complete = true;
 +      Status = StatDone;
 +      Dequeue();
 +      if(Debug)
 +       std::clog << "\n\nallDone: " << DestFile << "\n" << std::endl;
 +      return;
 +   }
 +
 +   if(Debug)
 +      std::clog << "Finishing: " << Desc.URI << std::endl;
 +   Complete = false;
 +   Status = StatDone;
 +   Dequeue();
 +   return;
 +}
 +
 +
 +
 +bool pkgAcqIndexDiffs::QueueNextDiff()
 +{
 +
 +   // calc sha1 of the just patched file
 +   string FinalFile = _config->FindDir("Dir::State::lists");
 +   FinalFile += URItoFileName(RealURI);
 +
 +   FileFd fd(FinalFile, FileFd::ReadOnly);
 +   SHA1Summation SHA1;
 +   SHA1.AddFD(fd.Fd(), fd.Size());
 +   string local_sha1 = string(SHA1.Result());
 +   if(Debug)
 +      std::clog << "QueueNextDiff: " 
 +              << FinalFile << " (" << local_sha1 << ")"<<std::endl;
 +
 +   // remove all patches until the next matching patch is found
 +   // this requires the Index file to be ordered
 +   for(vector<DiffInfo>::iterator I=available_patches.begin();
 +       available_patches.size() > 0 && 
 +        I != available_patches.end() &&
 +        (*I).sha1 != local_sha1; 
 +       I++) 
 +   {
 +      available_patches.erase(I);
 +   }
 +
 +   // error checking and falling back if no patch was found
 +   if(available_patches.size() == 0) 
 +   { 
 +      Failed("", NULL);
 +      return false;
 +   }
 +
 +   // queue the right diff
 +   Desc.URI = string(RealURI) + ".diff/" + available_patches[0].file + ".gz";
 +   Desc.Description = Description + " " + available_patches[0].file + string(".pdiff");
 +   DestFile = _config->FindDir("Dir::State::lists") + "partial/";
 +   DestFile += URItoFileName(RealURI + ".diff/" + available_patches[0].file);
 +
 +   if(Debug)
 +      std::clog << "pkgAcqIndexDiffs::QueueNextDiff(): " << Desc.URI << std::endl;
 +   
 +   QueueURI(Desc);
 +
 +   return true;
 +}
 +
 +
 +
 +void pkgAcqIndexDiffs::Done(string Message,unsigned long Size,string Md5Hash,
 +                          pkgAcquire::MethodConfig *Cnf)
 +{
 +   if(Debug)
 +      std::clog << "pkgAcqIndexDiffs::Done(): " << Desc.URI << std::endl;
 +
 +   Item::Done(Message,Size,Md5Hash,Cnf);
 +
 +   string FinalFile;
 +   FinalFile = _config->FindDir("Dir::State::lists")+URItoFileName(RealURI);
 +
 +   // sucess in downloading a diff, enter ApplyDiff state
 +   if(State == StateFetchDiff) 
 +   {
 +
 +      if(Debug)
 +       std::clog << "Sending to gzip method: " << FinalFile << std::endl;
 +
 +      string FileName = LookupTag(Message,"Filename");
 +      State = StateUnzipDiff;
 +      Local = true;
 +      Desc.URI = "gzip:" + FileName;
 +      DestFile += ".decomp";
 +      QueueURI(Desc);
 +      Mode = "gzip";
 +      return;
 +   } 
 +
 +   // sucess in downloading a diff, enter ApplyDiff state
 +   if(State == StateUnzipDiff) 
 +   {
 +
 +      // rred excepts the patch as $FinalFile.ed
 +      Rename(DestFile,FinalFile+".ed");
 +
 +      if(Debug)
 +       std::clog << "Sending to rred method: " << FinalFile << std::endl;
 +
 +      State = StateApplyDiff;
 +      Local = true;
 +      Desc.URI = "rred:" + FinalFile;
 +      QueueURI(Desc);
 +      Mode = "rred";
 +      return;
 +   } 
 +
 +
 +   // success in download/apply a diff, queue next (if needed)
 +   if(State == StateApplyDiff)
 +   {
 +      // remove the just applied patch
 +      available_patches.erase(available_patches.begin());
 +
 +      // move into place
 +      if(Debug) 
 +      {
 +       std::clog << "Moving patched file in place: " << std::endl
 +                 << DestFile << " -> " << FinalFile << std::endl;
 +      }
 +      Rename(DestFile,FinalFile);
 +      chmod(FinalFile.c_str(),0644);
 +
 +      // see if there is more to download
 +      if(available_patches.size() > 0) {
 +       new pkgAcqIndexDiffs(Owner, RealURI, Description, Desc.ShortDesc,
 +                            ExpectedMD5, available_patches);
 +       return Finish();
 +      } else 
 +       return Finish(true);
 +   }
 +}
 +
 +
  // AcqIndex::AcqIndex - Constructor                                   /*{{{*/
  // ---------------------------------------------------------------------
  /* The package file is added to the queue and a second class is 
     instantiated to fetch the revision file */   
  pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner,
                         string URI,string URIDesc,string ShortDesc,
 -                       string ExpectedMD5, string comprExt) :
 -   Item(Owner), RealURI(URI), ExpectedMD5(ExpectedMD5)
 +                       string ExpectedMD5, string comprExt)
 +   Item(Owner), RealURI(URI), ExpectedMD5(ExpectedMD5)
  {
     Decompression = false;
     Erase = false;
@@@ -613,15 -194,9 +613,15 @@@ void pkgAcqIndex::Failed(string Message
        Complete = false;
        Dequeue();
        return;
 +   } 
 +   
 +   // on decompression failure, remove bad versions in partial/
 +   if(Decompression && Erase) {
 +      string s = _config->FindDir("Dir::State::lists") + "partial/";
 +      s += URItoFileName(RealURI);
 +      unlink(s.c_str());
     }
  
 -   
     Item::Failed(Message,Cnf);
  }
  
@@@ -688,8 -263,10 +688,10 @@@ void pkgAcqIndex::Done(string Message,u
     {
        // The files timestamp matches
        if (StringToBool(LookupTag(Message,"Alt-IMS-Hit"),false) == true)
+       {
+        unlink(FileName.c_str());
         return;
+       }
        Decompression = true;
        Local = true;
        DestFile += ".decomp";
     
     // The files timestamp matches
     if (StringToBool(LookupTag(Message,"IMS-Hit"),false) == true)
+    {
+       unlink(FileName.c_str());
        return;
+    }
  
     if (FileName == DestFile)
        Erase = true;
     Mode = decompProg;
  }
  
 +// AcqIndexTrans::pkgAcqIndexTrans - Constructor                      /*{{{*/
 +// ---------------------------------------------------------------------
 +/* The Translation file is added to the queue */
 +pkgAcqIndexTrans::pkgAcqIndexTrans(pkgAcquire *Owner,
 +                          string URI,string URIDesc,string ShortDesc) :
 +                      pkgAcqIndex(Owner, URI, URIDesc, ShortDesc, "", "")
 +{
 +}
 +
 +                                                                      /*}}}*/
 +// AcqIndexTrans::Failed - Silence failure messages for missing files /*{{{*/
 +// ---------------------------------------------------------------------
 +/* */
 +void pkgAcqIndexTrans::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
 +{
 +   if (Cnf->LocalOnly == true || 
 +       StringToBool(LookupTag(Message,"Transient-Failure"),false) == false)
 +   {      
 +      // Ignore this
 +      Status = StatDone;
 +      Complete = false;
 +      Dequeue();
 +      return;
 +   }
 +   
 +   Item::Failed(Message,Cnf);
 +}
 +                                                                      /*}}}*/
 +
  pkgAcqMetaSig::pkgAcqMetaSig(pkgAcquire *Owner,
                             string URI,string URIDesc,string ShortDesc,
                             string MetaIndexURI, string MetaIndexURIDesc,
     DestFile = _config->FindDir("Dir::State::lists") + "partial/";
     DestFile += URItoFileName(URI);
  
 -   // remove any partial downloaded sig-file. it may confuse proxies
 -   // and is too small to warrant a partial download anyway
 +   // remove any partial downloaded sig-file in partial/. 
 +   // it may confuse proxies and is too small to warrant a 
 +   // partial download anyway
     unlink(DestFile.c_str());
  
     // Create the item
@@@ -844,22 -394,17 +849,22 @@@ void pkgAcqMetaSig::Done(string Message
                                                                        /*}}}*/
  void pkgAcqMetaSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
  {
 +   string Final = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI);
  
     // if we get a network error we fail gracefully
 -   if(LookupTag(Message,"FailReason") == "Timeout" || 
 -      LookupTag(Message,"FailReason") == "TmpResolveFailure" ||
 -      LookupTag(Message,"FailReason") == "ConnectionRefused") {
 +   if(Status == StatTransientNetworkError)
 +   {
        Item::Failed(Message,Cnf);
 +      // move the sigfile back on transient network failures 
 +      if(FileExists(DestFile))
 +       Rename(DestFile,Final);
 +
 +      // set the status back to , Item::Failed likes to reset it
 +      Status = pkgAcquire::Item::StatTransientNetworkError;
        return;
     }
  
     // Delete any existing sigfile when the acquire failed
 -   string Final = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI);
     unlink(Final.c_str());
  
     // queue a pkgAcqMetaIndex with no sigfile
@@@ -884,8 -429,8 +889,8 @@@ pkgAcqMetaIndex::pkgAcqMetaIndex(pkgAcq
                                 string SigFile,
                                 const vector<struct IndexTarget*>* IndexTargets,
                                 indexRecords* MetaIndexParser) :
 -   Item(Owner), RealURI(URI), SigFile(SigFile), AuthPass(false),
 -   MetaIndexParser(MetaIndexParser), IndexTargets(IndexTargets), IMSHit(false)
 +   Item(Owner), RealURI(URI), SigFile(SigFile), IndexTargets(IndexTargets),
 +   MetaIndexParser(MetaIndexParser), AuthPass(false), IMSHit(false)
  {
     DestFile = _config->FindDir("Dir::State::lists") + "partial/";
     DestFile += URItoFileName(URI);
@@@ -980,18 -525,18 +985,18 @@@ void pkgAcqMetaIndex::RetrievalDone(str
  
     // see if the download was a IMSHit
     IMSHit = StringToBool(LookupTag(Message,"IMS-Hit"),false);
     Complete = true;
  
     string FinalFile = _config->FindDir("Dir::State::lists");
     FinalFile += URItoFileName(RealURI);
  
-    // The files timestamp matches
-    if (StringToBool(LookupTag(Message,"IMS-Hit"),false) == false)
-    {
-       // Move it into position
+    // If we get a IMS hit we can remove the empty file in partial
+    // othersie we move the file in place
+    if (IMSHit)
+       unlink(DestFile.c_str());
+    else
        Rename(DestFile,FinalFile);
-    }
     chmod(FinalFile.c_str(),0644);
     DestFile = FinalFile;
  }
@@@ -1062,14 -607,9 +1067,14 @@@ void pkgAcqMetaIndex::QueueIndexes(boo
           }
        }
        
 -      // Queue Packages file
 -      new pkgAcqIndex(Owner, (*Target)->URI, (*Target)->Description,
 -                      (*Target)->ShortDesc, ExpectedIndexMD5);
 +      // Queue Packages file (either diff or full packages files, depending
 +      // on the users option)
 +      if(_config->FindB("Acquire::PDiffs",true) == true) 
 +       new pkgAcqDiffIndex(Owner, (*Target)->URI, (*Target)->Description,
 +                           (*Target)->ShortDesc, ExpectedIndexMD5);
 +      else 
 +       new pkgAcqIndex(Owner, (*Target)->URI, (*Target)->Description,
 +                          (*Target)->ShortDesc, ExpectedIndexMD5);
     }
  }
  
diff --combined debian/changelog
index 75db9cc721e7a56ae89748b6046a77c531d29a02,06cede5313f7793702e86b9f2de7b9be5bdc11f7..b9824f84a9e6920fda6726652913d09788b525c8
 -apt (0.6.46.5) UNRELEASED; urgency=low
 +apt (0.7.7) UNRELEASED; urgency=low
  
 +  * apt-inst/contrib/extracttar.cc:
 +    - fix fd leak for zero size files (thanks to Bill Broadley for
 +      reporting this bug)
++  * apt-pkg/acquire-item.cc:
++    - remove zero size files on I-M-S hit
++  * methods/https.cc:
++    - only send LastModified if we actually have one
++    - send range request with if-range 
++    - delete failed downloads
 +
 + -- Michael Vogt <michael.vogt@ubuntu.com>  Thu, 02 Aug 2007 11:55:54 +0200
 +
 +apt (0.7.6) unstable; urgency=low
 +
 +  * Applied patch from Aurelien Jarno <aurel32@debian.org> to fix wrong
 +    directory downloading on non-linux architectures (closes: #435597)
 +
 + -- Otavio Salvador <otavio@debian.org>  Wed, 01 Aug 2007 19:49:51 -0300
 +
 +apt (0.7.5) unstable; urgency=low
 +
 +  [ Otavio Salvador ]
 +  * Applied patch from Guillem Jover <guillem@debian.org> to use
 +    dpkg-architecture to get the host architecture (closes: #407187)
 +  * Applied patch from Guillem Jover <guillem@debian.org> to add
 +    support to add lzma support (closes: #408201)
 +
 +  [ Michael Vogt ]
 +  * apt-pkg/depcache.cc:
 +    - support a list of sections for:
 +      APT::Install-Recommends-Sections
 +      APT::Never-MarkAuto-Sections
 +  * methods/makefile:
 +    - install lzma symlink method (for full lzma support)
 +  * debian/control:
 +    - suggest "lzma"
 +
 + -- Otavio Salvador <otavio@ossystems.com.br>  Wed, 25 Jul 2007 20:16:46 -0300
 +
 +apt (0.7.4) unstable; urgency=low
 +
 +  [ Michael Vogt ]
 +  * cmdline/apt-get.cc:
 +    - fix in the task-install code regexp (thanks to Adam Conrad and
 +      Colin Watson)
 +    - support task removal too: apt-get remove taskname^
 +      (thanks to Matt Zimmerman reporting this problem)
 +
 +  [ Otavio Salvador ]
 +  * Fix a typo on 0.7.3 changelog entry about g++ (7.3 to 4.3)
 +  * Fix compilation warnings:
 +    - apt-pkg/contrib/configuration.cc: wrong argument type;
 +    - apt-pkg/deb/dpkgpm.cc: wrong signess;
 +    - apt-pkg-acquire-item.cc: wrong signess and orderned initializers;
 +    - methods/https.cc:
 +      - type conversion;
 +      - unused variable;
 +      - changed SetupProxy() method to void;
 +  * Simplified HttpMethod::Fetch on http.cc removing Tail variable;
 +  * Fix pipeline handling on http.cc (closes: #413324)
 +  * Fix building to properly support binNMUs. Thanks to Daniel Schepler
 +    <schepler@math.unipd.it> by the patch (closes: #359634)
 +  * Fix example for Install-{Recommends,Suggests} options on
 +    configure-index example file. Thanks to Peter Eisentraut
 +    <peter_e@gmx.net> by the patch (closes: #432223)
 +
 +  [ Christian Perrier ]
 +  * Basque translation update. Closes: ##423766
 +  * Unfuzzy formerly complete translations
 +  * French translation update
 +  * Re-generate PO(T) files
 +  * Spanish translation update
 +  * Swedish translation update
 +
 + -- Otavio Salvador <otavio@debian.org>  Tue, 24 Jul 2007 09:55:50 -0300
 +
 +apt (0.7.3) unstable; urgency=low
 +
 +  * fixed compile errors with g++ 4.3 (thanks to 
 +    Daniel Burrows, closes: #429378)
 +  * fixes in the auto-mark code (thanks to Daniel
 +    Burrows)
 +  * fix FTFBFS by changing build-depends to
 +    libcurl4-gnutls-dev (closes: #428363)
 +  * cmdline/apt-get.cc:
 +    - fix InstallTask code when a pkgRecord ends 
 +      with a single '\n' (thanks to Soren Hansen for reporting)
 +  * merged from Christian Perrier:
 +        * vi.po: completed to 532t, again. Closes: #429899
 +        * gl.po: completed to 532t. Closes: #429506
 +        * vi.po: completed to 532t. Closes: #428672
 +        * Update all PO and the POT. Gives 514t14f4u for formerly
 +          complete translations
 +        * fr.po: completed to 532t
 +        * ku.po, uk.po, LINGUAS: reintegrate those translations
 +          which disappeared from the BZR repositories
 +
 + -- Michael Vogt <mvo@debian.org>  Sun, 01 Jul 2007 12:31:29 +0200
 +
 +apt (0.7.2-0.1) unstable; urgency=low
 +
 +  * Non-maintainer upload.
 +  * Build-depend on libcurl4-gnutls-dev instead of the obsolete
 +    libcurl3-gnutls-dev.  Closes: #428363.
 +
 + -- Steve Langasek <vorlon@debian.org>  Thu, 28 Jun 2007 18:46:53 -0700
 +
 +apt (0.7.2) unstable; urgency=low
 +  
 +  * merged the debian/experimental changes back
 +    into the debian/sid branch
 +  * merged from Christian Perrier:
 +    * mr.po: New Marathi translation  Closes: #416806
 +    * zh_CN.po: Updated by Eric Pareja  Closes: #416822
 +    * tl.po: Updated by Eric Pareja   Closes: #416638
 +    * gl.po: Updated by Jacobo Tarrio
 +           Closes: #412828
 +    * da.po: Updated by Claus Hindsgaul
 +           Closes: #409483
 +    * fr.po: Remove a non-breakable space for usability
 +           issues. Closes: #408877
 +    * ru.po: Updated Russian translation. Closes: #405476
 +    * *.po: Unfuzzy after upstream typo corrections
 +  * buildlib/archtable:
 +    - added support for sh3/sh4 (closes: #424870)
 +    - added support for m32r (closes: #394096)
 +  * buildlib/systemtable:
 +    - added support for lpia
 +  * configure.in:
 +    - check systemtable for architecture mapping too
 +  * fix error in AutocleanInterval, closes: #319339
 +    (thanks to Israel G. Lugo for the patch)
 +  * add "purge" commandline argument, closes: #133421)
 +    (thanks to Julien Danjou for the patch)
 +  * add "purge" commandline argument, closes: #133421)
 +    (thanks to Julien Danjou for the patch)
 +  * fix FTBFS with gcc 4.3, closes: #417090
 +    (thanks to Martin Michlmayr for the patch)
 +  * add --dsc-only option, thanks to K. Richard Pixley
 +  * Removed the more leftover #pragma interface/implementation
 +    closes: #306937 (thanks to Andreas Henriksson for the patch)
 +  
 + -- Michael Vogt <mvo@debian.org>  Wed, 06 Jun 2007 23:19:50 +0200
 +
 +apt (0.7.1) experimental; urgency=low
 +
 +  * ABI library name change because its build against
 +    new glibc
 +  * implement SourceVer() in pkgRecords 
 +     (thanks to Daniel Burrows for the patch!)
    * apt-pkg/algorithm.cc:
      - use clog for all debugging
      - only increase the score of installed applications if they 
        are not obsolete 
 +    - fix resolver bug on removal triggered by weak-dependencies 
 +      with or-groups
 +  * methods/http.cc:
 +    - send apt version in User-Agent
 +  * apt-pkg/deb/debrecords.cc:
 +    - fix SHA1Hash() return value
 +  * apt-pkg/cdrom.cc:
 +    - only unmount if APT::CDROM::NoMount is false
 +  * methods/cdrom.cc:  
 +    - only umount if it was mounted by the method before
 +  * po/gl.po:
 +    - fix error translation that causes trouble to lsb_release
 +  * apt-pkg/acquire-item.cc:
 +    - if decompression of a index fails, delete the index 
 +  * apt-pkg/acquire.{cc,h}:
 +    - deal better with duplicated sources.list entries (avoid
 +      double queuing of  URLs) - this fixes hangs in bzip/gzip
 +  * merged from Christian Perrier:
 +    * mr.po: New Marathi translation  Closes: #416806
 +    * zh_CN.po: Updated by Eric Pareja  Closes: #416822
 +    * tl.po: Updated by Eric Pareja   Closes: #416638
 +    * gl.po: Updated by Jacobo Tarrio
 +             Closes: #412828
 +    * da.po: Updated by Claus Hindsgaul
 +             Closes: #409483
 +    * fr.po: Remove a non-breakable space for usability
 +             issues. Closes: #408877
 +    * ru.po: Updated Russian translation. Closes: #405476
 +    * *.po: Unfuzzy after upstream typo corrections
 +    * vi.po: Updated to 515t. Closes: #426976
 +    * eu.po: Updated to 515t. Closes: #423766
 +    * pt.po: 515t. Closes: #423111
 +    * fr.po: Updated by Christian Perrier
 +    * Update all PO and the POT. Gives 513t2f for formerly
 +      complete translations
 +  * apt-pkg/policy.cc:
 +    - allow multiple packages (thanks to David Foerster)
 +
 + -- Michael Vogt <mvo@debian.org>  Wed,  2 May 2007 13:43:44 +0200
 +
 +apt (0.7.0) experimental; urgency=low
 +
 +  * Package that contains tall the new features
 +  * Removed all #pragma interface/implementation
 +  * Branch that contains tall the new features:
 +  * translated package descriptions
 +  * task install support
 +  * automatic dependency removal (thanks to Daniel Burrows)
 +  * merged support for the new dpkg "Breaks" field 
 +    (thanks to Ian Jackson)
 +  * handle network failures more gracefully on "update"
 +  * support for unattended-upgrades (via unattended-upgrades
 +    package)
 +  * added apt-transport-https method
 +
 + -- Michael Vogt <mvo@debian.org>  Fri, 12 Jan 2007 20:48:07 +0100
 +
 +apt (0.6.46.4-0.1) unstable; urgency=emergency
 +  
 +  * NMU
 +  * Fix broken use of awk in apt-key that caused removal of the wrong keys
 +    from the keyring. Closes: #412572
  
 - -- Michael Vogt <michael.vogt@ubuntu.com>  Mon, 18 Dec 2006 19:39:05 +0100
 + -- Joey Hess <joeyh@debian.org>  Mon, 26 Feb 2007 16:00:22 -0500
  
  apt (0.6.46.4) unstable; urgency=high
  
@@@ -258,53 -52,40 +264,53 @@@ apt (0.6.46.3) unstable; urgency=lo
        messages 
  
    * Merged from Christian Perrier bzr branch:
 -     - ca.po: Updated to 514t
 -     - be.po: Updated to 514t
 -     - it.po: Updated to 514t
 -     - hu.po: Updated to 514t
 -     - zh_TW.po: Updated to 514t
 -     - ar.po: Updated to 293t221u.
 -     - ru.po: Updated to 514t. Closes: #392466
 -     - nb.po: Updated to 514t. Closes: #392466
 -     - pt.po: Updated to 514t. Closes: #393199
 -     - fr.po: One spelling error corrected: s/accèder/accéder
 -     - km.po: Updated to 514t.
 -     - ko.po: Updated to 514t.
 -     - bg.po: Updated to 514t.
 -     - de.po: Updated to 514t.
 -     - en_GB.po: Updated to 514t.
 -
 - -- Michael Vogt <mvo@debian.org>  Thu, 2 Nov 2006 11:37:58 +0100 
 +    - ca.po: Updated to 514t
 +    - be.po: Updated to 514t
 +    - it.po: Updated to 514t
 +    - hu.po: Updated to 514t
 +    - zh_TW.po: Updated to 514t
 +    - ar.po: Updated to 293t221u.
 +    - ru.po: Updated to 514t. Closes: #392466
 +    - nb.po: Updated to 514t. Closes: #392466
 +    - pt.po: Updated to 514t. Closes: #393199
 +    - fr.po: One spelling error corrected: s/accèder/accéder
 +    - km.po: Updated to 514t.
 +    - ko.po: Updated to 514t.
 +    - bg.po: Updated to 514t.
 +    - de.po: Updated to 514t.
 +    - en_GB.po: Updated to 514t.
 +
 + -- Michael Vogt <mvo@debian.org>  Thu,  2 Nov 2006 11:37:58 +0100
  
  apt (0.6.46.2) unstable; urgency=low
  
 +  * debian/control:
 +    - depend on debian-archive-keyring to offer clean upgrade path 
 +      (closes: #386800)
    * Merged from Christian Perrier bzr branch:
      - es.po: Updated to 514t. Closes: #391661
      - da.po: Updated to 514t. Closes: #391424
      - cs.po: Updated. Closes: #391064
      - es.po: Updated to 514t. Closes: #391661
      - da.po: Updated to 514t. Closes: #391424
 -  
 +
   -- Michael Vogt <mvo@debian.org>  Wed, 11 Oct 2006 09:03:15 +0200
  
  apt (0.6.46.1) unstable; urgency=low
  
 +  * merged "install-recommends" branch (ABI break): 
 +    - new "--install-recommends"
 +    - install new recommends on "upgrade" if --install-recommends is 
 +      given
 +    - new "--fix-policy" option to install all packages with unmet
 +      important dependencies (usefull with --install-recommends to
 +      see what not-installed recommends are on the system)
 +    - fix of recommended packages display (only show CandidateVersion
 +      fix or-group handling)
 +  * merged "install-task" branch (use with "apt-get install taskname^")
    * methods/gzip.cc:
      - deal with empty files 
 -  * Applied patch from Daniel Schepler to make apt bin-NMU able.  
 +  * Applied patch from Daniel Schepler to make apt bin-NMU able.
      (closes: bug#359634)
    * rebuild against current g++ because of:
      http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29289
@@@ -392,42 -173,26 +398,42 @@@ apt (0.6.45) unstable; urgency=lo
      * dz.po: New Dzongkha translation: 512t
      * ro.po: Updated to 512t
      * eu.po: Updated
 +    * eu.po: Updated
 +  * fix apt-get dist-upgrade
 +  * fix warning if no /var/lib/apt/extended_states is present
 +  * don't download Translations for deb-src sources.list lines
 +  * apt-pkg/tagfile.cc:
 +    - support not-mmapable files again
  
 - -- Michael Vogt <mvo@debian.org>  Thu, 27 Jul 2006 00:52:05 +0200
 + -- Michael Vogt <michael.vogt@ubuntu.com>  Tue, 25 Jul 2006 11:55:22 +0200
  
 -apt  (0.6.44.2) unstable; urgency=low 
 -  
 -   * apt-pkg/depcache.cc:
 -     - added Debug::pkgDepCache::AutoInstall (thanks to infinity)
 -   * apt-pkg/acquire-item.cc:
 -     - fix missing chmod() in the new aquire code
 -       (thanks to Bastian Blank, Closes: #367425)
 -   * merged from
 -     http://www.perrier.eu.org/debian/packages/d-i/level4/apt-main:
 -     * sk.po: Completed to 512t
 -     * eu.po: Completed to 512t
 -     * fr.po: Completed to 512t
 -     * sv.po: Completed to 512t
 -     * Update all PO and the POT. Gives 506t6f for formerly
 -       complete translations
 -
 - -- Michael Vogt <mvo@debian.org>  Wed, 14 Jun 2006 12:00:57 +0200 
 +apt (0.6.44.2exp1) experimental; urgency=low
 +
 +  * added support for i18n of the package descriptions
 +  * added support for aptitude like auto-install tracking (a HUGE
 +    HUGE thanks to Daniel Burrows who made this possible) 
 +  * synced with the http://people.debian.org/~mvo/bzr/apt/debian-sid branch
 +  * build from http://people.debian.org/~mvo/bzr/apt/debian-experimental
 +
 + -- Michael Vogt <mvo@debian.org>  Mon,  3 Jul 2006 21:50:31 +0200
 +
 +apt (0.6.44.2) unstable; urgency=low
 +
 +  * apt-pkg/depcache.cc:
 +    - added Debug::pkgDepCache::AutoInstall (thanks to infinity)
 +  * apt-pkg/acquire-item.cc:
 +    - fix missing chmod() in the new aquire code 
 +      (thanks to Bastian Blank, Closes: #367425)
 +  * merged from 
 +    http://www.perrier.eu.org/debian/packages/d-i/level4/apt-main:
 +    * sk.po: Completed to 512t
 +    * eu.po: Completed to 512t
 +    * fr.po: Completed to 512t
 +    * sv.po: Completed to 512t
 +    * Update all PO and the POT. Gives 506t6f for formerly
 +      complete translations
 +
 + -- Michael Vogt <mvo@debian.org>  Wed, 14 Jun 2006 12:00:57 +0200
  
  apt (0.6.44.1-0.1) unstable; urgency=low
  
  
  apt (0.6.44.1) unstable; urgency=low
  
 +  * apt-pkg/acquire-item.cc:
 +    - fix reversed logic of the "Acquire::PDiffs" option
    * merged from 
      http://www.perrier.eu.org/debian/packages/d-i/level4/apt-main:
      - po/LINGUAS: added "bg" Closes: #360262
      - po/gl.po: Galician translation update. Closes: #366849
      - po/hu.po: Hungarian translation update. Closes: #365448
      - po/cs.po: Czech translation updated. Closes: #367244
 +  * apt-pkg/contrib/sha256.cc:
 +    - applied patch to fix unaligned access problem. Closes: #367417
 +      (thanks to David Mosberger)
  
   -- Michael Vogt <mvo@debian.org>  Tue, 16 May 2006 21:51:16 +0200
  
  apt (0.6.44) unstable; urgency=low
  
    * apt-pkg/acquire.cc: don't show ETA if it is 0 or absurdely large
 +  * apt-pkg/contrib/sha256.{cc,h},hashes.{cc,h}: support for sha256 
 +    (thanks to Anthony Towns)
 +  * ftparchive/cachedb.{cc,h},writer.{cc,h}: optimizations 
 +    (thanks to Anthony Towns)
 +  * apt pdiff support from experimental merged
 +  * apt-pkg/deb/dpkgpm.cc: wording fixes (thanks to Matt Zimmerman)
    * apt-pkg/deb/dpkgpm.cc: 
      - wording fixes (thanks to Matt Zimmerman)
 -    - fix error in dpkg interaction (closes: #364513, 
 -      thanks to Martin Dickopp)
 +    - fix error in dpkg interaction (closes: #364513, thanks to Martin Dickopp)
    * apt-pkg/tagfile.{cc,h}:
      - use MMap to read the entries (thanks to Zephaniah E. Hull for the
        patch) Closes: #350025
@@@ -659,7 -414,7 +665,7 @@@ apt (0.6.42) unstable; urgency=lo
    * cmdline/apt-cdrom.cc: 
      - fix some missing gettext() calls (closes: #334539)
    * doc/apt-cache.8.xml: fix typo (closes: #334714)
 -  
 +
   -- Michael Vogt <mvo@debian.org>  Wed, 19 Oct 2005 22:02:09 +0200
  
  apt (0.6.41) unstable; urgency=low
@@@ -759,7 -514,6 +765,7 @@@ apt (0.6.37) breezy; urgency=lo
    * Add Welsh translation from Dafydd Harries
      (daf@muse.19inch.net--2005/apt--main--0--patch-1)
    * Change debian/bugscript to use #!/bin/bash (Closes: #313402)
 +  * Fix a incorrect example in the man-page (closes: #282918)
  
   -- Matt Zimmerman <mdz@ubuntu.com>  Tue, 24 May 2005 14:38:25 -0700
  
@@@ -2607,3 -2361,4 +2613,3 @@@ apt (0.0.1) unstable; urgency=lo
    * Initial Release.
  
   -- Scott K. Ellis <scott@debian.org>  Tue, 31 Mar 1998 12:49:28 -0500
 -
diff --combined methods/https.cc
index d48ac97fb2df5d6d8434ff946ad619a4055b6df2,7a6148d146999dafb9558992e215cb646b0ea12d..e6717e63ae3f9b6aa4513508aca04b2a3571787a
@@@ -3,7 -3,7 +3,7 @@@
  // $Id: http.cc,v 1.59 2004/05/08 19:42:35 mdz Exp $
  /* ######################################################################
  
 -   HTTPS Aquire Method - This is the HTTPS aquire method for APT.
 +   HTTPS Acquire Method - This is the HTTPS aquire method for APT.
     
     It uses libcurl
  
@@@ -50,13 -50,13 +50,13 @@@ HttpsMethod::progress_callback(void *cl
  {
     HttpsMethod *me = (HttpsMethod *)clientp;
     if(dltotal > 0 && me->Res.Size == 0) {
 -      me->Res.Size = dltotal;
 +      me->Res.Size = (unsigned long)dltotal;
        me->URIStart(me->Res);
     }
     return 0;
  }
  
 -bool HttpsMethod::SetupProxy()
 +void HttpsMethod::SetupProxy()
  {
     URI ServerName = Queue->Uri;
  
@@@ -84,6 -84,7 +84,6 @@@
     }
     
     // Determine what host and port to use based on the proxy settings
 -   int Port = 0;
     string Host;   
     if (Proxy.empty() == true || Proxy.Host.empty() == true)
     {
@@@ -107,6 -108,7 +107,7 @@@ bool HttpsMethod::Fetch(FetchItem *Itm
     struct stat SBuf;
     struct curl_slist *headers=NULL;  
     char curl_errorstr[CURL_ERROR_SIZE];
+    long curl_responsecode;
  
     // TODO:
     //       - http::Timeout
     curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
  
     // set time values
-    curl_easy_setopt(curl, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE);
-    curl_easy_setopt(curl, CURLOPT_TIMEVALUE, Itm->LastModified);
+    if(Itm->LastModified > 0)
+    {
+       curl_easy_setopt(curl, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE);
+       curl_easy_setopt(curl, CURLOPT_TIMEVALUE, Itm->LastModified);
+    }
  
     // speed limit
     int dlLimit = _config->FindI("Acquire::http::Dl-Limit",0)*1024;
     curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_errorstr);
  
     // In this case we send an if-range query with a range header
-   if (stat(Itm->DestFile.c_str(),&SBuf) >= 0 && SBuf.st_size > 0)
-      curl_easy_setopt(curl, CURLOPT_RESUME_FROM, (long)SBuf.st_size);
+    if (stat(Itm->DestFile.c_str(),&SBuf) >= 0 && SBuf.st_size > 0)
+    {
+       char Buf[1000];
+       sprintf(Buf,"Range: bytes=%li-\r\nIf-Range: %s\r\n",
+             (long)SBuf.st_size - 1,
+             TimeRFC1123(SBuf.st_mtime).c_str());
+       headers = curl_slist_append(headers, Buf);
+    }
  
     // go for it - if the file exists, append on it
     File = new FileFd(Itm->DestFile, FileFd::WriteAny);
  
     // get it!
     CURLcode success = curl_easy_perform(curl);
+    curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &curl_responsecode);
  
     // cleanup
-    if(success != 0) {
+    if(success != 0) 
+    {
+       unlink(File->Name().c_str());
        _error->Error(curl_errorstr);
        Fail();
        return true;
     }
+    File->Close();
  
     if (Res.Size == 0)
        Res.Size = File->Size();
        Res.Filename = File->Name();
        Res.LastModified = Buf.st_mtime;
        Res.IMSHit = false;
-       if (Itm->LastModified != 0 && Buf.st_mtime >= Itm->LastModified)
+       if (curl_responsecode == 304)
        {
         Res.IMSHit = true;
         Res.LastModified = Itm->LastModified;
     URIDone(Res);
  
     // cleanup
-    File->Close();
     Res.Size = 0;
     delete File;
     curl_slist_free_all(headers);