From d4b29c84fcfdd893b4a19ac468c1152d94ddc5a4 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Tue, 17 Jun 2008 09:09:31 +0000 Subject: [PATCH] 2008-06-17 Tatsuhiro Tsujikawa 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 --- ChangeLog | 9 +++++++++ src/AbstractCommand.cc | 1 + src/HttpSkipResponseCommand.cc | 5 +++++ src/Request.cc | 12 ++++++++++++ src/Request.h | 8 ++++++++ test/RequestTest.cc | 2 ++ 6 files changed, 37 insertions(+) diff --git a/ChangeLog b/ChangeLog index ee8301c2..124ee89d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2008-06-17 Tatsuhiro Tsujikawa + + 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 Fixed unhandled exception(removed keyword `new'). diff --git a/src/AbstractCommand.cc b/src/AbstractCommand.cc index 26e6d8df..76773ee0 100644 --- a/src/AbstractCommand.cc +++ b/src/AbstractCommand.cc @@ -150,6 +150,7 @@ bool AbstractCommand::execute() { } catch(DlRetryEx& err) { logger->info(MSG_RESTARTING_DOWNLOAD, err, cuid, req->getUrl().c_str()); req->addTryCount(); + req->resetRedirectCount(); bool isAbort = e->option->getAsInt(PREF_MAX_TRIES) != 0 && req->getTryCount() >= (unsigned int)e->option->getAsInt(PREF_MAX_TRIES); if(isAbort) { diff --git a/src/HttpSkipResponseCommand.cc b/src/HttpSkipResponseCommand.cc index 6272b09a..8e6dafc9 100644 --- a/src/HttpSkipResponseCommand.cc +++ b/src/HttpSkipResponseCommand.cc @@ -129,6 +129,11 @@ bool HttpSkipResponseCommand::executeInternal() bool HttpSkipResponseCommand::processResponse() { 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(); logger->info(MSG_REDIRECT, cuid, _httpResponse->getRedirectURI().c_str()); return prepareForRetry(0); diff --git a/src/Request.cc b/src/Request.cc index aa66e2fa..1cb9124b 100644 --- a/src/Request.cc +++ b/src/Request.cc @@ -56,6 +56,7 @@ const std::string Request::PROTO_FTP("ftp"); Request::Request(): port(0), tryCount(0), + _redirectCount(0), _supportsPersistentConnection(true), _keepAliveHint(false), _pipeliningHint(false), @@ -78,6 +79,7 @@ bool Request::resetUrl() { bool Request::redirectUrl(const std::string& url) { previousUrl = A2STR::NIL; _supportsPersistentConnection = true; + ++_redirectCount; return parseUrl(url); } @@ -198,4 +200,14 @@ void Request::urlencode(std::string& result, const std::string& src) const result.erase(result.size()-2); } +void Request::resetRedirectCount() +{ + _redirectCount = 0; +} + +unsigned int Request::getRedirectCount() const +{ + return _redirectCount; +} + } // namespace aria2 diff --git a/src/Request.h b/src/Request.h index 8cc397e4..2b5c1740 100644 --- a/src/Request.h +++ b/src/Request.h @@ -73,6 +73,8 @@ private: std::string _query; unsigned int tryCount; + unsigned int _redirectCount; + // whether or not the server supports persistent connection bool _supportsPersistentConnection; // enable keep-alive if possible. @@ -111,6 +113,10 @@ public: unsigned int getTryCount() const { return tryCount; } //bool noMoreTry() const { return tryCount >= PREF_MAX_TRY; } + void resetRedirectCount(); + + unsigned int getRedirectCount() const; + const std::string& getUrl() const { return url; } const std::string& getCurrentUrl() const { return currentUrl; } const std::string& getPreviousUrl() const { return previousUrl; } @@ -180,6 +186,8 @@ public: static const std::string PROTO_FTP; + static const unsigned int MAX_REDIRECT = 20; + }; typedef SharedHandle RequestHandle; diff --git a/test/RequestTest.cc b/test/RequestTest.cc index 5692f392..510b0f2c 100644 --- a/test/RequestTest.cc +++ b/test/RequestTest.cc @@ -291,6 +291,8 @@ void RequestTest::testRedirectUrl() { CPPUNIT_ASSERT_EQUAL(std::string("/"), req.getDir()); CPPUNIT_ASSERT_EQUAL(std::string(""), req.getFile()); CPPUNIT_ASSERT_EQUAL(std::string(""), req.getQuery()); + // See redirect count is incremented. + CPPUNIT_ASSERT_EQUAL((unsigned int)1, req.getRedirectCount()); } void RequestTest::testRedirectUrl2() {