diff options
| author | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2007-05-31 15:56:20 +0000 |
|---|---|---|
| committer | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2007-05-31 15:56:20 +0000 |
| commit | ccdd5b31a3dfa07cd13d6f7f0f5eaa3d8ff8a61e (patch) | |
| tree | 4513f2373675d69e97170388b93a455cbb53b333 /src | |
| parent | 8eeeac71928919fa5e4fb0c1c389fa229637bea3 (diff) | |
2007-06-01 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
* src/FileAllocationCommand.cc: Derived from RealtimeCommand.
* src/CheckIntegrityCommand.cc: Derived from RealtimeCommand.
* src/MetalinkEntry.h
(checksum): Changed to ChecksumHandle
* src/MetalinkRequestInfo.cc
(checksum): Changed to ChecksumHandle
* src/File.cc
(mkdirs): OPEN_MODE -> DIR_OPEN_MODE
* src/common.h
(DIR_OPEN_MODE): New definition
* src/RequestGroup.cc
(prepareForNextAction): Added an argument.
* src/message.h
(MSG_GOOD_CHECKSUM): New definition
(MSG_BAD_CHECKSUM): New definition
* src/HttpResponseCommand.cc
(handleDefaultEncoding): Continue download sequence in new
non-segmented download.
* src/FileAllocationEntry.h
(_nextDownloadCommand): New variable.
* src/DownloadCommand.cc
(prepareForNextSegment): Create ChecksumCommand if checksum is
available.
* src/RealtimeCommand.h, src/RealtimeCommand.cc: New class.
* src/IteratableChecksumValidator.h,
src/IteratableChecksumValidator.cc: New class.
* src/ChecksumCommand.h, src/ChecksumCommand.cc: New class.
Diffstat (limited to 'src')
32 files changed, 637 insertions, 131 deletions
diff --git a/src/CheckIntegrityCommand.cc b/src/CheckIntegrityCommand.cc index 7a4bf430..51df08d3 100644 --- a/src/CheckIntegrityCommand.cc +++ b/src/CheckIntegrityCommand.cc @@ -51,20 +51,23 @@ void CheckIntegrityCommand::initValidator() _validator->init(); } -bool CheckIntegrityCommand::execute() +bool CheckIntegrityCommand::executeInternal() { - setStatusRealtime(); - _e->noWait = true; - - try { - _validator->validateChunk(); - if(_validator->finished()) { - if(_requestGroup->downloadFinished()) { - logger->notice(MSG_DOWNLOAD_ALREADY_COMPLETED, cuid, _requestGroup->getFilePath().c_str()); - return true; - } - if(_requestGroup->needsFileAllocation()) { - _e->_fileAllocationMan->pushFileAllocationEntry(new FileAllocationEntry(cuid, _req, _requestGroup)); + _validator->validateChunk(); + if(_validator->finished()) { + if(_requestGroup->downloadFinished()) { + logger->notice(MSG_DOWNLOAD_ALREADY_COMPLETED, cuid, _requestGroup->getFilePath().c_str()); + return true; + } + if(_requestGroup->needsFileAllocation()) { + FileAllocationEntryHandle entry = new FileAllocationEntry(cuid, _req, _requestGroup); + entry->setNextDownloadCommand(_nextDownloadCommand); + _nextDownloadCommand = 0; + _e->_fileAllocationMan->pushFileAllocationEntry(entry); + } else { + if(_nextDownloadCommand) { + _e->commands.push_back(_nextDownloadCommand); + _nextDownloadCommand = 0; } else { int32_t numCommandsToGenerate = 15; Commands commands = _requestGroup->getNextCommand(_e, numCommandsToGenerate); @@ -72,19 +75,23 @@ bool CheckIntegrityCommand::execute() commands.push_front(command); _e->addCommand(commands); } - return true; - } else { - _e->commands.push_back(this); - return false; } - } catch(Exception* e) { - _requestGroup->getSegmentMan()->errors++; - logger->error("CUID#%d - Exception caught while validating file integrity.", e, cuid); - delete e; - logger->error(MSG_DOWNLOAD_NOT_COMPLETE, cuid, _requestGroup->getFilePath().c_str()); - // TODO this is wrong. There may exist invalid chunk data before catching - // exception. Fix this. - _requestGroup->markPieceDone(_validator->getCurrentOffset()); return true; + } else { + _e->commands.push_back(this); + return false; } } + +bool CheckIntegrityCommand::handleException(Exception* e) +{ + logger->error("CUID#%d - Exception caught while validating file integrity.", e, cuid); + delete e; + logger->error(MSG_DOWNLOAD_NOT_COMPLETE, cuid, _requestGroup->getFilePath().c_str()); + // TODO this is wrong. There may exist invalid chunk data before catching + // exception. Fix this. + // The one of the solution is having a copy of bitfield before settting its + // all bit to 1. If exception is thrown, then assign the copy to the bitfield. + _requestGroup->markPieceDone(_validator->getCurrentOffset()); + return true; +} diff --git a/src/CheckIntegrityCommand.h b/src/CheckIntegrityCommand.h index 88f19eb6..414b70da 100644 --- a/src/CheckIntegrityCommand.h +++ b/src/CheckIntegrityCommand.h @@ -35,25 +35,22 @@ #ifndef _D_CHECK_INTEGRITY_COMMAND_H_ #define _D_CHECK_INTEGRITY_COMMAND_H_ -#include "Command.h" +#include "RealtimeCommand.h" #include "Request.h" -#include "RequestGroup.h" -#include "DownloadEngine.h" #include "IteratableChunkChecksumValidator.h" +#include "DownloadCommand.h" -class CheckIntegrityCommand : public Command { +class CheckIntegrityCommand : public RealtimeCommand { private: RequestHandle _req; - RequestGroup* _requestGroup; - DownloadEngine* _e; IteratableChunkChecksumValidatorHandle _validator; + DownloadCommand* _nextDownloadCommand; public: CheckIntegrityCommand(int cuid, const RequestHandle& req, RequestGroup* requestGroup, DownloadEngine* e): - Command(cuid), + RealtimeCommand(cuid, requestGroup, e), _req(req), - _requestGroup(requestGroup), - _e(e), - _validator(0) + _validator(0), + _nextDownloadCommand(0) { ++_requestGroup->numConnection; } @@ -61,11 +58,19 @@ public: virtual ~CheckIntegrityCommand() { --_requestGroup->numConnection; + delete _nextDownloadCommand; } void initValidator(); - virtual bool execute(); + virtual bool executeInternal(); + + virtual bool handleException(Exception* e); + + void setNextDownloadCommand(DownloadCommand* command) + { + _nextDownloadCommand = command; + } }; #endif // _D_CHECK_INTEGRITY_COMMAND_H_ diff --git a/src/Checksum.h b/src/Checksum.h index d4134510..eb1d5c34 100644 --- a/src/Checksum.h +++ b/src/Checksum.h @@ -74,4 +74,6 @@ class Checksum { }; #endif // ENABLE_MESSAGE_DIGEST +typedef SharedHandle<Checksum> ChecksumHandle; + #endif // _D_CHECKSUM_H_ diff --git a/src/ChecksumCommand.cc b/src/ChecksumCommand.cc new file mode 100644 index 00000000..dcfdc0bb --- /dev/null +++ b/src/ChecksumCommand.cc @@ -0,0 +1,79 @@ +/* <!-- 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 "ChecksumCommand.h" +#include "DlAbortEx.h" +#include "message.h" + +void ChecksumCommand::initValidator() +{ + _validator = new IteratableChecksumValidator(); + _validator->setChecksum(_requestGroup->getChecksum()); + _validator->setDiskWriter(_requestGroup->getSegmentMan()->diskWriter); + _validator->setBitfield(_requestGroup->getSegmentMan()->getBitfield()); + if(!_validator->canValidate()) { + // insufficient checksums. + throw new DlAbortEx("Insufficient checksums."); + } + _validator->init(); +} + +bool ChecksumCommand::executeInternal() +{ + _validator->validateChunk(); + if(_validator->finished()) { + if(_requestGroup->downloadFinished()) { + logger->notice(MSG_GOOD_CHECKSUM, cuid, _requestGroup->getFilePath().c_str()); + return true; + } else { + logger->error(MSG_BAD_CHECKSUM, cuid, _requestGroup->getFilePath().c_str()); + return true; + } + } else { + _e->commands.push_back(this); + return false; + } + +} + +bool ChecksumCommand::handleException(Exception* e) +{ + logger->error("CUID#%d - Exception caught while validating file integrity.", e, cuid); + delete e; + logger->error(MSG_DOWNLOAD_NOT_COMPLETE, cuid, _requestGroup->getFilePath().c_str()); + // TODO We need to set bitfield back to the state when validation begun. + // The one of the solution is having a copy of bitfield before settting its + // all bit to 1. If exception is thrown, then assign the copy to the bitfield. + return true; +} diff --git a/src/ChecksumCommand.h b/src/ChecksumCommand.h new file mode 100644 index 00000000..06260380 --- /dev/null +++ b/src/ChecksumCommand.h @@ -0,0 +1,66 @@ +/* <!-- 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_CHECKSUM_COMMAND_H_ +#define _D_CHECKSUM_COMMAND_H_ + +#include "RealtimeCommand.h" +#include "IteratableChecksumValidator.h" + +class ChecksumCommand : public RealtimeCommand +{ +private: + IteratableChecksumValidatorHandle _validator; +public: + ChecksumCommand(int cuid, RequestGroup* requestGroup, DownloadEngine* e): + RealtimeCommand(cuid, requestGroup, e), + _validator(0) + { + ++_requestGroup->numConnection; + } + + virtual ~ChecksumCommand() + { + --_requestGroup->numConnection; + } + + void initValidator(); + + virtual bool executeInternal(); + + virtual bool handleException(Exception* e); +}; + + +#endif // _D_CHECKSUM_COMMAND_H_ diff --git a/src/ChunkChecksumValidator.cc b/src/ChunkChecksumValidator.cc index cb9590fb..ee0d537f 100644 --- a/src/ChunkChecksumValidator.cc +++ b/src/ChunkChecksumValidator.cc @@ -49,7 +49,7 @@ void ChunkChecksumValidator::validateSameLengthChecksum(BitfieldMan* bitfieldMan string actualChecksum = diskWriter->messageDigest(offset, dataLength, algo); if(actualChecksum != expectedChecksum) { logger->info(EX_INVALID_CHUNK_CHECKSUM, - index, offset, dataLength, + index, offset, expectedChecksum.c_str(), actualChecksum.c_str()); bitfieldMan->unsetBit(index); } @@ -71,7 +71,7 @@ void ChunkChecksumValidator::validateDifferentLengthChecksum(BitfieldMan* bitfie if(expectedChecksum != actualChecksum) { // wrong checksum logger->info(EX_INVALID_CHUNK_CHECKSUM, - index, offset, dataLength, + index, offset, expectedChecksum.c_str(), actualChecksum.c_str()); bitfieldMan->unsetBitRange(startIndex, endIndex); } diff --git a/src/Command.cc b/src/Command.cc index e9b7f25f..7f701883 100644 --- a/src/Command.cc +++ b/src/Command.cc @@ -35,18 +35,3 @@ #include "Command.h" int Command::uuidGen = 0; - -bool Command::statusMatch(Command::STATUS statusFilter) const -{ - return statusFilter <= status; -} - -void Command::transitStatus() -{ - switch(status) { - case STATUS_REALTIME: - break; - default: - status = STATUS_INACTIVE; - } -} diff --git a/src/Command.h b/src/Command.h index 87cdd825..49f4b3d4 100644 --- a/src/Command.h +++ b/src/Command.h @@ -71,9 +71,20 @@ public: void setStatusRealtime() { this->status = STATUS_REALTIME; } - void transitStatus(); + bool statusMatch(Command::STATUS statusFilter) const + { + return statusFilter <= status; + } - bool statusMatch(Command::STATUS statusFilter) const; + void transitStatus() + { + switch(status) { + case STATUS_REALTIME: + break; + default: + status = STATUS_INACTIVE; + } + } }; typedef deque<Command*> Commands; diff --git a/src/DownloadCommand.cc b/src/DownloadCommand.cc index f28cc4c6..2e488ee9 100644 --- a/src/DownloadCommand.cc +++ b/src/DownloadCommand.cc @@ -40,6 +40,7 @@ #include "InitiateConnectionCommandFactory.h" #include "message.h" #include "prefs.h" +#include "ChecksumCommand.h" #include <sys/time.h> DownloadCommand::DownloadCommand(int cuid, @@ -125,6 +126,11 @@ bool DownloadCommand::executeInternal() { bool DownloadCommand::prepareForNextSegment() { if(_requestGroup->getSegmentMan()->finished()) { + if(!_requestGroup->getChecksum().isNull() && + !_requestGroup->getChecksum()->isEmpty()) { + ChecksumCommand* command = new ChecksumCommand(cuid, _requestGroup, e); + e->commands.push_back(command); + } return true; } else { // Merge segment with next segment, if segment.index+1 == nextSegment.index diff --git a/src/File.cc b/src/File.cc index 4100348c..7ddc71a2 100644 --- a/src/File.cc +++ b/src/File.cc @@ -94,6 +94,7 @@ bool File::mkdirs() { if(!dirs.size()) { return true; } + string accDir; if(Util::startsWith(name, "/")) { accDir = "/"; @@ -104,7 +105,7 @@ bool File::mkdirs() { if(File(accDir).isDir()) { continue; } - if(mkdir(accDir.c_str(), OPEN_MODE) == -1) { + if(mkdir(accDir.c_str(), DIR_OPEN_MODE) == -1) { return false; } } diff --git a/src/FileAllocationCommand.cc b/src/FileAllocationCommand.cc index 92f26b6f..ae9750cf 100644 --- a/src/FileAllocationCommand.cc +++ b/src/FileAllocationCommand.cc @@ -35,39 +35,43 @@ #include "FileAllocationCommand.h" #include "InitiateConnectionCommandFactory.h" #include "message.h" +#include "DownloadCommand.h" -bool FileAllocationCommand::execute() +bool FileAllocationCommand::executeInternal() { - setStatusRealtime(); - _e->noWait = true; - try { - _fileAllocationEntry->allocateChunk(); - - if(_fileAllocationEntry->allocationFinished()) { - int64_t totalLength = _requestGroup->getSegmentMan()->totalSize; - logger->debug("%d seconds to allocate %lld byte(s)", - _timer.difference(), totalLength); + _fileAllocationEntry->allocateChunk(); + + if(_fileAllocationEntry->allocationFinished()) { + int64_t totalLength = _requestGroup->getSegmentMan()->totalSize; + logger->debug("%d seconds to allocate %lld byte(s)", + _timer.difference(), totalLength); - _e->_fileAllocationMan->markCurrentFileAllocationEntryDone(); - + _e->_fileAllocationMan->markCurrentFileAllocationEntryDone(); + + if(_fileAllocationEntry->getNextDownloadCommand()) { + _e->commands.push_back(_fileAllocationEntry->getNextDownloadCommand()); + _fileAllocationEntry->setNextDownloadCommand(0); + } else { int32_t numCommandsToGenerate = 15; Commands commands = _requestGroup->getNextCommand(_e, numCommandsToGenerate); - + Command* command = InitiateConnectionCommandFactory::createInitiateConnectionCommand(cuid, _req, _requestGroup, _e); - + commands.push_front(command); - + _e->addCommand(commands); - return true; - } else { - _e->commands.push_back(this); - return false; } - } catch(Exception* e) { - _requestGroup->getSegmentMan()->errors++; - logger->error("CUID#%d - Exception caught while allocating file space.", e, cuid); - delete e; - logger->notice(MSG_DOWNLOAD_NOT_COMPLETE, cuid, _requestGroup->getFilePath().c_str()); return true; + } else { + _e->commands.push_back(this); + return false; } } + +bool FileAllocationCommand::handleException(Exception* e) +{ + logger->error("CUID#%d - Exception caught while allocating file space.", e, cuid); + delete e; + logger->error(MSG_DOWNLOAD_NOT_COMPLETE, cuid, _requestGroup->getFilePath().c_str()); + return true; +} diff --git a/src/FileAllocationCommand.h b/src/FileAllocationCommand.h index 0ca78937..22d77a07 100644 --- a/src/FileAllocationCommand.h +++ b/src/FileAllocationCommand.h @@ -35,29 +35,25 @@ #ifndef _D_FILE_ALLOCATION_COMMAND_H_ #define _D_FILE_ALLOCATION_COMMAND_H_ -#include "Command.h" +#include "RealtimeCommand.h" #include "Request.h" -#include "RequestGroup.h" -#include "DownloadEngine.h" #include "TimeA2.h" #include "FileAllocationEntry.h" -class FileAllocationCommand : public Command { +class FileAllocationCommand : public RealtimeCommand { private: RequestHandle _req; - RequestGroup* _requestGroup; - DownloadEngine* _e; FileAllocationEntryHandle _fileAllocationEntry; Time _timer; public: FileAllocationCommand(int cuid, const RequestHandle& req, RequestGroup* requestGroup, DownloadEngine* e, const FileAllocationEntryHandle& fileAllocationEntry): - Command(cuid), + RealtimeCommand(cuid, requestGroup, e), _req(req), - _requestGroup(requestGroup), - _e(e), _fileAllocationEntry(fileAllocationEntry) {} - virtual bool execute(); + virtual bool executeInternal(); + + virtual bool handleException(Exception* e); }; #endif // _D_FILE_ALLOCATION_COMMAND_H_ diff --git a/src/FileAllocationEntry.cc b/src/FileAllocationEntry.cc index 77690475..80809030 100644 --- a/src/FileAllocationEntry.cc +++ b/src/FileAllocationEntry.cc @@ -33,9 +33,16 @@ */ /* copyright --> */ #include "FileAllocationEntry.h" +#include "DownloadCommand.h" #define BUFSIZE 16*1024 +FileAllocationEntry::~FileAllocationEntry() +{ + --_requestGroup->numConnection; + delete _nextDownloadCommand; +} + void FileAllocationEntry::allocateChunk() { int32_t bufSize = BUFSIZE; diff --git a/src/FileAllocationEntry.h b/src/FileAllocationEntry.h index f3f9446c..d8cea83a 100644 --- a/src/FileAllocationEntry.h +++ b/src/FileAllocationEntry.h @@ -39,12 +39,15 @@ #include "Request.h" #include "RequestGroup.h" +class DownloadCommand; + class FileAllocationEntry { private: int _cuid; RequestHandle _currentRequest; RequestGroup* _requestGroup; int64_t _offset; + DownloadCommand* _nextDownloadCommand; public: FileAllocationEntry(int cuid, const RequestHandle& currentRequest, @@ -53,15 +56,13 @@ public: _cuid(cuid), _currentRequest(currentRequest), _requestGroup(requestGroup), - _offset(offset) + _offset(offset), + _nextDownloadCommand(0) { ++_requestGroup->numConnection; } - ~FileAllocationEntry() - { - --_requestGroup->numConnection; - } + ~FileAllocationEntry(); int getCUID() const { @@ -94,6 +95,16 @@ public: { return _requestGroup->getSegmentMan()->totalSize <= _offset; } + + void setNextDownloadCommand(DownloadCommand* command) + { + _nextDownloadCommand = command; + } + + DownloadCommand* getNextDownloadCommand() const + { + return _nextDownloadCommand; + } }; typedef SharedHandle<FileAllocationEntry> FileAllocationEntryHandle; diff --git a/src/HttpDownloadCommand.cc b/src/HttpDownloadCommand.cc index c23142ee..de4d6f27 100644 --- a/src/HttpDownloadCommand.cc +++ b/src/HttpDownloadCommand.cc @@ -47,9 +47,7 @@ HttpDownloadCommand::HttpDownloadCommand(int cuid, HttpDownloadCommand::~HttpDownloadCommand() {} bool HttpDownloadCommand::prepareForNextSegment() { - if(_requestGroup->getSegmentMan()->finished()) { - return true; - } else { + if(!_requestGroup->getSegmentMan()->finished()) { if(req->isKeepAlive()) { Command* command = new HttpRequestCommand(cuid, req, _requestGroup, e, socket); e->commands.push_back(command); @@ -57,5 +55,7 @@ bool HttpDownloadCommand::prepareForNextSegment() { } else { return DownloadCommand::prepareForNextSegment(); } + } else { + return DownloadCommand::prepareForNextSegment(); } } diff --git a/src/HttpResponseCommand.cc b/src/HttpResponseCommand.cc index 1ba9b680..f3dcfe09 100644 --- a/src/HttpResponseCommand.cc +++ b/src/HttpResponseCommand.cc @@ -91,7 +91,7 @@ bool HttpResponseCommand::executeInternal() _requestGroup->validateFilename(httpResponse->determinFilename()); _requestGroup->validateTotalLength(httpResponse->getEntityLength()); - createHttpDownloadCommand(httpResponse); + e->commands.push_back(createHttpDownloadCommand(httpResponse)); return true; } else { // TODO validate totalsize against hintTotalSize if it is provided. @@ -136,8 +136,13 @@ bool HttpResponseCommand::handleDefaultEncoding(const HttpResponseHandle& httpRe } } + DownloadCommand* command = 0; + File file(_requestGroup->getFilePath()); + if(_requestGroup->getRemainingUris().empty() && !file.exists()) { + command = createHttpDownloadCommand(httpResponse); + } _requestGroup->loadAndOpenFile(); - _requestGroup->prepareForNextAction(cuid, req, e); + _requestGroup->prepareForNextAction(cuid, req, e, command); e->noWait = true; return true; } @@ -157,11 +162,11 @@ bool HttpResponseCommand::handleOtherEncoding(const HttpResponseHandle& httpResp req->setKeepAlive(false); segment = _requestGroup->getSegmentMan()->getSegment(cuid); _requestGroup->getSegmentMan()->diskWriter->initAndOpenFile(_requestGroup->getSegmentMan()->getFilePath()); - createHttpDownloadCommand(httpResponse); + e->commands.push_back(createHttpDownloadCommand(httpResponse)); return true; } -void HttpResponseCommand::createHttpDownloadCommand(const HttpResponseHandle& httpResponse) +HttpDownloadCommand* HttpResponseCommand::createHttpDownloadCommand(const HttpResponseHandle& httpResponse) { TransferEncodingHandle enc = 0; if(httpResponse->isTransferEncodingSpecified()) { @@ -179,7 +184,7 @@ void HttpResponseCommand::createHttpDownloadCommand(const HttpResponseHandle& ht command->setLowestDownloadSpeedLimit(e->option->getAsInt(PREF_LOWEST_SPEED_LIMIT)); command->setTransferDecoder(enc); - e->commands.push_back(command); + return command; } bool HttpResponseCommand::doTorrentStuff(const HttpResponseHandle& httpResponse) @@ -195,6 +200,6 @@ bool HttpResponseCommand::doTorrentStuff(const HttpResponseHandle& httpResponse) _requestGroup->getSegmentMan()->isSplittable = false; _requestGroup->getSegmentMan()->downloadStarted = true; _requestGroup->getSegmentMan()->diskWriter->initAndOpenFile("/tmp/aria2"+Util::itos((int32_t)getpid())); - createHttpDownloadCommand(httpResponse); + e->commands.push_back(createHttpDownloadCommand(httpResponse)); return true; } diff --git a/src/HttpResponseCommand.h b/src/HttpResponseCommand.h index 8c1c6576..f2c77061 100644 --- a/src/HttpResponseCommand.h +++ b/src/HttpResponseCommand.h @@ -37,6 +37,7 @@ #include "AbstractCommand.h" #include "HttpConnection.h" +#include "HttpDownloadCommand.h" class HttpResponseCommand : public AbstractCommand { private: @@ -44,7 +45,7 @@ private: bool handleDefaultEncoding(const HttpResponseHandle& httpResponse); bool handleOtherEncoding(const HttpResponseHandle& httpResponse); - void createHttpDownloadCommand(const HttpResponseHandle& httpResponse); + HttpDownloadCommand* createHttpDownloadCommand(const HttpResponseHandle& httpResponse); bool doTorrentStuff(const HttpResponseHandle& httpResponse); protected: bool executeInternal(); diff --git a/src/IteratableChecksumValidator.cc b/src/IteratableChecksumValidator.cc new file mode 100644 index 00000000..e094a632 --- /dev/null +++ b/src/IteratableChecksumValidator.cc @@ -0,0 +1,81 @@ +/* <!-- 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 "IteratableChecksumValidator.h" +#include "Util.h" +#include "message.h" + +#define BUFSIZE 16*1024 + +void IteratableChecksumValidator::validateChunk() +{ + if(!finished()) { + + char data[BUFSIZE]; + + int32_t size = _diskWriter->readData(data, sizeof(data), _currentOffset); + + _ctx->digestUpdate(data, size); + _currentOffset += sizeof(data); + + if(finished()) { + unsigned char* digest = new unsigned char[_ctx->digestLength()]; + try { + _ctx->digestFinal(digest); + if(_checksum->getMessageDigest() != Util::toHex(digest, _ctx->digestLength())) { + _bitfield->clearAllBit(); + } + delete [] digest; + } catch(...) { + delete [] digest; + throw; + } + } + } +} + +bool IteratableChecksumValidator::canValidate() const +{ + // We assume file is already opened using DiskWriter::open or openExistingFile. + return !_checksum.isNull() && !_checksum->isEmpty(); +} + +void IteratableChecksumValidator::init() +{ + _bitfield->setAllBit(); + _currentOffset = 0; + + _ctx = new MessageDigestContext(_checksum->getDigestAlgo()); + _ctx->digestInit(); +} diff --git a/src/IteratableChecksumValidator.h b/src/IteratableChecksumValidator.h new file mode 100644 index 00000000..fd941072 --- /dev/null +++ b/src/IteratableChecksumValidator.h @@ -0,0 +1,93 @@ +/* <!-- 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_ITERATABLE_CHECKSUM_VALIDATOR_H_ +#define _D_ITERATABLE_CHECKSUM_VALIDATOR_H_ + +#include "common.h" +#include "BitfieldMan.h" +#include "Checksum.h" +#include "DiskWriter.h" +#include "LogFactory.h" +#include "messageDigest.h" + +class IteratableChecksumValidator +{ +private: + DiskWriterHandle _diskWriter; + BitfieldMan* _bitfield; + int64_t _currentOffset; + ChecksumHandle _checksum; + const Logger* logger; + MessageDigestContextHandle _ctx; + + string calculateActualChecksum(); +public: + IteratableChecksumValidator():_diskWriter(0), _bitfield(0), _currentOffset(0), _checksum(0), logger(LogFactory::getInstance()), _ctx(0) {} + + bool canValidate() const; + + void init(); + + void validateChunk(); + + bool finished() const + { + return _currentOffset >= _bitfield->getTotalLength(); + } + + void setDiskWriter(const DiskWriterHandle& diskWriter) + { + _diskWriter = diskWriter; + } + + void setBitfield(BitfieldMan* bitfield) + { + _bitfield = bitfield; + } + + void setChecksum(const ChecksumHandle& checksum) + { + _checksum = checksum; + } + + int64_t getCurrentOffset() const + { + return _currentOffset; + } +}; + +typedef SharedHandle<IteratableChecksumValidator> IteratableChecksumValidatorHandle; + +#endif // _D_ITERATABLE_CHECKSUM_VALIDATOR_H_ diff --git a/src/Makefile.am b/src/Makefile.am index 2da5d272..069533b0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -95,7 +95,10 @@ SRCS = Socket.h\ UriFileListParser.cc UriFileListParser.h\ SegmentManFactory.h\ AbstractSegmentManFactory.h\ - DefaultSegmentManFactory.cc DefaultSegmentManFactory.h + DefaultSegmentManFactory.cc DefaultSegmentManFactory.h\ + RealtimeCommand.cc RealtimeCommand.h\ + IteratableChecksumValidator.cc IteratableChecksumValidator.h\ + ChecksumCommand.cc ChecksumCommand.h # debug_new.cpp if ENABLE_BITTORRENT @@ -220,9 +223,9 @@ libaria2c_a_SOURCES = $(SRCS) aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\ @LIBGCRYPT_LIBS@ @OPENSSL_LIBS@ @XML_LIBS@ @LIBARES_LIBS@\ @LIBCARES_LIBS@ -#aria2c_LDFLAGS = -pg +aria2c_LDFLAGS = -pg AM_CPPFLAGS = -Wall\ -I../lib -I../intl -I$(top_srcdir)/intl\ @LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@ @XML_CPPFLAGS@\ @LIBARES_CPPFLAGS@ @LIBCARES_CPPFLAGS@\ - -D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@# -pg
\ No newline at end of file + -D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@ -pg
\ No newline at end of file diff --git a/src/Makefile.in b/src/Makefile.in index 98e61e0a..61b0b801 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -237,8 +237,11 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \ MultiUrlRequestInfo.h UriFileListParser.cc UriFileListParser.h \ SegmentManFactory.h AbstractSegmentManFactory.h \ DefaultSegmentManFactory.cc DefaultSegmentManFactory.h \ - MetaEntry.h Data.cc Data.h Dictionary.cc Dictionary.h List.cc \ - List.h MetaFileUtil.cc MetaFileUtil.h MetaEntryVisitor.h \ + RealtimeCommand.cc RealtimeCommand.h \ + IteratableChecksumValidator.cc IteratableChecksumValidator.h \ + ChecksumCommand.cc ChecksumCommand.h MetaEntry.h Data.cc \ + Data.h Dictionary.cc Dictionary.h List.cc List.h \ + MetaFileUtil.cc MetaFileUtil.h MetaEntryVisitor.h \ ShaVisitor.cc ShaVisitor.h PeerConnection.cc PeerConnection.h \ PeerMessageUtil.cc PeerMessageUtil.h PeerAbstractCommand.cc \ PeerAbstractCommand.h PeerInitiateConnectionCommand.cc \ @@ -419,8 +422,9 @@ am__objects_3 = SocketCore.$(OBJEXT) Command.$(OBJEXT) \ IteratableChunkChecksumValidator.$(OBJEXT) \ CheckIntegrityCommand.$(OBJEXT) SingleUrlRequestInfo.$(OBJEXT) \ MultiUrlRequestInfo.$(OBJEXT) UriFileListParser.$(OBJEXT) \ - DefaultSegmentManFactory.$(OBJEXT) $(am__objects_1) \ - $(am__objects_2) + DefaultSegmentManFactory.$(OBJEXT) RealtimeCommand.$(OBJEXT) \ + IteratableChecksumValidator.$(OBJEXT) \ + ChecksumCommand.$(OBJEXT) $(am__objects_1) $(am__objects_2) am_libaria2c_a_OBJECTS = $(am__objects_3) libaria2c_a_OBJECTS = $(am_libaria2c_a_OBJECTS) am__installdirs = "$(DESTDIR)$(bindir)" @@ -649,19 +653,22 @@ SRCS = Socket.h SocketCore.cc SocketCore.h Command.cc Command.h \ MultiUrlRequestInfo.h UriFileListParser.cc UriFileListParser.h \ SegmentManFactory.h AbstractSegmentManFactory.h \ DefaultSegmentManFactory.cc DefaultSegmentManFactory.h \ - $(am__append_1) $(am__append_2) + RealtimeCommand.cc RealtimeCommand.h \ + IteratableChecksumValidator.cc IteratableChecksumValidator.h \ + ChecksumCommand.cc ChecksumCommand.h $(am__append_1) \ + $(am__append_2) noinst_LIBRARIES = libaria2c.a libaria2c_a_SOURCES = $(SRCS) aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\ @LIBGCRYPT_LIBS@ @OPENSSL_LIBS@ @XML_LIBS@ @LIBARES_LIBS@\ @LIBCARES_LIBS@ -#aria2c_LDFLAGS = -pg +aria2c_LDFLAGS = -pg AM_CPPFLAGS = -Wall\ -I../lib -I../intl -I$(top_srcdir)/intl\ @LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@ @XML_CPPFLAGS@\ @LIBARES_CPPFLAGS@ @LIBCARES_CPPFLAGS@\ - -D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@# -pg + -D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@ -pg all: all-am @@ -769,6 +776,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtUnchokeMessage.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ByteArrayDiskWriter.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CheckIntegrityCommand.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ChecksumCommand.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ChunkChecksumValidator.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ChunkedEncoding.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Command.Po@am__quote@ @@ -828,6 +836,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpResponse.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpResponseCommand.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/InitiateConnectionCommandFactory.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IteratableChecksumValidator.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IteratableChunkChecksumValidator.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/List.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LogFactory.Po@am__quote@ @@ -853,6 +862,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PeerListenCommand.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PeerMessageUtil.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Piece.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RealtimeCommand.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Request.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RequestFactory.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RequestGroup.Po@am__quote@ diff --git a/src/MetalinkEntry.cc b/src/MetalinkEntry.cc index 55d44407..6c77f848 100644 --- a/src/MetalinkEntry.cc +++ b/src/MetalinkEntry.cc @@ -40,6 +40,7 @@ MetalinkEntry::MetalinkEntry(): size(0) #ifdef ENABLE_MESSAGE_DIGEST , + checksum(0), chunkChecksum(0) #endif // ENABLE_MESSAGE_DIGEST {} diff --git a/src/MetalinkEntry.h b/src/MetalinkEntry.h index 71c9df31..bc9aa4e2 100644 --- a/src/MetalinkEntry.h +++ b/src/MetalinkEntry.h @@ -48,7 +48,7 @@ public: string language; string os; int64_t size; - Checksum checksum; + ChecksumHandle checksum; public: MetalinkResources resources; #ifdef ENABLE_MESSAGE_DIGEST diff --git a/src/MetalinkRequestInfo.cc b/src/MetalinkRequestInfo.cc index 495a5c3e..69e28c2a 100644 --- a/src/MetalinkRequestInfo.cc +++ b/src/MetalinkRequestInfo.cc @@ -106,7 +106,7 @@ RequestInfos MetalinkRequestInfo::execute() { FindBitTorrentUrl()); Strings urls; int maxConnection = 0; - Checksum checksum; + ChecksumHandle checksum = 0; if(itr == entry->resources.end()) { entry->reorderResourcesByPreference(); diff --git a/src/RealtimeCommand.cc b/src/RealtimeCommand.cc new file mode 100644 index 00000000..a613fc59 --- /dev/null +++ b/src/RealtimeCommand.cc @@ -0,0 +1,49 @@ +/* <!-- 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 "RealtimeCommand.h" + +bool RealtimeCommand::execute() +{ + setStatusRealtime(); + _e->noWait = true; + try { + return executeInternal(); + } catch(Exception* e) { + _requestGroup->getSegmentMan()->errors++; + bool r = handleException(e); + delete e; + return r; + } +} diff --git a/src/RealtimeCommand.h b/src/RealtimeCommand.h new file mode 100644 index 00000000..915aa56b --- /dev/null +++ b/src/RealtimeCommand.h @@ -0,0 +1,62 @@ +/* <!-- 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_REALTIME_COMMAND_H_ +#define _D_REALTIME_COMMAND_H_ + +#include "common.h" +#include "RequestGroup.h" +#include "DownloadEngine.h" +#include "Exception.h" + +class RealtimeCommand : public Command { +protected: + RequestGroup* _requestGroup; + DownloadEngine* _e; +public: + RealtimeCommand(int cuid, RequestGroup* requestGroup, DownloadEngine* e): + Command(cuid), + _requestGroup(requestGroup), + _e(e) {} + + virtual ~RealtimeCommand() {} + + virtual bool execute(); + + virtual bool executeInternal() = 0; + + virtual bool handleException(Exception* e) = 0; +}; + +#endif // _D_REALTIME_COMMAND_H_ diff --git a/src/RequestGroup.cc b/src/RequestGroup.cc index 7ebb011b..63e8ac7b 100644 --- a/src/RequestGroup.cc +++ b/src/RequestGroup.cc @@ -191,21 +191,28 @@ bool RequestGroup::downloadFinishedByFileLength() } } -void RequestGroup::prepareForNextAction(int cuid, const RequestHandle& req, DownloadEngine* e) +void RequestGroup::prepareForNextAction(int cuid, const RequestHandle& req, DownloadEngine* e, DownloadCommand* downloadCommand) { File existingFile(getFilePath()); if(existingFile.size() > 0 && _option->get(PREF_CHECK_INTEGRITY) == V_TRUE) { CheckIntegrityCommand* command = new CheckIntegrityCommand(cuid, req, this, e); + command->setNextDownloadCommand(downloadCommand); command->initValidator(); e->commands.push_back(command); } else if(needsFileAllocation()) { - e->_fileAllocationMan->pushFileAllocationEntry(new FileAllocationEntry(cuid, req, this)); + FileAllocationEntryHandle entry = new FileAllocationEntry(cuid, req, this); + entry->setNextDownloadCommand(downloadCommand); + e->_fileAllocationMan->pushFileAllocationEntry(entry); } else { - int32_t numCommandsToGenerate = 15; - Commands commands = getNextCommand(e, numCommandsToGenerate); - Command* command = InitiateConnectionCommandFactory::createInitiateConnectionCommand(cuid, req, this, e); - commands.push_front(command); - e->addCommand(commands); + if(downloadCommand) { + e->commands.push_back(downloadCommand); + } else { + int32_t numCommandsToGenerate = 15; + Commands commands = getNextCommand(e, numCommandsToGenerate); + Command* command = InitiateConnectionCommandFactory::createInitiateConnectionCommand(cuid, req, this, e); + commands.push_front(command); + e->addCommand(commands); + } } } diff --git a/src/RequestGroup.h b/src/RequestGroup.h index fc15f8ca..d1e496b7 100644 --- a/src/RequestGroup.h +++ b/src/RequestGroup.h @@ -44,6 +44,8 @@ #include "SegmentManFactory.h" #include "DefaultSegmentManFactory.h" +class DownloadCommand; + class DownloadEngine; class RequestGroup { @@ -57,7 +59,7 @@ private: const Option* _option; const Logger* logger; ChunkChecksumHandle _chunkChecksum; - Checksum _checksum; + ChecksumHandle _checksum; void validateFilename(const string& expectedFilename, const string& actualFilename) const; @@ -79,6 +81,7 @@ public: _option(option), logger(LogFactory::getInstance()), _chunkChecksum(0), + _checksum(0), numConnection(0), isTorrent(false) {} @@ -186,15 +189,20 @@ public: void loadAndOpenFile(); - void prepareForNextAction(int cuid, const RequestHandle& req, DownloadEngine* e); + void prepareForNextAction(int cuid, const RequestHandle& req, DownloadEngine* e, DownloadCommand* downloadCommand = 0); bool downloadFinishedByFileLength(); - void setChecksum(const Checksum& checksum) + void setChecksum(const ChecksumHandle& checksum) { _checksum = checksum; } + ChecksumHandle getChecksum() const + { + return _checksum; + } + const string& getHintFilename() const { return _hintFilename; diff --git a/src/Xml2MetalinkProcessor.cc b/src/Xml2MetalinkProcessor.cc index 67925ddc..8289e551 100644 --- a/src/Xml2MetalinkProcessor.cc +++ b/src/Xml2MetalinkProcessor.cc @@ -112,13 +112,15 @@ MetalinkEntryHandle Xml2MetalinkProcessor::getEntry(const string& xpath) { string md; md = Util::toLower(Util::trim(xpathContent(xpath+"/m:verification/m:hash[@type=\"sha1\"]"))); if(md.size() > 0) { - entry->checksum.setMessageDigest(md); - entry->checksum.setDigestAlgo(DIGEST_ALGO_SHA1); + entry->checksum = new Checksum(); + entry->checksum->setMessageDigest(md); + entry->checksum->setDigestAlgo(DIGEST_ALGO_SHA1); } else { md = Util::toLower(Util::trim(xpathContent(xpath+"/m:verification/m:hash[@type=\"md5\"]"))); if(md.size() > 0) { - entry->checksum.setMessageDigest(md); - entry->checksum.setDigestAlgo(DIGEST_ALGO_MD5); + entry->checksum = new Checksum(); + entry->checksum->setMessageDigest(md); + entry->checksum->setDigestAlgo(DIGEST_ALGO_MD5); } } string piecesPath = xpath+"/m:verification/m:pieces"; diff --git a/src/common.h b/src/common.h index ce6a63ab..2c61b472 100644 --- a/src/common.h +++ b/src/common.h @@ -79,5 +79,6 @@ typedef deque<string> Strings; typedef deque<int32_t> Integers; #define OPEN_MODE S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH +#define DIR_OPEN_MODE S_IRWXU|S_IRWXG|S_IRWXO #endif // _D_COMMON_H_ diff --git a/src/message.h b/src/message.h index 17a3f1ee..e45de293 100644 --- a/src/message.h +++ b/src/message.h @@ -57,6 +57,8 @@ #define MSG_GOT_WRONG_PIECE _("CUID#%d - we got wrong piece. index=%d") #define MSG_DOWNLOAD_NOT_COMPLETE _("CUID#%d - Download not complete: %s") #define MSG_DOWNLOAD_ALREADY_COMPLETED _("CUID#%d - Download already completed: %s") +#define MSG_GOOD_CHECKSUM _("CUID#%d - Good checksum: %s") +#define MSG_BAD_CHECKSUM _("CUID#%d - Bad checksum: %s") #define MSG_TRACKER_WARNING_MESSAGE _("Tracker returned warning message: %s") #define MSG_SEGMENT_FILE_EXISTS _("The segment file %s exists.") diff --git a/src/messageDigest.h b/src/messageDigest.h index 8da9a25a..d7743586 100644 --- a/src/messageDigest.h +++ b/src/messageDigest.h @@ -146,5 +146,6 @@ public: } #endif // HAVE_LIBGCRYPT }; +typedef SharedHandle<MessageDigestContext> MessageDigestContextHandle; #endif // ENABLE_SSL #endif // _D_MESSAGE_DIGEST_H_ |
