diff options
| author | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2006-10-18 14:57:00 +0000 |
|---|---|---|
| committer | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2006-10-18 14:57:00 +0000 |
| commit | c0fd1fff2a6d78d3157790bbef6f98d54f31d0fc (patch) | |
| tree | de5f55ca5926df5dbd3fa83f28437d34e19c4f07 /src | |
| parent | c35b68082519bcb4400d23d694bdaad9ffba6679 (diff) | |
2006-10-18 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Request -> RequestHandle:
* src/HttpResponseCommand.h: Request->RequestHandle
* src/AbstractCommand.cc: Request->RequestHandle
* src/HttpDownloadCommand.cc: Request->RequestHandle
* src/HttpRequestCommand.cc: Request->RequestHandle
* src/FtpInitiateConnectionCommand.h: Request->RequestHandle
* src/AbstractCommand.h: Request->RequestHandle
* src/HttpProxyRequestCommand.h: Request->RequestHandle
* src/HttpResponseCommand.cc: Request->RequestHandle
* src/HttpInitiateConnectionCommand.h: Request->RequestHandle
* src/FtpNegotiateCommand.cc: Request->RequestHandle
* src/FtpTunnelResponseCommand.h: Request->RequestHandle
* src/HttpConnection.h: Request->RequestHandle
* src/HttpProxyResponseCommand.cc: Request->RequestHandle
* src/InitiateConnectionCommandFactory.h: Request->RequestHandle
* src/FtpTunnelResponseCommand.cc: Request->RequestHandle
* src/DownloadCommand.h: Request->RequestHandle
* src/FtpDowndloadCommand.cc: Request->RequestHandle
* src/HttpInitiateConnectionCommand.cc: Request->RequestHandle
* src/HttpRequestCommand.h: Request->RequestHandle
* src/FtpNegotiateCommand.h: Request->RequestHandle
* src/FtpTunnelResponseCommand.cc: Request->RequestHandle
* src/FtpInitiateConnectionCommand.cc: Request->RequestHandle
* src/HttpDownloadCommand.h: Request->RequestHandle
* src/FtpConnection.cc: Request->RequestHandle
* src/InitiateConnectionCommandFactory.cc:
Request->RequestHandle
* src/UrlRequestInfo.cc: Request->RequestHandle
* src/HttpProxyResponseCommand.h: Request->RequestHandle
* src/HttpConnection.h: Request->RequestHandle
* src/DownloadCommand.cc: Request->RequestHandle
* src/FtpConnection.h: Request->RequestHandle
* src/FtpDowndloadCommand.h: Request->RequestHandle
* src/HttpProxyRequestCommand.cc: Request->RequestHandle
* src/FtpTunnelRequestCommand.h: Request->RequestHandle
* src/Request.h
(SharedHandle.h): New include.
(RequestHandle): New type definition.
(Requests): Redefined.
To add MULTITRACKER support:
* src/TrackerWatcherCommand.h
(createRequestCommand): New function.
* src/DownloadEngineFactory.cc
(newTorrentConsoleEngine): Removed req.
* src/prefs.h
(PREF_TRACKER_MAX_TRIES): New definition.
* src/TorrentMan.cc
(TorrentMan): Removed req. Added trackerNumTry.
(~TorrentMan): Removed req.
(setupInternal1): Added announceList.
* src/TorrentRequestInfo.cc
(execute): Set PREF_MAX_TIRES to 1. The max number of tries for
announces is now specified by PREF_TRACKER_MAX_TRIES.
* src/main.cc
(main): Added PREF_TRACKER_MAX_TRIES.
* src/TorrentMan.h
(Request.h): Removed.
(AnnounceList.h): New include.
(trackerNumTry): New variable.
(req): Removed.
(announceList): New variable.
* src/TrackerWatcherCommand.cc
(execute): Rewritten.
(createRequestCommand): New function.
* src/TrackerUpdateCommand.cc
(execute): Updated with the use of AnnounceList.
* src/AnnounceList.cc: New class.
* src/AnnounceList.h: New class.
To fix typo:
* src/prefs.h
(PREF_MAX_TRIES): max_try->max_tries
To not to decode "+" as space in URL decode:
* src/Util.cc
(urldecode): Removed "+"->space decoding rule. Test case was
updated.
Diffstat (limited to 'src')
48 files changed, 569 insertions, 146 deletions
diff --git a/src/AbstractCommand.cc b/src/AbstractCommand.cc index 9ffa549c..fb2cb4c7 100644 --- a/src/AbstractCommand.cc +++ b/src/AbstractCommand.cc @@ -41,7 +41,9 @@ #include "SleepCommand.h" #include "prefs.h" -AbstractCommand::AbstractCommand(int cuid, Request* req, DownloadEngine* e, +AbstractCommand::AbstractCommand(int cuid, + const RequestHandle req, + DownloadEngine* e, const SocketHandle& s): Command(cuid), req(req), e(e), socket(s), checkSocketIsReadable(false), checkSocketIsWritable(false), @@ -125,7 +127,7 @@ bool AbstractCommand::execute() { void AbstractCommand::tryReserved() { if(!e->segmentMan->reserved.empty()) { - Request* req = e->segmentMan->reserved.front(); + RequestHandle req = e->segmentMan->reserved.front(); e->segmentMan->reserved.pop_front(); Command* command = InitiateConnectionCommandFactory::createInitiateConnectionCommand(cuid, req, e); e->commands.push_back(command); diff --git a/src/AbstractCommand.h b/src/AbstractCommand.h index fba4997f..c4f115cc 100644 --- a/src/AbstractCommand.h +++ b/src/AbstractCommand.h @@ -46,7 +46,7 @@ private: Time checkPoint; int timeout; protected: - Request* req; + RequestHandle req; DownloadEngine* e; SocketHandle socket; @@ -73,7 +73,7 @@ private: SocketHandle writeCheckTarget; bool nameResolverCheck; public: - AbstractCommand(int cuid, Request* req, DownloadEngine* e, const SocketHandle& s = SocketHandle()); + AbstractCommand(int cuid, const RequestHandle req, DownloadEngine* e, const SocketHandle& s = SocketHandle()); virtual ~AbstractCommand(); bool execute(); }; diff --git a/src/AnnounceList.cc b/src/AnnounceList.cc new file mode 100644 index 00000000..43d0daa7 --- /dev/null +++ b/src/AnnounceList.cc @@ -0,0 +1,225 @@ +/* <!-- copyright */ +/* + * aria2 - The high speed download utility + * + * Copyright (C) 2006 Tatsuhiro Tsujikawa + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations + * including the two. + * You must obey the GNU General Public License in all respects + * for all of the code used other than OpenSSL. If you modify + * file(s) with this exception, you may extend this exception to your + * version of the file(s), but you are not obligated to do so. If you + * do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source + * files in the program, then also delete it here. + */ +/* copyright --> */ +#include "AnnounceList.h" +#include "List.h" +#include "Data.h" + +AnnounceList::AnnounceList(const MetaEntry* announceListEntry): + currentTrackerInitialized(false) { + reconfigure(announceListEntry); +} + +AnnounceList::AnnounceList(const AnnounceTiers& announceTiers): + tiers(announceTiers), currentTrackerInitialized(false) { + resetIterator(); +} + +void AnnounceList::reconfigure(const MetaEntry* announceListEntry) { + const List* l = dynamic_cast<const List*>(announceListEntry); + if(l) { + for(MetaList::const_iterator itr = l->getList().begin(); + itr != l->getList().end(); itr++) { + const List* elem = (List*)*itr; + Strings urls; + for(MetaList::const_iterator elemItr = elem->getList().begin(); + elemItr != elem->getList().end(); elemItr++) { + const Data* data = (Data*)*elemItr; + urls.push_back(data->toString()); + } + if(urls.size()) { + AnnounceTier tier(urls); + tiers.push_back(tier); + } + } + resetIterator(); + } +} + +void AnnounceList::reconfigure(const string& url) { + Strings urls; + urls.push_back(url); + tiers.push_back(AnnounceTier(urls)); + resetIterator(); +} + +void AnnounceList::resetIterator() { + currentTier = tiers.begin(); + if(currentTier != tiers.end() && currentTier->urls.size()) { + currentTracker = currentTier->urls.begin(); + currentTrackerInitialized = true; + } else { + currentTrackerInitialized = false; + } +} + +string AnnounceList::getAnnounce() const { + if(currentTrackerInitialized) { + return *currentTracker; + } else { + return ""; + } +} + +void AnnounceList::announceSuccess() { + if(currentTrackerInitialized) { + currentTier->nextEvent(); + string url = *currentTracker; + currentTier->urls.erase(currentTracker); + currentTier->urls.push_front(url); + currentTier = tiers.begin(); + currentTracker = currentTier->urls.begin(); + } +} + +void AnnounceList::announceFailure() { + if(currentTrackerInitialized) { + currentTracker++; + if(currentTracker == currentTier->urls.end()) { + currentTier++; + if(currentTier == tiers.end()) { + currentTier = tiers.begin(); + } + currentTracker = currentTier->urls.begin(); + } + } +} + +AnnounceTier::AnnounceEvent AnnounceList::getEvent() const { + if(currentTrackerInitialized) { + return currentTier->event; + } else { + return AnnounceTier::STARTED; + } +} + +void AnnounceList::setEvent(AnnounceTier::AnnounceEvent event) { + if(currentTrackerInitialized) { + currentTier->event = event; + } +} + +string AnnounceList::getEventString() const { + if(currentTrackerInitialized) { + switch(currentTier->event) { + case AnnounceTier::STARTED: + case AnnounceTier::STARTED_AFTER_COMPLETION: + return "started"; + case AnnounceTier::STOPPED: + return "stopped"; + case AnnounceTier::COMPLETED: + return "completed"; + default: + return ""; + } + } else { + return ""; + } +} + +class FindStoppedAllowedTier { +public: + bool operator()(const AnnounceTier& tier) const { + switch(tier.event) { + case AnnounceTier::DOWNLOADING: + case AnnounceTier::STOPPED: + case AnnounceTier::COMPLETED: + case AnnounceTier::SEEDING: + return true; + default: + return false; + } + } +}; + +class FindCompletedAllowedTier { +public: + bool operator()(const AnnounceTier& tier) const { + switch(tier.event) { + case AnnounceTier::DOWNLOADING: + case AnnounceTier::COMPLETED: + return true; + default: + return false; + } + } +}; + +int AnnounceList::countStoppedAllowedTier() const { + return count_if(tiers.begin(), tiers.end(), FindStoppedAllowedTier()); +} + +int AnnounceList::countCompletedAllowedTier() const { + return count_if(tiers.begin(), tiers.end(), FindCompletedAllowedTier()); +} + +void AnnounceList::setCurrentTier(const AnnounceTiers::iterator& itr) { + if(itr != tiers.end()) { + currentTier = itr; + currentTracker = currentTier->urls.begin(); + } +} + +template<class InputIterator, class Predicate> +InputIterator +find_wrap_if(InputIterator first, InputIterator last, + InputIterator current, Predicate pred) { + InputIterator itr = find_if(current, last, + pred); + if(itr == last) { + itr = find_if(first, current, pred); + } + return itr; +} + +void AnnounceList::moveToStoppedAllowedTier() { + AnnounceTiers::iterator itr = find_wrap_if(tiers.begin(), tiers.end(), + currentTier, + FindStoppedAllowedTier()); + setCurrentTier(itr); +} + +void AnnounceList::moveToCompletedAllowedTier() { + AnnounceTiers::iterator itr = find_wrap_if(tiers.begin(), tiers.end(), + currentTier, + FindCompletedAllowedTier()); + setCurrentTier(itr); +} + +void AnnounceList::shuffle() { + for(AnnounceTiers::iterator itr = tiers.begin(); + itr != tiers.end(); itr++) { + random_shuffle(itr->urls.begin(), itr->urls.end()); + } +} diff --git a/src/AnnounceList.h b/src/AnnounceList.h new file mode 100644 index 00000000..d2ecb3d8 --- /dev/null +++ b/src/AnnounceList.h @@ -0,0 +1,158 @@ +/* <!-- copyright */ +/* + * aria2 - The high speed download utility + * + * Copyright (C) 2006 Tatsuhiro Tsujikawa + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations + * including the two. + * You must obey the GNU General Public License in all respects + * for all of the code used other than OpenSSL. If you modify + * file(s) with this exception, you may extend this exception to your + * version of the file(s), but you are not obligated to do so. If you + * do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source + * files in the program, then also delete it here. + */ +/* copyright --> */ +#ifndef _D_ANNOUNCE_LIST_H_ +#define _D_ANNOUNCE_LIST_H_ + +#include "common.h" +#include "MetaEntry.h" + +class AnnounceTier { +public: + enum AnnounceEvent { + STARTED, + STARTED_AFTER_COMPLETION, + DOWNLOADING, + STOPPED, + COMPLETED, + SEEDING, + HALTED + }; + + AnnounceEvent event; + Strings urls; + + AnnounceTier(const Strings& urls):event(STARTED), urls(urls) {} + + void nextEvent() { + switch(event) { + case STARTED: + event = DOWNLOADING; + break; + case STARTED_AFTER_COMPLETION: + event = SEEDING; + break; + case STOPPED: + event = HALTED; + break; + case COMPLETED: + event = SEEDING; + break; + default: + break; + } + } +}; + +typedef deque<AnnounceTier> AnnounceTiers; + +class AnnounceList { +public: +private: + AnnounceTiers tiers; + AnnounceTiers::iterator currentTier; + Strings::iterator currentTracker; + bool currentTrackerInitialized; + + void resetIterator(); + void setCurrentTier(const AnnounceTiers::iterator& itr); +public: + AnnounceList():currentTrackerInitialized(false) {} + AnnounceList(const MetaEntry* announceListEntry); + AnnounceList(const AnnounceTiers& tiers); + + void reconfigure(const MetaEntry* announceListEntry); + void reconfigure(const string& url); + + int countTier() const { + return tiers.size(); + } + + /** + * Shuffles all the URLs in each group. + */ + void shuffle(); + + /** + * Returns announce URL. + */ + string getAnnounce() const; + + /** + * Returns announce event, such as started, stopped, completed, etc. + */ + string getEventString() const; + + AnnounceTier::AnnounceEvent getEvent() const; + + void setEvent(AnnounceTier::AnnounceEvent event); + + /** + * Removes current announce URL from its group and inserts it before the + * first element of the group. + * The internal announce group pointer points to the first element of the + * first group after this call. + */ + void announceSuccess(); + + /** + * The internal announce URL pointer points to next URL. + * If the current URL is the last element of its group, then the first + * element of the next group is pointed. + */ + void announceFailure(); + + /** + * Counts the number of tiers to which the "stopped" event can be sent. + */ + int countStoppedAllowedTier() const; + + /** + * Counts the number of tiers to which the "completed" event can be sent. + */ + int countCompletedAllowedTier() const; + + /** + * Moves current tier pointer to the tier to which the "stopped" event can + * be sent. + * 2-stage search operation is made. + * The first search operation is performed from current pointer position + * to the end. If no such tier is found, the second search is performed from + * the first to the current pointer position. + */ + void moveToStoppedAllowedTier(); + void moveToCompletedAllowedTier(); +}; + +#endif // _D_ANNOUNCE_LIST_H_ diff --git a/src/DownloadCommand.cc b/src/DownloadCommand.cc index 691e9f62..3c9cc8e3 100644 --- a/src/DownloadCommand.cc +++ b/src/DownloadCommand.cc @@ -42,7 +42,9 @@ #include "prefs.h" #include <sys/time.h> -DownloadCommand::DownloadCommand(int cuid, Request* req, DownloadEngine* e, +DownloadCommand::DownloadCommand(int cuid, + const RequestHandle req, + DownloadEngine* e, const SocketHandle& s): AbstractCommand(cuid, req, e, s), lastSize(0) { PeerStatHandle peerStat = PeerStatHandle(new PeerStat(cuid)); diff --git a/src/DownloadCommand.h b/src/DownloadCommand.h index 1b6b29fc..dc1f68c4 100644 --- a/src/DownloadCommand.h +++ b/src/DownloadCommand.h @@ -49,7 +49,7 @@ protected: virtual bool prepareForNextSegment(const Segment& currentSegment); public: - DownloadCommand(int cuid, Request* req, DownloadEngine* e, + DownloadCommand(int cuid, const RequestHandle req, DownloadEngine* e, const SocketHandle& s); virtual ~DownloadCommand(); diff --git a/src/DownloadEngineFactory.cc b/src/DownloadEngineFactory.cc index 1aebc1a6..4adc6d2f 100644 --- a/src/DownloadEngineFactory.cc +++ b/src/DownloadEngineFactory.cc @@ -80,9 +80,6 @@ DownloadEngineFactory::newTorrentConsoleEngine(const Option* op, const string& torrentFile, const Strings& targetFiles) { - Request* req = new Request(); - req->isTorrent = true; - req->setTrackerEvent(Request::STARTED); TorrentConsoleDownloadEngine* te = new TorrentConsoleDownloadEngine(); te->option = op; ByteArrayDiskWriter* byteArrayDiskWriter = new ByteArrayDiskWriter(); @@ -92,7 +89,6 @@ DownloadEngineFactory::newTorrentConsoleEngine(const Option* op, te->torrentMan = new TorrentMan(); te->torrentMan->setStoreDir(op->get(PREF_DIR)); te->torrentMan->option = op; - te->torrentMan->req = req; Integers selectIndexes; Util::unfoldRange(op->get(PREF_SELECT_FILE), selectIndexes); if(selectIndexes.size()) { diff --git a/src/FtpConnection.cc b/src/FtpConnection.cc index 36ddb971..57de9a06 100644 --- a/src/FtpConnection.cc +++ b/src/FtpConnection.cc @@ -41,7 +41,7 @@ #include "LogFactory.h" FtpConnection::FtpConnection(int cuid, const SocketHandle& socket, - const Request* req, const Option* op) + const RequestHandle req, const Option* op) :cuid(cuid), socket(socket), req(req), option(op) { logger = LogFactory::getInstance(); } diff --git a/src/FtpConnection.h b/src/FtpConnection.h index bdef42a8..9a6c6be4 100644 --- a/src/FtpConnection.h +++ b/src/FtpConnection.h @@ -49,7 +49,7 @@ class FtpConnection { private: int cuid; SocketHandle socket; - const Request* req; + RequestHandle req; const Option* option; const Logger* logger; @@ -60,7 +60,7 @@ private: bool bulkReceiveResponse(pair<int, string>& response); public: FtpConnection(int cuid, const SocketHandle& socket, - const Request* req, const Option* op); + const RequestHandle req, const Option* op); ~FtpConnection(); void sendUser() const; void sendPass() const; diff --git a/src/FtpDownloadCommand.cc b/src/FtpDownloadCommand.cc index 16e2e41a..c5377a0b 100644 --- a/src/FtpDownloadCommand.cc +++ b/src/FtpDownloadCommand.cc @@ -34,7 +34,8 @@ /* copyright --> */ #include "FtpDownloadCommand.h" -FtpDownloadCommand::FtpDownloadCommand(int cuid, Request* req, +FtpDownloadCommand::FtpDownloadCommand(int cuid, + const RequestHandle req, DownloadEngine* e, const SocketHandle& dataSocket, const SocketHandle& ctrlSocket) diff --git a/src/FtpDownloadCommand.h b/src/FtpDownloadCommand.h index 91d5caa3..6e969ef4 100644 --- a/src/FtpDownloadCommand.h +++ b/src/FtpDownloadCommand.h @@ -41,7 +41,7 @@ class FtpDownloadCommand : public DownloadCommand { private: SocketHandle ctrlSocket; public: - FtpDownloadCommand(int cuid, Request* req, DownloadEngine* e, + FtpDownloadCommand(int cuid, const RequestHandle req, DownloadEngine* e, const SocketHandle& dataSocket, const SocketHandle& ctrlSocket); ~FtpDownloadCommand(); diff --git a/src/FtpInitiateConnectionCommand.cc b/src/FtpInitiateConnectionCommand.cc index 2be27d53..456c369c 100644 --- a/src/FtpInitiateConnectionCommand.cc +++ b/src/FtpInitiateConnectionCommand.cc @@ -42,7 +42,7 @@ #include "Util.h" FtpInitiateConnectionCommand::FtpInitiateConnectionCommand(int cuid, - Request* req, + const RequestHandle req, DownloadEngine* e) :AbstractCommand(cuid, req, e) { diff --git a/src/FtpInitiateConnectionCommand.h b/src/FtpInitiateConnectionCommand.h index 48f0adc2..52a3fc02 100644 --- a/src/FtpInitiateConnectionCommand.h +++ b/src/FtpInitiateConnectionCommand.h @@ -54,7 +54,7 @@ private: protected: bool executeInternal(Segment& segment); public: - FtpInitiateConnectionCommand(int cuid, Request* req, DownloadEngine* e); + FtpInitiateConnectionCommand(int cuid, const RequestHandle req, DownloadEngine* e); ~FtpInitiateConnectionCommand(); }; diff --git a/src/FtpNegotiationCommand.cc b/src/FtpNegotiationCommand.cc index f4fae85c..407aa438 100644 --- a/src/FtpNegotiationCommand.cc +++ b/src/FtpNegotiationCommand.cc @@ -39,7 +39,7 @@ #include "message.h" #include "prefs.h" -FtpNegotiationCommand::FtpNegotiationCommand(int cuid, Request* req, +FtpNegotiationCommand::FtpNegotiationCommand(int cuid, const RequestHandle req, DownloadEngine* e, const SocketHandle& s): AbstractCommand(cuid, req, e, s), sequence(SEQ_RECV_GREETING) diff --git a/src/FtpNegotiationCommand.h b/src/FtpNegotiationCommand.h index e1814559..87b66a27 100644 --- a/src/FtpNegotiationCommand.h +++ b/src/FtpNegotiationCommand.h @@ -93,7 +93,7 @@ private: protected: bool executeInternal(Segment& segment); public: - FtpNegotiationCommand(int cuid, Request* req, DownloadEngine* e, + FtpNegotiationCommand(int cuid, const RequestHandle req, DownloadEngine* e, const SocketHandle& s); ~FtpNegotiationCommand(); }; diff --git a/src/FtpTunnelRequestCommand.cc b/src/FtpTunnelRequestCommand.cc index 2a34bf0a..c1051d20 100644 --- a/src/FtpTunnelRequestCommand.cc +++ b/src/FtpTunnelRequestCommand.cc @@ -36,7 +36,8 @@ #include "FtpTunnelResponseCommand.h" #include "HttpConnection.h" -FtpTunnelRequestCommand::FtpTunnelRequestCommand(int cuid, Request* req, +FtpTunnelRequestCommand::FtpTunnelRequestCommand(int cuid, + const RequestHandle req, DownloadEngine* e, const SocketHandle& s) :AbstractCommand(cuid, req, e, s) { diff --git a/src/FtpTunnelRequestCommand.h b/src/FtpTunnelRequestCommand.h index beb6a49b..92126597 100644 --- a/src/FtpTunnelRequestCommand.h +++ b/src/FtpTunnelRequestCommand.h @@ -41,7 +41,7 @@ class FtpTunnelRequestCommand : public AbstractCommand { protected: bool executeInternal(Segment& segment); public: - FtpTunnelRequestCommand(int cuid, Request* req, DownloadEngine* e, + FtpTunnelRequestCommand(int cuid, const RequestHandle req, DownloadEngine* e, const SocketHandle& s); ~FtpTunnelRequestCommand(); }; diff --git a/src/FtpTunnelResponseCommand.cc b/src/FtpTunnelResponseCommand.cc index 45dc56be..4f09a649 100644 --- a/src/FtpTunnelResponseCommand.cc +++ b/src/FtpTunnelResponseCommand.cc @@ -37,7 +37,8 @@ #include "DlRetryEx.h" #include "message.h" -FtpTunnelResponseCommand::FtpTunnelResponseCommand(int cuid, Request* req, +FtpTunnelResponseCommand::FtpTunnelResponseCommand(int cuid, + const RequestHandle req, DownloadEngine* e, const SocketHandle& s) :AbstractCommand(cuid, req, e, s) { diff --git a/src/FtpTunnelResponseCommand.h b/src/FtpTunnelResponseCommand.h index 1a972082..3dc19d0f 100644 --- a/src/FtpTunnelResponseCommand.h +++ b/src/FtpTunnelResponseCommand.h @@ -44,7 +44,7 @@ private: protected: bool executeInternal(Segment& segment); public: - FtpTunnelResponseCommand(int cuid, Request* req, DownloadEngine* e, + FtpTunnelResponseCommand(int cuid, const RequestHandle req, DownloadEngine* e, const SocketHandle& s); ~FtpTunnelResponseCommand(); }; diff --git a/src/HttpConnection.cc b/src/HttpConnection.cc index 1096e452..7c080864 100644 --- a/src/HttpConnection.cc +++ b/src/HttpConnection.cc @@ -41,7 +41,7 @@ #include "LogFactory.h" HttpConnection::HttpConnection(int cuid, const SocketHandle& socket, - const Request* req, const Option* op): + const RequestHandle req, const Option* op): cuid(cuid), socket(socket), req(req), option(op), headerBufLength(0) { logger = LogFactory::getInstance(); } diff --git a/src/HttpConnection.h b/src/HttpConnection.h index 925cf63d..e01f6b22 100644 --- a/src/HttpConnection.h +++ b/src/HttpConnection.h @@ -60,13 +60,13 @@ private: string getProxyAuthString() const; int cuid; SocketHandle socket; - const Request* req; + RequestHandle req; const Option* option; const Logger* logger; char headerBuf[HEADERBUF_SIZE+1]; int headerBufLength; public: - HttpConnection(int cuid, const SocketHandle& socket, const Request* req, + HttpConnection(int cuid, const SocketHandle& socket, const RequestHandle req, const Option* op); /** diff --git a/src/HttpDownloadCommand.cc b/src/HttpDownloadCommand.cc index fbd019ab..9ea89ef4 100644 --- a/src/HttpDownloadCommand.cc +++ b/src/HttpDownloadCommand.cc @@ -45,7 +45,7 @@ using namespace std; -HttpDownloadCommand::HttpDownloadCommand(int cuid, Request* req, +HttpDownloadCommand::HttpDownloadCommand(int cuid, const RequestHandle req, DownloadEngine* e, const SocketHandle& socket) :DownloadCommand(cuid, req, e, socket) diff --git a/src/HttpDownloadCommand.h b/src/HttpDownloadCommand.h index 8e2408aa..ecb2e398 100644 --- a/src/HttpDownloadCommand.h +++ b/src/HttpDownloadCommand.h @@ -52,7 +52,7 @@ private: protected: virtual bool prepareForNextSegment(const Segment& currentSegment); public: - HttpDownloadCommand(int cuid, Request* req, DownloadEngine* e, + HttpDownloadCommand(int cuid, const RequestHandle req, DownloadEngine* e, const SocketHandle& s); ~HttpDownloadCommand(); diff --git a/src/HttpInitiateConnectionCommand.cc b/src/HttpInitiateConnectionCommand.cc index 297ef4dd..4d1492f2 100644 --- a/src/HttpInitiateConnectionCommand.cc +++ b/src/HttpInitiateConnectionCommand.cc @@ -42,7 +42,7 @@ #include "prefs.h" HttpInitiateConnectionCommand::HttpInitiateConnectionCommand(int cuid, - Request* req, + const RequestHandle req, DownloadEngine* e): AbstractCommand(cuid, req, e) { diff --git a/src/HttpInitiateConnectionCommand.h b/src/HttpInitiateConnectionCommand.h index 8eecbbcc..8f9b32e4 100644 --- a/src/HttpInitiateConnectionCommand.h +++ b/src/HttpInitiateConnectionCommand.h @@ -62,7 +62,7 @@ protected: } #endif // ENABLE_ASYNC_DNS public: - HttpInitiateConnectionCommand(int cuid, Request* req, DownloadEngine* e); + HttpInitiateConnectionCommand(int cuid, const RequestHandle req, DownloadEngine* e); ~HttpInitiateConnectionCommand(); }; diff --git a/src/HttpProxyRequestCommand.cc b/src/HttpProxyRequestCommand.cc index 37717b0b..6f6f486e 100644 --- a/src/HttpProxyRequestCommand.cc +++ b/src/HttpProxyRequestCommand.cc @@ -36,7 +36,8 @@ #include "HttpConnection.h" #include "HttpProxyResponseCommand.h" -HttpProxyRequestCommand::HttpProxyRequestCommand(int cuid, Request* req, +HttpProxyRequestCommand::HttpProxyRequestCommand(int cuid, + const RequestHandle req, DownloadEngine* e, const SocketHandle& s) :AbstractCommand(cuid, req, e, s) { diff --git a/src/HttpProxyRequestCommand.h b/src/HttpProxyRequestCommand.h index 9c87c5cb..ffec1746 100644 --- a/src/HttpProxyRequestCommand.h +++ b/src/HttpProxyRequestCommand.h @@ -41,7 +41,7 @@ class HttpProxyRequestCommand : public AbstractCommand { protected: bool executeInternal(Segment& segment); public: - HttpProxyRequestCommand(int cuid, Request* req, DownloadEngine* e, + HttpProxyRequestCommand(int cuid, const RequestHandle req, DownloadEngine* e, const SocketHandle& s); ~HttpProxyRequestCommand(); }; diff --git a/src/HttpProxyResponseCommand.cc b/src/HttpProxyResponseCommand.cc index 373887d9..e611acc0 100644 --- a/src/HttpProxyResponseCommand.cc +++ b/src/HttpProxyResponseCommand.cc @@ -37,7 +37,8 @@ #include "DlRetryEx.h" #include "message.h" -HttpProxyResponseCommand::HttpProxyResponseCommand(int cuid, Request* req, +HttpProxyResponseCommand::HttpProxyResponseCommand(int cuid, + const RequestHandle req, DownloadEngine* e, const SocketHandle& s) :AbstractCommand(cuid, req, e, s) { diff --git a/src/HttpProxyResponseCommand.h b/src/HttpProxyResponseCommand.h index e26bee14..f5b11af6 100644 --- a/src/HttpProxyResponseCommand.h +++ b/src/HttpProxyResponseCommand.h @@ -44,7 +44,7 @@ private: protected: bool executeInternal(Segment& segment); public: - HttpProxyResponseCommand(int cuid, Request* req, DownloadEngine* e, + HttpProxyResponseCommand(int cuid, const RequestHandle req, DownloadEngine* e, const SocketHandle& s); ~HttpProxyResponseCommand(); }; diff --git a/src/HttpRequestCommand.cc b/src/HttpRequestCommand.cc index 1230fe0d..7775fc30 100644 --- a/src/HttpRequestCommand.cc +++ b/src/HttpRequestCommand.cc @@ -37,7 +37,8 @@ #include "HttpConnection.h" #include "prefs.h" -HttpRequestCommand::HttpRequestCommand(int cuid, Request* req, +HttpRequestCommand::HttpRequestCommand(int cuid, + const RequestHandle req, DownloadEngine* e, const SocketHandle& s) :AbstractCommand(cuid, req, e, s) { diff --git a/src/HttpRequestCommand.h b/src/HttpRequestCommand.h index ef2253e9..41a17099 100644 --- a/src/HttpRequestCommand.h +++ b/src/HttpRequestCommand.h @@ -42,7 +42,7 @@ protected: bool executeInternal(Segment& segment); Command* getNextCommand() const; public: - HttpRequestCommand(int cuid, Request* req, DownloadEngine* e, + HttpRequestCommand(int cuid, const RequestHandle req, DownloadEngine* e, const SocketHandle& s); ~HttpRequestCommand(); }; diff --git a/src/HttpResponseCommand.cc b/src/HttpResponseCommand.cc index baeda574..618cbbbf 100644 --- a/src/HttpResponseCommand.cc +++ b/src/HttpResponseCommand.cc @@ -43,7 +43,8 @@ #include <sys/types.h> #include <unistd.h> -HttpResponseCommand::HttpResponseCommand(int cuid, Request* req, +HttpResponseCommand::HttpResponseCommand(int cuid, + const RequestHandle req, DownloadEngine* e, const SocketHandle& s) :AbstractCommand(cuid, req, e, s) { diff --git a/src/HttpResponseCommand.h b/src/HttpResponseCommand.h index bf5f1ace..35b99697 100644 --- a/src/HttpResponseCommand.h +++ b/src/HttpResponseCommand.h @@ -54,7 +54,7 @@ private: protected: bool executeInternal(Segment& segment); public: - HttpResponseCommand(int cuid, Request* req, DownloadEngine* e, + HttpResponseCommand(int cuid, const RequestHandle req, DownloadEngine* e, const SocketHandle& s); ~HttpResponseCommand(); }; diff --git a/src/InitiateConnectionCommandFactory.cc b/src/InitiateConnectionCommandFactory.cc index 827e2ce8..536cea0b 100644 --- a/src/InitiateConnectionCommandFactory.cc +++ b/src/InitiateConnectionCommandFactory.cc @@ -37,7 +37,7 @@ #include "FtpInitiateConnectionCommand.h" #include "DlAbortEx.h" -Command* InitiateConnectionCommandFactory::createInitiateConnectionCommand(int cuid, Request* req, DownloadEngine* e) { +Command* InitiateConnectionCommandFactory::createInitiateConnectionCommand(int cuid, const RequestHandle req, DownloadEngine* e) { if(req->getProtocol() == "http" #ifdef ENABLE_SSL // for SSL diff --git a/src/InitiateConnectionCommandFactory.h b/src/InitiateConnectionCommandFactory.h index 952252e2..820d38bf 100644 --- a/src/InitiateConnectionCommandFactory.h +++ b/src/InitiateConnectionCommandFactory.h @@ -41,7 +41,8 @@ class InitiateConnectionCommandFactory { public: - static Command* createInitiateConnectionCommand(int cuid, Request* req, + static Command* createInitiateConnectionCommand(int cuid, + const RequestHandle req, DownloadEngine* e); }; diff --git a/src/Makefile.am b/src/Makefile.am index cc0f408d..3807881e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -124,7 +124,8 @@ SRCS += MetaEntry.h\ PeerListProcessor.h\ DefaultPeerListProcessor.cc DefaultPeerListProcessor.h\ CompactPeerListProcessor.cc CompactPeerListProcessor.h\ - DelegatingPeerListProcessor.cc DelegatingPeerListProcessor.h + DelegatingPeerListProcessor.cc DelegatingPeerListProcessor.h\ + AnnounceList.h AnnounceList.cc endif # ENABLE_BITTORRENT if ENABLE_METALINK diff --git a/src/Makefile.in b/src/Makefile.in index 5670f7e6..f52fe022 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -101,7 +101,8 @@ bin_PROGRAMS = aria2c$(EXEEXT) @ENABLE_BITTORRENT_TRUE@ PeerListProcessor.h\ @ENABLE_BITTORRENT_TRUE@ DefaultPeerListProcessor.cc DefaultPeerListProcessor.h\ @ENABLE_BITTORRENT_TRUE@ CompactPeerListProcessor.cc CompactPeerListProcessor.h\ -@ENABLE_BITTORRENT_TRUE@ DelegatingPeerListProcessor.cc DelegatingPeerListProcessor.h +@ENABLE_BITTORRENT_TRUE@ DelegatingPeerListProcessor.cc DelegatingPeerListProcessor.h\ +@ENABLE_BITTORRENT_TRUE@ AnnounceList.h AnnounceList.cc @ENABLE_METALINK_TRUE@am__append_3 = Metalinker.cc Metalinker.h\ @ENABLE_METALINK_TRUE@ MetalinkEntry.cc MetalinkEntry.h\ @@ -117,14 +118,14 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/codeset.m4 \ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/glibc21.m4 \ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intdiv0.m4 \ $(top_srcdir)/m4/inttypes-pri.m4 $(top_srcdir)/m4/inttypes.m4 \ - $(top_srcdir)/m4/inttypes_h.m4 $(top_srcdir)/m4/lcmessage.m4 \ - $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ - $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libares.m4 \ - $(top_srcdir)/m4/libcares.m4 $(top_srcdir)/m4/nls.m4 \ - $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/po.m4 \ - $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/stdint_h.m4 \ - $(top_srcdir)/m4/uintmax_t.m4 $(top_srcdir)/m4/ulonglong.m4 \ - $(top_srcdir)/configure.ac + $(top_srcdir)/m4/inttypes_h.m4 $(top_srcdir)/m4/isc-posix.m4 \ + $(top_srcdir)/m4/lcmessage.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/libares.m4 $(top_srcdir)/m4/libcares.m4 \ + $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/openssl.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/m4/stdint_h.m4 $(top_srcdir)/m4/uintmax_t.m4 \ + $(top_srcdir)/m4/ulonglong.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs @@ -210,9 +211,9 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \ PeerListProcessor.h DefaultPeerListProcessor.cc \ DefaultPeerListProcessor.h CompactPeerListProcessor.cc \ CompactPeerListProcessor.h DelegatingPeerListProcessor.cc \ - DelegatingPeerListProcessor.h Metalinker.cc Metalinker.h \ - MetalinkEntry.cc MetalinkEntry.h MetalinkResource.cc \ - MetalinkResource.h MetalinkProcessor.h \ + DelegatingPeerListProcessor.h AnnounceList.h AnnounceList.cc \ + Metalinker.cc Metalinker.h MetalinkEntry.cc MetalinkEntry.h \ + MetalinkResource.cc MetalinkResource.h MetalinkProcessor.h \ Xml2MetalinkProcessor.cc Xml2MetalinkProcessor.h \ MetalinkRequestInfo.cc MetalinkRequestInfo.h @ENABLE_ASYNC_DNS_TRUE@am__objects_1 = NameResolver.$(OBJEXT) @@ -268,7 +269,8 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \ @ENABLE_BITTORRENT_TRUE@ SeedCheckCommand.$(OBJEXT) \ @ENABLE_BITTORRENT_TRUE@ DefaultPeerListProcessor.$(OBJEXT) \ @ENABLE_BITTORRENT_TRUE@ CompactPeerListProcessor.$(OBJEXT) \ -@ENABLE_BITTORRENT_TRUE@ DelegatingPeerListProcessor.$(OBJEXT) +@ENABLE_BITTORRENT_TRUE@ DelegatingPeerListProcessor.$(OBJEXT) \ +@ENABLE_BITTORRENT_TRUE@ AnnounceList.$(OBJEXT) @ENABLE_METALINK_TRUE@am__objects_3 = Metalinker.$(OBJEXT) \ @ENABLE_METALINK_TRUE@ MetalinkEntry.$(OBJEXT) \ @ENABLE_METALINK_TRUE@ MetalinkResource.$(OBJEXT) \ @@ -364,6 +366,7 @@ EXEEXT = @EXEEXT@ GENCAT = @GENCAT@ GLIBC21 = @GLIBC21@ GMSGFMT = @GMSGFMT@ +GREP = @GREP@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ @@ -418,10 +421,9 @@ XML2_CONFIG = @XML2_CONFIG@ XML_CPPFLAGS = @XML_CPPFLAGS@ XML_LIBS = @XML_LIBS@ YACC = @YACC@ +YFLAGS = @YFLAGS@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ -ac_ct_RANLIB = @ac_ct_RANLIB@ -ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ @@ -438,12 +440,16 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ +htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ @@ -454,8 +460,10 @@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ +psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ @@ -586,6 +594,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AbstractCommand.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AbstractDiskWriter.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AllowedFastMessage.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AnnounceList.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Base64.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BitfieldMan.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BitfieldMessage.Po@am__quote@ diff --git a/src/Request.h b/src/Request.h index fc0bfd8c..7b998d4a 100644 --- a/src/Request.h +++ b/src/Request.h @@ -39,6 +39,7 @@ #include "CookieBox.h" #include "Segment.h" #include "common.h" +#include "SharedHandle.h" using namespace std; @@ -120,6 +121,7 @@ public: }; -typedef deque<Request*> Requests; +typedef SharedHandle<Request> RequestHandle; +typedef deque<RequestHandle> Requests; #endif // _D_REQUEST_H_ diff --git a/src/TorrentMan.cc b/src/TorrentMan.cc index 82bc254f..fbf9b98c 100644 --- a/src/TorrentMan.cc +++ b/src/TorrentMan.cc @@ -72,7 +72,7 @@ TorrentMan::TorrentMan():bitfield(0), incomplete(0), connections(0), trackers(0), - req(0), + trackerNumTry(0), diskAdaptor(0) { logger = LogFactory::getInstance(); @@ -81,7 +81,6 @@ TorrentMan::TorrentMan():bitfield(0), TorrentMan::~TorrentMan() { delete bitfield; delete diskAdaptor; - delete req; } // TODO do not use this method in application code @@ -447,7 +446,15 @@ void TorrentMan::setupInternal1(const string& metaInfoFile) { Directory* topDir = NULL; readFileEntry(fileEntries, &topDir, infoDic, metaInfoFile); - announce = ((Data*)topDic->get("announce"))->toString(); + string announce = ((Data*)topDic->get("announce"))->toString(); + const MetaEntry* announces = topDic->get("announce-list"); + if(announces) { + announceList.reconfigure(announces); + announceList.shuffle(); + } + if(!announceList.countTier()) { + announceList.reconfigure(announce); + } pieceLength = ((Data*)infoDic->get("piece length"))->toInt(); pieces = totalLength/pieceLength+(totalLength%pieceLength ? 1 : 0); Data* piecesHashData = (Data*)infoDic->get("pieces"); diff --git a/src/TorrentMan.h b/src/TorrentMan.h index 54473c12..240fc1c8 100644 --- a/src/TorrentMan.h +++ b/src/TorrentMan.h @@ -45,7 +45,7 @@ #include "Option.h" #include "FileEntry.h" #include "DiskAdaptor.h" -#include "Request.h" +#include "AnnounceList.h" #include "TimeA2.h" #include "PeerListProcessor.h" #include <deque> @@ -142,8 +142,9 @@ public: int connections; // The number of tracker request command currently in the command queue. int trackers; + int trackerNumTry; // tracker request - Request* req; + AnnounceList announceList; public: TorrentMan(); ~TorrentMan(); diff --git a/src/TorrentRequestInfo.cc b/src/TorrentRequestInfo.cc index defcea83..3760da2e 100644 --- a/src/TorrentRequestInfo.cc +++ b/src/TorrentRequestInfo.cc @@ -54,6 +54,8 @@ RequestInfo* TorrentRequestInfo::execute() { if(!timeoutSpecified) { op->put(PREF_TIMEOUT, "180"); } + // set max_tries to 1. AnnounceList handles retries. + op->put(PREF_MAX_TRIES, "1"); e = DownloadEngineFactory::newTorrentConsoleEngine(op, torrentFile, targetFiles); diff --git a/src/TrackerUpdateCommand.cc b/src/TrackerUpdateCommand.cc index bb39dc86..f32c1238 100644 --- a/src/TrackerUpdateCommand.cc +++ b/src/TrackerUpdateCommand.cc @@ -155,21 +155,17 @@ bool TrackerUpdateCommand::execute() { if(!peersEntry) { logger->info("CUID#%d - No peer list received.", cuid); } - - if(e->torrentMan->req->getTrackerEvent() == Request::STARTED) { - e->torrentMan->req->setTrackerEvent(Request::AUTO); - } + e->torrentMan->announceList.announceSuccess(); + e->torrentMan->trackers = 0; + e->segmentMan->init(); } catch(Exception* err) { logger->error("CUID#%d - Error occurred while processing tracker response.", cuid, err); + e->segmentMan->errors++; delete err; } - if(trackerResponse != NULL) { + if(trackerResponse) { delete [] trackerResponse; } - e->torrentMan->trackers = 0; - - e->segmentMan->init(); - if(e->torrentMan->isHalt()) { return true; } else { diff --git a/src/TrackerWatcherCommand.cc b/src/TrackerWatcherCommand.cc index e76701cf..be7ed234 100644 --- a/src/TrackerWatcherCommand.cc +++ b/src/TrackerWatcherCommand.cc @@ -49,83 +49,98 @@ TrackerWatcherCommand::TrackerWatcherCommand(int cuid, TrackerWatcherCommand::~TrackerWatcherCommand() {} bool TrackerWatcherCommand::execute() { - if(e->segmentMan->errors > 0) { - if(e->torrentMan->isHalt()) { + Command* command = 0; + if(e->torrentMan->trackers == 0 && e->torrentMan->isHalt()) { + // Download is going to halt. + // Check whether there are at least one tracker which can receive + // "stopped" event. + if(e->torrentMan->announceList.countStoppedAllowedTier()) { + e->torrentMan->announceList.moveToStoppedAllowedTier(); + e->torrentMan->announceList.setEvent(AnnounceTier::STOPPED); + command = createRequestCommand(); + } else { + // We don't send "stopped" event since no tracker cares about it. return true; } + } else if(e->torrentMan->trackers == 0 && + e->torrentMan->downloadComplete() && + e->torrentMan->announceList.countCompletedAllowedTier()) { + // Send "completed" event to all trackers which can accept it. + e->torrentMan->announceList.moveToCompletedAllowedTier(); + e->torrentMan->announceList.setEvent(AnnounceTier::COMPLETED); + command = createRequestCommand(); + } else if(e->torrentMan->trackers == 0 && + checkPoint.elapsed(interval)) { + checkPoint.reset(); + // If download completed before "started" event is sent to a tracker, + // we change the event to something else to prevent us from + // sending "completed" event. + if(e->torrentMan->downloadComplete() && + e->torrentMan->announceList.getEvent() == AnnounceTier::STARTED) { + e->torrentMan->announceList.setEvent(AnnounceTier::STARTED_AFTER_COMPLETION); + } + command = createRequestCommand(); + } else if(e->segmentMan->errors > 0) { + e->torrentMan->trackerNumTry++; + checkPoint.reset(); // we assume the tracker request has failed. + e->torrentMan->announceList.announceFailure(); e->torrentMan->trackers = 0; e->segmentMan->init(); - // sleep a few seconds. - SleepCommand* sleepCommand = - new SleepCommand(cuid, e, this, e->option->getAsInt(PREF_RETRY_WAIT)); - e->commands.push_back(sleepCommand); - return false; - } - if(e->torrentMan->trackers == 0 && - (e->torrentMan->isHalt() || - checkPoint.elapsed(interval))) { - checkPoint.reset(); - e->torrentMan->req->resetTryCount(); - int numWant = 50; - if(e->torrentMan->connections >= MIN_PEERS || e->torrentMan->isHalt()) { - numWant = 0; - } - if(e->torrentMan->isHalt()) { - e->torrentMan->req->setTrackerEvent(Request::STOPPED); - } else if(e->torrentMan->downloadComplete()) { - if(e->torrentMan->req->getTrackerEvent() == Request::COMPLETED) { - e->torrentMan->req->setTrackerEvent(Request::AFTER_COMPLETED); - } else { - if(e->torrentMan->req->getTrackerEvent() == Request::STARTED) { - // in case where download had completed when aria2c started. - e->torrentMan->req->setTrackerEvent(Request::AFTER_COMPLETED); - } else if(e->torrentMan->req->getTrackerEvent() != Request::AFTER_COMPLETED) { - e->torrentMan->req->setTrackerEvent(Request::COMPLETED); - } + if(e->torrentMan->trackerNumTry >= e->option->getAsInt(PREF_TRACKER_MAX_TRIES)) { + // abort tracker request + e->torrentMan->trackerNumTry = 0; + if(e->torrentMan->isHalt()) { + return true; } + } else { + // sleep a few seconds. + command = + new SleepCommand(cuid, e, + createRequestCommand(), + e->option->getAsInt(PREF_RETRY_WAIT)); } - string event; - switch(e->torrentMan->req->getTrackerEvent()) { - case Request::STARTED: - event = "started"; - break; - case Request::STOPPED: - event = "stopped"; - break; - case Request::COMPLETED: - event = "completed"; - break; - } - string url = e->torrentMan->announce+"?"+ - "info_hash="+Util::torrentUrlencode(e->torrentMan->getInfoHash(), 20)+"&"+ - "peer_id="+e->torrentMan->peerId+"&"+ - "port="+Util::itos(e->torrentMan->getPort())+"&"+ - "uploaded="+Util::llitos(e->torrentMan->getSessionUploadLength())+"&"+ - "downloaded="+Util::llitos(e->torrentMan->getSessionDownloadLength())+"&"+ - "left="+(e->torrentMan->getTotalLength()-e->torrentMan->getDownloadLength() <= 0 - ? "0" : Util::llitos(e->torrentMan->getTotalLength()-e->torrentMan->getDownloadLength()))+"&"+ - "compact=1"+"&"+ - "key="+e->torrentMan->key+"&"+ - "numwant="+Util::itos(numWant)+"&"+ - "no_peer_id=1"; - if(!event.empty()) { - url += string("&")+"event="+event; - } - if(!e->torrentMan->trackerId.empty()) { - url += string("&")+"trackerid="+e->torrentMan->trackerId; - } - e->torrentMan->req->setUrl(url); - Command* command = InitiateConnectionCommandFactory::createInitiateConnectionCommand(e->torrentMan->getNewCuid(), e->torrentMan->req, e); + } + + if(command) { e->commands.push_back(command); e->torrentMan->trackers++; - logger->info("CUID#%d - Creating new tracker request command #%d", cuid, - command->getCuid()); - if(e->torrentMan->isHalt()) { - return true; - } } + // updates interval with newest minInterval interval = e->torrentMan->minInterval; e->commands.push_back(this); return false; } + +Command* TrackerWatcherCommand::createRequestCommand() { + int numWant = 50; + if(e->torrentMan->connections >= MIN_PEERS || e->torrentMan->isHalt()) { + numWant = 0; + } + string url = e->torrentMan->announceList.getAnnounce()+"?"+ + "info_hash="+Util::torrentUrlencode(e->torrentMan->getInfoHash(), 20)+"&"+ + "peer_id="+e->torrentMan->peerId+"&"+ + "port="+Util::itos(e->torrentMan->getPort())+"&"+ + "uploaded="+Util::llitos(e->torrentMan->getSessionUploadLength())+"&"+ + "downloaded="+Util::llitos(e->torrentMan->getSessionDownloadLength())+"&"+ + "left="+(e->torrentMan->getTotalLength()-e->torrentMan->getDownloadLength() <= 0 + ? "0" : Util::llitos(e->torrentMan->getTotalLength()-e->torrentMan->getDownloadLength()))+"&"+ + "compact=1"+"&"+ + "key="+e->torrentMan->key+"&"+ + "numwant="+Util::itos(numWant)+"&"+ + "no_peer_id=1"; + string event = e->torrentMan->announceList.getEventString(); + if(!event.empty()) { + url += string("&")+"event="+event; + } + if(!e->torrentMan->trackerId.empty()) { + url += string("&")+"trackerid="+e->torrentMan->trackerId; + } + RequestHandle req; + req->setUrl(url); + req->isTorrent = true; + Command* command = InitiateConnectionCommandFactory::createInitiateConnectionCommand(e->torrentMan->getNewCuid(), req, e); + logger->info("CUID#%d - Creating new tracker request command #%d", cuid, + command->getCuid()); + return command; +} diff --git a/src/TrackerWatcherCommand.h b/src/TrackerWatcherCommand.h index e32efdfa..03d79c94 100644 --- a/src/TrackerWatcherCommand.h +++ b/src/TrackerWatcherCommand.h @@ -44,6 +44,8 @@ private: TorrentDownloadEngine* e; int interval; Time checkPoint; + + Command* createRequestCommand(); public: TrackerWatcherCommand(int cuid, TorrentDownloadEngine* e, int interval); ~TrackerWatcherCommand(); diff --git a/src/UrlRequestInfo.cc b/src/UrlRequestInfo.cc index f3645a50..a338430a 100644 --- a/src/UrlRequestInfo.cc +++ b/src/UrlRequestInfo.cc @@ -97,14 +97,13 @@ public: void operator()(const string& url) { for(int s = 1; s <= split; s++) { - Request* req = new Request(); + RequestHandle req; req->setReferer(referer); if(req->setUrl(url)) { requestsPtr->push_back(req); } else { fprintf(stderr, _("Unrecognized URL or unsupported protocol: %s\n"), req->getUrl().c_str()); - delete req; } } } @@ -146,9 +145,6 @@ RequestInfo* UrlRequestInfo::execute() { delete e; fail = true; } - for_each(requests.begin(), requests.end(), Deleter()); - for_each(reserved.begin(), reserved.end(), Deleter()); - setSignalHander(SIGINT, SIG_DFL, 0); setSignalHander(SIGTERM, SIG_DFL, 0); diff --git a/src/Util.cc b/src/Util.cc index 0f47f8ee..ef2aafd7 100644 --- a/src/Util.cc +++ b/src/Util.cc @@ -221,9 +221,7 @@ string Util::urldecode(const string& target) { string result; for(string::const_iterator itr = target.begin(); itr != target.end(); itr++) { - if(*itr == '+') { - result += ' '; - } else if(*itr == '%') { + if(*itr == '%') { if(itr+1 != target.end() && itr+2 != target.end() && isxdigit(*(itr+1)) && isxdigit(*(itr+2))) { char temp[3]; diff --git a/src/main.cc b/src/main.cc index fb60a14e..ca4344c3 100644 --- a/src/main.cc +++ b/src/main.cc @@ -332,6 +332,7 @@ int main(int argc, char* argv[]) { op->put(PREF_MAX_DOWNLOAD_LIMIT, "0"); op->put(PREF_MAX_UPLOAD_LIMIT, "0"); op->put(PREF_STARTUP_IDLE_TIME, "10"); + op->put(PREF_TRACKER_MAX_TRIES, "10"); while(1) { int optIndex = 0; int lopt; diff --git a/src/prefs.h b/src/prefs.h index e5e05520..f451edc4 100644 --- a/src/prefs.h +++ b/src/prefs.h @@ -53,7 +53,7 @@ // values: 1*digit #define PREF_DNS_TIMEOUT "dns_timeout" // values: 1*digit -#define PREF_MAX_TRIES "max_try" +#define PREF_MAX_TRIES "max_tries" // values: 1*digit #define PREF_MIN_SEGMENT_SIZE "min_segment_size" // values: 1*digit @@ -149,6 +149,8 @@ #define PREF_SEED_TIME "seed_time" // values: 1*digit ['.' [ 1*digit ] ] #define PREF_SEED_RATIO "seed_ratio" +// values: 1*digit +#define PREF_TRACKER_MAX_TRIES "tracker_max_tries" /** * Metalink related preferences |
