From 3adebc4d451655d7607706bfbe9712993a8f0047 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Tue, 13 Nov 2007 11:46:58 +0000 Subject: [PATCH] 2007-11-13 Tatsuhiro Tsujikawa Added the ability to detect duplicate download entry which is about to download the same file other RequestGroup is downloading. * src/RequestGroup.cc * src/HttpResponseCommand.cc * src/FtpNegotiationCommand.cc --- ChangeLog | 8 ++++++++ TODO | 1 - src/FtpNegotiationCommand.cc | 7 +++++++ src/HttpResponseCommand.cc | 6 ++++++ src/RequestGroup.cc | 22 ++++++++++++++++------ 5 files changed, 37 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5ab48102..4df3afcb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2007-11-13 Tatsuhiro Tsujikawa + + Added the ability to detect duplicate download entry which is about to + download the same file other RequestGroup is downloading. + * src/RequestGroup.cc + * src/HttpResponseCommand.cc + * src/FtpNegotiationCommand.cc + 2007-11-13 Tatsuhiro Tsujikawa Recalculates download progress when loading a control file, diff --git a/TODO b/TODO index c80738f0..063579d1 100644 --- a/TODO +++ b/TODO @@ -56,5 +56,4 @@ FatalException .... Program should abort. -- remaining features to be implemented for 0.12.0 release -* Implement duplicate download checking * improve --metalink-location field diff --git a/src/FtpNegotiationCommand.cc b/src/FtpNegotiationCommand.cc index 21c04ea7..6372be9a 100644 --- a/src/FtpNegotiationCommand.cc +++ b/src/FtpNegotiationCommand.cc @@ -45,6 +45,8 @@ #include "Util.h" #include "SingleFileDownloadContext.h" #include "DefaultBtProgressInfoFile.h" +#include "RequestGroupMan.h" +#include "DownloadFailureException.h" FtpNegotiationCommand::FtpNegotiationCommand(int32_t cuid, const RequestHandle& req, @@ -199,6 +201,11 @@ bool FtpNegotiationCommand::recvSize() { dctx->setTotalLength(size); dctx->setFilename(Util::urldecode(req->getFile())); + if(e->_requestGroupMan->isSameFileBeingDownloaded(_requestGroup)) { + throw new DownloadFailureException(EX_DUPLICATE_FILE_DOWNLOAD, + _requestGroup->getFilePath().c_str()); + } + _requestGroup->initPieceStorage(); // validate totalsize against hintTotalSize if it is provided. diff --git a/src/HttpResponseCommand.cc b/src/HttpResponseCommand.cc index adfb63a8..a7d62346 100644 --- a/src/HttpResponseCommand.cc +++ b/src/HttpResponseCommand.cc @@ -49,6 +49,8 @@ #include "DiskAdaptor.h" #include "PieceStorage.h" #include "DefaultBtProgressInfoFile.h" +#include "RequestGroupMan.h" +#include "DownloadFailureException.h" #include #include @@ -91,6 +93,10 @@ bool HttpResponseCommand::executeInternal() SingleFileDownloadContextHandle dctx = _requestGroup->getDownloadContext(); dctx->setTotalLength(totalLength); dctx->setFilename(httpResponse->determinFilename()); + if(e->_requestGroupMan->isSameFileBeingDownloaded(_requestGroup)) { + throw new DownloadFailureException(EX_DUPLICATE_FILE_DOWNLOAD, + _requestGroup->getFilePath().c_str()); + } if(totalLength == 0 || httpResponse->isTransferEncodingSpecified()) { // we ignore content-length when transfer-encoding is set dctx->setTotalLength(0); diff --git a/src/RequestGroup.cc b/src/RequestGroup.cc index 03bb8cea..510a11d4 100644 --- a/src/RequestGroup.cc +++ b/src/RequestGroup.cc @@ -55,6 +55,7 @@ #include "SingleFileDownloadContext.h" #include "DlAbortEx.h" #include "DownloadFailureException.h" +#include "RequestGroupMan.h" #ifdef ENABLE_MESSAGE_DIGEST # include "CheckIntegrityCommand.h" #endif // ENABLE_MESSAGE_DIGEST @@ -139,15 +140,14 @@ void RequestGroup::closeFile() Commands RequestGroup::createInitialCommand(DownloadEngine* e) { - // If this includes torrent download, then this method returns - // the command that torrent download requires, such as - // TrackerWatcherCommand and so on. - - // It is better to avoid to using BtTorrent specific classes here. #ifdef ENABLE_BITTORRENT { BtContextHandle btContext = _downloadContext; if(!btContext.isNull()) { + if(e->_requestGroupMan->isSameFileBeingDownloaded(this)) { + throw new DownloadFailureException(EX_DUPLICATE_FILE_DOWNLOAD, + getFilePath().c_str()); + } if(btContext->getFileEntries().size() > 1) { // this is really multi file torrent. // clear http/ftp uris because the current implementation does not @@ -155,6 +155,7 @@ Commands RequestGroup::createInitialCommand(DownloadEngine* e) _logger->debug("Clearing http/ftp URIs because the current implementation does not allow integrating multi-file torrent and http/ftp."); _uris.clear(); } + initPieceStorage(); BtProgressInfoFileHandle progressInfoFile = @@ -216,6 +217,10 @@ Commands RequestGroup::createInitialCommand(DownloadEngine* e) if(_downloadContext->getTotalLength() == 0) { return createNextCommand(e, 1); }else { + if(e->_requestGroupMan->isSameFileBeingDownloaded(this)) { + throw new DownloadFailureException(EX_DUPLICATE_FILE_DOWNLOAD, + getFilePath().c_str()); + } initPieceStorage(); BtProgressInfoFileHandle infoFile = new DefaultBtProgressInfoFile(_downloadContext, _pieceStorage, _option); @@ -545,7 +550,12 @@ void RequestGroup::releaseRuntimeResource() #ifdef ENABLE_BITTORRENT BtContextHandle btContext = _downloadContext; if(!btContext.isNull()) { - BtRegistry::unregister(btContext->getInfoHashAsString()); + BtContextHandle btContextInReg = BtRegistry::getBtContext(btContext->getInfoHashAsString()); + if(!btContextInReg.isNull() && + btContextInReg->getOwnerRequestGroup()->getGID() == + btContext->getOwnerRequestGroup()->getGID()) { + BtRegistry::unregister(btContext->getInfoHashAsString()); + } } #endif // ENABLE_BITTORRENT if(!_pieceStorage.isNull()) {