From a27968bedadaca57e1792ae410d1a946fd936646 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Wed, 15 Sep 2010 11:46:25 +0000 Subject: [PATCH] 2010-09-15 Tatsuhiro Tsujikawa Fixed the bug that a file gets overwritten if -V is given and no hash is provided. Fixed the bug that --dry-run leads download error. Added RequestGroup::createCheckIntegrityEntry() which correctly creates CheckIntegrityEntry objects and open files based on -V option and the existence of control file. * src/AbstractCommand.cc * src/AbstractCommand.h * src/ChecksumCheckIntegrityEntry.cc * src/DownloadContext.cc * src/DownloadContext.h * src/FtpNegotiationCommand.cc * src/HttpResponseCommand.cc * src/PieceHashCheckIntegrityEntry.cc * src/RequestGroup.cc * src/RequestGroup.h * src/RequestGroupEntry.cc * src/RequestGroupEntry.h --- ChangeLog | 20 +++++ src/AbstractCommand.cc | 23 +---- src/AbstractCommand.h | 3 +- src/ChecksumCheckIntegrityEntry.cc | 5 +- src/DownloadContext.cc | 11 +++ src/DownloadContext.h | 6 ++ src/FtpNegotiationCommand.cc | 29 ++----- src/HttpResponseCommand.cc | 26 ++---- src/PieceHashCheckIntegrityEntry.cc | 4 +- src/RequestGroup.cc | 129 +++++++++++++++++----------- src/RequestGroup.h | 4 + src/RequestGroupEntry.cc | 6 ++ src/RequestGroupEntry.h | 2 + 13 files changed, 156 insertions(+), 112 deletions(-) diff --git a/ChangeLog b/ChangeLog index aebf56c4..ad1604dc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2010-09-15 Tatsuhiro Tsujikawa + + Fixed the bug that a file gets overwritten if -V is given and no + hash is provided. Fixed the bug that --dry-run leads download + error. Added RequestGroup::createCheckIntegrityEntry() which + correctly creates CheckIntegrityEntry objects and open files based + on -V option and the existence of control file. + * src/AbstractCommand.cc + * src/AbstractCommand.h + * src/ChecksumCheckIntegrityEntry.cc + * src/DownloadContext.cc + * src/DownloadContext.h + * src/FtpNegotiationCommand.cc + * src/HttpResponseCommand.cc + * src/PieceHashCheckIntegrityEntry.cc + * src/RequestGroup.cc + * src/RequestGroup.h + * src/RequestGroupEntry.cc + * src/RequestGroupEntry.h + 2010-09-13 Tatsuhiro Tsujikawa Fixed compile error without zlib diff --git a/src/AbstractCommand.cc b/src/AbstractCommand.cc index ae8b0936..616e4612 100644 --- a/src/AbstractCommand.cc +++ b/src/AbstractCommand.cc @@ -777,28 +777,9 @@ std::string AbstractCommand::resolveHostname return ipaddr; } -// nextCommand is going to be managed by CheckIntegrityEntry which is -// created in side this function. Don't release nextCommand after this -// function call. -void AbstractCommand::prepareForNextAction(Command* nextCommand) +void AbstractCommand::prepareForNextAction +(const SharedHandle& checkEntry) { - SharedHandle checkEntry; -#ifdef ENABLE_MESSAGE_DIGEST - if(requestGroup_->downloadFinished() && - getDownloadContext()->isChecksumVerificationNeeded()) { - if(getLogger()->info()) { - getLogger()->info(MSG_HASH_CHECK_NOT_DONE); - } - SharedHandle entry - (new ChecksumCheckIntegrityEntry(requestGroup_, nextCommand)); - entry->setRedownload(true); - checkEntry = entry; - } else -#endif // ENABLE_MESSAGE_DIGEST - { - checkEntry.reset - (new StreamCheckIntegrityEntry(requestGroup_, nextCommand)); - } std::vector* commands = new std::vector(); auto_delete_container > commandsDel(commands); requestGroup_->processCheckIntegrityEntry(*commands, checkEntry, e_); diff --git a/src/AbstractCommand.h b/src/AbstractCommand.h index 75d50d57..810ba487 100644 --- a/src/AbstractCommand.h +++ b/src/AbstractCommand.h @@ -176,7 +176,8 @@ protected: void setTimeout(time_t timeout) { timeout_ = timeout; } - void prepareForNextAction(Command* nextCommand = 0); + void prepareForNextAction + (const SharedHandle& checkEntry); // Check if socket is connected. If socket is not connected and // there are other addresses to try, command is created using diff --git a/src/ChecksumCheckIntegrityEntry.cc b/src/ChecksumCheckIntegrityEntry.cc index d21e7916..6b384d58 100644 --- a/src/ChecksumCheckIntegrityEntry.cc +++ b/src/ChecksumCheckIntegrityEntry.cc @@ -54,8 +54,9 @@ ChecksumCheckIntegrityEntry::~ChecksumCheckIntegrityEntry() {} bool ChecksumCheckIntegrityEntry::isValidationReady() { - return !getRequestGroup()->getDownloadContext()->getChecksum().empty() && - !getRequestGroup()->getDownloadContext()->getChecksumHashAlgo().empty(); + const SharedHandle& dctx = + getRequestGroup()->getDownloadContext(); + return dctx->isChecksumVerificationAvailable(); } void ChecksumCheckIntegrityEntry::initValidator() diff --git a/src/DownloadContext.cc b/src/DownloadContext.cc index 58965be5..ac84fd3e 100644 --- a/src/DownloadContext.cc +++ b/src/DownloadContext.cc @@ -213,4 +213,15 @@ bool DownloadContext::isChecksumVerificationNeeded() const !checksum_.empty() && !checksumHashAlgo_.empty() && !checksumVerified_; } +bool DownloadContext::isChecksumVerificationAvailable() const +{ + return !checksum_.empty() && !checksumHashAlgo_.empty(); +} + +bool DownloadContext::isPieceHashVerificationAvailable() const +{ + return !pieceHashAlgo_.empty() && + pieceHashes_.size() > 0 && pieceHashes_.size() == getNumPieces(); +} + } // namespace aria2 diff --git a/src/DownloadContext.h b/src/DownloadContext.h index cc6a7f9f..e5a2c6d0 100644 --- a/src/DownloadContext.h +++ b/src/DownloadContext.h @@ -206,6 +206,12 @@ public: // need to be done bool isChecksumVerificationNeeded() const; + // Returns true if whole hash(not piece hash) is available. + bool isChecksumVerificationAvailable() const; + + // Returns true if piece hash(not whole file hash) is available. + bool isPieceHashVerificationAvailable() const; + void setChecksumVerified(bool f) { checksumVerified_ = f; diff --git a/src/FtpNegotiationCommand.cc b/src/FtpNegotiationCommand.cc index e6379e47..ae1e1c9d 100644 --- a/src/FtpNegotiationCommand.cc +++ b/src/FtpNegotiationCommand.cc @@ -452,32 +452,20 @@ bool FtpNegotiationCommand::onFileSizeDetermined(uint64_t totalLength) return false; } - BtProgressInfoFileHandle infoFile - (new DefaultBtProgressInfoFile(getDownloadContext(), - getPieceStorage(), - getOption().get())); - if(!infoFile->exists() && - getRequestGroup()->downloadFinishedByFileLength()) { - getPieceStorage()->markAllPiecesDone(); - // See also RequestGroup::createInitialCommand() - if(!getOption()->getAsBool(PREF_CHECK_INTEGRITY) || - !getDownloadContext()->isChecksumVerificationNeeded()) { - getDownloadContext()->setChecksumVerified(true); - sequence_ = SEQ_DOWNLOAD_ALREADY_COMPLETED; - getLogger()->notice(MSG_DOWNLOAD_ALREADY_COMPLETED, - util::itos(getRequestGroup()->getGID()).c_str(), - getRequestGroup()->getFirstFilePath().c_str()); - poolConnection(); - return false; - } + SharedHandle checkIntegrityEntry = + getRequestGroup()->createCheckIntegrityEntry(); + if(checkIntegrityEntry.isNull()) { + sequence_ = SEQ_DOWNLOAD_ALREADY_COMPLETED; + poolConnection(); + return false; } - getRequestGroup()->loadAndOpenFile(infoFile); + checkIntegrityEntry->pushNextCommand(this); // We have to make sure that command that has Request object must // have segment after PieceStorage is initialized. See // AbstractCommand::execute() getSegmentMan()->getSegmentWithIndex(getCuid(), 0); - prepareForNextAction(this); + prepareForNextAction(checkIntegrityEntry); disableReadCheckSocket(); } @@ -960,6 +948,7 @@ void FtpNegotiationCommand::poolConnection() const void FtpNegotiationCommand::onDryRunFileFound() { getPieceStorage()->markAllPiecesDone(); + getDownloadContext()->setChecksumVerified(true); poolConnection(); sequence_ = SEQ_HEAD_OK; } diff --git a/src/HttpResponseCommand.cc b/src/HttpResponseCommand.cc index 32fb6dbb..ae741fc3 100644 --- a/src/HttpResponseCommand.cc +++ b/src/HttpResponseCommand.cc @@ -265,23 +265,11 @@ bool HttpResponseCommand::handleDefaultEncoding return true; } - BtProgressInfoFileHandle infoFile - (new DefaultBtProgressInfoFile(getDownloadContext(), - getPieceStorage(), - getOption().get())); - if(!infoFile->exists() && getRequestGroup()->downloadFinishedByFileLength()) { - getPieceStorage()->markAllPiecesDone(); - // See also RequestGroup::createInitialCommand() - if(!getOption()->getAsBool(PREF_CHECK_INTEGRITY) || - !getDownloadContext()->isChecksumVerificationNeeded()) { - getDownloadContext()->setChecksumVerified(true); - getLogger()->notice(MSG_DOWNLOAD_ALREADY_COMPLETED, - util::itos(getRequestGroup()->getGID()).c_str(), - getRequestGroup()->getFirstFilePath().c_str()); - return true; - } + SharedHandle checkEntry = + getRequestGroup()->createCheckIntegrityEntry(); + if(checkEntry.isNull()) { + return true; } - getRequestGroup()->loadAndOpenFile(infoFile); File file(getRequestGroup()->getFirstFilePath()); // We have to make sure that command that has Request object must // have segment after PieceStorage is initialized. See @@ -306,8 +294,11 @@ bool HttpResponseCommand::handleDefaultEncoding } // After command is passed to prepareForNextAction(), it is managed // by CheckIntegrityEntry. - prepareForNextAction(command); + checkEntry->pushNextCommand(command); command = 0; + + prepareForNextAction(checkEntry); + if(getRequest()->getMethod() == Request::METHOD_HEAD) { poolConnection(); getRequest()->setMethod(Request::METHOD_GET); @@ -506,6 +497,7 @@ void HttpResponseCommand::poolConnection() void HttpResponseCommand::onDryRunFileFound() { getPieceStorage()->markAllPiecesDone(); + getDownloadContext()->setChecksumVerified(true); poolConnection(); } diff --git a/src/PieceHashCheckIntegrityEntry.cc b/src/PieceHashCheckIntegrityEntry.cc index aea5d80c..40665b76 100644 --- a/src/PieceHashCheckIntegrityEntry.cc +++ b/src/PieceHashCheckIntegrityEntry.cc @@ -51,9 +51,7 @@ bool PieceHashCheckIntegrityEntry::isValidationReady() { const SharedHandle& dctx = getRequestGroup()->getDownloadContext(); - return !dctx->getPieceHashAlgo().empty() && - dctx->getPieceHashes().size() > 0 && - dctx->getPieceHashes().size() == dctx->getNumPieces(); + return dctx->isPieceHashVerificationAvailable(); } void PieceHashCheckIntegrityEntry::initValidator() diff --git a/src/RequestGroup.cc b/src/RequestGroup.cc index 8dcea974..978604a9 100644 --- a/src/RequestGroup.cc +++ b/src/RequestGroup.cc @@ -164,6 +164,13 @@ RequestGroup::RequestGroup(const SharedHandle