}
/*}}}*/
+// 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 /*{{{*/
// ---------------------------------------------------------------------
/* */
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;};
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:
{
# 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)
unsigned char InstState; // Flags
unsigned char CurrentState; // State
- unsigned short ID;
+ unsigned int ID;
unsigned long Flags;
};
// Linked list
map_ptrloc NextFile; // PackageFile
- unsigned short ID;
+ unsigned int ID;
time_t mtime; // Modification time for the file
};
map_ptrloc Size; // These are the .deb size
map_ptrloc InstalledSize;
unsigned short Hash;
- unsigned short ID;
+ unsigned int ID;
unsigned char Priority;
};
map_ptrloc NextDesc; // Description
map_ptrloc ParentPkg; // Package
- unsigned short ID;
+ unsigned int ID;
};
struct pkgCache::Dependency
* 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:
- 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
#include <stdio.h>
#include <errno.h>
#include <string.h>
+#include <map>
#include <apti18n.h>
// Internet stuff
time_t HttpMethod::FailTime = 0;
unsigned long PipelineDepth = 10;
unsigned long TimeOut = 120;
+bool AllowRedirect = false;
bool Debug = false;
URI Proxy;
return true;
}
+ if (stringcasecmp(Tag,"Location:") == 0)
+ {
+ Location = Val;
+ return true;
+ }
+
return true;
}
/*}}}*/
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
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)
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);
/* */
int HttpMethod::Loop()
{
+ typedef vector<string> StringVector;
+ typedef vector<string>::iterator StringVectorIterator;
+ map<string, StringVector> Redirected;
+
signal(SIGTERM,SigTerm);
signal(SIGINT,SigTerm);
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;
enum {Chunked,Stream,Closes} Encoding;
enum {Header, Data} State;
bool Persistent;
+ string Location;
// This is a Persistent attribute of the server itself.
bool Pipeline;
protected:
virtual bool Fetch(FetchItem *);
+ string NextURI;
+
public:
friend class ServerState;
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