浏览代码

2008-06-17 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

	Cancel download if http redirect is bounded more than 20 times.
	* src/AbstractCommand.cc
	* src/HttpSkipResponseCommand.cc
	* src/Request.cc
	* src/Request.h
	* test/RequestTest.cc
Tatsuhiro Tsujikawa 17 年之前
父节点
当前提交
d4b29c84fc
共有 6 个文件被更改,包括 37 次插入0 次删除
  1. 9 0
      ChangeLog
  2. 1 0
      src/AbstractCommand.cc
  3. 5 0
      src/HttpSkipResponseCommand.cc
  4. 12 0
      src/Request.cc
  5. 8 0
      src/Request.h
  6. 2 0
      test/RequestTest.cc

+ 9 - 0
ChangeLog

@@ -1,3 +1,12 @@
+2008-06-17  Tatsuhiro Tsujikawa  <tujikawa at rednoah dot com>
+
+	Cancel download if http redirect is bounded more than 20 times.
+	* src/AbstractCommand.cc
+	* src/HttpSkipResponseCommand.cc
+	* src/Request.cc
+	* src/Request.h
+	* test/RequestTest.cc
+
 2008-06-17  Tatsuhiro Tsujikawa  <tujikawa at rednoah dot com>
 2008-06-17  Tatsuhiro Tsujikawa  <tujikawa at rednoah dot com>
 
 
 	Fixed unhandled exception(removed keyword `new').
 	Fixed unhandled exception(removed keyword `new').

+ 1 - 0
src/AbstractCommand.cc

@@ -150,6 +150,7 @@ bool AbstractCommand::execute() {
   } catch(DlRetryEx& err) {
   } catch(DlRetryEx& err) {
     logger->info(MSG_RESTARTING_DOWNLOAD, err, cuid, req->getUrl().c_str());
     logger->info(MSG_RESTARTING_DOWNLOAD, err, cuid, req->getUrl().c_str());
     req->addTryCount();
     req->addTryCount();
+    req->resetRedirectCount();
     bool isAbort = e->option->getAsInt(PREF_MAX_TRIES) != 0 &&
     bool isAbort = e->option->getAsInt(PREF_MAX_TRIES) != 0 &&
       req->getTryCount() >= (unsigned int)e->option->getAsInt(PREF_MAX_TRIES);
       req->getTryCount() >= (unsigned int)e->option->getAsInt(PREF_MAX_TRIES);
     if(isAbort) {
     if(isAbort) {

+ 5 - 0
src/HttpSkipResponseCommand.cc

@@ -129,6 +129,11 @@ bool HttpSkipResponseCommand::executeInternal()
 bool HttpSkipResponseCommand::processResponse()
 bool HttpSkipResponseCommand::processResponse()
 {
 {
   if(_httpResponse->isRedirect()) {
   if(_httpResponse->isRedirect()) {
+    unsigned int rnum =
+      _httpResponse->getHttpRequest()->getRequest()->getRedirectCount();
+    if(rnum >= Request::MAX_REDIRECT) {
+      throw DlAbortEx(StringFormat("Too many redirects: count=%u", rnum).str());
+    }
     _httpResponse->processRedirect();
     _httpResponse->processRedirect();
     logger->info(MSG_REDIRECT, cuid, _httpResponse->getRedirectURI().c_str());
     logger->info(MSG_REDIRECT, cuid, _httpResponse->getRedirectURI().c_str());
     return prepareForRetry(0);
     return prepareForRetry(0);

+ 12 - 0
src/Request.cc

@@ -56,6 +56,7 @@ const std::string Request::PROTO_FTP("ftp");
 
 
 Request::Request():
 Request::Request():
   port(0), tryCount(0),
   port(0), tryCount(0),
+  _redirectCount(0),
   _supportsPersistentConnection(true),
   _supportsPersistentConnection(true),
   _keepAliveHint(false),
   _keepAliveHint(false),
   _pipeliningHint(false),
   _pipeliningHint(false),
@@ -78,6 +79,7 @@ bool Request::resetUrl() {
 bool Request::redirectUrl(const std::string& url) {
 bool Request::redirectUrl(const std::string& url) {
   previousUrl = A2STR::NIL;
   previousUrl = A2STR::NIL;
   _supportsPersistentConnection = true;
   _supportsPersistentConnection = true;
+  ++_redirectCount;
   return parseUrl(url);
   return parseUrl(url);
 }
 }
 
 
@@ -198,4 +200,14 @@ void Request::urlencode(std::string& result, const std::string& src) const
   result.erase(result.size()-2);
   result.erase(result.size()-2);
 }
 }
 
 
+void Request::resetRedirectCount()
+{
+  _redirectCount = 0;
+}
+  
+unsigned int Request::getRedirectCount() const
+{
+  return _redirectCount;
+}
+
 } // namespace aria2
 } // namespace aria2

+ 8 - 0
src/Request.h

@@ -73,6 +73,8 @@ private:
   std::string _query;
   std::string _query;
   unsigned int tryCount;
   unsigned int tryCount;
 
 
+  unsigned int _redirectCount;
+
   // whether or not the server supports persistent connection
   // whether or not the server supports persistent connection
   bool _supportsPersistentConnection;
   bool _supportsPersistentConnection;
   // enable keep-alive if possible.
   // enable keep-alive if possible.
@@ -111,6 +113,10 @@ public:
   unsigned int getTryCount() const { return tryCount; }
   unsigned int getTryCount() const { return tryCount; }
   //bool noMoreTry() const { return tryCount >= PREF_MAX_TRY; }
   //bool noMoreTry() const { return tryCount >= PREF_MAX_TRY; }
 
 
+  void resetRedirectCount();
+  
+  unsigned int getRedirectCount() const;
+
   const std::string& getUrl() const { return url; }
   const std::string& getUrl() const { return url; }
   const std::string& getCurrentUrl() const { return currentUrl; }
   const std::string& getCurrentUrl() const { return currentUrl; }
   const std::string& getPreviousUrl() const { return previousUrl; }
   const std::string& getPreviousUrl() const { return previousUrl; }
@@ -180,6 +186,8 @@ public:
 
 
   static const std::string PROTO_FTP;
   static const std::string PROTO_FTP;
 
 
+  static const unsigned int MAX_REDIRECT = 20;
+
 };
 };
 
 
 typedef SharedHandle<Request> RequestHandle;
 typedef SharedHandle<Request> RequestHandle;

+ 2 - 0
test/RequestTest.cc

@@ -291,6 +291,8 @@ void RequestTest::testRedirectUrl() {
   CPPUNIT_ASSERT_EQUAL(std::string("/"), req.getDir());
   CPPUNIT_ASSERT_EQUAL(std::string("/"), req.getDir());
   CPPUNIT_ASSERT_EQUAL(std::string(""), req.getFile());
   CPPUNIT_ASSERT_EQUAL(std::string(""), req.getFile());
   CPPUNIT_ASSERT_EQUAL(std::string(""), req.getQuery());
   CPPUNIT_ASSERT_EQUAL(std::string(""), req.getQuery());
+  // See redirect count is incremented.
+  CPPUNIT_ASSERT_EQUAL((unsigned int)1, req.getRedirectCount());
 }
 }
 
 
 void RequestTest::testRedirectUrl2() {
 void RequestTest::testRedirectUrl2() {