|
|
@@ -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;
|