mirror of https://github.com/aria2/aria2
2010-09-10 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Check hash(hash for entire file, not piece hash) if --check-integrity option is given and file is downloaded(determined by file length). If it fails, re-download file. * src/AbstractCommand.cc * src/ChecksumCheckIntegrityEntry.cc * src/ChecksumCheckIntegrityEntry.h * src/FtpNegotiationCommand.cc * src/HttpResponseCommand.cc * src/RequestGroup.ccpull/1/head
parent
6e7dd1650e
commit
32e3ebf112
13
ChangeLog
13
ChangeLog
|
@ -1,3 +1,16 @@
|
|||
2010-09-10 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||
|
||||
Check hash(hash for entire file, not piece hash) if
|
||||
--check-integrity option is given and file is
|
||||
downloaded(determined by file length). If it fails, re-download
|
||||
file.
|
||||
* src/AbstractCommand.cc
|
||||
* src/ChecksumCheckIntegrityEntry.cc
|
||||
* src/ChecksumCheckIntegrityEntry.h
|
||||
* src/FtpNegotiationCommand.cc
|
||||
* src/HttpResponseCommand.cc
|
||||
* src/RequestGroup.cc
|
||||
|
||||
2010-09-10 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||
|
||||
Make finished() return true only when offset == totalLength.
|
||||
|
|
|
@ -780,29 +780,26 @@ std::string AbstractCommand::resolveHostname
|
|||
// function call.
|
||||
void AbstractCommand::prepareForNextAction(Command* nextCommand)
|
||||
{
|
||||
SharedHandle<CheckIntegrityEntry> checkEntry;
|
||||
#ifdef ENABLE_MESSAGE_DIGEST
|
||||
if(requestGroup_->downloadFinished() &&
|
||||
getDownloadContext()->isChecksumVerificationNeeded()) {
|
||||
if(getLogger()->info()) {
|
||||
getLogger()->info(MSG_HASH_CHECK_NOT_DONE);
|
||||
}
|
||||
SharedHandle<CheckIntegrityEntry> entry
|
||||
(new ChecksumCheckIntegrityEntry(requestGroup_));
|
||||
if(entry->isValidationReady()) {
|
||||
delete nextCommand;
|
||||
entry->initValidator();
|
||||
entry->cutTrailingGarbage();
|
||||
e_->getCheckIntegrityMan()->pushEntry(entry);
|
||||
return;
|
||||
}
|
||||
}
|
||||
SharedHandle<ChecksumCheckIntegrityEntry> entry
|
||||
(new ChecksumCheckIntegrityEntry(requestGroup_, nextCommand));
|
||||
entry->setRedownload(true);
|
||||
checkEntry = entry;
|
||||
} else
|
||||
#endif // ENABLE_MESSAGE_DIGEST
|
||||
SharedHandle<CheckIntegrityEntry> entry
|
||||
(new StreamCheckIntegrityEntry(requestGroup_, nextCommand));
|
||||
|
||||
{
|
||||
checkEntry.reset
|
||||
(new StreamCheckIntegrityEntry(requestGroup_, nextCommand));
|
||||
}
|
||||
std::vector<Command*>* commands = new std::vector<Command*>();
|
||||
auto_delete_container<std::vector<Command*> > commandsDel(commands);
|
||||
requestGroup_->processCheckIntegrityEntry(*commands, entry, e_);
|
||||
requestGroup_->processCheckIntegrityEntry(*commands, checkEntry, e_);
|
||||
e_->addCommand(*commands);
|
||||
commands->clear();
|
||||
e_->setNoWait(true);
|
||||
|
|
|
@ -42,11 +42,13 @@
|
|||
#include "RequestGroupMan.h"
|
||||
#include "FileAllocationEntry.h"
|
||||
#include "ServerStatMan.h"
|
||||
#include "StreamFileAllocationEntry.h"
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
ChecksumCheckIntegrityEntry::ChecksumCheckIntegrityEntry(RequestGroup* requestGroup, Command* nextCommand):
|
||||
CheckIntegrityEntry(requestGroup, nextCommand) {}
|
||||
CheckIntegrityEntry(requestGroup, nextCommand),
|
||||
redownload_(false) {}
|
||||
|
||||
ChecksumCheckIntegrityEntry::~ChecksumCheckIntegrityEntry() {}
|
||||
|
||||
|
@ -75,6 +77,12 @@ ChecksumCheckIntegrityEntry::onDownloadFinished
|
|||
void
|
||||
ChecksumCheckIntegrityEntry::onDownloadIncomplete
|
||||
(std::vector<Command*>& commands, DownloadEngine* e)
|
||||
{}
|
||||
{
|
||||
if(redownload_) {
|
||||
SharedHandle<FileAllocationEntry> entry
|
||||
(new StreamFileAllocationEntry(getRequestGroup(), popNextCommand()));
|
||||
proceedFileAllocation(commands, entry, e);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -41,6 +41,8 @@ namespace aria2 {
|
|||
|
||||
class ChecksumCheckIntegrityEntry:public CheckIntegrityEntry
|
||||
{
|
||||
private:
|
||||
bool redownload_;
|
||||
public:
|
||||
ChecksumCheckIntegrityEntry(RequestGroup* requestGroup, Command* nextCommand = 0);
|
||||
|
||||
|
@ -55,6 +57,11 @@ public:
|
|||
|
||||
virtual void onDownloadIncomplete(std::vector<Command*>& commands,
|
||||
DownloadEngine* e);
|
||||
|
||||
void setRedownload(bool redownload)
|
||||
{
|
||||
redownload_ = redownload;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -454,19 +454,17 @@ bool FtpNegotiationCommand::onFileSizeDetermined(uint64_t totalLength)
|
|||
if(!infoFile->exists() &&
|
||||
getRequestGroup()->downloadFinishedByFileLength()) {
|
||||
getPieceStorage()->markAllPiecesDone();
|
||||
// TODO It would be good to issue ChecksumCheckIntegrity here
|
||||
// instead of just pretending checksum verification is done.
|
||||
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;
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
getRequestGroup()->loadAndOpenFile(infoFile);
|
||||
// We have to make sure that command that has Request object must
|
||||
|
|
|
@ -131,8 +131,7 @@ bool HttpResponseCommand::executeInternal()
|
|||
getFileEntry()->setLength(totalLength);
|
||||
getRequestGroup()->initPieceStorage();
|
||||
getPieceStorage()->markAllPiecesDone();
|
||||
// TODO It would be good to issue ChecksumCheckIntegrity here
|
||||
// instead of just pretending checksum verification is done.
|
||||
// Just set checksum verification done.
|
||||
getDownloadContext()->setChecksumVerified(true);
|
||||
getLogger()->notice(MSG_DOWNLOAD_ALREADY_COMPLETED,
|
||||
util::itos(getRequestGroup()->getGID()).c_str(),
|
||||
|
@ -268,13 +267,15 @@ bool HttpResponseCommand::handleDefaultEncoding
|
|||
getOption().get()));
|
||||
if(!infoFile->exists() && getRequestGroup()->downloadFinishedByFileLength()) {
|
||||
getPieceStorage()->markAllPiecesDone();
|
||||
// TODO It would be good to issue ChecksumCheckIntegrity here
|
||||
// instead of just pretending checksum verification is done.
|
||||
getDownloadContext()->setChecksumVerified(true);
|
||||
getLogger()->notice(MSG_DOWNLOAD_ALREADY_COMPLETED,
|
||||
util::itos(getRequestGroup()->getGID()).c_str(),
|
||||
getRequestGroup()->getFirstFilePath().c_str());
|
||||
return true;
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
getRequestGroup()->loadAndOpenFile(infoFile);
|
||||
File file(getRequestGroup()->getFirstFilePath());
|
||||
|
@ -376,8 +377,7 @@ bool HttpResponseCommand::handleOtherEncoding
|
|||
if(getRequestGroup()->downloadFinishedByFileLength()) {
|
||||
getRequestGroup()->initPieceStorage();
|
||||
getPieceStorage()->markAllPiecesDone();
|
||||
// TODO It would be good to issue ChecksumCheckIntegrity here
|
||||
// instead of just pretending checksum verification is done.
|
||||
// This is zero-size file, so hash check is no use.
|
||||
getDownloadContext()->setChecksumVerified(true);
|
||||
getLogger()->notice(MSG_DOWNLOAD_ALREADY_COMPLETED,
|
||||
util::itos(getRequestGroup()->getGID()).c_str(),
|
||||
|
|
|
@ -424,34 +424,43 @@ void RequestGroup::createInitialCommand
|
|||
BtProgressInfoFileHandle infoFile
|
||||
(new DefaultBtProgressInfoFile(downloadContext_, pieceStorage_,
|
||||
option_.get()));
|
||||
if(!infoFile->exists() && downloadFinishedByFileLength()) {
|
||||
bool finishedBySize =
|
||||
!infoFile->exists() && downloadFinishedByFileLength();
|
||||
if(finishedBySize) {
|
||||
pieceStorage_->markAllPiecesDone();
|
||||
// TODO It would be good to issue ChecksumCheckIntegrity here
|
||||
// instead of just pretending checksum verification is done.
|
||||
downloadContext_->setChecksumVerified(true);
|
||||
logger_->notice(MSG_DOWNLOAD_ALREADY_COMPLETED,
|
||||
util::itos(gid_).c_str(),
|
||||
downloadContext_->getBasePath().c_str());
|
||||
} else {
|
||||
if(!option_->getAsBool(PREF_CHECK_INTEGRITY) ||
|
||||
!downloadContext_->isChecksumVerificationNeeded()) {
|
||||
// If --check-integrity=false and no checksum is provided,
|
||||
// and .aria2 file does not exist, we just report download
|
||||
// finished. We need
|
||||
// DownloadContext::setChecksumVerified(true): without this,
|
||||
// aria2 reports error for this download.
|
||||
downloadContext_->setChecksumVerified(true);
|
||||
logger_->notice(MSG_DOWNLOAD_ALREADY_COMPLETED,
|
||||
util::itos(gid_).c_str(),
|
||||
downloadContext_->getBasePath().c_str());
|
||||
} else {
|
||||
finishedBySize = false;
|
||||
}
|
||||
}
|
||||
if(!finishedBySize) {
|
||||
loadAndOpenFile(infoFile);
|
||||
SharedHandle<CheckIntegrityEntry> checkIntegrityEntry;
|
||||
#ifdef ENABLE_MESSAGE_DIGEST
|
||||
if(downloadFinished() &&
|
||||
downloadContext_->isChecksumVerificationNeeded()) {
|
||||
if(logger_->info()) {
|
||||
logger_->info(MSG_HASH_CHECK_NOT_DONE);
|
||||
}
|
||||
SharedHandle<CheckIntegrityEntry> entry
|
||||
SharedHandle<ChecksumCheckIntegrityEntry> entry
|
||||
(new ChecksumCheckIntegrityEntry(this));
|
||||
if(entry->isValidationReady()) {
|
||||
entry->initValidator();
|
||||
entry->cutTrailingGarbage();
|
||||
e->getCheckIntegrityMan()->pushEntry(entry);
|
||||
return;
|
||||
}
|
||||
}
|
||||
entry->setRedownload(true);
|
||||
checkIntegrityEntry = entry;
|
||||
} else
|
||||
#endif // ENABLE_MESSAGE_DIGEST
|
||||
SharedHandle<CheckIntegrityEntry> checkIntegrityEntry
|
||||
(new StreamCheckIntegrityEntry(this));
|
||||
{
|
||||
checkIntegrityEntry.reset(new StreamCheckIntegrityEntry(this));
|
||||
}
|
||||
processCheckIntegrityEntry(commands, checkIntegrityEntry, e);
|
||||
}
|
||||
}
|
||||
|
@ -505,11 +514,15 @@ void RequestGroup::processCheckIntegrityEntry
|
|||
const SharedHandle<CheckIntegrityEntry>& entry,
|
||||
DownloadEngine* e)
|
||||
{
|
||||
uint64_t actualFileSize = pieceStorage_->getDiskAdaptor()->size();
|
||||
if(actualFileSize > downloadContext_->getTotalLength()) {
|
||||
entry->cutTrailingGarbage();
|
||||
}
|
||||
#ifdef ENABLE_MESSAGE_DIGEST
|
||||
if(option_->getAsBool(PREF_CHECK_INTEGRITY) &&
|
||||
if((option_->getAsBool(PREF_CHECK_INTEGRITY) ||
|
||||
downloadContext_->isChecksumVerificationNeeded()) &&
|
||||
entry->isValidationReady()) {
|
||||
entry->initValidator();
|
||||
entry->cutTrailingGarbage();
|
||||
// Don't save control file(.aria2 file) when user presses
|
||||
// control-c key while aria2 is checking hashes. If control file
|
||||
// doesn't exist when aria2 launched, the completed length in
|
||||
|
|
Loading…
Reference in New Issue