mirror of https://github.com/aria2/aria2
2007-11-10 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Don't connect server before checking file integrity at startup, if filesize and output file path are known. * src/AbstractCommand.cc * src/StreamFileAllocationEntry.cc * src/Metalink2RequestGroup.cc * src/RequestGroup.{h, cc} * src/HttpResponseCommand.cc * src/FtpNegotiationCommand.cc Added DownloadFailureException. If it is thrown, RequestGroup should halt. * src/AbstractCommand.cc * src/DownloadFailureException.h * src/RequestGroup.cc Catch RecoverableException, instead of DlAbortEx. * src/RequestGroupMan.cc * src/FillRequestGroupCommand.cc * src/MetaFileUtil.cc * src/IteratableChunkChecksumValidator.cc Now first parameter of MSG_DOWNLOAD_ABORTED is gid(RequestGroup:: getGID()) * src/CheckIntegrityCommand.cc * src/message.h Print gid instead of idx. * src/RequestGroupMan.cc Removed exception throwers declaration. * src/DirectDiskAdaptor.{h, cc} * src/SocketCore.{h, cc} * src/MultiDiskAdaptor.{h, cc} * src/HttpConnection.{h, cc} * src/HttpResponse.{h, cc} * src/DiskAdaptor.{h, cc} * src/CopyDiskAdaptor.{h, cc} * src/MultiDiskAdaptor.{h, cc} * src/HttpHeaderProcessor.{h, cc} * src/AbstractSingleDiskAdaptor.{h, cc} * src/Util.{h, cc} * test/UtilTest.cc * src/DefaultDiskWriter.{h, cc} * src/FtpConnection.{h, cc} * src/AbstractDiskWriter.{h, cc} Removed duplicate code. * src/StreamCheckIntegrityEntry.cc Removed unnecessary include. * src/DiskWriter.h Included Exception.h * src/option_processing.cc Included 2 files and added doc * src/TrackerWatcherCommand.cc * src/SocketCore.cc (writeData): Fixed send error with GnuTLS.pull/1/head
parent
76b9093d09
commit
b5ad009809
62
ChangeLog
62
ChangeLog
|
@ -1,3 +1,65 @@
|
||||||
|
2007-11-10 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||||
|
|
||||||
|
Don't connect server before checking file integrity at startup, if
|
||||||
|
filesize and output file path are known.
|
||||||
|
* src/AbstractCommand.cc
|
||||||
|
* src/StreamFileAllocationEntry.cc
|
||||||
|
* src/Metalink2RequestGroup.cc
|
||||||
|
* src/RequestGroup.{h, cc}
|
||||||
|
* src/HttpResponseCommand.cc
|
||||||
|
* src/FtpNegotiationCommand.cc
|
||||||
|
|
||||||
|
Added DownloadFailureException. If it is thrown, RequestGroup should
|
||||||
|
halt.
|
||||||
|
* src/AbstractCommand.cc
|
||||||
|
* src/DownloadFailureException.h
|
||||||
|
* src/RequestGroup.cc
|
||||||
|
|
||||||
|
Catch RecoverableException, instead of DlAbortEx.
|
||||||
|
* src/RequestGroupMan.cc
|
||||||
|
* src/FillRequestGroupCommand.cc
|
||||||
|
* src/MetaFileUtil.cc
|
||||||
|
* src/IteratableChunkChecksumValidator.cc
|
||||||
|
|
||||||
|
Now first parameter of MSG_DOWNLOAD_ABORTED is gid(RequestGroup::
|
||||||
|
getGID())
|
||||||
|
* src/CheckIntegrityCommand.cc
|
||||||
|
* src/message.h
|
||||||
|
|
||||||
|
Print gid instead of idx.
|
||||||
|
* src/RequestGroupMan.cc
|
||||||
|
|
||||||
|
Removed exception throwers declaration.
|
||||||
|
* src/DirectDiskAdaptor.{h, cc}
|
||||||
|
* src/SocketCore.{h, cc}
|
||||||
|
* src/MultiDiskAdaptor.{h, cc}
|
||||||
|
* src/HttpConnection.{h, cc}
|
||||||
|
* src/HttpResponse.{h, cc}
|
||||||
|
* src/DiskAdaptor.{h, cc}
|
||||||
|
* src/CopyDiskAdaptor.{h, cc}
|
||||||
|
* src/MultiDiskAdaptor.{h, cc}
|
||||||
|
* src/HttpHeaderProcessor.{h, cc}
|
||||||
|
* src/AbstractSingleDiskAdaptor.{h, cc}
|
||||||
|
* src/Util.{h, cc}
|
||||||
|
* test/UtilTest.cc
|
||||||
|
* src/DefaultDiskWriter.{h, cc}
|
||||||
|
* src/FtpConnection.{h, cc}
|
||||||
|
* src/AbstractDiskWriter.{h, cc}
|
||||||
|
|
||||||
|
Removed duplicate code.
|
||||||
|
* src/StreamCheckIntegrityEntry.cc
|
||||||
|
|
||||||
|
Removed unnecessary include.
|
||||||
|
* src/DiskWriter.h
|
||||||
|
|
||||||
|
Included Exception.h
|
||||||
|
* src/option_processing.cc
|
||||||
|
|
||||||
|
Included 2 files and added doc
|
||||||
|
* src/TrackerWatcherCommand.cc
|
||||||
|
|
||||||
|
* src/SocketCore.cc (writeData): Fixed send error with GnuTLS.
|
||||||
|
|
||||||
2007-11-08 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
2007-11-08 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||||
|
|
||||||
Changed CheckIntegrityEntry interface so that it can define
|
Changed CheckIntegrityEntry interface so that it can define
|
||||||
|
|
9
TODO
9
TODO
|
@ -48,10 +48,15 @@
|
||||||
* Implement the feature to treat http/ftp as auxuality download method for BitTorrent
|
* Implement the feature to treat http/ftp as auxuality download method for BitTorrent
|
||||||
* http-seeding(single and multi-file torrent)
|
* http-seeding(single and multi-file torrent)
|
||||||
* Use content-type for PostDownloadHandler
|
* Use content-type for PostDownloadHandler
|
||||||
|
* Rewrite exception usage:
|
||||||
|
RecoverableException
|
||||||
|
DlRetryEx .... Retry using same connection/url. Should be renamed to TemporaryFailureException
|
||||||
|
DlAbortEx .... Abort download with the connection/url. Should be renamed to PermanentFailureException
|
||||||
|
DownloadFailureException .... RequestGroup should halt.
|
||||||
|
FatalException .... Program should abort.
|
||||||
|
|
||||||
-- remaining features to be implemented for 0.12.0 release
|
-- remaining features to be implemented for 0.12.0 release
|
||||||
* Reimplement ChecksumCommand(validation using 1 checksum for 1 file)
|
* Reimplement ChecksumCommand(validation using 1 checksum for 1 file)
|
||||||
* Implement duplicate download checking in Bt
|
* Implement duplicate download checking in Bt
|
||||||
* improve --metalink-location field
|
* improve --metalink-location field
|
||||||
* Do not connect a server when before checking file integrity.
|
* Piece length conversion when loading file
|
||||||
* If size and filename is provided(for example, metalink), "HEAD" like behavior is unnecessary.
|
|
|
@ -38,25 +38,18 @@
|
||||||
#include "CUIDCounter.h"
|
#include "CUIDCounter.h"
|
||||||
#include "DlAbortEx.h"
|
#include "DlAbortEx.h"
|
||||||
#include "DlRetryEx.h"
|
#include "DlRetryEx.h"
|
||||||
#include "FatalException.h"
|
#include "DownloadFailureException.h"
|
||||||
#include "InitiateConnectionCommandFactory.h"
|
#include "InitiateConnectionCommandFactory.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
#include "SleepCommand.h"
|
#include "SleepCommand.h"
|
||||||
#include "prefs.h"
|
#include "prefs.h"
|
||||||
#include "DNSCache.h"
|
#include "DNSCache.h"
|
||||||
#include "SingleFileDownloadContext.h"
|
|
||||||
#include "DefaultPieceStorage.h"
|
|
||||||
#include "UnknownLengthPieceStorage.h"
|
|
||||||
#include "File.h"
|
|
||||||
#include "StreamCheckIntegrityEntry.h"
|
#include "StreamCheckIntegrityEntry.h"
|
||||||
#include "BtProgressInfoFile.h"
|
|
||||||
#include "CheckIntegrityCommand.h"
|
|
||||||
#include "DiskAdaptor.h"
|
|
||||||
#include "PeerStat.h"
|
#include "PeerStat.h"
|
||||||
#include "Segment.h"
|
#include "Segment.h"
|
||||||
#include "DiskWriterFactory.h"
|
|
||||||
#include "Option.h"
|
#include "Option.h"
|
||||||
|
#include "PieceStorage.h"
|
||||||
|
|
||||||
AbstractCommand::AbstractCommand(int32_t cuid,
|
AbstractCommand::AbstractCommand(int32_t cuid,
|
||||||
const RequestHandle& req,
|
const RequestHandle& req,
|
||||||
|
@ -158,7 +151,8 @@ bool AbstractCommand::execute() {
|
||||||
delete(err);
|
delete(err);
|
||||||
return prepareForRetry(e->option->getAsInt(PREF_RETRY_WAIT));
|
return prepareForRetry(e->option->getAsInt(PREF_RETRY_WAIT));
|
||||||
}
|
}
|
||||||
} catch(FatalException* err) {
|
} catch(DownloadFailureException* err) {
|
||||||
|
logger->error(EX_EXCEPTION_CAUGHT, err);
|
||||||
delete(err);
|
delete(err);
|
||||||
_requestGroup->setHaltRequested(true);
|
_requestGroup->setHaltRequested(true);
|
||||||
return true;
|
return true;
|
||||||
|
@ -300,131 +294,9 @@ bool AbstractCommand::nameResolveFinished() const {
|
||||||
}
|
}
|
||||||
#endif // ENABLE_ASYNC_DNS
|
#endif // ENABLE_ASYNC_DNS
|
||||||
|
|
||||||
void AbstractCommand::loadAndOpenFile(const BtProgressInfoFileHandle& progressInfoFile)
|
|
||||||
{
|
|
||||||
if(!_requestGroup->isPreLocalFileCheckEnabled()) {
|
|
||||||
_requestGroup->getPieceStorage()->getDiskAdaptor()->initAndOpenFile();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//_requestGroup->setProgressInfoFile(new DefaultBtProgressInfoFile(_requestGroup->getDownloadContext(), _requestGroup->getPieceStorage(), e->option));
|
|
||||||
if(progressInfoFile->exists()) {
|
|
||||||
progressInfoFile->load();
|
|
||||||
_requestGroup->getPieceStorage()->getDiskAdaptor()->openExistingFile();
|
|
||||||
} else {
|
|
||||||
File outfile(_requestGroup->getFilePath());
|
|
||||||
if(outfile.exists() && e->option->get(PREF_CONTINUE) == V_TRUE) {
|
|
||||||
if(_requestGroup->getTotalLength() < outfile.size()) {
|
|
||||||
throw new FatalException(EX_FILE_LENGTH_MISMATCH_BETWEEN_LOCAL_AND_REMOTE,
|
|
||||||
_requestGroup->getFilePath().c_str(),
|
|
||||||
Util::llitos(outfile.size()).c_str(),
|
|
||||||
Util::llitos(_requestGroup->getTotalLength()).c_str());
|
|
||||||
}
|
|
||||||
_requestGroup->getPieceStorage()->getDiskAdaptor()->openExistingFile();
|
|
||||||
_requestGroup->getPieceStorage()->markPiecesDone(outfile.size());
|
|
||||||
} else {
|
|
||||||
#ifdef ENABLE_MESSAGE_DIGEST
|
|
||||||
if(outfile.exists() && e->option->get(PREF_CHECK_INTEGRITY) == V_TRUE) {
|
|
||||||
_requestGroup->getPieceStorage()->getDiskAdaptor()->openExistingFile();
|
|
||||||
} else {
|
|
||||||
shouldCancelDownloadForSafety();
|
|
||||||
_requestGroup->getPieceStorage()->getDiskAdaptor()->initAndOpenFile();
|
|
||||||
}
|
|
||||||
#else // ENABLE_MESSAGE_DIGEST
|
|
||||||
shouldCancelDownloadForSafety();
|
|
||||||
_requestGroup->getPieceStorage()->getDiskAdaptor()->initAndOpenFile();
|
|
||||||
#endif // ENABLE_MESSAGE_DIGEST
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_requestGroup->setProgressInfoFile(progressInfoFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractCommand::shouldCancelDownloadForSafety()
|
|
||||||
{
|
|
||||||
File outfile(_requestGroup->getFilePath());
|
|
||||||
if(outfile.exists() && !_requestGroup->getProgressInfoFile()->exists()) {
|
|
||||||
if(e->option->get(PREF_AUTO_FILE_RENAMING) == V_TRUE) {
|
|
||||||
if(tryAutoFileRenaming()) {
|
|
||||||
logger->notice("File already exists. Renamed to %s.",
|
|
||||||
_requestGroup->getFilePath().c_str());
|
|
||||||
} else {
|
|
||||||
logger->notice("File renaming failed: %s",
|
|
||||||
_requestGroup->getFilePath().c_str());
|
|
||||||
throw new FatalException(EX_DOWNLOAD_ABORTED);
|
|
||||||
}
|
|
||||||
} else if(e->option->get(PREF_ALLOW_OVERWRITE) != V_TRUE) {
|
|
||||||
logger->notice(MSG_FILE_ALREADY_EXISTS,
|
|
||||||
_requestGroup->getFilePath().c_str(),
|
|
||||||
_requestGroup->getProgressInfoFile()->getFilename().c_str());
|
|
||||||
throw new FatalException(EX_DOWNLOAD_ABORTED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AbstractCommand::tryAutoFileRenaming()
|
|
||||||
{
|
|
||||||
string filepath = _requestGroup->getFilePath();
|
|
||||||
if(filepath.empty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for(int32_t i = 1; i < 10000; ++i) {
|
|
||||||
File newfile(filepath+"."+Util::itos(i));
|
|
||||||
if(!newfile.exists()) {
|
|
||||||
SingleFileDownloadContextHandle(_requestGroup->getDownloadContext())->setUFilename(newfile.getBasename());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractCommand::initPieceStorage()
|
|
||||||
{
|
|
||||||
if(_requestGroup->getDownloadContext()->getTotalLength() == 0) {
|
|
||||||
UnknownLengthPieceStorageHandle ps = new UnknownLengthPieceStorage(_requestGroup->getDownloadContext(), e->option);
|
|
||||||
if(!_requestGroup->getDiskWriterFactory().isNull()) {
|
|
||||||
ps->setDiskWriterFactory(_requestGroup->getDiskWriterFactory());
|
|
||||||
}
|
|
||||||
_requestGroup->setPieceStorage(ps);
|
|
||||||
} else {
|
|
||||||
DefaultPieceStorageHandle ps = new DefaultPieceStorage(_requestGroup->getDownloadContext(), e->option);
|
|
||||||
if(!_requestGroup->getDiskWriterFactory().isNull()) {
|
|
||||||
ps->setDiskWriterFactory(_requestGroup->getDiskWriterFactory());
|
|
||||||
}
|
|
||||||
_requestGroup->setPieceStorage(ps);
|
|
||||||
}
|
|
||||||
_requestGroup->getPieceStorage()->initStorage();
|
|
||||||
_requestGroup->initSegmentMan();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AbstractCommand::downloadFinishedByFileLength()
|
|
||||||
{
|
|
||||||
// TODO consider the case when the getFilePath() returns dir path.
|
|
||||||
File outfile(_requestGroup->getFilePath());
|
|
||||||
if(outfile.exists() &&
|
|
||||||
_requestGroup->getTotalLength() == outfile.size()) {
|
|
||||||
_requestGroup->getPieceStorage()->markAllPiecesDone();
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractCommand::prepareForNextAction(Command* nextCommand)
|
void AbstractCommand::prepareForNextAction(Command* nextCommand)
|
||||||
{
|
{
|
||||||
CheckIntegrityEntryHandle entry =
|
CheckIntegrityEntryHandle entry =
|
||||||
new StreamCheckIntegrityEntry(req, _requestGroup, nextCommand);
|
new StreamCheckIntegrityEntry(req, _requestGroup, nextCommand);
|
||||||
#ifdef ENABLE_MESSAGE_DIGEST
|
e->addCommand(_requestGroup->processCheckIntegrityEntry(entry, e));
|
||||||
if(File(_requestGroup->getFilePath()).size() > 0 &&
|
|
||||||
e->option->get(PREF_CHECK_INTEGRITY) == V_TRUE &&
|
|
||||||
entry->isValidationReady()) {
|
|
||||||
entry->initValidator();
|
|
||||||
logger->debug("Issuing CheckIntegrityCommand.");
|
|
||||||
CheckIntegrityCommand* command =
|
|
||||||
new CheckIntegrityCommand(CUIDCounterSingletonHolder::instance()->newID(), _requestGroup, e, entry);
|
|
||||||
e->commands.push_back(command);
|
|
||||||
} else
|
|
||||||
#endif // ENABLE_MESSAGE_DIGEST
|
|
||||||
{
|
|
||||||
e->addCommand(entry->onDownloadIncomplete(e));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
#include "LogFactory.h"
|
#include "LogFactory.h"
|
||||||
#include "a2io.h"
|
#include "a2io.h"
|
||||||
|
#include "DlAbortEx.h"
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
@ -55,7 +56,6 @@ AbstractDiskWriter::~AbstractDiskWriter()
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractDiskWriter::openFile(const string& filename, int64_t totalLength)
|
void AbstractDiskWriter::openFile(const string& filename, int64_t totalLength)
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
File f(filename);
|
File f(filename);
|
||||||
if(f.exists()) {
|
if(f.exists()) {
|
||||||
|
@ -75,7 +75,6 @@ void AbstractDiskWriter::closeFile()
|
||||||
|
|
||||||
void AbstractDiskWriter::openExistingFile(const string& filename,
|
void AbstractDiskWriter::openExistingFile(const string& filename,
|
||||||
int64_t totalLength)
|
int64_t totalLength)
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
this->filename = filename;
|
this->filename = filename;
|
||||||
File f(filename);
|
File f(filename);
|
||||||
|
@ -89,7 +88,6 @@ void AbstractDiskWriter::openExistingFile(const string& filename,
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractDiskWriter::createFile(const string& filename, int32_t addFlags)
|
void AbstractDiskWriter::createFile(const string& filename, int32_t addFlags)
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
this->filename = filename;
|
this->filename = filename;
|
||||||
assert(filename.size());
|
assert(filename.size());
|
||||||
|
@ -110,7 +108,6 @@ int32_t AbstractDiskWriter::readDataInternal(unsigned char* data, int32_t len)
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractDiskWriter::seek(int64_t offset)
|
void AbstractDiskWriter::seek(int64_t offset)
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
if(offset != lseek(fd, offset, SEEK_SET)) {
|
if(offset != lseek(fd, offset, SEEK_SET)) {
|
||||||
throw new DlAbortEx(EX_FILE_SEEK, filename.c_str(), strerror(errno));
|
throw new DlAbortEx(EX_FILE_SEEK, filename.c_str(), strerror(errno));
|
||||||
|
@ -118,7 +115,6 @@ void AbstractDiskWriter::seek(int64_t offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractDiskWriter::writeData(const unsigned char* data, int32_t len, int64_t offset)
|
void AbstractDiskWriter::writeData(const unsigned char* data, int32_t len, int64_t offset)
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
seek(offset);
|
seek(offset);
|
||||||
if(writeDataInternal(data, len) < 0) {
|
if(writeDataInternal(data, len) < 0) {
|
||||||
|
@ -127,7 +123,6 @@ void AbstractDiskWriter::writeData(const unsigned char* data, int32_t len, int64
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t AbstractDiskWriter::readData(unsigned char* data, int32_t len, int64_t offset)
|
int32_t AbstractDiskWriter::readData(unsigned char* data, int32_t len, int64_t offset)
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
int32_t ret;
|
int32_t ret;
|
||||||
seek(offset);
|
seek(offset);
|
||||||
|
@ -138,7 +133,6 @@ int32_t AbstractDiskWriter::readData(unsigned char* data, int32_t len, int64_t o
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractDiskWriter::truncate(int64_t length)
|
void AbstractDiskWriter::truncate(int64_t length)
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
if(fd == -1) {
|
if(fd == -1) {
|
||||||
throw new DlAbortEx("File not opened.");
|
throw new DlAbortEx("File not opened.");
|
||||||
|
@ -148,7 +142,6 @@ void AbstractDiskWriter::truncate(int64_t length)
|
||||||
|
|
||||||
// TODO the file descriptor fd must be opened before calling this function.
|
// TODO the file descriptor fd must be opened before calling this function.
|
||||||
int64_t AbstractDiskWriter::size() const
|
int64_t AbstractDiskWriter::size() const
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
if(fd == -1) {
|
if(fd == -1) {
|
||||||
throw new DlAbortEx("File not opened.");
|
throw new DlAbortEx("File not opened.");
|
||||||
|
|
|
@ -37,7 +37,6 @@
|
||||||
|
|
||||||
#include "DiskWriter.h"
|
#include "DiskWriter.h"
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
#include "DlAbortEx.h"
|
|
||||||
|
|
||||||
class AbstractDiskWriter : public DiskWriter {
|
class AbstractDiskWriter : public DiskWriter {
|
||||||
protected:
|
protected:
|
||||||
|
@ -45,31 +44,31 @@ protected:
|
||||||
int32_t fd;
|
int32_t fd;
|
||||||
const Logger* logger;
|
const Logger* logger;
|
||||||
|
|
||||||
void createFile(const string& filename, int32_t addFlags = 0) throw(DlAbortEx*);
|
void createFile(const string& filename, int32_t addFlags = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int32_t writeDataInternal(const unsigned char* data, int32_t len);
|
int32_t writeDataInternal(const unsigned char* data, int32_t len);
|
||||||
int32_t readDataInternal(unsigned char* data, int32_t len);
|
int32_t readDataInternal(unsigned char* data, int32_t len);
|
||||||
|
|
||||||
void seek(int64_t offset) throw(DlAbortEx*);
|
void seek(int64_t offset);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AbstractDiskWriter();
|
AbstractDiskWriter();
|
||||||
virtual ~AbstractDiskWriter();
|
virtual ~AbstractDiskWriter();
|
||||||
|
|
||||||
virtual void openFile(const string& filename, int64_t totalLength = 0) throw(DlAbortEx*);
|
virtual void openFile(const string& filename, int64_t totalLength = 0);
|
||||||
|
|
||||||
virtual void closeFile();
|
virtual void closeFile();
|
||||||
|
|
||||||
virtual void openExistingFile(const string& filename, int64_t totalLength = 0) throw(DlAbortEx*);
|
virtual void openExistingFile(const string& filename, int64_t totalLength = 0);
|
||||||
|
|
||||||
virtual void writeData(const unsigned char* data, int32_t len, int64_t offset) throw(DlAbortEx*);
|
virtual void writeData(const unsigned char* data, int32_t len, int64_t offset);
|
||||||
|
|
||||||
virtual int32_t readData(unsigned char* data, int32_t len, int64_t offset) throw(DlAbortEx*);
|
virtual int32_t readData(unsigned char* data, int32_t len, int64_t offset);
|
||||||
|
|
||||||
virtual void truncate(int64_t length) throw(DlAbortEx*);
|
virtual void truncate(int64_t length);
|
||||||
|
|
||||||
virtual int64_t size() const throw(DlAbortEx*);
|
virtual int64_t size() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _D_ABSTRACT_DISK_WRITER_H_
|
#endif // _D_ABSTRACT_DISK_WRITER_H_
|
||||||
|
|
|
@ -37,13 +37,11 @@
|
||||||
#include "SingleFileAllocationIterator.h"
|
#include "SingleFileAllocationIterator.h"
|
||||||
|
|
||||||
void AbstractSingleDiskAdaptor::initAndOpenFile()
|
void AbstractSingleDiskAdaptor::initAndOpenFile()
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
diskWriter->initAndOpenFile(getFilePath(), totalLength);
|
diskWriter->initAndOpenFile(getFilePath(), totalLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractSingleDiskAdaptor::openFile()
|
void AbstractSingleDiskAdaptor::openFile()
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
diskWriter->openFile(getFilePath(), totalLength);
|
diskWriter->openFile(getFilePath(), totalLength);
|
||||||
}
|
}
|
||||||
|
@ -54,19 +52,16 @@ void AbstractSingleDiskAdaptor::closeFile()
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractSingleDiskAdaptor::openExistingFile()
|
void AbstractSingleDiskAdaptor::openExistingFile()
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
diskWriter->openExistingFile(getFilePath(), totalLength);
|
diskWriter->openExistingFile(getFilePath(), totalLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractSingleDiskAdaptor::writeData(const unsigned char* data, int32_t len, int64_t offset)
|
void AbstractSingleDiskAdaptor::writeData(const unsigned char* data, int32_t len, int64_t offset)
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
diskWriter->writeData(data, len, offset);
|
diskWriter->writeData(data, len, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t AbstractSingleDiskAdaptor::readData(unsigned char* data, int32_t len, int64_t offset)
|
int32_t AbstractSingleDiskAdaptor::readData(unsigned char* data, int32_t len, int64_t offset)
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
return diskWriter->readData(data, len, offset);
|
return diskWriter->readData(data, len, offset);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,6 @@
|
||||||
|
|
||||||
#include "DiskAdaptor.h"
|
#include "DiskAdaptor.h"
|
||||||
#include "DiskWriter.h"
|
#include "DiskWriter.h"
|
||||||
#include "DlAbortEx.h"
|
|
||||||
|
|
||||||
class AbstractSingleDiskAdaptor : public DiskAdaptor {
|
class AbstractSingleDiskAdaptor : public DiskAdaptor {
|
||||||
protected:
|
protected:
|
||||||
|
@ -48,27 +47,27 @@ public:
|
||||||
|
|
||||||
virtual ~AbstractSingleDiskAdaptor() {}
|
virtual ~AbstractSingleDiskAdaptor() {}
|
||||||
|
|
||||||
virtual void initAndOpenFile() throw(DlAbortEx*);
|
virtual void initAndOpenFile();
|
||||||
|
|
||||||
virtual void openFile() throw(DlAbortEx*);
|
virtual void openFile();
|
||||||
|
|
||||||
virtual void closeFile();
|
virtual void closeFile();
|
||||||
|
|
||||||
virtual void openExistingFile() throw(DlAbortEx*);
|
virtual void openExistingFile();
|
||||||
|
|
||||||
virtual void writeData(const unsigned char* data, int32_t len,
|
virtual void writeData(const unsigned char* data, int32_t len,
|
||||||
int64_t offset) throw(DlAbortEx*);
|
int64_t offset);
|
||||||
|
|
||||||
virtual int32_t readData(unsigned char* data, int32_t len, int64_t offset) throw(DlAbortEx*);
|
virtual int32_t readData(unsigned char* data, int32_t len, int64_t offset);
|
||||||
|
|
||||||
virtual bool fileExists();
|
virtual bool fileExists();
|
||||||
|
|
||||||
virtual int64_t size() const throw(DlAbortEx*)
|
virtual int64_t size() const
|
||||||
{
|
{
|
||||||
return diskWriter->size();
|
return diskWriter->size();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void truncate(int64_t length) throw(DlAbortEx*)
|
virtual void truncate(int64_t length)
|
||||||
{
|
{
|
||||||
diskWriter->truncate(length);
|
diskWriter->truncate(length);
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,8 @@ bool CheckIntegrityCommand::executeInternal()
|
||||||
if(_entry->finished()) {
|
if(_entry->finished()) {
|
||||||
_entry->updatePieceStorage();
|
_entry->updatePieceStorage();
|
||||||
if(_requestGroup->downloadFinished()) {
|
if(_requestGroup->downloadFinished()) {
|
||||||
logger->notice(MSG_DOWNLOAD_ALREADY_COMPLETED, cuid, _requestGroup->getFilePath().c_str());
|
logger->notice(MSG_DOWNLOAD_ALREADY_COMPLETED, _requestGroup->getGID(),
|
||||||
|
_requestGroup->getFilePath().c_str());
|
||||||
_e->addCommand(_entry->onDownloadFinished(_e));
|
_e->addCommand(_entry->onDownloadFinished(_e));
|
||||||
} else {
|
} else {
|
||||||
_e->addCommand(_entry->onDownloadIncomplete(_e));
|
_e->addCommand(_entry->onDownloadIncomplete(_e));
|
||||||
|
|
|
@ -37,7 +37,6 @@
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
|
|
||||||
void CopyDiskAdaptor::onDownloadComplete()
|
void CopyDiskAdaptor::onDownloadComplete()
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
closeFile();
|
closeFile();
|
||||||
fixFilename();
|
fixFilename();
|
||||||
|
@ -45,7 +44,6 @@ void CopyDiskAdaptor::onDownloadComplete()
|
||||||
}
|
}
|
||||||
|
|
||||||
void CopyDiskAdaptor::fixFilename()
|
void CopyDiskAdaptor::fixFilename()
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
int64_t offset = 0;
|
int64_t offset = 0;
|
||||||
for(FileEntries::iterator itr = fileEntries.begin();
|
for(FileEntries::iterator itr = fileEntries.begin();
|
||||||
|
|
|
@ -36,14 +36,13 @@
|
||||||
#define _D_COPY_DISK_ADAPTOR_H_
|
#define _D_COPY_DISK_ADAPTOR_H_
|
||||||
|
|
||||||
#include "AbstractSingleDiskAdaptor.h"
|
#include "AbstractSingleDiskAdaptor.h"
|
||||||
#include "DlAbortEx.h"
|
|
||||||
|
|
||||||
class CopyDiskAdaptor : public AbstractSingleDiskAdaptor {
|
class CopyDiskAdaptor : public AbstractSingleDiskAdaptor {
|
||||||
private:
|
private:
|
||||||
string tempFilename;
|
string tempFilename;
|
||||||
string topDir;
|
string topDir;
|
||||||
|
|
||||||
void fixFilename() throw(DlAbortEx*);
|
void fixFilename();
|
||||||
public:
|
public:
|
||||||
CopyDiskAdaptor() {}
|
CopyDiskAdaptor() {}
|
||||||
|
|
||||||
|
@ -51,7 +50,7 @@ public:
|
||||||
|
|
||||||
virtual string getFilePath();
|
virtual string getFilePath();
|
||||||
|
|
||||||
virtual void onDownloadComplete() throw(DlAbortEx*);
|
virtual void onDownloadComplete();
|
||||||
|
|
||||||
// tempFilename is relative to storeDir
|
// tempFilename is relative to storeDir
|
||||||
void setTempFilename(const string& tempFilename) {
|
void setTempFilename(const string& tempFilename) {
|
||||||
|
|
|
@ -45,7 +45,6 @@ DefaultDiskWriter::~DefaultDiskWriter() {}
|
||||||
|
|
||||||
void DefaultDiskWriter::initAndOpenFile(const string& filename,
|
void DefaultDiskWriter::initAndOpenFile(const string& filename,
|
||||||
int64_t totalLength)
|
int64_t totalLength)
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
createFile(filename);
|
createFile(filename);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,6 @@
|
||||||
|
|
||||||
#include "AbstractDiskWriter.h"
|
#include "AbstractDiskWriter.h"
|
||||||
#include "Option.h"
|
#include "Option.h"
|
||||||
#include "DlAbortEx.h"
|
|
||||||
|
|
||||||
class DefaultDiskWriter:public AbstractDiskWriter {
|
class DefaultDiskWriter:public AbstractDiskWriter {
|
||||||
public:
|
public:
|
||||||
|
@ -45,8 +44,7 @@ public:
|
||||||
|
|
||||||
virtual ~DefaultDiskWriter();
|
virtual ~DefaultDiskWriter();
|
||||||
|
|
||||||
virtual void initAndOpenFile(const string& filename,
|
virtual void initAndOpenFile(const string& filename, int64_t totalLength = 0);
|
||||||
int64_t totalLength = 0) throw(DlAbortEx*);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef SharedHandle<DefaultDiskWriter> DefaultDiskWriterHandle;
|
typedef SharedHandle<DefaultDiskWriter> DefaultDiskWriterHandle;
|
||||||
|
|
|
@ -40,7 +40,6 @@ string DirectDiskAdaptor::getFilePath()
|
||||||
}
|
}
|
||||||
|
|
||||||
void DirectDiskAdaptor::onDownloadComplete()
|
void DirectDiskAdaptor::onDownloadComplete()
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
closeFile();
|
closeFile();
|
||||||
openFile();
|
openFile();
|
||||||
|
|
|
@ -36,7 +36,6 @@
|
||||||
#define _D_DIRECT_DISK_ADAPTOR_H_
|
#define _D_DIRECT_DISK_ADAPTOR_H_
|
||||||
|
|
||||||
#include "AbstractSingleDiskAdaptor.h"
|
#include "AbstractSingleDiskAdaptor.h"
|
||||||
#include "DlAbortEx.h"
|
|
||||||
|
|
||||||
class DirectDiskAdaptor : public AbstractSingleDiskAdaptor {
|
class DirectDiskAdaptor : public AbstractSingleDiskAdaptor {
|
||||||
public:
|
public:
|
||||||
|
@ -45,7 +44,7 @@ public:
|
||||||
|
|
||||||
virtual string getFilePath();
|
virtual string getFilePath();
|
||||||
|
|
||||||
virtual void onDownloadComplete() throw(DlAbortEx*);
|
virtual void onDownloadComplete();
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef SharedHandle<DirectDiskAdaptor> DirectDiskAdaptorHandle;
|
typedef SharedHandle<DirectDiskAdaptor> DirectDiskAdaptorHandle;
|
||||||
|
|
|
@ -35,13 +35,13 @@
|
||||||
#include "DiskAdaptor.h"
|
#include "DiskAdaptor.h"
|
||||||
#include "LogFactory.h"
|
#include "LogFactory.h"
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
|
#include "DlAbortEx.h"
|
||||||
|
|
||||||
DiskAdaptor::DiskAdaptor():logger(LogFactory::getInstance()) {}
|
DiskAdaptor::DiskAdaptor():logger(LogFactory::getInstance()) {}
|
||||||
|
|
||||||
DiskAdaptor::~DiskAdaptor() {}
|
DiskAdaptor::~DiskAdaptor() {}
|
||||||
|
|
||||||
FileEntryHandle DiskAdaptor::getFileEntryFromPath(const string& fileEntryPath) const
|
FileEntryHandle DiskAdaptor::getFileEntryFromPath(const string& fileEntryPath) const
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
for(FileEntries::const_iterator itr = fileEntries.begin();
|
for(FileEntries::const_iterator itr = fileEntries.begin();
|
||||||
itr != fileEntries.end(); itr++) {
|
itr != fileEntries.end(); itr++) {
|
||||||
|
|
|
@ -39,7 +39,6 @@
|
||||||
#include "FileEntry.h"
|
#include "FileEntry.h"
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
#include "FileAllocationIterator.h"
|
#include "FileAllocationIterator.h"
|
||||||
#include "DlAbortEx.h"
|
|
||||||
|
|
||||||
class DiskAdaptor:public BinaryStream {
|
class DiskAdaptor:public BinaryStream {
|
||||||
protected:
|
protected:
|
||||||
|
@ -73,8 +72,7 @@ public:
|
||||||
this->fileEntries = fileEntries;
|
this->fileEntries = fileEntries;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileEntryHandle
|
FileEntryHandle getFileEntryFromPath(const string& fileEntryPath) const;
|
||||||
getFileEntryFromPath(const string& fileEntryPath) const throw(DlAbortEx*);
|
|
||||||
|
|
||||||
const FileEntries& getFileEntries() const { return fileEntries; }
|
const FileEntries& getFileEntries() const { return fileEntries; }
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,6 @@
|
||||||
#define _D_DISK_WRITER_H_
|
#define _D_DISK_WRITER_H_
|
||||||
|
|
||||||
#include "BinaryStream.h"
|
#include "BinaryStream.h"
|
||||||
#include "DlAbortEx.h"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for writing to a binary stream of bytes.
|
* Interface for writing to a binary stream of bytes.
|
||||||
|
|
|
@ -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_DOWNLOAD_FAILURE_EXCEPTION_H_
|
||||||
|
#define _D_DOWNLOAD_FAILURE_EXCEPTION_H_
|
||||||
|
#include "RecoverableException.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throw this exception when a RequestGroup should aborted.
|
||||||
|
* FYI, DlAbortEx is the exception to abort 1 Request.
|
||||||
|
*/
|
||||||
|
class DownloadFailureException : public RecoverableException {
|
||||||
|
public:
|
||||||
|
DownloadFailureException(Exception* cause = 0):RecoverableException(cause) {}
|
||||||
|
|
||||||
|
DownloadFailureException(const char* msg, ...) {
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, msg);
|
||||||
|
setMsg(string(msg), ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
DownloadFailureException(Exception* cause, const char* msg, ...):RecoverableException(cause) {
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, msg);
|
||||||
|
setMsg(string(msg), ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _D_DOWNLOAD_FAILURE_EXCEPTION_H_
|
|
@ -36,7 +36,7 @@
|
||||||
#include "DownloadEngine.h"
|
#include "DownloadEngine.h"
|
||||||
#include "RequestGroupMan.h"
|
#include "RequestGroupMan.h"
|
||||||
#include "RequestGroup.h"
|
#include "RequestGroup.h"
|
||||||
#include "DlAbortEx.h"
|
#include "RecoverableException.h"
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
|
|
||||||
FillRequestGroupCommand::FillRequestGroupCommand(int32_t cuid,
|
FillRequestGroupCommand::FillRequestGroupCommand(int32_t cuid,
|
||||||
|
@ -55,7 +55,7 @@ bool FillRequestGroupCommand::execute()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
_e->_requestGroupMan->fillRequestGroupFromReserver(_e);
|
_e->_requestGroupMan->fillRequestGroupFromReserver(_e);
|
||||||
} catch(DlAbortEx* ex) {
|
} catch(RecoverableException* ex) {
|
||||||
logger->error(EX_EXCEPTION_CAUGHT, ex);
|
logger->error(EX_EXCEPTION_CAUGHT, ex);
|
||||||
delete ex;
|
delete ex;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#include "LogFactory.h"
|
#include "LogFactory.h"
|
||||||
#include "AuthConfigFactory.h"
|
#include "AuthConfigFactory.h"
|
||||||
#include "AuthConfig.h"
|
#include "AuthConfig.h"
|
||||||
|
#include "DlRetryEx.h"
|
||||||
|
|
||||||
FtpConnection::FtpConnection(int32_t cuid, const SocketHandle& socket,
|
FtpConnection::FtpConnection(int32_t cuid, const SocketHandle& socket,
|
||||||
const RequestHandle req, const Option* op)
|
const RequestHandle req, const Option* op)
|
||||||
|
@ -49,7 +50,6 @@ FtpConnection::FtpConnection(int32_t cuid, const SocketHandle& socket,
|
||||||
FtpConnection::~FtpConnection() {}
|
FtpConnection::~FtpConnection() {}
|
||||||
|
|
||||||
void FtpConnection::sendUser() const
|
void FtpConnection::sendUser() const
|
||||||
throw(DlRetryEx*)
|
|
||||||
{
|
{
|
||||||
string request = "USER "+AuthConfigFactorySingleton::instance()->createAuthConfig(req)->getUser()+"\r\n";
|
string request = "USER "+AuthConfigFactorySingleton::instance()->createAuthConfig(req)->getUser()+"\r\n";
|
||||||
logger->info(MSG_SENDING_REQUEST, cuid, request.c_str());
|
logger->info(MSG_SENDING_REQUEST, cuid, request.c_str());
|
||||||
|
@ -57,7 +57,6 @@ void FtpConnection::sendUser() const
|
||||||
}
|
}
|
||||||
|
|
||||||
void FtpConnection::sendPass() const
|
void FtpConnection::sendPass() const
|
||||||
throw(DlRetryEx*)
|
|
||||||
{
|
{
|
||||||
string request = "PASS "+AuthConfigFactorySingleton::instance()->createAuthConfig(req)->getPassword()+"\r\n";
|
string request = "PASS "+AuthConfigFactorySingleton::instance()->createAuthConfig(req)->getPassword()+"\r\n";
|
||||||
logger->info(MSG_SENDING_REQUEST, cuid, "PASS ********");
|
logger->info(MSG_SENDING_REQUEST, cuid, "PASS ********");
|
||||||
|
@ -65,7 +64,6 @@ void FtpConnection::sendPass() const
|
||||||
}
|
}
|
||||||
|
|
||||||
void FtpConnection::sendType() const
|
void FtpConnection::sendType() const
|
||||||
throw(DlRetryEx*)
|
|
||||||
{
|
{
|
||||||
string type;
|
string type;
|
||||||
if(option->get(PREF_FTP_TYPE) == V_ASCII) {
|
if(option->get(PREF_FTP_TYPE) == V_ASCII) {
|
||||||
|
@ -79,7 +77,6 @@ void FtpConnection::sendType() const
|
||||||
}
|
}
|
||||||
|
|
||||||
void FtpConnection::sendCwd() const
|
void FtpConnection::sendCwd() const
|
||||||
throw(DlRetryEx*)
|
|
||||||
{
|
{
|
||||||
string request = "CWD "+Util::urldecode(req->getDir())+"\r\n";
|
string request = "CWD "+Util::urldecode(req->getDir())+"\r\n";
|
||||||
logger->info(MSG_SENDING_REQUEST, cuid, request.c_str());
|
logger->info(MSG_SENDING_REQUEST, cuid, request.c_str());
|
||||||
|
@ -87,7 +84,6 @@ void FtpConnection::sendCwd() const
|
||||||
}
|
}
|
||||||
|
|
||||||
void FtpConnection::sendSize() const
|
void FtpConnection::sendSize() const
|
||||||
throw(DlRetryEx*)
|
|
||||||
{
|
{
|
||||||
string request = "SIZE "+Util::urldecode(req->getFile())+"\r\n";
|
string request = "SIZE "+Util::urldecode(req->getFile())+"\r\n";
|
||||||
logger->info(MSG_SENDING_REQUEST, cuid, request.c_str());
|
logger->info(MSG_SENDING_REQUEST, cuid, request.c_str());
|
||||||
|
@ -95,7 +91,6 @@ void FtpConnection::sendSize() const
|
||||||
}
|
}
|
||||||
|
|
||||||
void FtpConnection::sendPasv() const
|
void FtpConnection::sendPasv() const
|
||||||
throw(DlRetryEx*)
|
|
||||||
{
|
{
|
||||||
string request = "PASV\r\n";
|
string request = "PASV\r\n";
|
||||||
logger->info(MSG_SENDING_REQUEST, cuid, request.c_str());
|
logger->info(MSG_SENDING_REQUEST, cuid, request.c_str());
|
||||||
|
@ -103,7 +98,6 @@ void FtpConnection::sendPasv() const
|
||||||
}
|
}
|
||||||
|
|
||||||
SocketHandle FtpConnection::sendPort() const
|
SocketHandle FtpConnection::sendPort() const
|
||||||
throw(DlAbortEx*, DlRetryEx*)
|
|
||||||
{
|
{
|
||||||
SocketHandle serverSocket;
|
SocketHandle serverSocket;
|
||||||
serverSocket->beginListen();
|
serverSocket->beginListen();
|
||||||
|
@ -124,7 +118,6 @@ SocketHandle FtpConnection::sendPort() const
|
||||||
}
|
}
|
||||||
|
|
||||||
void FtpConnection::sendRest(const SegmentHandle& segment) const
|
void FtpConnection::sendRest(const SegmentHandle& segment) const
|
||||||
throw(DlRetryEx*)
|
|
||||||
{
|
{
|
||||||
string request = "REST "+Util::llitos(segment->getPositionToWrite())+"\r\n";
|
string request = "REST "+Util::llitos(segment->getPositionToWrite())+"\r\n";
|
||||||
logger->info(MSG_SENDING_REQUEST, cuid, request.c_str());
|
logger->info(MSG_SENDING_REQUEST, cuid, request.c_str());
|
||||||
|
@ -132,7 +125,6 @@ void FtpConnection::sendRest(const SegmentHandle& segment) const
|
||||||
}
|
}
|
||||||
|
|
||||||
void FtpConnection::sendRetr() const
|
void FtpConnection::sendRetr() const
|
||||||
throw(DlRetryEx*)
|
|
||||||
{
|
{
|
||||||
string request = "RETR "+Util::urldecode(req->getFile())+"\r\n";
|
string request = "RETR "+Util::urldecode(req->getFile())+"\r\n";
|
||||||
logger->info(MSG_SENDING_REQUEST, cuid, request.c_str());
|
logger->info(MSG_SENDING_REQUEST, cuid, request.c_str());
|
||||||
|
@ -177,7 +169,6 @@ bool FtpConnection::isEndOfResponse(int32_t status, const string& response) cons
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FtpConnection::bulkReceiveResponse(pair<int32_t, string>& response)
|
bool FtpConnection::bulkReceiveResponse(pair<int32_t, string>& response)
|
||||||
throw(DlRetryEx*)
|
|
||||||
{
|
{
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
while(socket->isReadable(0)) {
|
while(socket->isReadable(0)) {
|
||||||
|
@ -211,7 +202,6 @@ bool FtpConnection::bulkReceiveResponse(pair<int32_t, string>& response)
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t FtpConnection::receiveResponse()
|
int32_t FtpConnection::receiveResponse()
|
||||||
throw(DlRetryEx*)
|
|
||||||
{
|
{
|
||||||
pair<int32_t, string> response;
|
pair<int32_t, string> response;
|
||||||
if(bulkReceiveResponse(response)) {
|
if(bulkReceiveResponse(response)) {
|
||||||
|
@ -222,7 +212,6 @@ int32_t FtpConnection::receiveResponse()
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t FtpConnection::receiveSizeResponse(int64_t& size)
|
int32_t FtpConnection::receiveSizeResponse(int64_t& size)
|
||||||
throw(DlRetryEx*)
|
|
||||||
{
|
{
|
||||||
pair<int32_t, string> response;
|
pair<int32_t, string> response;
|
||||||
if(bulkReceiveResponse(response)) {
|
if(bulkReceiveResponse(response)) {
|
||||||
|
@ -236,7 +225,6 @@ int32_t FtpConnection::receiveSizeResponse(int64_t& size)
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t FtpConnection::receivePasvResponse(pair<string, int32_t>& dest)
|
int32_t FtpConnection::receivePasvResponse(pair<string, int32_t>& dest)
|
||||||
throw(DlRetryEx*)
|
|
||||||
{
|
{
|
||||||
pair<int32_t, string> response;
|
pair<int32_t, string> response;
|
||||||
if(bulkReceiveResponse(response)) {
|
if(bulkReceiveResponse(response)) {
|
||||||
|
|
|
@ -41,8 +41,6 @@
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
#include "Segment.h"
|
#include "Segment.h"
|
||||||
#include "Request.h"
|
#include "Request.h"
|
||||||
#include "DlAbortEx.h"
|
|
||||||
#include "DlRetryEx.h"
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
class FtpConnection {
|
class FtpConnection {
|
||||||
|
@ -57,24 +55,24 @@ private:
|
||||||
|
|
||||||
int32_t getStatus(const string& response) const;
|
int32_t getStatus(const string& response) const;
|
||||||
bool isEndOfResponse(int32_t status, const string& response) const;
|
bool isEndOfResponse(int32_t status, const string& response) const;
|
||||||
bool bulkReceiveResponse(pair<int32_t, string>& response) throw(DlRetryEx*);
|
bool bulkReceiveResponse(pair<int32_t, string>& response);
|
||||||
public:
|
public:
|
||||||
FtpConnection(int32_t cuid, const SocketHandle& socket,
|
FtpConnection(int32_t cuid, const SocketHandle& socket,
|
||||||
const RequestHandle req, const Option* op);
|
const RequestHandle req, const Option* op);
|
||||||
~FtpConnection();
|
~FtpConnection();
|
||||||
void sendUser() const throw(DlRetryEx*);
|
void sendUser() const;
|
||||||
void sendPass() const throw(DlRetryEx*);
|
void sendPass() const;
|
||||||
void sendType() const throw(DlRetryEx*);
|
void sendType() const;
|
||||||
void sendCwd() const throw(DlRetryEx*);
|
void sendCwd() const;
|
||||||
void sendSize() const throw(DlRetryEx*);
|
void sendSize() const;
|
||||||
void sendPasv() const throw(DlRetryEx*);
|
void sendPasv() const;
|
||||||
SocketHandle sendPort() const throw(DlAbortEx*, DlRetryEx*);
|
SocketHandle sendPort() const;
|
||||||
void sendRest(const SegmentHandle& segment) const throw(DlRetryEx*);
|
void sendRest(const SegmentHandle& segment) const;
|
||||||
void sendRetr() const throw(DlRetryEx*);
|
void sendRetr() const;
|
||||||
|
|
||||||
int32_t receiveResponse() throw(DlRetryEx*);
|
int32_t receiveResponse();
|
||||||
int32_t receiveSizeResponse(int64_t& size) throw(DlRetryEx*);
|
int32_t receiveSizeResponse(int64_t& size);
|
||||||
int32_t receivePasvResponse(pair<string, int32_t>& dest) throw(DlRetryEx*);
|
int32_t receivePasvResponse(pair<string, int32_t>& dest);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _D_FTP_CONNECTION_H_
|
#endif // _D_FTP_CONNECTION_H_
|
||||||
|
|
|
@ -195,29 +195,26 @@ bool FtpNegotiationCommand::recvSize() {
|
||||||
throw new DlAbortEx(EX_TOO_LARGE_FILE, Util::llitos(size, true).c_str());
|
throw new DlAbortEx(EX_TOO_LARGE_FILE, Util::llitos(size, true).c_str());
|
||||||
}
|
}
|
||||||
if(_requestGroup->getPieceStorage().isNull()) {
|
if(_requestGroup->getPieceStorage().isNull()) {
|
||||||
SingleFileDownloadContextHandle(_requestGroup->getDownloadContext())->setTotalLength(size);
|
SingleFileDownloadContextHandle dctx = _requestGroup->getDownloadContext();
|
||||||
SingleFileDownloadContextHandle(_requestGroup->getDownloadContext())->setFilename(Util::urldecode(req->getFile()));
|
dctx->setTotalLength(size);
|
||||||
|
dctx->setFilename(Util::urldecode(req->getFile()));
|
||||||
|
|
||||||
initPieceStorage();
|
_requestGroup->initPieceStorage();
|
||||||
|
|
||||||
// TODO validate totalsize against hintTotalSize if it is provided.
|
// validate totalsize against hintTotalSize if it is provided.
|
||||||
_requestGroup->validateTotalLengthByHint(size);
|
_requestGroup->validateTotalLengthByHint(size);
|
||||||
// TODO Is this really necessary?
|
// TODO Is this really necessary?
|
||||||
if(req->getMethod() == Request::METHOD_HEAD) {
|
if(req->getMethod() == Request::METHOD_HEAD) {
|
||||||
// TODO because we don't want segment file to be saved.
|
|
||||||
sequence = SEQ_HEAD_OK;
|
sequence = SEQ_HEAD_OK;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
BtProgressInfoFileHandle infoFile = new DefaultBtProgressInfoFile(_requestGroup->getDownloadContext(), _requestGroup->getPieceStorage(), e->option);
|
BtProgressInfoFileHandle infoFile = new DefaultBtProgressInfoFile(_requestGroup->getDownloadContext(), _requestGroup->getPieceStorage(), e->option);
|
||||||
if(e->option->get(PREF_CHECK_INTEGRITY) != V_TRUE) {
|
if(!infoFile->exists() && _requestGroup->downloadFinishedByFileLength()) {
|
||||||
if(!infoFile->exists() && downloadFinishedByFileLength()) {
|
sequence = SEQ_DOWNLOAD_ALREADY_COMPLETED;
|
||||||
logger->notice(MSG_DOWNLOAD_ALREADY_COMPLETED, cuid, _requestGroup->getFilePath().c_str());
|
return false;
|
||||||
sequence = SEQ_DOWNLOAD_ALREADY_COMPLETED;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
loadAndOpenFile(infoFile);
|
_requestGroup->loadAndOpenFile(infoFile);
|
||||||
prepareForNextAction();
|
prepareForNextAction();
|
||||||
|
|
||||||
sequence = SEQ_FILE_PREPARATION;
|
sequence = SEQ_FILE_PREPARATION;
|
||||||
|
|
|
@ -37,6 +37,8 @@
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
#include "prefs.h"
|
#include "prefs.h"
|
||||||
#include "LogFactory.h"
|
#include "LogFactory.h"
|
||||||
|
#include "DlRetryEx.h"
|
||||||
|
#include "DlAbortEx.h"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
HttpConnection::HttpConnection(int32_t cuid,
|
HttpConnection::HttpConnection(int32_t cuid,
|
||||||
|
@ -63,7 +65,6 @@ string HttpConnection::eraseConfidentialInfo(const string& request)
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpConnection::sendRequest(const HttpRequestHandle& httpRequest)
|
void HttpConnection::sendRequest(const HttpRequestHandle& httpRequest)
|
||||||
throw(DlRetryEx*)
|
|
||||||
{
|
{
|
||||||
string request = httpRequest->createRequest();
|
string request = httpRequest->createRequest();
|
||||||
logger->info(MSG_SENDING_REQUEST, cuid, eraseConfidentialInfo(request).c_str());
|
logger->info(MSG_SENDING_REQUEST, cuid, eraseConfidentialInfo(request).c_str());
|
||||||
|
@ -73,7 +74,6 @@ void HttpConnection::sendRequest(const HttpRequestHandle& httpRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpConnection::sendProxyRequest(const HttpRequestHandle& httpRequest)
|
void HttpConnection::sendProxyRequest(const HttpRequestHandle& httpRequest)
|
||||||
throw(DlRetryEx*)
|
|
||||||
{
|
{
|
||||||
string request = httpRequest->createProxyRequest();
|
string request = httpRequest->createProxyRequest();
|
||||||
logger->info(MSG_SENDING_REQUEST, cuid, eraseConfidentialInfo(request).c_str());
|
logger->info(MSG_SENDING_REQUEST, cuid, eraseConfidentialInfo(request).c_str());
|
||||||
|
@ -83,7 +83,6 @@ void HttpConnection::sendProxyRequest(const HttpRequestHandle& httpRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpResponseHandle HttpConnection::receiveResponse()
|
HttpResponseHandle HttpConnection::receiveResponse()
|
||||||
throw(DlAbortEx*, DlRetryEx*)
|
|
||||||
{
|
{
|
||||||
if(outstandingHttpRequests.size() == 0) {
|
if(outstandingHttpRequests.size() == 0) {
|
||||||
throw new DlAbortEx(EX_NO_HTTP_REQUEST_ENTRY_FOUND);
|
throw new DlAbortEx(EX_NO_HTTP_REQUEST_ENTRY_FOUND);
|
||||||
|
|
|
@ -44,8 +44,6 @@
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
#include "HttpResponse.h"
|
#include "HttpResponse.h"
|
||||||
#include "HttpHeaderProcessor.h"
|
#include "HttpHeaderProcessor.h"
|
||||||
#include "DlRetryEx.h"
|
|
||||||
#include "DlAbortEx.h"
|
|
||||||
|
|
||||||
class HttpRequestEntry {
|
class HttpRequestEntry {
|
||||||
private:
|
private:
|
||||||
|
@ -95,12 +93,12 @@ public:
|
||||||
* HTTP proxy(GET method).
|
* HTTP proxy(GET method).
|
||||||
* @param segment indicates starting postion of the file for downloading
|
* @param segment indicates starting postion of the file for downloading
|
||||||
*/
|
*/
|
||||||
void sendRequest(const HttpRequestHandle& httpRequest) throw(DlRetryEx*);
|
void sendRequest(const HttpRequestHandle& httpRequest);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends Http proxy request using CONNECT method.
|
* Sends Http proxy request using CONNECT method.
|
||||||
*/
|
*/
|
||||||
void sendProxyRequest(const HttpRequestHandle& httpRequest) throw(DlRetryEx*);
|
void sendProxyRequest(const HttpRequestHandle& httpRequest);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Receives HTTP response from the server and returns HttpResponseHandle
|
* Receives HTTP response from the server and returns HttpResponseHandle
|
||||||
|
@ -113,7 +111,7 @@ public:
|
||||||
*
|
*
|
||||||
* @return HttpResponse or 0 if whole response header is not received
|
* @return HttpResponse or 0 if whole response header is not received
|
||||||
*/
|
*/
|
||||||
HttpResponseHandle receiveResponse() throw(DlAbortEx*, DlRetryEx*);
|
HttpResponseHandle receiveResponse();
|
||||||
|
|
||||||
HttpRequestHandle getFirstHttpRequest() const
|
HttpRequestHandle getFirstHttpRequest() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -35,23 +35,22 @@
|
||||||
#include "HttpHeaderProcessor.h"
|
#include "HttpHeaderProcessor.h"
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
|
#include "DlRetryEx.h"
|
||||||
|
#include "DlAbortEx.h"
|
||||||
|
|
||||||
void HttpHeaderProcessor::update(const char* data, int32_t length)
|
void HttpHeaderProcessor::update(const char* data, int32_t length)
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
checkHeaderLimit(length);
|
checkHeaderLimit(length);
|
||||||
strm.write(data, length);
|
strm.write(data, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpHeaderProcessor::update(const string& data)
|
void HttpHeaderProcessor::update(const string& data)
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
checkHeaderLimit(data.size());
|
checkHeaderLimit(data.size());
|
||||||
strm << data;
|
strm << data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpHeaderProcessor::checkHeaderLimit(int32_t incomingLength)
|
void HttpHeaderProcessor::checkHeaderLimit(int32_t incomingLength)
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
strm.seekg(0, ios::end);
|
strm.seekg(0, ios::end);
|
||||||
if((int32_t)strm.tellg()+incomingLength > _limit) {
|
if((int32_t)strm.tellg()+incomingLength > _limit) {
|
||||||
|
@ -88,7 +87,6 @@ void HttpHeaderProcessor::clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
pair<string, HttpHeaderHandle> HttpHeaderProcessor::getHttpStatusHeader()
|
pair<string, HttpHeaderHandle> HttpHeaderProcessor::getHttpStatusHeader()
|
||||||
throw(DlRetryEx*)
|
|
||||||
{
|
{
|
||||||
strm.seekg(0, ios::beg);
|
strm.seekg(0, ios::beg);
|
||||||
string line;
|
string line;
|
||||||
|
|
|
@ -37,8 +37,6 @@
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "HttpHeader.h"
|
#include "HttpHeader.h"
|
||||||
#include "DlRetryEx.h"
|
|
||||||
#include "DlAbortEx.h"
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
@ -47,16 +45,16 @@ private:
|
||||||
stringstream strm;
|
stringstream strm;
|
||||||
int32_t _limit;
|
int32_t _limit;
|
||||||
|
|
||||||
void checkHeaderLimit(int32_t incomingLength) throw(DlAbortEx*);
|
void checkHeaderLimit(int32_t incomingLength);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
HttpHeaderProcessor():_limit(4096) {}
|
HttpHeaderProcessor():_limit(4096) {}
|
||||||
|
|
||||||
~HttpHeaderProcessor() {}
|
~HttpHeaderProcessor() {}
|
||||||
|
|
||||||
void update(const char* data, int32_t length) throw(DlAbortEx*);
|
void update(const char* data, int32_t length);
|
||||||
|
|
||||||
void update(const string& data) throw(DlAbortEx*);
|
void update(const string& data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if end of header is reached.
|
* Returns true if end of header is reached.
|
||||||
|
@ -68,7 +66,7 @@ public:
|
||||||
*/
|
*/
|
||||||
int32_t getPutBackDataLength() const;
|
int32_t getPutBackDataLength() const;
|
||||||
|
|
||||||
pair<string, HttpHeaderHandle> getHttpStatusHeader() throw(DlRetryEx*);
|
pair<string, HttpHeaderHandle> getHttpStatusHeader();
|
||||||
|
|
||||||
string getHeaderString() const;
|
string getHeaderString() const;
|
||||||
|
|
||||||
|
|
|
@ -36,9 +36,10 @@
|
||||||
#include "ChunkedEncoding.h"
|
#include "ChunkedEncoding.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
|
#include "DlAbortEx.h"
|
||||||
|
#include "DlRetryEx.h"
|
||||||
|
|
||||||
void HttpResponse::validateResponse() const
|
void HttpResponse::validateResponse() const
|
||||||
throw(DlAbortEx*, DlRetryEx*)
|
|
||||||
{
|
{
|
||||||
if(status == 401) {
|
if(status == 401) {
|
||||||
throw new DlAbortEx(EX_AUTH_FAILED);
|
throw new DlAbortEx(EX_AUTH_FAILED);
|
||||||
|
|
|
@ -40,8 +40,6 @@
|
||||||
#include "HttpHeader.h"
|
#include "HttpHeader.h"
|
||||||
#include "TransferEncoding.h"
|
#include "TransferEncoding.h"
|
||||||
#include "LogFactory.h"
|
#include "LogFactory.h"
|
||||||
#include "DlAbortEx.h"
|
|
||||||
#include "DlRetryEx.h"
|
|
||||||
|
|
||||||
class HttpResponse {
|
class HttpResponse {
|
||||||
private:
|
private:
|
||||||
|
@ -60,7 +58,7 @@ public:
|
||||||
|
|
||||||
~HttpResponse() {}
|
~HttpResponse() {}
|
||||||
|
|
||||||
void validateResponse() const throw(DlAbortEx*, DlRetryEx*);
|
void validateResponse() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns filename.
|
* Returns filename.
|
||||||
|
|
|
@ -84,35 +84,32 @@ bool HttpResponseCommand::executeInternal()
|
||||||
e->noWait = true;
|
e->noWait = true;
|
||||||
return prepareForRetry(0);
|
return prepareForRetry(0);
|
||||||
}
|
}
|
||||||
if(!_requestGroup->getPieceStorage().isNull()) {
|
if(_requestGroup->getPieceStorage().isNull()) {
|
||||||
// validate totalsize
|
|
||||||
_requestGroup->validateTotalLength(httpResponse->getEntityLength());
|
|
||||||
|
|
||||||
e->commands.push_back(createHttpDownloadCommand(httpResponse));
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
// validate totalsize against hintTotalSize if it is provided.
|
// validate totalsize against hintTotalSize if it is provided.
|
||||||
_requestGroup->validateTotalLengthByHint(httpResponse->getEntityLength());
|
int64_t totalLength = httpResponse->getEntityLength();
|
||||||
|
_requestGroup->validateTotalLengthByHint(totalLength);
|
||||||
SingleFileDownloadContextHandle(_requestGroup->getDownloadContext())->setFilename(httpResponse->determinFilename());
|
SingleFileDownloadContextHandle dctx = _requestGroup->getDownloadContext();
|
||||||
if(httpResponse->isTransferEncodingSpecified()) {
|
dctx->setTotalLength(totalLength);
|
||||||
|
dctx->setFilename(httpResponse->determinFilename());
|
||||||
|
if(totalLength == 0 || httpResponse->isTransferEncodingSpecified()) {
|
||||||
|
// we ignore content-length when transfer-encoding is set
|
||||||
|
dctx->setTotalLength(0);
|
||||||
return handleOtherEncoding(httpResponse);
|
return handleOtherEncoding(httpResponse);
|
||||||
} else {
|
} else {
|
||||||
return handleDefaultEncoding(httpResponse);
|
return handleDefaultEncoding(httpResponse);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// validate totalsize
|
||||||
|
_requestGroup->validateTotalLength(httpResponse->getEntityLength());
|
||||||
|
e->commands.push_back(createHttpDownloadCommand(httpResponse));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HttpResponseCommand::handleDefaultEncoding(const HttpResponseHandle& httpResponse)
|
bool HttpResponseCommand::handleDefaultEncoding(const HttpResponseHandle& httpResponse)
|
||||||
{
|
{
|
||||||
HttpRequestHandle httpRequest = httpResponse->getHttpRequest();
|
HttpRequestHandle httpRequest = httpResponse->getHttpRequest();
|
||||||
int64_t size = httpResponse->getEntityLength();
|
_requestGroup->initPieceStorage();
|
||||||
if(size == INT64_MAX || size < 0) {
|
|
||||||
throw new DlAbortEx(EX_TOO_LARGE_FILE, Util::llitos(size, true).c_str());
|
|
||||||
}
|
|
||||||
SingleFileDownloadContextHandle(_requestGroup->getDownloadContext())->setTotalLength(size);
|
|
||||||
|
|
||||||
initPieceStorage();
|
|
||||||
|
|
||||||
// quick hack for method 'head',, is it necessary?
|
// quick hack for method 'head',, is it necessary?
|
||||||
if(httpRequest->getMethod() == Request::METHOD_HEAD) {
|
if(httpRequest->getMethod() == Request::METHOD_HEAD) {
|
||||||
|
@ -121,16 +118,13 @@ bool HttpResponseCommand::handleDefaultEncoding(const HttpResponseHandle& httpRe
|
||||||
}
|
}
|
||||||
|
|
||||||
BtProgressInfoFileHandle infoFile = new DefaultBtProgressInfoFile(_requestGroup->getDownloadContext(), _requestGroup->getPieceStorage(), e->option);
|
BtProgressInfoFileHandle infoFile = new DefaultBtProgressInfoFile(_requestGroup->getDownloadContext(), _requestGroup->getPieceStorage(), e->option);
|
||||||
if(e->option->get(PREF_CHECK_INTEGRITY) != V_TRUE) {
|
if(!infoFile->exists() && _requestGroup->downloadFinishedByFileLength()) {
|
||||||
if(!infoFile->exists() && downloadFinishedByFileLength()) {
|
return true;
|
||||||
logger->notice(MSG_DOWNLOAD_ALREADY_COMPLETED, cuid, _requestGroup->getFilePath().c_str());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DownloadCommand* command = 0;
|
DownloadCommand* command = 0;
|
||||||
try {
|
try {
|
||||||
loadAndOpenFile(infoFile);
|
_requestGroup->loadAndOpenFile(infoFile);
|
||||||
File file(_requestGroup->getFilePath());
|
File file(_requestGroup->getFilePath());
|
||||||
if(_requestGroup->getRemainingUris().empty() && !file.exists()) {
|
if(_requestGroup->getRemainingUris().empty() && !file.exists()) {
|
||||||
command = createHttpDownloadCommand(httpResponse);
|
command = createHttpDownloadCommand(httpResponse);
|
||||||
|
@ -145,7 +139,6 @@ bool HttpResponseCommand::handleDefaultEncoding(const HttpResponseHandle& httpRe
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HttpResponseCommand::handleOtherEncoding(const HttpResponseHandle& httpResponse) {
|
bool HttpResponseCommand::handleOtherEncoding(const HttpResponseHandle& httpResponse) {
|
||||||
// we ignore content-length when transfer-encoding is set
|
|
||||||
HttpRequestHandle httpRequest = httpResponse->getHttpRequest();
|
HttpRequestHandle httpRequest = httpResponse->getHttpRequest();
|
||||||
// quick hack for method 'head',, is it necessary?
|
// quick hack for method 'head',, is it necessary?
|
||||||
if(httpRequest->getMethod() == Request::METHOD_HEAD) {
|
if(httpRequest->getMethod() == Request::METHOD_HEAD) {
|
||||||
|
@ -153,11 +146,8 @@ bool HttpResponseCommand::handleOtherEncoding(const HttpResponseHandle& httpResp
|
||||||
}
|
}
|
||||||
// disable keep-alive
|
// disable keep-alive
|
||||||
req->setKeepAlive(false);
|
req->setKeepAlive(false);
|
||||||
|
_requestGroup->initPieceStorage();
|
||||||
initPieceStorage();
|
_requestGroup->shouldCancelDownloadForSafety();
|
||||||
|
|
||||||
shouldCancelDownloadForSafety();
|
|
||||||
// TODO handle file-size unknown case
|
|
||||||
_requestGroup->getPieceStorage()->getDiskAdaptor()->initAndOpenFile();
|
_requestGroup->getPieceStorage()->getDiskAdaptor()->initAndOpenFile();
|
||||||
e->commands.push_back(createHttpDownloadCommand(httpResponse));
|
e->commands.push_back(createHttpDownloadCommand(httpResponse));
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
#include "MessageDigestHelper.h"
|
#include "MessageDigestHelper.h"
|
||||||
#include "DiskAdaptor.h"
|
#include "DiskAdaptor.h"
|
||||||
|
#include "RecoverableException.h"
|
||||||
|
|
||||||
void IteratableChunkChecksumValidator::validateChunk()
|
void IteratableChunkChecksumValidator::validateChunk()
|
||||||
{
|
{
|
||||||
|
@ -44,7 +45,7 @@ void IteratableChunkChecksumValidator::validateChunk()
|
||||||
string actualChecksum;
|
string actualChecksum;
|
||||||
try {
|
try {
|
||||||
actualChecksum = calculateActualChecksum();
|
actualChecksum = calculateActualChecksum();
|
||||||
} catch(DlAbortEx* ex) {
|
} catch(RecoverableException* ex) {
|
||||||
_logger->debug("Caught exception while validating piece index=%d. Some part of file may be missing. Continue operation.", ex, _currentIndex);
|
_logger->debug("Caught exception while validating piece index=%d. Some part of file may be missing. Continue operation.", ex, _currentIndex);
|
||||||
delete ex;
|
delete ex;
|
||||||
_bitfield->unsetBit(_currentIndex);
|
_bitfield->unsetBit(_currentIndex);
|
||||||
|
|
|
@ -73,7 +73,7 @@ MetaEntry* MetaFileUtil::bdecoding(const char* buf, int32_t len) {
|
||||||
const char* end = buf+len;
|
const char* end = buf+len;
|
||||||
entry = bdecodingR(&p, end);
|
entry = bdecodingR(&p, end);
|
||||||
return entry;
|
return entry;
|
||||||
} catch(DlAbortEx* ex) {
|
} catch(RecoverableException* ex) {
|
||||||
if(entry != NULL) {
|
if(entry != NULL) {
|
||||||
delete entry;
|
delete entry;
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,7 +158,7 @@ RequestGroups Metalink2RequestGroup::generate(const string& metalinkFile)
|
||||||
}
|
}
|
||||||
SingleFileDownloadContextHandle dctx =
|
SingleFileDownloadContextHandle dctx =
|
||||||
new SingleFileDownloadContext(pieceLength,
|
new SingleFileDownloadContext(pieceLength,
|
||||||
0,
|
entry->getLength(),
|
||||||
"",
|
"",
|
||||||
entry->file->getPath());
|
entry->file->getPath());
|
||||||
dctx->setDir(_option->get(PREF_DIR));
|
dctx->setDir(_option->get(PREF_DIR));
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "MultiFileAllocationIterator.h"
|
#include "MultiFileAllocationIterator.h"
|
||||||
#include "DefaultDiskWriterFactory.h"
|
#include "DefaultDiskWriterFactory.h"
|
||||||
|
#include "DlAbortEx.h"
|
||||||
|
|
||||||
void MultiDiskAdaptor::resetDiskWriterEntries()
|
void MultiDiskAdaptor::resetDiskWriterEntries()
|
||||||
{
|
{
|
||||||
|
@ -60,7 +61,6 @@ string MultiDiskAdaptor::getTopDirPath() const
|
||||||
}
|
}
|
||||||
|
|
||||||
void MultiDiskAdaptor::mkdir() const
|
void MultiDiskAdaptor::mkdir() const
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
for(FileEntries::const_iterator itr = fileEntries.begin();
|
for(FileEntries::const_iterator itr = fileEntries.begin();
|
||||||
itr != fileEntries.end(); itr++) {
|
itr != fileEntries.end(); itr++) {
|
||||||
|
@ -69,7 +69,6 @@ void MultiDiskAdaptor::mkdir() const
|
||||||
}
|
}
|
||||||
|
|
||||||
void MultiDiskAdaptor::openFile()
|
void MultiDiskAdaptor::openFile()
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
mkdir();
|
mkdir();
|
||||||
resetDiskWriterEntries();
|
resetDiskWriterEntries();
|
||||||
|
@ -80,7 +79,6 @@ void MultiDiskAdaptor::openFile()
|
||||||
}
|
}
|
||||||
|
|
||||||
void MultiDiskAdaptor::initAndOpenFile()
|
void MultiDiskAdaptor::initAndOpenFile()
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
mkdir();
|
mkdir();
|
||||||
resetDiskWriterEntries();
|
resetDiskWriterEntries();
|
||||||
|
@ -91,7 +89,6 @@ void MultiDiskAdaptor::initAndOpenFile()
|
||||||
}
|
}
|
||||||
|
|
||||||
void MultiDiskAdaptor::openExistingFile()
|
void MultiDiskAdaptor::openExistingFile()
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
resetDiskWriterEntries();
|
resetDiskWriterEntries();
|
||||||
for(DiskWriterEntries::iterator itr = diskWriterEntries.begin();
|
for(DiskWriterEntries::iterator itr = diskWriterEntries.begin();
|
||||||
|
@ -109,7 +106,6 @@ void MultiDiskAdaptor::closeFile()
|
||||||
}
|
}
|
||||||
|
|
||||||
void MultiDiskAdaptor::onDownloadComplete()
|
void MultiDiskAdaptor::onDownloadComplete()
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
closeFile();
|
closeFile();
|
||||||
openFile();
|
openFile();
|
||||||
|
@ -117,7 +113,6 @@ void MultiDiskAdaptor::onDownloadComplete()
|
||||||
|
|
||||||
void MultiDiskAdaptor::writeData(const unsigned char* data, int32_t len,
|
void MultiDiskAdaptor::writeData(const unsigned char* data, int32_t len,
|
||||||
int64_t offset)
|
int64_t offset)
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
int64_t fileOffset = offset;
|
int64_t fileOffset = offset;
|
||||||
bool writing = false;
|
bool writing = false;
|
||||||
|
@ -160,7 +155,6 @@ int32_t MultiDiskAdaptor::calculateLength(const DiskWriterEntryHandle entry,
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t MultiDiskAdaptor::readData(unsigned char* data, int32_t len, int64_t offset)
|
int32_t MultiDiskAdaptor::readData(unsigned char* data, int32_t len, int64_t offset)
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
int64_t fileOffset = offset;
|
int64_t fileOffset = offset;
|
||||||
bool reading = false;
|
bool reading = false;
|
||||||
|
@ -200,7 +194,6 @@ bool MultiDiskAdaptor::fileExists()
|
||||||
|
|
||||||
// TODO call DiskWriter::openFile() before calling this function.
|
// TODO call DiskWriter::openFile() before calling this function.
|
||||||
int64_t MultiDiskAdaptor::size() const
|
int64_t MultiDiskAdaptor::size() const
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
int64_t size = 0;
|
int64_t size = 0;
|
||||||
for(DiskWriterEntries::const_iterator itr = diskWriterEntries.begin();
|
for(DiskWriterEntries::const_iterator itr = diskWriterEntries.begin();
|
||||||
|
|
|
@ -39,7 +39,6 @@
|
||||||
#include "Option.h"
|
#include "Option.h"
|
||||||
#include "DiskWriter.h"
|
#include "DiskWriter.h"
|
||||||
#include "File.h"
|
#include "File.h"
|
||||||
#include "DlAbortEx.h"
|
|
||||||
|
|
||||||
class DiskWriterEntry {
|
class DiskWriterEntry {
|
||||||
private:
|
private:
|
||||||
|
@ -58,19 +57,16 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void initAndOpenFile(const string& topDir)
|
void initAndOpenFile(const string& topDir)
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
diskWriter->initAndOpenFile(getFilePath(topDir), fileEntry->getLength());
|
diskWriter->initAndOpenFile(getFilePath(topDir), fileEntry->getLength());
|
||||||
}
|
}
|
||||||
|
|
||||||
void openFile(const string& topDir)
|
void openFile(const string& topDir)
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
diskWriter->openFile(getFilePath(topDir), fileEntry->getLength());
|
diskWriter->openFile(getFilePath(topDir), fileEntry->getLength());
|
||||||
}
|
}
|
||||||
|
|
||||||
void openExistingFile(const string& topDir)
|
void openExistingFile(const string& topDir)
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
diskWriter->openExistingFile(getFilePath(topDir), fileEntry->getLength());
|
diskWriter->openExistingFile(getFilePath(topDir), fileEntry->getLength());
|
||||||
}
|
}
|
||||||
|
@ -86,7 +82,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t size() const
|
int64_t size() const
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
return diskWriter->size();
|
return diskWriter->size();
|
||||||
}
|
}
|
||||||
|
@ -117,7 +112,7 @@ private:
|
||||||
|
|
||||||
void resetDiskWriterEntries();
|
void resetDiskWriterEntries();
|
||||||
|
|
||||||
void mkdir() const throw(DlAbortEx*);
|
void mkdir() const;
|
||||||
|
|
||||||
bool isInRange(const DiskWriterEntryHandle entry, int64_t offset) const;
|
bool isInRange(const DiskWriterEntryHandle entry, int64_t offset) const;
|
||||||
|
|
||||||
|
@ -133,20 +128,20 @@ public:
|
||||||
|
|
||||||
virtual ~MultiDiskAdaptor() {}
|
virtual ~MultiDiskAdaptor() {}
|
||||||
|
|
||||||
virtual void initAndOpenFile() throw(DlAbortEx*);
|
virtual void initAndOpenFile();
|
||||||
|
|
||||||
virtual void openFile() throw(DlAbortEx*);
|
virtual void openFile();
|
||||||
|
|
||||||
virtual void openExistingFile() throw(DlAbortEx*);
|
virtual void openExistingFile();
|
||||||
|
|
||||||
virtual void closeFile();
|
virtual void closeFile();
|
||||||
|
|
||||||
virtual void onDownloadComplete() throw(DlAbortEx*);
|
virtual void onDownloadComplete();
|
||||||
|
|
||||||
virtual void writeData(const unsigned char* data, int32_t len,
|
virtual void writeData(const unsigned char* data, int32_t len,
|
||||||
int64_t offset) throw(DlAbortEx*);
|
int64_t offset);
|
||||||
|
|
||||||
virtual int32_t readData(unsigned char* data, int32_t len, int64_t offset) throw(DlAbortEx*);
|
virtual int32_t readData(unsigned char* data, int32_t len, int64_t offset);
|
||||||
|
|
||||||
virtual bool fileExists();
|
virtual bool fileExists();
|
||||||
|
|
||||||
|
@ -155,7 +150,7 @@ public:
|
||||||
return getTopDirPath();
|
return getTopDirPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int64_t size() const throw(DlAbortEx*);
|
virtual int64_t size() const;
|
||||||
|
|
||||||
virtual FileAllocationIteratorHandle fileAllocationIterator();
|
virtual FileAllocationIteratorHandle fileAllocationIterator();
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,6 @@ bool RealtimeCommand::execute()
|
||||||
try {
|
try {
|
||||||
return executeInternal();
|
return executeInternal();
|
||||||
} catch(Exception* e) {
|
} catch(Exception* e) {
|
||||||
//_requestGroup->getSegmentMan()->errors++;
|
|
||||||
bool r = handleException(e);
|
bool r = handleException(e);
|
||||||
delete e;
|
delete e;
|
||||||
return r;
|
return r;
|
||||||
|
|
|
@ -49,6 +49,12 @@
|
||||||
#include "DiskAdaptor.h"
|
#include "DiskAdaptor.h"
|
||||||
#include "DiskWriterFactory.h"
|
#include "DiskWriterFactory.h"
|
||||||
#include "RecoverableException.h"
|
#include "RecoverableException.h"
|
||||||
|
#include "StreamCheckIntegrityEntry.h"
|
||||||
|
#include "CheckIntegrityCommand.h"
|
||||||
|
#include "UnknownLengthPieceStorage.h"
|
||||||
|
#include "SingleFileDownloadContext.h"
|
||||||
|
#include "DlAbortEx.h"
|
||||||
|
#include "DownloadFailureException.h"
|
||||||
#ifdef ENABLE_MESSAGE_DIGEST
|
#ifdef ENABLE_MESSAGE_DIGEST
|
||||||
# include "CheckIntegrityCommand.h"
|
# include "CheckIntegrityCommand.h"
|
||||||
#endif // ENABLE_MESSAGE_DIGEST
|
#endif // ENABLE_MESSAGE_DIGEST
|
||||||
|
@ -149,10 +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.");
|
_logger->debug("Clearing http/ftp URIs because the current implementation does not allow integrating multi-file torrent and http/ftp.");
|
||||||
_uris.clear();
|
_uris.clear();
|
||||||
}
|
}
|
||||||
|
initPieceStorage();
|
||||||
_pieceStorage = new DefaultPieceStorage(btContext, _option);
|
|
||||||
_pieceStorage->initStorage();
|
|
||||||
initSegmentMan();
|
|
||||||
|
|
||||||
BtProgressInfoFileHandle progressInfoFile =
|
BtProgressInfoFileHandle progressInfoFile =
|
||||||
new DefaultBtProgressInfoFile(_downloadContext,
|
new DefaultBtProgressInfoFile(_downloadContext,
|
||||||
|
@ -201,26 +204,159 @@ Commands RequestGroup::createInitialCommand(DownloadEngine* e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_progressInfoFile = progressInfoFile;
|
_progressInfoFile = progressInfoFile;
|
||||||
Commands commands;
|
|
||||||
CheckIntegrityEntryHandle entry = new BtCheckIntegrityEntry(this);
|
CheckIntegrityEntryHandle entry = new BtCheckIntegrityEntry(this);
|
||||||
#ifdef ENABLE_MESSAGE_DIGEST
|
|
||||||
if(File(getFilePath()).size() > 0 &&
|
return processCheckIntegrityEntry(entry, e);
|
||||||
e->option->get(PREF_CHECK_INTEGRITY) == V_TRUE &&
|
|
||||||
entry->isValidationReady()) {
|
|
||||||
entry->initValidator();
|
|
||||||
CheckIntegrityCommand* command =
|
|
||||||
new CheckIntegrityCommand(CUIDCounterSingletonHolder::instance()->newID(), this, e, entry);
|
|
||||||
commands.push_back(command);
|
|
||||||
} else
|
|
||||||
#endif // ENABLE_MESSAGE_DIGEST
|
|
||||||
{
|
|
||||||
commands = entry->onDownloadIncomplete(e);
|
|
||||||
}
|
|
||||||
return commands;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // ENABLE_BITTORRENT
|
#endif // ENABLE_BITTORRENT
|
||||||
return createNextCommand(e, 1);
|
// TODO I assume here when totallength is set to DownloadContext and it is
|
||||||
|
// not 0, then filepath is also set DownloadContext correctly....
|
||||||
|
if(_downloadContext->getTotalLength() == 0) {
|
||||||
|
return createNextCommand(e, 1);
|
||||||
|
}else {
|
||||||
|
initPieceStorage();
|
||||||
|
BtProgressInfoFileHandle infoFile =
|
||||||
|
new DefaultBtProgressInfoFile(_downloadContext, _pieceStorage, _option);
|
||||||
|
if(!infoFile->exists() && downloadFinishedByFileLength()) {
|
||||||
|
return Commands();
|
||||||
|
}
|
||||||
|
loadAndOpenFile(infoFile);
|
||||||
|
return processCheckIntegrityEntry(new StreamCheckIntegrityEntry(0, this), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Commands RequestGroup::processCheckIntegrityEntry(const CheckIntegrityEntryHandle& entry, DownloadEngine* e)
|
||||||
|
{
|
||||||
|
#ifdef ENABLE_MESSAGE_DIGEST
|
||||||
|
if(File(getFilePath()).size() > 0 &&
|
||||||
|
e->option->get(PREF_CHECK_INTEGRITY) == V_TRUE &&
|
||||||
|
entry->isValidationReady()) {
|
||||||
|
entry->initValidator();
|
||||||
|
CheckIntegrityCommand* command =
|
||||||
|
new CheckIntegrityCommand(CUIDCounterSingletonHolder::instance()->newID(), this, e, entry);
|
||||||
|
Commands commands;
|
||||||
|
commands.push_back(command);
|
||||||
|
return commands;
|
||||||
|
} else
|
||||||
|
#endif // ENABLE_MESSAGE_DIGEST
|
||||||
|
{
|
||||||
|
return entry->onDownloadIncomplete(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RequestGroup::initPieceStorage()
|
||||||
|
{
|
||||||
|
if(_downloadContext->getTotalLength() == 0) {
|
||||||
|
UnknownLengthPieceStorageHandle ps = new UnknownLengthPieceStorage(_downloadContext, _option);
|
||||||
|
if(!_diskWriterFactory.isNull()) {
|
||||||
|
ps->setDiskWriterFactory(_diskWriterFactory);
|
||||||
|
}
|
||||||
|
_pieceStorage = ps;
|
||||||
|
} else {
|
||||||
|
DefaultPieceStorageHandle ps = new DefaultPieceStorage(_downloadContext, _option);
|
||||||
|
if(!_diskWriterFactory.isNull()) {
|
||||||
|
ps->setDiskWriterFactory(_diskWriterFactory);
|
||||||
|
}
|
||||||
|
_pieceStorage = ps;
|
||||||
|
}
|
||||||
|
_pieceStorage->initStorage();
|
||||||
|
initSegmentMan();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RequestGroup::downloadFinishedByFileLength()
|
||||||
|
{
|
||||||
|
if(_option->get(PREF_CHECK_INTEGRITY) == V_TRUE &&
|
||||||
|
!_downloadContext->getPieceHashes().empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// TODO consider the case when the getFilePath() returns dir path.
|
||||||
|
File outfile(getFilePath());
|
||||||
|
if(outfile.exists() && getTotalLength() == outfile.size()) {
|
||||||
|
_pieceStorage->markAllPiecesDone();
|
||||||
|
_logger->notice(MSG_DOWNLOAD_ALREADY_COMPLETED, _gid, getFilePath().c_str());
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RequestGroup::loadAndOpenFile(const BtProgressInfoFileHandle& progressInfoFile)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if(!isPreLocalFileCheckEnabled()) {
|
||||||
|
_pieceStorage->getDiskAdaptor()->initAndOpenFile();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(progressInfoFile->exists()) {
|
||||||
|
progressInfoFile->load();
|
||||||
|
_pieceStorage->getDiskAdaptor()->openExistingFile();
|
||||||
|
} else {
|
||||||
|
File outfile(getFilePath());
|
||||||
|
if(outfile.exists() && _option->get(PREF_CONTINUE) == V_TRUE) {
|
||||||
|
if(getTotalLength() < outfile.size()) {
|
||||||
|
throw new DlAbortEx(EX_FILE_LENGTH_MISMATCH_BETWEEN_LOCAL_AND_REMOTE,
|
||||||
|
getFilePath().c_str(),
|
||||||
|
Util::llitos(outfile.size()).c_str(),
|
||||||
|
Util::llitos(getTotalLength()).c_str());
|
||||||
|
}
|
||||||
|
_pieceStorage->getDiskAdaptor()->openExistingFile();
|
||||||
|
_pieceStorage->markPiecesDone(outfile.size());
|
||||||
|
} else {
|
||||||
|
#ifdef ENABLE_MESSAGE_DIGEST
|
||||||
|
if(outfile.exists() && _option->get(PREF_CHECK_INTEGRITY) == V_TRUE) {
|
||||||
|
_pieceStorage->getDiskAdaptor()->openExistingFile();
|
||||||
|
} else {
|
||||||
|
shouldCancelDownloadForSafety();
|
||||||
|
_pieceStorage->getDiskAdaptor()->initAndOpenFile();
|
||||||
|
}
|
||||||
|
#else // ENABLE_MESSAGE_DIGEST
|
||||||
|
shouldCancelDownloadForSafety();
|
||||||
|
_pieceStorage->getDiskAdaptor()->initAndOpenFile();
|
||||||
|
#endif // ENABLE_MESSAGE_DIGEST
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setProgressInfoFile(progressInfoFile);
|
||||||
|
} catch(RecoverableException* e) {
|
||||||
|
throw new DownloadFailureException(e, EX_DOWNLOAD_ABORTED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RequestGroup::shouldCancelDownloadForSafety()
|
||||||
|
{
|
||||||
|
File outfile(getFilePath());
|
||||||
|
if(outfile.exists() && !_progressInfoFile->exists()) {
|
||||||
|
if(_option->get(PREF_AUTO_FILE_RENAMING) == V_TRUE) {
|
||||||
|
if(tryAutoFileRenaming()) {
|
||||||
|
_logger->notice("File already exists. Renamed to %s.",
|
||||||
|
getFilePath().c_str());
|
||||||
|
} else {
|
||||||
|
_logger->notice("File renaming failed: %s", getFilePath().c_str());
|
||||||
|
throw new DownloadFailureException(EX_DOWNLOAD_ABORTED);
|
||||||
|
}
|
||||||
|
} else if(_option->get(PREF_ALLOW_OVERWRITE) != V_TRUE) {
|
||||||
|
_logger->notice(MSG_FILE_ALREADY_EXISTS,
|
||||||
|
getFilePath().c_str(),
|
||||||
|
_progressInfoFile->getFilename().c_str());
|
||||||
|
throw new DownloadFailureException(EX_DOWNLOAD_ABORTED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RequestGroup::tryAutoFileRenaming()
|
||||||
|
{
|
||||||
|
string filepath = getFilePath();
|
||||||
|
if(filepath.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for(int32_t i = 1; i < 10000; ++i) {
|
||||||
|
File newfile(filepath+"."+Util::itos(i));
|
||||||
|
if(!newfile.exists()) {
|
||||||
|
SingleFileDownloadContextHandle(_downloadContext)->setUFilename(newfile.getBasename());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Commands RequestGroup::createNextCommandWithAdj(DownloadEngine* e, int32_t numAdj)
|
Commands RequestGroup::createNextCommandWithAdj(DownloadEngine* e, int32_t numAdj)
|
||||||
|
|
|
@ -61,10 +61,12 @@ class DiskWriterFactory;
|
||||||
extern typedef SharedHandle<DiskWriterFactory> DiskWriterFactoryHandle;
|
extern typedef SharedHandle<DiskWriterFactory> DiskWriterFactoryHandle;
|
||||||
class Option;
|
class Option;
|
||||||
class Logger;
|
class Logger;
|
||||||
|
|
||||||
class RequestGroup;
|
class RequestGroup;
|
||||||
extern typedef SharedHandle<RequestGroup> RequestGroupHandle;
|
extern typedef SharedHandle<RequestGroup> RequestGroupHandle;
|
||||||
extern typedef deque<RequestGroupHandle> RequestGroups;
|
extern typedef deque<RequestGroupHandle> RequestGroups;
|
||||||
|
class CheckIntegrityEntry;
|
||||||
|
extern typedef SharedHandle<CheckIntegrityEntry> CheckIntegrityEntryHandle;
|
||||||
|
|
||||||
|
|
||||||
class RequestGroup {
|
class RequestGroup {
|
||||||
private:
|
private:
|
||||||
|
@ -124,6 +126,9 @@ private:
|
||||||
int64_t actualTotalLength) const;
|
int64_t actualTotalLength) const;
|
||||||
|
|
||||||
void initializePostDownloadHandler();
|
void initializePostDownloadHandler();
|
||||||
|
|
||||||
|
bool tryAutoFileRenaming();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RequestGroup(const Option* option, const Strings& uris);
|
RequestGroup(const Option* option, const Strings& uris);
|
||||||
|
|
||||||
|
@ -300,6 +305,16 @@ public:
|
||||||
void addPostDownloadHandler(const PostDownloadHandlerHandle& handler);
|
void addPostDownloadHandler(const PostDownloadHandlerHandle& handler);
|
||||||
|
|
||||||
void clearPostDowloadHandler();
|
void clearPostDowloadHandler();
|
||||||
|
|
||||||
|
Commands processCheckIntegrityEntry(const CheckIntegrityEntryHandle& entry, DownloadEngine* e);
|
||||||
|
|
||||||
|
void initPieceStorage();
|
||||||
|
|
||||||
|
bool downloadFinishedByFileLength();
|
||||||
|
|
||||||
|
void loadAndOpenFile(const BtProgressInfoFileHandle& progressInfoFile);
|
||||||
|
|
||||||
|
void shouldCancelDownloadForSafety();
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef SharedHandle<RequestGroup> RequestGroupHandle;
|
typedef SharedHandle<RequestGroup> RequestGroupHandle;
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
/* copyright --> */
|
/* copyright --> */
|
||||||
#include "RequestGroupMan.h"
|
#include "RequestGroupMan.h"
|
||||||
#include "BtProgressInfoFile.h"
|
#include "BtProgressInfoFile.h"
|
||||||
#include "DlAbortEx.h"
|
#include "RecoverableException.h"
|
||||||
#include "RequestGroup.h"
|
#include "RequestGroup.h"
|
||||||
#include "LogFactory.h"
|
#include "LogFactory.h"
|
||||||
#include "DownloadEngine.h"
|
#include "DownloadEngine.h"
|
||||||
|
@ -120,7 +120,7 @@ void RequestGroupMan::removeStoppedGroup()
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
(*itr)->getProgressInfoFile()->save();
|
(*itr)->getProgressInfoFile()->save();
|
||||||
} catch(DlAbortEx* ex) {
|
} catch(RecoverableException* ex) {
|
||||||
_logger->error(EX_EXCEPTION_CAUGHT, ex);
|
_logger->error(EX_EXCEPTION_CAUGHT, ex);
|
||||||
delete ex;
|
delete ex;
|
||||||
}
|
}
|
||||||
|
@ -154,7 +154,7 @@ void RequestGroupMan::fillRequestGroupFromReserver(DownloadEngine* e)
|
||||||
Commands commands = groupToAdd->createInitialCommand(e);
|
Commands commands = groupToAdd->createInitialCommand(e);
|
||||||
++count;
|
++count;
|
||||||
e->addCommand(commands);
|
e->addCommand(commands);
|
||||||
} catch(DlAbortEx* ex) {
|
} catch(RecoverableException* ex) {
|
||||||
_logger->error(EX_EXCEPTION_CAUGHT, ex);
|
_logger->error(EX_EXCEPTION_CAUGHT, ex);
|
||||||
delete ex;
|
delete ex;
|
||||||
}
|
}
|
||||||
|
@ -175,7 +175,7 @@ Commands RequestGroupMan::getInitialCommands(DownloadEngine* e)
|
||||||
Commands nextCommands = (*itr)->createInitialCommand(e);
|
Commands nextCommands = (*itr)->createInitialCommand(e);
|
||||||
copy(nextCommands.begin(), nextCommands.end(), back_inserter(commands));
|
copy(nextCommands.begin(), nextCommands.end(), back_inserter(commands));
|
||||||
++itr;
|
++itr;
|
||||||
} catch(DlAbortEx* e) {
|
} catch(RecoverableException* e) {
|
||||||
_logger->error(EX_EXCEPTION_CAUGHT, e);
|
_logger->error(EX_EXCEPTION_CAUGHT, e);
|
||||||
delete e;
|
delete e;
|
||||||
}
|
}
|
||||||
|
@ -196,7 +196,7 @@ void RequestGroupMan::save()
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
(*itr)->getProgressInfoFile()->save();
|
(*itr)->getProgressInfoFile()->save();
|
||||||
} catch(DlAbortEx* e) {
|
} catch(RecoverableException* e) {
|
||||||
_logger->error(EX_EXCEPTION_CAUGHT, e);
|
_logger->error(EX_EXCEPTION_CAUGHT, e);
|
||||||
delete e;
|
delete e;
|
||||||
}
|
}
|
||||||
|
@ -220,7 +220,7 @@ void RequestGroupMan::showDownloadResults(ostream& o) const
|
||||||
o << "\n"
|
o << "\n"
|
||||||
<<_("Download Results:") << "\n"
|
<<_("Download Results:") << "\n"
|
||||||
<< " (OK):download completed.(ERR):error occurred.(INPR):download in-progress." << "\n"
|
<< " (OK):download completed.(ERR):error occurred.(INPR):download in-progress." << "\n"
|
||||||
<< "idx|stat|path/URI" << "\n"
|
<< "gid|stat|path/URI" << "\n"
|
||||||
<< "===+====+======================================================================" << "\n";
|
<< "===+====+======================================================================" << "\n";
|
||||||
for(RequestGroups::const_iterator itr = _spentGroups.begin();
|
for(RequestGroups::const_iterator itr = _spentGroups.begin();
|
||||||
itr != _spentGroups.end(); ++itr) {
|
itr != _spentGroups.end(); ++itr) {
|
||||||
|
|
|
@ -36,6 +36,8 @@
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
#include "a2netcompat.h"
|
#include "a2netcompat.h"
|
||||||
#include "a2time.h"
|
#include "a2time.h"
|
||||||
|
#include "DlRetryEx.h"
|
||||||
|
#include "DlAbortEx.h"
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -81,7 +83,6 @@ SocketCore::~SocketCore() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SocketCore::beginListen(int32_t port)
|
void SocketCore::beginListen(int32_t port)
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
closeConnection();
|
closeConnection();
|
||||||
//sockfd = socket(AF_UNSPEC, SOCK_STREAM, PF_UNSPEC);
|
//sockfd = socket(AF_UNSPEC, SOCK_STREAM, PF_UNSPEC);
|
||||||
|
@ -118,7 +119,6 @@ void SocketCore::beginListen(int32_t port)
|
||||||
}
|
}
|
||||||
|
|
||||||
SocketCore* SocketCore::acceptConnection() const
|
SocketCore* SocketCore::acceptConnection() const
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
struct sockaddr_in sockaddr;
|
struct sockaddr_in sockaddr;
|
||||||
socklen_t len = sizeof(sockaddr);
|
socklen_t len = sizeof(sockaddr);
|
||||||
|
@ -133,7 +133,6 @@ SocketCore* SocketCore::acceptConnection() const
|
||||||
}
|
}
|
||||||
|
|
||||||
void SocketCore::getAddrInfo(pair<string, int32_t>& addrinfo) const
|
void SocketCore::getAddrInfo(pair<string, int32_t>& addrinfo) const
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
struct sockaddr_in listenaddr;
|
struct sockaddr_in listenaddr;
|
||||||
memset((char*)&listenaddr, 0, sizeof(listenaddr));
|
memset((char*)&listenaddr, 0, sizeof(listenaddr));
|
||||||
|
@ -146,7 +145,6 @@ void SocketCore::getAddrInfo(pair<string, int32_t>& addrinfo) const
|
||||||
}
|
}
|
||||||
|
|
||||||
void SocketCore::getPeerInfo(pair<string, int32_t>& peerinfo) const
|
void SocketCore::getPeerInfo(pair<string, int32_t>& peerinfo) const
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
struct sockaddr_in peerin;
|
struct sockaddr_in peerin;
|
||||||
memset(&peerin, 0, sizeof(peerin));
|
memset(&peerin, 0, sizeof(peerin));
|
||||||
|
@ -159,7 +157,6 @@ void SocketCore::getPeerInfo(pair<string, int32_t>& peerinfo) const
|
||||||
}
|
}
|
||||||
|
|
||||||
void SocketCore::establishConnection(const string& host, int32_t port)
|
void SocketCore::establishConnection(const string& host, int32_t port)
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
closeConnection();
|
closeConnection();
|
||||||
sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
@ -209,7 +206,6 @@ WSAEWOULDBLOCK
|
||||||
}
|
}
|
||||||
|
|
||||||
void SocketCore::setNonBlockingMode()
|
void SocketCore::setNonBlockingMode()
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
static u_long flag = 1;
|
static u_long flag = 1;
|
||||||
|
@ -225,7 +221,6 @@ void SocketCore::setNonBlockingMode()
|
||||||
}
|
}
|
||||||
|
|
||||||
void SocketCore::setBlockingMode()
|
void SocketCore::setBlockingMode()
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
static u_long flag = 0;
|
static u_long flag = 0;
|
||||||
|
@ -277,7 +272,6 @@ void SocketCore::closeConnection()
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SocketCore::isWritable(int32_t timeout) const
|
bool SocketCore::isWritable(int32_t timeout) const
|
||||||
throw(DlRetryEx*)
|
|
||||||
{
|
{
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
FD_ZERO(&fds);
|
FD_ZERO(&fds);
|
||||||
|
@ -303,7 +297,6 @@ bool SocketCore::isWritable(int32_t timeout) const
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SocketCore::isReadable(int32_t timeout) const
|
bool SocketCore::isReadable(int32_t timeout) const
|
||||||
throw(DlRetryEx*)
|
|
||||||
{
|
{
|
||||||
#ifdef HAVE_LIBGNUTLS
|
#ifdef HAVE_LIBGNUTLS
|
||||||
if(secure && peekBufLength > 0) {
|
if(secure && peekBufLength > 0) {
|
||||||
|
@ -334,7 +327,6 @@ bool SocketCore::isReadable(int32_t timeout) const
|
||||||
}
|
}
|
||||||
|
|
||||||
void SocketCore::writeData(const char* data, int32_t len)
|
void SocketCore::writeData(const char* data, int32_t len)
|
||||||
throw(DlRetryEx*)
|
|
||||||
{
|
{
|
||||||
int32_t ret = 0;
|
int32_t ret = 0;
|
||||||
|
|
||||||
|
@ -351,7 +343,7 @@ void SocketCore::writeData(const char* data, int32_t len)
|
||||||
}
|
}
|
||||||
#endif // HAVE_LIBSSL
|
#endif // HAVE_LIBSSL
|
||||||
#ifdef HAVE_LIBGNUTLS
|
#ifdef HAVE_LIBGNUTLS
|
||||||
if((ret = gnutls_record_send(sslSession, data, len)) == len) {
|
if((ret = gnutls_record_send(sslSession, data, len)) != len) {
|
||||||
throw new DlRetryEx(EX_SOCKET_SEND, gnutls_strerror(ret));
|
throw new DlRetryEx(EX_SOCKET_SEND, gnutls_strerror(ret));
|
||||||
}
|
}
|
||||||
#endif // HAVE_LIBGNUTLS
|
#endif // HAVE_LIBGNUTLS
|
||||||
|
@ -359,7 +351,6 @@ void SocketCore::writeData(const char* data, int32_t len)
|
||||||
}
|
}
|
||||||
|
|
||||||
void SocketCore::readData(char* data, int32_t& len)
|
void SocketCore::readData(char* data, int32_t& len)
|
||||||
throw(DlRetryEx*)
|
|
||||||
{
|
{
|
||||||
int32_t ret = 0;
|
int32_t ret = 0;
|
||||||
|
|
||||||
|
@ -386,7 +377,6 @@ void SocketCore::readData(char* data, int32_t& len)
|
||||||
}
|
}
|
||||||
|
|
||||||
void SocketCore::peekData(char* data, int32_t& len)
|
void SocketCore::peekData(char* data, int32_t& len)
|
||||||
throw(DlRetryEx*)
|
|
||||||
{
|
{
|
||||||
int32_t ret = 0;
|
int32_t ret = 0;
|
||||||
|
|
||||||
|
@ -446,7 +436,6 @@ void SocketCore::addPeekData(char* data, int32_t len)
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t SocketCore::gnutlsRecv(char* data, int32_t len)
|
int32_t SocketCore::gnutlsRecv(char* data, int32_t len)
|
||||||
throw(DlRetryEx*)
|
|
||||||
{
|
{
|
||||||
int32_t plen = shiftPeekData(data, len);
|
int32_t plen = shiftPeekData(data, len);
|
||||||
if(plen < len) {
|
if(plen < len) {
|
||||||
|
@ -461,7 +450,6 @@ int32_t SocketCore::gnutlsRecv(char* data, int32_t len)
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t SocketCore::gnutlsPeek(char* data, int32_t len)
|
int32_t SocketCore::gnutlsPeek(char* data, int32_t len)
|
||||||
throw(DlRetryEx*)
|
|
||||||
{
|
{
|
||||||
if(peekBufLength >= len) {
|
if(peekBufLength >= len) {
|
||||||
memcpy(data, peekBuf, len);
|
memcpy(data, peekBuf, len);
|
||||||
|
@ -479,7 +467,6 @@ int32_t SocketCore::gnutlsPeek(char* data, int32_t len)
|
||||||
#endif // HAVE_LIBGNUTLS
|
#endif // HAVE_LIBGNUTLS
|
||||||
|
|
||||||
void SocketCore::initiateSecureConnection()
|
void SocketCore::initiateSecureConnection()
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
#ifdef HAVE_LIBSSL
|
#ifdef HAVE_LIBSSL
|
||||||
// for SSL
|
// for SSL
|
||||||
|
|
|
@ -36,8 +36,6 @@
|
||||||
#define _D_SOCKET_CORE_H_
|
#define _D_SOCKET_CORE_H_
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "DlRetryEx.h"
|
|
||||||
#include "DlAbortEx.h"
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
@ -77,8 +75,8 @@ private:
|
||||||
|
|
||||||
int32_t shiftPeekData(char* data, int32_t len);
|
int32_t shiftPeekData(char* data, int32_t len);
|
||||||
void addPeekData(char* data, int32_t len);
|
void addPeekData(char* data, int32_t len);
|
||||||
int32_t gnutlsRecv(char* data, int32_t len) throw(DlRetryEx*);
|
int32_t gnutlsRecv(char* data, int32_t len);
|
||||||
int32_t gnutlsPeek(char* data, int32_t len) throw(DlRetryEx*);
|
int32_t gnutlsPeek(char* data, int32_t len);
|
||||||
#endif // HAVE_LIBGNUTLS
|
#endif // HAVE_LIBGNUTLS
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
@ -99,26 +97,26 @@ public:
|
||||||
* @param port port to listen. If 0 is specified, os automaticaly
|
* @param port port to listen. If 0 is specified, os automaticaly
|
||||||
* choose avaiable port.
|
* choose avaiable port.
|
||||||
*/
|
*/
|
||||||
void beginListen(int32_t port = 0) throw(DlAbortEx*);
|
void beginListen(int32_t port = 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores host address and port of this socket to addrinfo.
|
* Stores host address and port of this socket to addrinfo.
|
||||||
* @param addrinfo placeholder to store host address and port.
|
* @param addrinfo placeholder to store host address and port.
|
||||||
*/
|
*/
|
||||||
void getAddrInfo(pair<string, int32_t>& addrinfo) const throw(DlAbortEx*);
|
void getAddrInfo(pair<string, int32_t>& addrinfo) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores peer's address and port to peerinfo.
|
* Stores peer's address and port to peerinfo.
|
||||||
* @param peerinfo placeholder to store peer's address and port.
|
* @param peerinfo placeholder to store peer's address and port.
|
||||||
*/
|
*/
|
||||||
void getPeerInfo(pair<string, int32_t>& peerinfo) const throw(DlAbortEx*);
|
void getPeerInfo(pair<string, int32_t>& peerinfo) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accepts incoming connection on this socket.
|
* Accepts incoming connection on this socket.
|
||||||
* You must call beginListen() before calling this method.
|
* You must call beginListen() before calling this method.
|
||||||
* @return accepted socket. The caller must delete it after using it.
|
* @return accepted socket. The caller must delete it after using it.
|
||||||
*/
|
*/
|
||||||
SocketCore* acceptConnection() const throw(DlAbortEx*);
|
SocketCore* acceptConnection() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connects to the server named host and the destination port is port.
|
* Connects to the server named host and the destination port is port.
|
||||||
|
@ -128,14 +126,14 @@ public:
|
||||||
* @param host hostname or ip address to connect to
|
* @param host hostname or ip address to connect to
|
||||||
* @param port service port number to connect to
|
* @param port service port number to connect to
|
||||||
*/
|
*/
|
||||||
void establishConnection(const string& host, int32_t port) throw(DlAbortEx*);
|
void establishConnection(const string& host, int32_t port);
|
||||||
|
|
||||||
void setNonBlockingMode() throw(DlAbortEx*);
|
void setNonBlockingMode();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes this socket blocking mode.
|
* Makes this socket blocking mode.
|
||||||
*/
|
*/
|
||||||
void setBlockingMode() throw(DlAbortEx*);
|
void setBlockingMode();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Closes the connection of this socket.
|
* Closes the connection of this socket.
|
||||||
|
@ -149,7 +147,7 @@ public:
|
||||||
* @return true if the socket is available for writing,
|
* @return true if the socket is available for writing,
|
||||||
* otherwise returns false.
|
* otherwise returns false.
|
||||||
*/
|
*/
|
||||||
bool isWritable(int32_t timeout) const throw(DlRetryEx*);
|
bool isWritable(int32_t timeout) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether this socket is available for reading.
|
* Checks whether this socket is available for reading.
|
||||||
|
@ -158,7 +156,7 @@ public:
|
||||||
* @return true if the socket is available for reading,
|
* @return true if the socket is available for reading,
|
||||||
* otherwise returns false.
|
* otherwise returns false.
|
||||||
*/
|
*/
|
||||||
bool isReadable(int32_t timeout) const throw(DlRetryEx*);
|
bool isReadable(int32_t timeout) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes characters into this socket. data is a pointer pointing the first
|
* Writes characters into this socket. data is a pointer pointing the first
|
||||||
|
@ -168,8 +166,8 @@ public:
|
||||||
* @param data data to write
|
* @param data data to write
|
||||||
* @param len length of data
|
* @param len length of data
|
||||||
*/
|
*/
|
||||||
void writeData(const char* data, int32_t len) throw(DlRetryEx*);
|
void writeData(const char* data, int32_t len);
|
||||||
void writeData(const string& msg) throw(DlRetryEx*)
|
void writeData(const string& msg)
|
||||||
{
|
{
|
||||||
writeData(msg.c_str(), msg.size());
|
writeData(msg.c_str(), msg.size());
|
||||||
}
|
}
|
||||||
|
@ -186,7 +184,7 @@ public:
|
||||||
* @param len the maximum size data can store. This method assigns
|
* @param len the maximum size data can store. This method assigns
|
||||||
* the number of bytes read to len.
|
* the number of bytes read to len.
|
||||||
*/
|
*/
|
||||||
void readData(char* data, int32_t& len) throw(DlRetryEx*);
|
void readData(char* data, int32_t& len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads up to len bytes from this socket, but bytes are not removed from
|
* Reads up to len bytes from this socket, but bytes are not removed from
|
||||||
|
@ -197,14 +195,14 @@ public:
|
||||||
* @param len the maximum size data can store. This method assigns
|
* @param len the maximum size data can store. This method assigns
|
||||||
* the number of bytes read to len.
|
* the number of bytes read to len.
|
||||||
*/
|
*/
|
||||||
void peekData(char* data, int32_t& len) throw(DlRetryEx*);
|
void peekData(char* data, int32_t& len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes this socket secure.
|
* Makes this socket secure.
|
||||||
* If the system has not OpenSSL, then this method do nothing.
|
* If the system has not OpenSSL, then this method do nothing.
|
||||||
* connection must be established before calling this method.
|
* connection must be established before calling this method.
|
||||||
*/
|
*/
|
||||||
void initiateSecureConnection() throw(DlAbortEx*);
|
void initiateSecureConnection();
|
||||||
|
|
||||||
bool operator==(const SocketCore& s) {
|
bool operator==(const SocketCore& s) {
|
||||||
return sockfd == s.sockfd;
|
return sockfd == s.sockfd;
|
||||||
|
|
|
@ -54,22 +54,13 @@ StreamCheckIntegrityEntry::~StreamCheckIntegrityEntry() {}
|
||||||
Commands StreamCheckIntegrityEntry::onDownloadIncomplete(DownloadEngine* e)
|
Commands StreamCheckIntegrityEntry::onDownloadIncomplete(DownloadEngine* e)
|
||||||
{
|
{
|
||||||
Commands commands;
|
Commands commands;
|
||||||
|
FileAllocationEntryHandle entry =
|
||||||
|
new StreamFileAllocationEntry(_currentRequest, _requestGroup,
|
||||||
|
popNextCommand());
|
||||||
if(_requestGroup->needsFileAllocation()) {
|
if(_requestGroup->needsFileAllocation()) {
|
||||||
FileAllocationEntryHandle entry =
|
|
||||||
new StreamFileAllocationEntry(_currentRequest, _requestGroup,
|
|
||||||
popNextCommand());
|
|
||||||
e->_fileAllocationMan->pushFileAllocationEntry(entry);
|
e->_fileAllocationMan->pushFileAllocationEntry(entry);
|
||||||
} else {
|
} else {
|
||||||
if(_nextCommand) {
|
commands = entry->prepareForNextAction(e);
|
||||||
commands.push_back(popNextCommand());
|
|
||||||
} else {
|
|
||||||
Commands streamCommands = _requestGroup->createNextCommandWithAdj(e, -1);
|
|
||||||
Command* command = InitiateConnectionCommandFactory::createInitiateConnectionCommand(CUIDCounterSingletonHolder::instance()->newID(),
|
|
||||||
_currentRequest, _requestGroup, e);
|
|
||||||
|
|
||||||
commands.push_front(command);
|
|
||||||
copy(streamCommands.begin(), streamCommands.end(), back_inserter(commands));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return commands;
|
return commands;
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,12 +58,16 @@ Commands StreamFileAllocationEntry::prepareForNextAction(DownloadEngine* e)
|
||||||
_nextCommand) {
|
_nextCommand) {
|
||||||
commands.push_back(popNextCommand());
|
commands.push_back(popNextCommand());
|
||||||
} else {
|
} else {
|
||||||
Commands streamCommands = _requestGroup->createNextCommandWithAdj(e, -1);
|
if(_currentRequest.isNull()) {
|
||||||
Command* command = InitiateConnectionCommandFactory::createInitiateConnectionCommand(CUIDCounterSingletonHolder::instance()->newID(),
|
commands = _requestGroup->createNextCommandWithAdj(e, 0);
|
||||||
_currentRequest, _requestGroup, e);
|
} else {
|
||||||
|
Commands streamCommands = _requestGroup->createNextCommandWithAdj(e, -1);
|
||||||
commands.push_back(command);
|
Command* command = InitiateConnectionCommandFactory::createInitiateConnectionCommand(CUIDCounterSingletonHolder::instance()->newID(),
|
||||||
copy(streamCommands.begin(), streamCommands.end(), back_inserter(commands));
|
_currentRequest, _requestGroup, e);
|
||||||
|
|
||||||
|
commands.push_back(command);
|
||||||
|
copy(streamCommands.begin(), streamCommands.end(), back_inserter(commands));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return commands;
|
return commands;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,8 @@
|
||||||
#include "DiskAdaptor.h"
|
#include "DiskAdaptor.h"
|
||||||
#include "RequestGroup.h"
|
#include "RequestGroup.h"
|
||||||
#include "Option.h"
|
#include "Option.h"
|
||||||
|
#include "DlRetryEx.h"
|
||||||
|
#include "DlAbortEx.h"
|
||||||
|
|
||||||
TrackerWatcherCommand::TrackerWatcherCommand(int32_t cuid,
|
TrackerWatcherCommand::TrackerWatcherCommand(int32_t cuid,
|
||||||
RequestGroup* requestGroup,
|
RequestGroup* requestGroup,
|
||||||
|
@ -87,6 +89,7 @@ bool TrackerWatcherCommand::execute() {
|
||||||
btAnnounce->announceFailure();
|
btAnnounce->announceFailure();
|
||||||
btAnnounce->resetAnnounce();
|
btAnnounce->resetAnnounce();
|
||||||
} catch(DlRetryEx* ex) {
|
} catch(DlRetryEx* ex) {
|
||||||
|
// TODO Can I remove this catch clause?
|
||||||
logger->error(EX_EXCEPTION_CAUGHT, ex);
|
logger->error(EX_EXCEPTION_CAUGHT, ex);
|
||||||
delete ex;
|
delete ex;
|
||||||
btAnnounce->announceFailure();
|
btAnnounce->announceFailure();
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include "Randomizer.h"
|
#include "Randomizer.h"
|
||||||
#include "a2netcompat.h"
|
#include "a2netcompat.h"
|
||||||
#include "a2time.h"
|
#include "a2time.h"
|
||||||
|
#include "DlAbortEx.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
@ -331,7 +332,6 @@ void Util::fileCopy(const string& dest, const string& src) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Util::rangedFileCopy(const string& dest, const string& src, int64_t srcOffset, int64_t length)
|
void Util::rangedFileCopy(const string& dest, const string& src, int64_t srcOffset, int64_t length)
|
||||||
throw(DlAbortEx*)
|
|
||||||
{
|
{
|
||||||
int32_t bufSize = 4096;
|
int32_t bufSize = 4096;
|
||||||
char buf[bufSize];
|
char buf[bufSize];
|
||||||
|
|
|
@ -36,7 +36,6 @@
|
||||||
#define _D_UTIL_H_
|
#define _D_UTIL_H_
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "DlAbortEx.h"
|
|
||||||
#include "a2time.h"
|
#include "a2time.h"
|
||||||
#include "FileEntry.h"
|
#include "FileEntry.h"
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
@ -100,7 +99,7 @@ public:
|
||||||
|
|
||||||
static void fileCopy(const string& destFile, const string& src);
|
static void fileCopy(const string& destFile, const string& src);
|
||||||
|
|
||||||
static void rangedFileCopy(const string& destFile, const string& src, int64_t srcOffset, int64_t length) throw(DlAbortEx*);
|
static void rangedFileCopy(const string& destFile, const string& src, int64_t srcOffset, int64_t length);
|
||||||
|
|
||||||
static bool isPowerOf(int32_t num, int32_t base);
|
static bool isPowerOf(int32_t num, int32_t base);
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@
|
||||||
#define MSG_GOT_NEW_PIECE _("CUID#%d - we got new piece. index=%d")
|
#define MSG_GOT_NEW_PIECE _("CUID#%d - we got new piece. index=%d")
|
||||||
#define MSG_GOT_WRONG_PIECE _("CUID#%d - we got wrong piece. index=%d")
|
#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_NOT_COMPLETE _("CUID#%d - Download not complete: %s")
|
||||||
#define MSG_DOWNLOAD_ALREADY_COMPLETED _("CUID#%d - Download has already completed: %s")
|
#define MSG_DOWNLOAD_ALREADY_COMPLETED _("#%d - Download has already completed: %s")
|
||||||
#define MSG_GOOD_CHECKSUM _("CUID#%d - Good checksum: %s")
|
#define MSG_GOOD_CHECKSUM _("CUID#%d - Good checksum: %s")
|
||||||
#define MSG_BAD_CHECKSUM _("CUID#%d - Bad checksum: %s")
|
#define MSG_BAD_CHECKSUM _("CUID#%d - Bad checksum: %s")
|
||||||
#define MSG_RESOLVING_HOSTNAME _("CUID#%d - Resolving hostname %s")
|
#define MSG_RESOLVING_HOSTNAME _("CUID#%d - Resolving hostname %s")
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#include "OptionHandlerFactory.h"
|
#include "OptionHandlerFactory.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
|
#include "Exception.h"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "FixedNumberRandomizer.h"
|
#include "FixedNumberRandomizer.h"
|
||||||
|
#include "DlAbortEx.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cppunit/extensions/HelperMacros.h>
|
#include <cppunit/extensions/HelperMacros.h>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue