]> git.saurik.com Git - apt.git/commitdiff
* [ABI break] merge support for http redirects, thanks to
authorMichael Vogt <michael.vogt@ubuntu.com>
Mon, 2 Feb 2009 11:14:36 +0000 (12:14 +0100)
committerMichael Vogt <michael.vogt@ubuntu.com>
Mon, 2 Feb 2009 11:14:36 +0000 (12:14 +0100)
  Jeff Licquia and Anthony Towns
* [ABI break] use int for the package IDs (thanks to Steve Cotton)
  - Galician updated. Closes: #509151
  - Catalan updated. Closes: #509375
  - Vietnamese updated. Closes: #509422
  - Traditional Chinese added. Closes: #510664
* COPYING:
  - Actualized. Removed obsolete Qt section, added GPLv2 clause.
    (Closes: #440049, #509337)
* Clarify the --help for 'purge' (LP: #243948)

apt-pkg/acquire-method.cc
apt-pkg/acquire-method.h
apt-pkg/acquire-worker.cc
apt-pkg/makefile
apt-pkg/pkgcache.h
debian/changelog
methods/http.cc
methods/http.h
methods/makefile

index 26f992bcff007dbae483dfc2bcd741c227990a63..150fbb77b8a5663f6b4da0e658c4300678d7c322 100644 (file)
@@ -452,6 +452,38 @@ void pkgAcqMethod::Status(const char *Format,...)
 }
                                                                        /*}}}*/
 
+// AcqMethod::Redirect - Send a redirect message                       /*{{{*/
+// ---------------------------------------------------------------------
+/* This method sends the redirect message and also manipulates the queue
+   to keep the pipeline synchronized. */
+void pkgAcqMethod::Redirect(const string &NewURI)
+{
+   string CurrentURI = "<UNKNOWN>";
+   if (Queue != 0)
+      CurrentURI = Queue->Uri;
+   char S[1024];
+   snprintf(S, sizeof(S)-50, "103 Redirect\nURI: %s\nNew-URI: %s\n\n",
+         CurrentURI.c_str(), NewURI.c_str());
+
+   if (write(STDOUT_FILENO,S,strlen(S)) != (ssize_t)strlen(S))
+      exit(100);
+
+   // Change the URI for the request.
+   Queue->Uri = NewURI;
+
+   /* To keep the pipeline synchronized, move the current request to
+      the end of the queue, past the end of the current pipeline. */
+   FetchItem *I;
+   for (I = Queue; I->Next != 0; I = I->Next) ;
+   I->Next = Queue;
+   Queue = Queue->Next;
+   I->Next->Next = 0;
+   if (QueueBack == 0)
+      QueueBack = I->Next;
+}
+                                                                        /*}}}*/
+
 // AcqMethod::FetchResult::FetchResult - Constructor                   /*{{{*/
 // ---------------------------------------------------------------------
 /* */
index 18c2cf009b5b93db686f734b755a16c89f35e40e..99a4605b146ae3b03b7db8bc4e9e242de4b6deda 100644 (file)
@@ -86,6 +86,8 @@ class pkgAcqMethod
    void Log(const char *Format,...);
    void Status(const char *Format,...);
    
+   void Redirect(const string &NewURI);
    int Run(bool Single = false);
    inline void SetFailReason(string Msg) {FailReason = Msg;};
    inline void SetIP(string aIP) {IP = aIP;};
index 1a754dae905cd3f8aa6e49076ed07c7098be3e65..78c68737c32f4d3aef1a37de6314e6b4cfd4d3e8 100644 (file)
@@ -220,6 +220,20 @@ bool pkgAcquire::Worker::RunMessages()
         Status = LookupTag(Message,"Message");
         break;
            
+         // 103 Redirect
+         case 103:
+         {
+            if (Itm == 0)
+            {
+               _error->Error("Method gave invalid 103 Redirect message");
+               break;
+            }
+            string NewURI = LookupTag(Message,"New-URI",URI.c_str());
+            Itm->URI = NewURI;
+            break;
+         }
+   
         // 200 URI Start
         case 200:
         {
index 1b78c94f687667eb0305fff122070187fce0c348..087f177409aea21afbea679ad0a552a52d1b8ece 100644 (file)
@@ -13,7 +13,7 @@ include ../buildlib/defaults.mak
 # methods/makefile - FIXME
 LIBRARY=apt-pkg
 LIBEXT=$(GLIBC_VER)$(LIBSTDCPP_VER)
-MAJOR=4.6
+MAJOR=4.7
 MINOR=0
 SLIBS=$(PTHREADLIB) $(INTLLIBS) -lutil
 APT_DOMAIN:=libapt-pkg$(MAJOR)
index 59d5003bba4f7ecc0f151b1c8e82ba94639d13eb..759e9a2251fdf8d706c91ee9adf67123c545b201 100644 (file)
@@ -214,7 +214,7 @@ struct pkgCache::Package
    unsigned char InstState;         // Flags
    unsigned char CurrentState;      // State
    
-   unsigned short ID;
+   unsigned int ID;
    unsigned long Flags;
 };
 
@@ -235,7 +235,7 @@ struct pkgCache::PackageFile
    
    // Linked list
    map_ptrloc NextFile;        // PackageFile
-   unsigned short ID;
+   unsigned int ID;
    time_t mtime;                  // Modification time for the file
 };
 
@@ -272,7 +272,7 @@ struct pkgCache::Version
    map_ptrloc Size;              // These are the .deb size
    map_ptrloc InstalledSize;
    unsigned short Hash;
-   unsigned short ID;
+   unsigned int ID;
    unsigned char Priority;
 };
 
@@ -289,7 +289,7 @@ struct pkgCache::Description
    map_ptrloc NextDesc;          // Description
    map_ptrloc ParentPkg;         // Package
 
-   unsigned short ID;
+   unsigned int ID;
 };
 
 struct pkgCache::Dependency
index 478638a63a28eebf3f0d3fc809d466b93036b9e0..bfbe6be5c504360dd59243f9cefca7c61047fa65 100644 (file)
@@ -6,29 +6,11 @@ apt (0.7.19ubuntu3) jaunty; urgency=low
   * apt-inst/contrib/arfile.cc:
     - support members ending with '/' as well (thanks to Michal Cihr,
       closes: #500988)
- * debian/apt.conf.autoremove:
-   - readd "linux-image" (and friends) to the auto-remove
 * debian/apt.conf.autoremove:
+    - readd "linux-image" (and friends) to the auto-remove
      blacklist
- * fix some i18n issues (thanks to  Gabor Kelemen)
-   LP: #263089
-
-  [ Christian Perrier ]
-  * Translations:
-    - Galician updated. Closes: #509151
-    - Catalan updated. Closes: #509375
-    - Vietnamese updated. Closes: #509422
-    - Traditional Chinese added. Closes: #510664
-
-  [ Eugene V. Lyubimkin ]  
-  * COPYING:
-    - Actualized. Removed obsolete Qt section, added GPLv2 clause.
-      (Closes: #440049, #509337)
-
- -- Michael Vogt <mvo@debian.org>  Mon, 05 Jan 2009 08:59:20 +0100
-
-apt (0.7.19ubuntu2) jaunty; urgency=low
-
-  [ Michael Vogt ]
+  * fix some i18n issues (thanks to  Gabor Kelemen)
+    LP: #263089
   * apt-pkg/deb/dpkgpm.cc:
     - filter "ENOMEM" errors when creating apport reports 
   * cmdline/apt-get.cc:
@@ -40,15 +22,27 @@ apt (0.7.19ubuntu2) jaunty; urgency=low
     - add new strprintf() function to make i18n strings easier
   * apt-pkg/dev/debsystem.cc:
     - add missing apti18n.h header
-
-  [ Dereck Wonnacott ]
-  * Clarify the --help for 'purge' (LP: #243948)
+  * [ABI break] merge support for http redirects, thanks to
+    Jeff Licquia and Anthony Towns
+  * [ABI break] use int for the package IDs (thanks to Steve Cotton)
 
   [ Christian Perrier ]
   * Translations:
+    - Galician updated. Closes: #509151
+    - Catalan updated. Closes: #509375
+    - Vietnamese updated. Closes: #509422
+    - Traditional Chinese added. Closes: #510664
     - French corrected (remove awful use of first person) 
     - Finnish updated. Closes: #508449 
 
+  [ Eugene V. Lyubimkin ]  
+  * COPYING:
+    - Actualized. Removed obsolete Qt section, added GPLv2 clause.
+      (Closes: #440049, #509337)
+
+  [ Dereck Wonnacott ]
+  * Clarify the --help for 'purge' (LP: #243948)
+
   [ Eugene V. Lyubimkin ]
   * doc/examples/sources.list:
     - Removed obsolete commented non-us deb-src entry, replaced it with
index b0fb89fdacfcd1772e9a196afc0c2a3cafcf3ecc..44274bd78de90ffa4184578f3746e4b6607e3f6f 100644 (file)
@@ -38,6 +38,7 @@
 #include <stdio.h>
 #include <errno.h>
 #include <string.h>
+#include <map>
 #include <apti18n.h>
 
 // Internet stuff
@@ -56,6 +57,7 @@ int HttpMethod::FailFd = -1;
 time_t HttpMethod::FailTime = 0;
 unsigned long PipelineDepth = 10;
 unsigned long TimeOut = 120;
+bool AllowRedirect = false;
 bool Debug = false;
 URI Proxy;
 
@@ -627,6 +629,12 @@ bool ServerState::HeaderLine(string Line)
       return true;
    }
 
+   if (stringcasecmp(Tag,"Location:") == 0)
+   {
+      Location = Val;
+      return true;
+   }
+
    return true;
 }
                                                                        /*}}}*/
@@ -899,7 +907,9 @@ bool HttpMethod::ServerDie(ServerState *Srv)
      1 - IMS hit
      3 - Unrecoverable error 
      4 - Error with error content page
-     5 - Unrecoverable non-server error (close the connection) */
+     5 - Unrecoverable non-server error (close the connection) 
+     6 - Try again with a new or changed URI
+ */
 int HttpMethod::DealWithHeaders(FetchResult &Res,ServerState *Srv)
 {
    // Not Modified
@@ -911,6 +921,27 @@ int HttpMethod::DealWithHeaders(FetchResult &Res,ServerState *Srv)
       return 1;
    }
    
+   /* Redirect
+    *
+    * Note that it is only OK for us to treat all redirection the same
+    * because we *always* use GET, not other HTTP methods.  There are
+    * three redirection codes for which it is not appropriate that we
+    * redirect.  Pass on those codes so the error handling kicks in.
+    */
+   if (AllowRedirect
+       && (Srv->Result > 300 && Srv->Result < 400)
+       && (Srv->Result != 300       // Multiple Choices
+           && Srv->Result != 304    // Not Modified
+           && Srv->Result != 306))  // (Not part of HTTP/1.1, reserved)
+   {
+      if (!Srv->Location.empty())
+      {
+         NextURI = Srv->Location;
+         return 6;
+      }
+      /* else pass through for error message */
+   }
    /* We have a reply we dont handle. This should indicate a perm server
       failure */
    if (Srv->Result < 200 || Srv->Result >= 300)
@@ -1028,6 +1059,7 @@ bool HttpMethod::Configuration(string Message)
    if (pkgAcqMethod::Configuration(Message) == false)
       return false;
    
+   AllowRedirect = _config->FindB("Acquire::http::AllowRedirect",true);
    TimeOut = _config->FindI("Acquire::http::Timeout",TimeOut);
    PipelineDepth = _config->FindI("Acquire::http::Pipeline-Depth",
                                  PipelineDepth);
@@ -1041,6 +1073,10 @@ bool HttpMethod::Configuration(string Message)
 /* */
 int HttpMethod::Loop()
 {
+   typedef vector<string> StringVector;
+   typedef vector<string>::iterator StringVectorIterator;
+   map<string, StringVector> Redirected;
+
    signal(SIGTERM,SigTerm);
    signal(SIGINT,SigTerm);
    
@@ -1227,6 +1263,46 @@ int HttpMethod::Loop()
            break;
         }
         
+         // Try again with a new URL
+         case 6:
+         {
+            // Clear rest of response if there is content
+            if (Server->HaveContent)
+            {
+               File = new FileFd("/dev/null",FileFd::WriteExists);
+               Server->RunData();
+               delete File;
+               File = 0;
+            }
+
+            /* Detect redirect loops.  No more redirects are allowed
+               after the same URI is seen twice in a queue item. */
+            StringVector &R = Redirected[Queue->DestFile];
+            bool StopRedirects = false;
+            if (R.size() == 0)
+               R.push_back(Queue->Uri);
+            else if (R[0] == "STOP" || R.size() > 10)
+               StopRedirects = true;
+            else
+            {
+               for (StringVectorIterator I = R.begin(); I != R.end(); I++)
+                  if (Queue->Uri == *I)
+                  {
+                     R[0] = "STOP";
+                     break;
+                  }
+               R.push_back(Queue->Uri);
+            }
+            if (StopRedirects == false)
+               Redirect(NextURI);
+            else
+               Fail();
+            break;
+         }
+
         default:
         Fail(_("Internal error"));
         break;
index dec5cd80f3105788d01512bcda625ada112a8736..bc076e1f8ae1996dc00d86ffb8302deebd6db60a 100644 (file)
@@ -99,6 +99,7 @@ struct ServerState
    enum {Chunked,Stream,Closes} Encoding;
    enum {Header, Data} State;
    bool Persistent;
+   string Location;
    
    // This is a Persistent attribute of the server itself.
    bool Pipeline;
@@ -145,6 +146,8 @@ class HttpMethod : public pkgAcqMethod
    protected:
    virtual bool Fetch(FetchItem *);
    
+   string NextURI;
+   
    public:
    friend class ServerState;
 
index 5c4fa82bf7a9795e12ede86a64fd3afef34bc134..1d022be90bf8e609fe7e26cc162b04e57781c581 100644 (file)
@@ -7,7 +7,7 @@ include ../buildlib/defaults.mak
 BIN := $(BIN)/methods
 
 # FIXME..
-LIB_APT_PKG_MAJOR = 4.6
+LIB_APT_PKG_MAJOR = 4.7
 APT_DOMAIN := libapt-pkg$(LIB_APT_PKG_MAJOR)
 
 # The file method