mirror of https://github.com/aria2/aria2
2007-01-11 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
To add RecoverableException, FatalException: * src/AbstractCommand.cc (onAbort): Exception -> RecoverableException * src/PeerAbstractCommand.h (RecoverableException.h): New include. (onAbort): Exception -> RecoverableException. * src/PeerInteractionCommand.cc (onAbort): Exception -> RecoverableException. * src/PeerAbstractCommand.cc (execute): Exception -> RecoverableException. (onAbort): Exception -> RecoverableException. * src/TorrentRequestInfo.cc (execute): Exception -> RecoverableException. * src/MetalinkRequestInfo.cc (execute): Exception -> RecoverableException. * src/MetaFileUtil.cc: RecoverableException. * src/AbstractCommand.h (onAbort): Exception -> RecoverableException. * src/DlRetryEx.h: Exception -> RecoverableException. * src/DlAbortEx.h: Exception -> RecoverableException. * src/PeerListenCommand.cc: Exception -> RecoverableException. * src/Util.cc: Exception -> RecoverableException. * src/DefauldDiskWriter.cc: Exception -> RecoverableException. * src/TrackerUpdateCommand.cc: Exception -> RecoverableException. * src/UrlRequestInfo.cc: Exception -> RecoverableException. To make ID static const int * src/BtInterestedMessage.h (ID_t): Removed. (ID): New variable. (getId): Made non-const. * src/BtPieceMessage.h (ID_t): Removed. (ID): New variable. (getId): Made non-const. * src/BtChokeMessage.h (ID_t): Removed. (ID): New variable. (getId): Made non-const. * src/BtHaveAllMessage.h (ID_t): Removed. (ID): New variable. (getId): Made non-const. * src/BtKeepAliveMessage.h (ID_t): Removed. (ID): New variable. (getId): Made non-const. * src/BtHandshakeMessage.h (ID): New variable. (getId): Made non-const. * src/BtSuggestPieceMessage.h (ID_t): Removed. (ID): New variable. (getId): Made non-const. * src/BtPortMessage.h (ID_t): Removed. (ID): New variable. (getId): Made non-const. * src/AbstractBtMessage.h (id): Removed. (AbstractBtMessage): Removed id. (getId): Removed. * src/BtHaveMessage.h (ID_t): Removed. (ID): New variable. (getId): Made non-const. * src/BtAllowedFastMessage.h (ID_t): Removed. (ID): New variable. (getId): Made non-const. * src/BtCancelMessage.h (ID_t): Removed. (ID): New variable. (getId): Made non-const. * src/BtNotInterestedMessage.h (ID_t): Removed. (ID): New variable. (getId): Made non-const. * src/BtChokeMessage.h (ID_t): Removed. (ID): New variable. (getId): Made non-const. * src/BtRejectMessage.h (ID_t): Removed. (ID): New variable. (getId): Made non-const. * src/BtBitfieldMessage.h (ID_t): Removed. (ID): New variable. (getId): Made non-const. * src/BtUnchokeMessage.h (ID_t): Removed. (ID): New variable. (getId): Made non-const. * src/BtRequestMessage.h (ID_t): Removed. (ID): New variable. (getId): Made non-const. * src/BtHaveMessage.h (ID_t): Removed. (ID): New variable. (getId): Made non-const. To add --force-truncate command-line option and a check whether the file already exists: * src/DirectDiskAdaptor.h (getFilePath): Made virtual public. * src/MultiDiskAdaptor.h (File.h): New include. (DiskWriterEntry::fileEntry): Made private. (DiskWriterEntry::fileExists): New function. (DiskWriterEntry::getFileEntry): New function. (fileExists): New function. (getFilePath): New function. * src/TorrentRequestInfo.cc (FatalException.h): New include. (message.h): New include. (RecoverableException.h): New include. (execute): Added a check whether file is already exists or not. * src/DiskAdaptor.h (fileExists): New function. (getFilePath): New function. * src/main.cc (showUsage): Added an explanation of --force-truncate command-line option. (main): Added --force-truncate command-line option. * src/Exception.h (setMsg): buf[256] -> buf[1024] * src/CopyDiskWriter.h (getFilePath): Made public virtual. * src/MultiDiskAdaptor.cc: fileEntry -> getFileEntry() (fileExists): New function. * src/DownloadEngineFactory.cc (newTorrentConsoleEngine): Don't open file here. * src/message.h (EX_FILE_ALREADY_EXISTS): New definition. * src/prefs.h (PREF_FOECE_TRUNCATE): New definition. * src/HttpResponseCommand.cc (handleDefaultEncoding): Added a check whether the file already exists. * src/SegmentMan.h (fileExists): New function. (shouldCancelDownloadForSafety): New function. * src/FtpNegotiateCommand.cc (recvSize): Added a check whether the file already exists. * src/AbstractSingleDiskAdaptor.cc (File.h): New include. (fileExists): New function. * src/AbstractSingleDiskAdaptor.h (getFilePath): Removed. (fileExists): New function. * src/SegmentMan.cc (fileExists): New function. (shouldCancelDownloadForSafety): New function. To fix regression bug in torrent downloading: * src/DefaultBtRequestFactory.cc (doChokedAction): New function. * src/DefaultBtRequestFactory.h (doChokedAction): New function. * src/DefaultBtMessageDispatcher.cc (doChokedAction): Do not delete request if its target is in allowed fast set. * src/DefaultBtInteractive.cc (doPostHandshakeProcessing): Added a call to sendPendingMessage(). (sendKeepAlive): Send keep alive message even if the outgoing message queue is not empty. (decideInterest): Simplified the code. (fillPiece): Remove a call to dispatcher->doChokedAction() because it is already called when BtChokeMessage is received from a peer. * src/BtRequestFactory.h (doChokedAction): New function. To clean up code: * src/PeerInteractionCommand.h (executeInternal): Added virtual keyword explicitly. (prepareForRetry): Added virtual keyword explicitly. (prepareForNextPeer): Added virtual keyword explicitly. (onAbort): Added virtual keyword explicitly. * src/RequestSlot.cc (isTimeout): Use Time::elapsed() instead of differenceInMillis(). * src/BtPieceMessage.cc (doReceivedAction): Added a debug log of piece's bitfield. * src/Piece.h (getBitfieldLength): New function. * src/ByteArrayDiskWriter.cc (clear): Added buf = 0 to avoid double free corruption. * src/FileAllocator.cc (allocate): Fixed an assignment of fileAllocationMonitor->currentValue. Added cp.reset(). * src/BitfieldMan.h (operator=): Rewritten. * src/BitfieldMan.cc (BitfieldMan): Initialized bitfield, useBitfield. * src/PeerConnection.cc (receiveMessage): Added a call to socket->readable() after getting message length to avoid possible EOF. * src/Util.cc (torrentUrlencode): Fixed an encodeing bug. BUG#1629912pull/1/head
parent
e8034f2fd4
commit
d28e6aca15
214
ChangeLog
214
ChangeLog
|
@ -1,3 +1,217 @@
|
|||
2007-01-11 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||
|
||||
To add RecoverableException, FatalException:
|
||||
|
||||
* src/AbstractCommand.cc
|
||||
(onAbort): Exception -> RecoverableException
|
||||
* src/PeerAbstractCommand.h
|
||||
(RecoverableException.h): New include.
|
||||
(onAbort): Exception -> RecoverableException.
|
||||
* src/PeerInteractionCommand.cc
|
||||
(onAbort): Exception -> RecoverableException.
|
||||
* src/PeerAbstractCommand.cc
|
||||
(execute): Exception -> RecoverableException.
|
||||
(onAbort): Exception -> RecoverableException.
|
||||
* src/TorrentRequestInfo.cc
|
||||
(execute): Exception -> RecoverableException.
|
||||
* src/MetalinkRequestInfo.cc
|
||||
(execute): Exception -> RecoverableException.
|
||||
* src/MetaFileUtil.cc: RecoverableException.
|
||||
* src/AbstractCommand.h
|
||||
(onAbort): Exception -> RecoverableException.
|
||||
* src/DlRetryEx.h: Exception -> RecoverableException.
|
||||
* src/DlAbortEx.h: Exception -> RecoverableException.
|
||||
* src/PeerListenCommand.cc: Exception -> RecoverableException.
|
||||
* src/Util.cc: Exception -> RecoverableException.
|
||||
* src/DefauldDiskWriter.cc: Exception -> RecoverableException.
|
||||
* src/TrackerUpdateCommand.cc: Exception -> RecoverableException.
|
||||
* src/UrlRequestInfo.cc: Exception -> RecoverableException.
|
||||
|
||||
To make ID static const int
|
||||
|
||||
* src/BtInterestedMessage.h
|
||||
(ID_t): Removed.
|
||||
(ID): New variable.
|
||||
(getId): Made non-const.
|
||||
* src/BtPieceMessage.h
|
||||
(ID_t): Removed.
|
||||
(ID): New variable.
|
||||
(getId): Made non-const.
|
||||
* src/BtChokeMessage.h
|
||||
(ID_t): Removed.
|
||||
(ID): New variable.
|
||||
(getId): Made non-const.
|
||||
* src/BtHaveAllMessage.h
|
||||
(ID_t): Removed.
|
||||
(ID): New variable.
|
||||
(getId): Made non-const.
|
||||
* src/BtKeepAliveMessage.h
|
||||
(ID_t): Removed.
|
||||
(ID): New variable.
|
||||
(getId): Made non-const.
|
||||
* src/BtHandshakeMessage.h
|
||||
(ID): New variable.
|
||||
(getId): Made non-const.
|
||||
* src/BtSuggestPieceMessage.h
|
||||
(ID_t): Removed.
|
||||
(ID): New variable.
|
||||
(getId): Made non-const.
|
||||
* src/BtPortMessage.h
|
||||
(ID_t): Removed.
|
||||
(ID): New variable.
|
||||
(getId): Made non-const.
|
||||
* src/AbstractBtMessage.h
|
||||
(id): Removed.
|
||||
(AbstractBtMessage): Removed id.
|
||||
(getId): Removed.
|
||||
* src/BtHaveMessage.h
|
||||
(ID_t): Removed.
|
||||
(ID): New variable.
|
||||
(getId): Made non-const.
|
||||
* src/BtAllowedFastMessage.h
|
||||
(ID_t): Removed.
|
||||
(ID): New variable.
|
||||
(getId): Made non-const.
|
||||
* src/BtCancelMessage.h
|
||||
(ID_t): Removed.
|
||||
(ID): New variable.
|
||||
(getId): Made non-const.
|
||||
* src/BtNotInterestedMessage.h
|
||||
(ID_t): Removed.
|
||||
(ID): New variable.
|
||||
(getId): Made non-const.
|
||||
* src/BtChokeMessage.h
|
||||
(ID_t): Removed.
|
||||
(ID): New variable.
|
||||
(getId): Made non-const.
|
||||
* src/BtRejectMessage.h
|
||||
(ID_t): Removed.
|
||||
(ID): New variable.
|
||||
(getId): Made non-const.
|
||||
* src/BtBitfieldMessage.h
|
||||
(ID_t): Removed.
|
||||
(ID): New variable.
|
||||
(getId): Made non-const.
|
||||
* src/BtUnchokeMessage.h
|
||||
(ID_t): Removed.
|
||||
(ID): New variable.
|
||||
(getId): Made non-const.
|
||||
* src/BtRequestMessage.h
|
||||
(ID_t): Removed.
|
||||
(ID): New variable.
|
||||
(getId): Made non-const.
|
||||
* src/BtHaveMessage.h
|
||||
(ID_t): Removed.
|
||||
(ID): New variable.
|
||||
(getId): Made non-const.
|
||||
|
||||
To add --force-truncate command-line option and a check whether
|
||||
the file already exists:
|
||||
|
||||
* src/DirectDiskAdaptor.h
|
||||
(getFilePath): Made virtual public.
|
||||
* src/MultiDiskAdaptor.h
|
||||
(File.h): New include.
|
||||
(DiskWriterEntry::fileEntry): Made private.
|
||||
(DiskWriterEntry::fileExists): New function.
|
||||
(DiskWriterEntry::getFileEntry): New function.
|
||||
(fileExists): New function.
|
||||
(getFilePath): New function.
|
||||
* src/TorrentRequestInfo.cc
|
||||
(FatalException.h): New include.
|
||||
(message.h): New include.
|
||||
(RecoverableException.h): New include.
|
||||
(execute): Added a check whether file is already exists or not.
|
||||
* src/DiskAdaptor.h
|
||||
(fileExists): New function.
|
||||
(getFilePath): New function.
|
||||
* src/main.cc
|
||||
(showUsage): Added an explanation of --force-truncate command-line
|
||||
option.
|
||||
(main): Added --force-truncate command-line option.
|
||||
* src/Exception.h
|
||||
(setMsg): buf[256] -> buf[1024]
|
||||
* src/CopyDiskWriter.h
|
||||
(getFilePath): Made public virtual.
|
||||
* src/MultiDiskAdaptor.cc: fileEntry -> getFileEntry()
|
||||
(fileExists): New function.
|
||||
* src/DownloadEngineFactory.cc
|
||||
(newTorrentConsoleEngine): Don't open file here.
|
||||
* src/message.h
|
||||
(EX_FILE_ALREADY_EXISTS): New definition.
|
||||
* src/prefs.h
|
||||
(PREF_FOECE_TRUNCATE): New definition.
|
||||
* src/HttpResponseCommand.cc
|
||||
(handleDefaultEncoding): Added a check whether the file already exists.
|
||||
* src/SegmentMan.h
|
||||
(fileExists): New function.
|
||||
(shouldCancelDownloadForSafety): New function.
|
||||
* src/FtpNegotiateCommand.cc
|
||||
(recvSize): Added a check whether the file already exists.
|
||||
* src/AbstractSingleDiskAdaptor.cc
|
||||
(File.h): New include.
|
||||
(fileExists): New function.
|
||||
* src/AbstractSingleDiskAdaptor.h
|
||||
(getFilePath): Removed.
|
||||
(fileExists): New function.
|
||||
* src/SegmentMan.cc
|
||||
(fileExists): New function.
|
||||
(shouldCancelDownloadForSafety): New function.
|
||||
|
||||
To fix regression bug in torrent downloading:
|
||||
|
||||
* src/DefaultBtRequestFactory.cc
|
||||
(doChokedAction): New function.
|
||||
* src/DefaultBtRequestFactory.h
|
||||
(doChokedAction): New function.
|
||||
* src/DefaultBtMessageDispatcher.cc
|
||||
(doChokedAction): Do not delete request if its target is in allowed
|
||||
fast set.
|
||||
* src/DefaultBtInteractive.cc
|
||||
(doPostHandshakeProcessing): Added a call to sendPendingMessage().
|
||||
(sendKeepAlive): Send keep alive message even if the outgoing message
|
||||
queue is not empty.
|
||||
(decideInterest): Simplified the code.
|
||||
(fillPiece): Remove a call to dispatcher->doChokedAction() because
|
||||
it is already called when BtChokeMessage is received from a peer.
|
||||
* src/BtRequestFactory.h
|
||||
(doChokedAction): New function.
|
||||
|
||||
To clean up code:
|
||||
|
||||
* src/PeerInteractionCommand.h
|
||||
(executeInternal): Added virtual keyword explicitly.
|
||||
(prepareForRetry): Added virtual keyword explicitly.
|
||||
(prepareForNextPeer): Added virtual keyword explicitly.
|
||||
(onAbort): Added virtual keyword explicitly.
|
||||
|
||||
* src/RequestSlot.cc
|
||||
(isTimeout): Use Time::elapsed() instead of differenceInMillis().
|
||||
|
||||
* src/BtPieceMessage.cc
|
||||
(doReceivedAction): Added a debug log of piece's bitfield.
|
||||
* src/Piece.h
|
||||
(getBitfieldLength): New function.
|
||||
|
||||
* src/ByteArrayDiskWriter.cc
|
||||
(clear): Added buf = 0 to avoid double free corruption.
|
||||
|
||||
* src/FileAllocator.cc
|
||||
(allocate): Fixed an assignment of fileAllocationMonitor->currentValue.
|
||||
Added cp.reset().
|
||||
|
||||
* src/BitfieldMan.h
|
||||
(operator=): Rewritten.
|
||||
* src/BitfieldMan.cc
|
||||
(BitfieldMan): Initialized bitfield, useBitfield.
|
||||
|
||||
* src/PeerConnection.cc
|
||||
(receiveMessage): Added a call to socket->readable() after getting
|
||||
message length to avoid possible EOF.
|
||||
|
||||
* src/Util.cc
|
||||
(torrentUrlencode): Fixed an encodeing bug. BUG#1629912
|
||||
|
||||
2007-01-08 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||
|
||||
To add an ability to pre-allocate file space:
|
||||
|
|
8
TODO
8
TODO
|
@ -21,9 +21,7 @@
|
|||
* Add the message like "you can resume the transfer by invoking aria2 again" when the download stops.
|
||||
* Add --bt-timeout command line option.
|
||||
* Fix DefaultBtProgressInfoFile.cc: save(), load()
|
||||
* Add a feature that if any existing file is detected, then
|
||||
do not start downloading and print some useful message to the user.
|
||||
* Fix Segfaults in BitfieldMan.cc:71
|
||||
https://sourceforge.net/tracker/index.php?func=detail&aid=1606060&group_id=159897&atid=813673
|
||||
* int32_t
|
||||
* remove blockIndex
|
||||
* Add piece hash checking
|
||||
* Stop download after selective download completes
|
||||
* Add an ability of seeding
|
||||
|
|
|
@ -50,7 +50,6 @@ protected:
|
|||
bool sendingInProgress;
|
||||
bool invalidate;
|
||||
bool uploading;
|
||||
int32_t id;
|
||||
int32_t cuid;
|
||||
|
||||
BtContextHandle btContext;
|
||||
|
@ -66,7 +65,6 @@ public:
|
|||
AbstractBtMessage():sendingInProgress(false),
|
||||
invalidate(false),
|
||||
uploading(false),
|
||||
id(0),
|
||||
cuid(0),
|
||||
btContext(0),
|
||||
pieceStorage(0),
|
||||
|
@ -100,10 +98,6 @@ public:
|
|||
this->uploading = uploading;
|
||||
}
|
||||
|
||||
virtual uint8_t getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
int32_t getCuid() const {
|
||||
return cuid;
|
||||
}
|
||||
|
|
|
@ -146,7 +146,7 @@ bool AbstractCommand::prepareForRetry(int wait) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void AbstractCommand::onAbort(Exception* ex) {
|
||||
void AbstractCommand::onAbort(RecoverableException* ex) {
|
||||
logger->debug(MSG_UNREGISTER_CUID, cuid);
|
||||
//e->segmentMan->unregisterId(cuid);
|
||||
e->segmentMan->cancelSegment(cuid);
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "DownloadEngine.h"
|
||||
#include "SegmentMan.h"
|
||||
#include "TimeA2.h"
|
||||
#include "RecoverableException.h"
|
||||
|
||||
class AbstractCommand : public Command {
|
||||
private:
|
||||
|
@ -52,7 +53,7 @@ protected:
|
|||
|
||||
void tryReserved();
|
||||
virtual bool prepareForRetry(int wait);
|
||||
virtual void onAbort(Exception* ex);
|
||||
virtual void onAbort(RecoverableException* ex);
|
||||
virtual bool executeInternal(Segment& segment) = 0;
|
||||
|
||||
void setReadCheckSocket(const SocketHandle& socket);
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
*/
|
||||
/* copyright --> */
|
||||
#include "AbstractSingleDiskAdaptor.h"
|
||||
#include "File.h"
|
||||
|
||||
void AbstractSingleDiskAdaptor::initAndOpenFile() {
|
||||
diskWriter->initAndOpenFile(getFilePath(), totalLength);
|
||||
|
@ -61,3 +62,8 @@ int AbstractSingleDiskAdaptor::readData(unsigned char* data, uint32_t len, int64
|
|||
string AbstractSingleDiskAdaptor::sha1Sum(int64_t offset, uint64_t length) {
|
||||
return diskWriter->sha1Sum(offset, length);
|
||||
}
|
||||
|
||||
bool AbstractSingleDiskAdaptor::fileExists()
|
||||
{
|
||||
return File(getFilePath()).exists();
|
||||
}
|
||||
|
|
|
@ -42,8 +42,6 @@ class AbstractSingleDiskAdaptor : public DiskAdaptor {
|
|||
protected:
|
||||
DiskWriterHandle diskWriter;
|
||||
uint64_t totalLength;
|
||||
|
||||
virtual string getFilePath() = 0;
|
||||
public:
|
||||
AbstractSingleDiskAdaptor():diskWriter(0), totalLength(0) {}
|
||||
|
||||
|
@ -63,7 +61,9 @@ public:
|
|||
virtual int readData(unsigned char* data, uint32_t len, int64_t offset);
|
||||
|
||||
virtual string sha1Sum(int64_t offset, uint64_t length);
|
||||
|
||||
|
||||
virtual bool fileExists();
|
||||
|
||||
void setDiskWriter(const DiskWriterHandle diskWriter) {
|
||||
this->diskWriter = diskWriter;
|
||||
}
|
||||
|
|
|
@ -37,8 +37,14 @@
|
|||
#include <string.h>
|
||||
|
||||
BitfieldMan::BitfieldMan(uint32_t blockLength, uint64_t totalLength)
|
||||
:blockLength(blockLength), totalLength(totalLength), filterBitfield(0),
|
||||
filterEnabled(false), randomizer(0) {
|
||||
:blockLength(blockLength),
|
||||
totalLength(totalLength),
|
||||
bitfield(0),
|
||||
useBitfield(0),
|
||||
filterBitfield(0),
|
||||
filterEnabled(false),
|
||||
randomizer(0)
|
||||
{
|
||||
if(blockLength > 0 && totalLength > 0) {
|
||||
blocks = totalLength/blockLength+(totalLength%blockLength ? 1 : 0);
|
||||
bitfieldLength = blocks/8+(blocks%8 ? 1 : 0);
|
||||
|
@ -49,7 +55,13 @@ BitfieldMan::BitfieldMan(uint32_t blockLength, uint64_t totalLength)
|
|||
}
|
||||
}
|
||||
|
||||
BitfieldMan::BitfieldMan(const BitfieldMan& bitfieldMan):randomizer(0) {
|
||||
BitfieldMan::BitfieldMan(const BitfieldMan& bitfieldMan)
|
||||
:bitfield(0),
|
||||
useBitfield(0),
|
||||
filterBitfield(0),
|
||||
filterEnabled(false),
|
||||
randomizer(0)
|
||||
{
|
||||
blockLength = bitfieldMan.blockLength;
|
||||
totalLength = bitfieldMan.totalLength;
|
||||
blocks = bitfieldMan.blocks;
|
||||
|
@ -59,7 +71,7 @@ BitfieldMan::BitfieldMan(const BitfieldMan& bitfieldMan):randomizer(0) {
|
|||
memcpy(bitfield, bitfieldMan.bitfield, bitfieldLength);
|
||||
memcpy(useBitfield, bitfieldMan.useBitfield, bitfieldLength);
|
||||
filterEnabled = bitfieldMan.filterEnabled;
|
||||
if(bitfieldMan.filterBitfield) {
|
||||
if(filterBitfield) {
|
||||
filterBitfield = new unsigned char[bitfieldLength];
|
||||
memcpy(filterBitfield, bitfieldMan.filterBitfield, bitfieldLength);
|
||||
} else {
|
||||
|
|
|
@ -73,26 +73,24 @@ public:
|
|||
if(this != &bitfieldMan) {
|
||||
blockLength = bitfieldMan.blockLength;
|
||||
totalLength = bitfieldMan.totalLength;
|
||||
if(bitfieldLength != bitfieldMan.bitfieldLength) {
|
||||
delete [] bitfield;
|
||||
delete [] useBitfield;
|
||||
bitfield = new unsigned char[bitfieldMan.bitfieldLength];
|
||||
useBitfield = new unsigned char[bitfieldMan.bitfieldLength];
|
||||
}
|
||||
blocks = bitfieldMan.blocks;
|
||||
bitfieldLength = bitfieldMan.bitfieldLength;
|
||||
memcpy(bitfield, bitfieldMan.bitfield, bitfieldLength);
|
||||
memcpy(useBitfield, bitfieldMan.useBitfield, bitfieldLength);
|
||||
filterEnabled = bitfieldMan.filterEnabled;
|
||||
if(bitfieldLength != bitfieldMan.bitfieldLength) {
|
||||
delete [] filterBitfield;
|
||||
filterBitfield = 0;
|
||||
}
|
||||
if(bitfieldMan.filterBitfield) {
|
||||
if(!filterBitfield) {
|
||||
filterBitfield = new unsigned char[bitfieldLength];
|
||||
}
|
||||
|
||||
delete [] bitfield;
|
||||
bitfield = new unsigned char[bitfieldLength];
|
||||
memcpy(bitfield, bitfieldMan.bitfield, bitfieldLength);
|
||||
|
||||
delete [] useBitfield;
|
||||
useBitfield = new unsigned char[bitfieldLength];
|
||||
memcpy(useBitfield, bitfieldMan.useBitfield, bitfieldLength);
|
||||
|
||||
delete [] filterBitfield;
|
||||
if(filterEnabled) {
|
||||
filterBitfield = new unsigned char[bitfieldLength];
|
||||
memcpy(filterBitfield, bitfieldMan.filterBitfield, bitfieldLength);
|
||||
} else {
|
||||
filterBitfield = 0;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
|
|
|
@ -57,9 +57,7 @@ public:
|
|||
delete [] msg;
|
||||
}
|
||||
|
||||
enum ID_t {
|
||||
ID = 17
|
||||
};
|
||||
static const uint8_t ID = 17;
|
||||
|
||||
void setIndex(int32_t index) {
|
||||
this->index = index;
|
||||
|
@ -68,7 +66,7 @@ public:
|
|||
|
||||
static BtAllowedFastMessageHandle create(const unsigned char* data, uint32_t dataLength);
|
||||
|
||||
virtual uint8_t getId() const { return ID; }
|
||||
virtual uint8_t getId() { return ID; }
|
||||
|
||||
virtual void doReceivedAction();
|
||||
|
||||
|
|
|
@ -72,9 +72,7 @@ public:
|
|||
delete [] msg;
|
||||
}
|
||||
|
||||
enum ID_t {
|
||||
ID = 5
|
||||
};
|
||||
static const uint8_t ID = 5;
|
||||
|
||||
void setBitfield(const unsigned char* bitfield, uint32_t bitfieldLength);
|
||||
|
||||
|
@ -84,7 +82,7 @@ public:
|
|||
|
||||
static BtBitfieldMessageHandle create(const unsigned char* data, uint32_t dataLength);
|
||||
|
||||
virtual uint8_t getId() const { return ID; }
|
||||
virtual uint8_t getId() { return ID; }
|
||||
|
||||
virtual void doReceivedAction();
|
||||
|
||||
|
|
|
@ -61,9 +61,7 @@ public:
|
|||
delete [] msg;
|
||||
}
|
||||
|
||||
enum ID_t {
|
||||
ID = 8
|
||||
};
|
||||
static const uint8_t ID = 8;
|
||||
|
||||
int32_t getIndex() const { return index; }
|
||||
|
||||
|
@ -79,7 +77,7 @@ public:
|
|||
|
||||
static BtCancelMessageHandle create(const unsigned char* data, uint32_t dataLength);
|
||||
|
||||
virtual uint8_t getId() const { return ID; }
|
||||
virtual uint8_t getId() { return ID; }
|
||||
|
||||
virtual void doReceivedAction();
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@ BtChokeMessageHandle BtChokeMessage::create(const unsigned char* data, uint32_t
|
|||
void BtChokeMessage::doReceivedAction() {
|
||||
peer->peerChoking = true;
|
||||
BT_MESSAGE_DISPATCHER(btContext, peer)->doChokedAction();
|
||||
BT_REQUEST_FACTORY(btContext, peer)->doChokedAction();
|
||||
}
|
||||
|
||||
bool BtChokeMessage::sendPredicate() const {
|
||||
|
|
|
@ -53,11 +53,9 @@ public:
|
|||
delete [] msg;
|
||||
}
|
||||
|
||||
enum ID_t {
|
||||
ID = 0
|
||||
};
|
||||
static const uint8_t ID = 0;
|
||||
|
||||
virtual uint8_t getId() const { return ID; }
|
||||
virtual uint8_t getId() { return ID; }
|
||||
|
||||
virtual void doReceivedAction();
|
||||
|
||||
|
|
|
@ -73,7 +73,9 @@ public:
|
|||
delete [] peerId;
|
||||
}
|
||||
|
||||
virtual uint8_t getId() const { return UINT8_MAX; }
|
||||
static const uint8_t ID = UINT8_MAX;
|
||||
|
||||
virtual uint8_t getId() { return ID; }
|
||||
|
||||
virtual void doReceivedAction() {};
|
||||
|
||||
|
|
|
@ -53,13 +53,11 @@ public:
|
|||
delete [] msg;
|
||||
}
|
||||
|
||||
enum ID_t {
|
||||
ID = 14
|
||||
};
|
||||
static const uint8_t ID = 14;
|
||||
|
||||
static BtHaveAllMessageHandle create(const unsigned char* data, uint32_t dataLength);
|
||||
|
||||
virtual uint8_t getId() const { return ID; }
|
||||
virtual uint8_t getId() { return ID; }
|
||||
|
||||
virtual void doReceivedAction();
|
||||
|
||||
|
|
|
@ -53,9 +53,7 @@ public:
|
|||
delete [] msg;
|
||||
}
|
||||
|
||||
enum ID_t {
|
||||
ID = 4
|
||||
};
|
||||
static const uint8_t ID = 4;
|
||||
|
||||
void setIndex(int32_t index) {
|
||||
this->index = index;
|
||||
|
@ -65,7 +63,7 @@ public:
|
|||
|
||||
static BtHaveMessageHandle create(const unsigned char* data, uint32_t dataLength);
|
||||
|
||||
virtual uint8_t getId() const { return ID; }
|
||||
virtual uint8_t getId() { return ID; }
|
||||
|
||||
virtual void doReceivedAction();
|
||||
|
||||
|
|
|
@ -53,13 +53,11 @@ public:
|
|||
delete [] msg;
|
||||
}
|
||||
|
||||
enum ID_t {
|
||||
ID = 15
|
||||
};
|
||||
|
||||
static const uint8_t ID = 15;
|
||||
|
||||
static BtHaveNoneMessageHandle create(const unsigned char* data, uint32_t dataLength);
|
||||
|
||||
virtual uint8_t getId() const { return ID; }
|
||||
virtual uint8_t getId() { return ID; }
|
||||
|
||||
virtual void doReceivedAction();
|
||||
|
||||
|
|
|
@ -53,13 +53,11 @@ public:
|
|||
delete [] msg;
|
||||
}
|
||||
|
||||
enum ID_t {
|
||||
ID = 2
|
||||
};
|
||||
static const uint8_t ID = 2;
|
||||
|
||||
static BtInterestedMessageHandle create(const unsigned char* data, uint32_t dataLength);
|
||||
|
||||
virtual uint8_t getId() const { return ID; }
|
||||
virtual uint8_t getId() { return ID; }
|
||||
|
||||
virtual void doReceivedAction();
|
||||
|
||||
|
|
|
@ -53,11 +53,9 @@ public:
|
|||
delete [] msg;
|
||||
}
|
||||
|
||||
enum ID_t {
|
||||
ID = 99
|
||||
};
|
||||
static const uint8_t ID = 99;
|
||||
|
||||
virtual uint8_t getId() const { return ID; }
|
||||
virtual uint8_t getId() { return ID; }
|
||||
|
||||
virtual void doReceivedAction() {}
|
||||
|
||||
|
|
|
@ -53,13 +53,11 @@ public:
|
|||
delete [] msg;
|
||||
}
|
||||
|
||||
enum ID_t {
|
||||
ID = 3
|
||||
};
|
||||
static const uint8_t ID = 3;
|
||||
|
||||
static BtNotInterestedMessageHandle create(const unsigned char* data, uint32_t dataLength);
|
||||
|
||||
virtual uint8_t getId() const { return ID; }
|
||||
virtual uint8_t getId() { return ID; }
|
||||
|
||||
virtual void doReceivedAction();
|
||||
|
||||
|
|
|
@ -81,6 +81,10 @@ void BtPieceMessage::doReceivedAction() {
|
|||
blockLength,
|
||||
offset);
|
||||
piece->completeBlock(slot.getBlockIndex());
|
||||
logger->debug("CUID#%d - Piece bitfield %s",
|
||||
cuid,
|
||||
Util::toHex(piece->getBitfield(),
|
||||
piece->getBitfieldLength()).c_str());
|
||||
BT_MESSAGE_DISPATCHER(btContext, peer)->removeOutstandingRequest(slot);
|
||||
if(piece->pieceComplete()) {
|
||||
if(checkPieceHash(piece)) {
|
||||
|
|
|
@ -112,9 +112,7 @@ public:
|
|||
delete [] block;
|
||||
}
|
||||
|
||||
enum ID_t {
|
||||
ID = 7
|
||||
};
|
||||
static const uint8_t ID = 7;
|
||||
|
||||
int32_t getIndex() const { return index; }
|
||||
|
||||
|
@ -134,7 +132,7 @@ public:
|
|||
|
||||
static BtPieceMessageHandle create(const unsigned char* data, uint32_t dataLength);
|
||||
|
||||
virtual uint8_t getId() const { return ID; }
|
||||
virtual uint8_t getId() { return ID; }
|
||||
|
||||
virtual void doReceivedAction();
|
||||
|
||||
|
|
|
@ -49,15 +49,13 @@ public:
|
|||
|
||||
virtual ~BtPortMessage() {}
|
||||
|
||||
enum ID_t {
|
||||
ID = 9
|
||||
};
|
||||
static const uint8_t ID = 9;
|
||||
|
||||
uint16_t getPort() const { return port; }
|
||||
|
||||
void setPort(uint16_t port) { this->port = port; }
|
||||
|
||||
virtual uint8_t getId() const { return ID; }
|
||||
virtual uint8_t getId() { return ID; }
|
||||
|
||||
static BtPortMessageHandle create(const unsigned char* data, uint32_t dataLength);
|
||||
|
||||
|
|
|
@ -59,9 +59,7 @@ public:
|
|||
delete [] msg;
|
||||
}
|
||||
|
||||
enum ID_t {
|
||||
ID = 16
|
||||
};
|
||||
static const uint8_t ID = 16;
|
||||
|
||||
int32_t getIndex() const { return index; }
|
||||
void setIndex(int32_t index) { this->index = index; }
|
||||
|
@ -74,7 +72,7 @@ public:
|
|||
|
||||
static BtRejectMessageHandle create(const unsigned char* data, uint32_t dataLength);
|
||||
|
||||
virtual uint8_t getId() const { return ID; }
|
||||
virtual uint8_t getId() { return ID; }
|
||||
|
||||
virtual void doReceivedAction();
|
||||
|
||||
|
|
|
@ -53,6 +53,8 @@ public:
|
|||
|
||||
virtual void removeCompletedPiece() = 0;
|
||||
|
||||
virtual void doChokedAction() = 0;
|
||||
|
||||
/**
|
||||
* Creates RequestMessage objects associated to the pieces added by
|
||||
* addTargetPiece() and returns them.
|
||||
|
|
|
@ -84,9 +84,7 @@ public:
|
|||
delete [] msg;
|
||||
}
|
||||
|
||||
enum ID_t {
|
||||
ID = 6
|
||||
};
|
||||
static const uint8_t ID = 6;
|
||||
|
||||
int32_t getIndex() const { return index; }
|
||||
void setIndex(int32_t index) { this->index = index; }
|
||||
|
@ -102,7 +100,7 @@ public:
|
|||
|
||||
static BtRequestMessageHandle create(const unsigned char* data, uint32_t dataLength);
|
||||
|
||||
virtual uint8_t getId() const { return ID; }
|
||||
virtual uint8_t getId() { return ID; }
|
||||
|
||||
virtual void doReceivedAction();
|
||||
|
||||
|
|
|
@ -53,9 +53,7 @@ public:
|
|||
delete [] msg;
|
||||
}
|
||||
|
||||
enum ID_t {
|
||||
ID = 13
|
||||
};
|
||||
static const uint8_t ID = 13;
|
||||
|
||||
void setIndex(int32_t index) {
|
||||
this->index = index;
|
||||
|
@ -65,7 +63,7 @@ public:
|
|||
|
||||
static BtSuggestPieceMessageHandle create(const unsigned char* data, uint32_t dataLength);
|
||||
|
||||
virtual uint8_t getId() const { return ID; }
|
||||
virtual uint8_t getId() { return ID; }
|
||||
|
||||
virtual void doReceivedAction() {
|
||||
// TODO Current implementation ignores this message.
|
||||
|
|
|
@ -52,13 +52,11 @@ public:
|
|||
delete [] msg;
|
||||
}
|
||||
|
||||
enum ID_t {
|
||||
ID = 1
|
||||
};
|
||||
static const uint8_t ID = 1;
|
||||
|
||||
static BtUnchokeMessageHandle create(const unsigned char* data, uint32_t dataLength);
|
||||
|
||||
virtual uint8_t getId() const { return ID; }
|
||||
virtual uint8_t getId() { return ID; }
|
||||
|
||||
virtual void doReceivedAction();
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ ByteArrayDiskWriter::~ByteArrayDiskWriter() {
|
|||
|
||||
void ByteArrayDiskWriter::clear() {
|
||||
delete [] buf;
|
||||
buf = 0;
|
||||
}
|
||||
|
||||
void ByteArrayDiskWriter::init() {
|
||||
|
|
|
@ -1,149 +0,0 @@
|
|||
/* <!-- copyright */
|
||||
/*
|
||||
* aria2 - The high speed download utility
|
||||
*
|
||||
* Copyright (C) 2006 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* In addition, as a special exception, the copyright holders give
|
||||
* permission to link the code of portions of this program with the
|
||||
* OpenSSL library under certain conditions as described in each
|
||||
* individual source file, and distribute linked combinations
|
||||
* including the two.
|
||||
* You must obey the GNU General Public License in all respects
|
||||
* for all of the code used other than OpenSSL. If you modify
|
||||
* file(s) with this exception, you may extend this exception to your
|
||||
* version of the file(s), but you are not obligated to do so. If you
|
||||
* do not wish to do so, delete this exception statement from your
|
||||
* version. If you delete this exception statement from all source
|
||||
* files in the program, then also delete it here.
|
||||
*/
|
||||
/* copyright --> */
|
||||
#include "CompactTrackerResponseProcessor.h"
|
||||
#include "LogFactory.h"
|
||||
#include "TorrentDownloadEngine.h"
|
||||
#include "MetaFileUtil.h"
|
||||
#include "DlAbortEx.h"
|
||||
#include "message.h"
|
||||
#include "PeerInitiateConnectionCommand.h"
|
||||
#include <netinet/in.h>
|
||||
|
||||
CompactTrackerResponseProcessor::CompactTrackerResponseProcessor(ByteArrayDiskWriter* diskWriter, TorrentDownloadEngine* e, Request* req):
|
||||
diskWriter(diskWriter),
|
||||
e(e),
|
||||
req(req) {
|
||||
logger = LogFactory::getInstance();
|
||||
}
|
||||
|
||||
CompactTrackerResponseProcessor::~CompactTrackerResponseProcessor() {}
|
||||
|
||||
void CompactTrackerResponseProcessor::resetTrackerResponse() {
|
||||
if(e->segmentMan->finished()) {
|
||||
diskWriter->reset();
|
||||
e->segmentMan->init();
|
||||
}
|
||||
}
|
||||
|
||||
void CompactTrackerResponseProcessor::execute() {
|
||||
MetaEntry* entry = NULL;
|
||||
try {
|
||||
entry = MetaFileUtil::bdecoding(diskWriter->getByteArray(),
|
||||
diskWriter->getByteArrayLength());
|
||||
Dictionary* response = (Dictionary*)entry;
|
||||
Data* failureReason = (Data*)response->get("failure reason");
|
||||
if(failureReason != NULL) {
|
||||
throw new DlAbortEx("Tracker returned failure reason: %s", failureReason->toString().c_str());
|
||||
}
|
||||
Data* warningMessage = (Data*)response->get("warning message");
|
||||
if(warningMessage != NULL) {
|
||||
logger->warn(MSG_TRACKER_WARNING_MESSAGE, warningMessage->toString().c_str());
|
||||
}
|
||||
Data* trackerId = (Data*)response->get("tracker id");
|
||||
if(trackerId != NULL) {
|
||||
e->torrentMan->trackerId = trackerId->toString();
|
||||
logger->debug("Tracker ID:%s", e->torrentMan->trackerId.c_str());
|
||||
}
|
||||
Data* interval = (Data*)response->get("interval");
|
||||
if(interval != NULL) {
|
||||
e->torrentMan->interval = interval->toInt();
|
||||
logger->debug("interval:%d", e->torrentMan->interval);
|
||||
}
|
||||
Data* minInterval = (Data*)response->get("min interval");
|
||||
if(minInterval != NULL) {
|
||||
e->torrentMan->minInterval = minInterval->toInt();
|
||||
logger->debug("min interval:%d", e->torrentMan->minInterval);
|
||||
}
|
||||
if(e->torrentMan->minInterval > e->torrentMan->interval) {
|
||||
e->torrentMan->minInterval = e->torrentMan->interval;
|
||||
}
|
||||
Data* complete = (Data*)response->get("complete");
|
||||
if(complete != NULL) {
|
||||
e->torrentMan->complete = complete->toInt();
|
||||
logger->debug("complete:%d", e->torrentMan->complete);
|
||||
}
|
||||
Data* incomplete = (Data*)response->get("incomplete");
|
||||
if(incomplete != NULL) {
|
||||
e->torrentMan->incomplete = incomplete->toInt();
|
||||
logger->debug("incomplete:%d", e->torrentMan->incomplete);
|
||||
}
|
||||
Data* peers = (Data*)response->get("peers");
|
||||
if(peers != NULL) {
|
||||
for(int i = 0; i < peers->getLen(); i += 6) {
|
||||
unsigned int ipaddr1 = (unsigned char)*(peers->getData()+i);
|
||||
unsigned int ipaddr2 = (unsigned char)*(peers->getData()+i+1);
|
||||
unsigned int ipaddr3 = (unsigned char)*(peers->getData()+i+2);
|
||||
unsigned int ipaddr4 = (unsigned char)*(peers->getData()+i+3);
|
||||
unsigned int port = ntohs(*(unsigned short int*)(peers->getData()+i+4));
|
||||
char ipaddr[16];
|
||||
|
||||
snprintf(ipaddr, sizeof(ipaddr), "%d.%d.%d.%d",
|
||||
ipaddr1, ipaddr2, ipaddr3, ipaddr4);
|
||||
Peer* peer = new Peer(ipaddr, port, e->torrentMan->pieceLength,
|
||||
e->torrentMan->getTotalLength());
|
||||
if(e->torrentMan->addPeer(peer)) {
|
||||
logger->debug("adding peer %s:%d", peer->ipaddr.c_str(), peer->port);
|
||||
} else {
|
||||
delete peer;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logger->info("no peer list received.");
|
||||
}
|
||||
while(e->torrentMan->isPeerAvailable() &&
|
||||
e->torrentMan->connections < MAX_PEER_UPDATE) {
|
||||
Peer* peer = e->torrentMan->getPeer();
|
||||
int newCuid = e->torrentMan->getNewCuid();
|
||||
peer->cuid = newCuid;
|
||||
PeerInitiateConnectionCommand* command = new PeerInitiateConnectionCommand(newCuid, peer, e);
|
||||
e->commands.push(command);
|
||||
logger->debug("adding new command CUID#%d", newCuid);
|
||||
}
|
||||
if(req->getTrackerEvent() == Request::STARTED) {
|
||||
req->setTrackerEvent(Request::AUTO);
|
||||
}
|
||||
} catch(Exception* err) {
|
||||
logger->error("Error occurred while processing tracker response.", err);
|
||||
delete(err);
|
||||
}
|
||||
if(entry != NULL) {
|
||||
delete entry;
|
||||
}
|
||||
e->torrentMan->trackers = 0;
|
||||
}
|
||||
|
||||
bool CompactTrackerResponseProcessor::isFeeded() const {
|
||||
return e->segmentMan->finished();
|
||||
}
|
|
@ -43,13 +43,13 @@ private:
|
|||
string topDir;
|
||||
|
||||
void fixFilename();
|
||||
protected:
|
||||
virtual string getFilePath();
|
||||
public:
|
||||
CopyDiskAdaptor() {}
|
||||
|
||||
virtual ~CopyDiskAdaptor() {}
|
||||
|
||||
virtual string getFilePath();
|
||||
|
||||
virtual void onDownloadComplete();
|
||||
|
||||
// tempFilename is relative to storeDir
|
||||
|
|
|
@ -75,6 +75,7 @@ void DefaultBtInteractive::doPostHandshakeProcessing() {
|
|||
floodingCheckPoint.reset();
|
||||
addBitfieldMessageToQueue();
|
||||
addAllowedFastMessageToQueue();
|
||||
sendPendingMessage();
|
||||
}
|
||||
|
||||
void DefaultBtInteractive::addBitfieldMessageToQueue() {
|
||||
|
@ -142,10 +143,8 @@ void DefaultBtInteractive::checkHave() {
|
|||
|
||||
void DefaultBtInteractive::sendKeepAlive() {
|
||||
if(keepAliveCheckPoint.elapsed(option->getAsInt(PREF_BT_KEEP_ALIVE_INTERVAL))) {
|
||||
if(dispatcher->countMessageInQueue() == 0) {
|
||||
dispatcher->addMessageToQueue(BT_MESSAGE_FACTORY(btContext, peer)->createKeepAliveMessage());
|
||||
dispatcher->sendMessages();
|
||||
}
|
||||
dispatcher->addMessageToQueue(BT_MESSAGE_FACTORY(btContext, peer)->createKeepAliveMessage());
|
||||
dispatcher->sendMessages();
|
||||
keepAliveCheckPoint.reset();
|
||||
}
|
||||
}
|
||||
|
@ -187,27 +186,26 @@ void DefaultBtInteractive::receiveMessages() {
|
|||
}
|
||||
|
||||
void DefaultBtInteractive::decideInterest() {
|
||||
if(!pieceStorage->hasMissingPiece(peer)) {
|
||||
if(peer->amInterested) {
|
||||
logger->debug("CUID#%d - Not interested in the peer", cuid);
|
||||
dispatcher->
|
||||
addMessageToQueue(BT_MESSAGE_FACTORY(btContext, peer)->
|
||||
createNotInterestedMessage());
|
||||
}
|
||||
} else {
|
||||
if(pieceStorage->hasMissingPiece(peer)) {
|
||||
if(!peer->amInterested) {
|
||||
logger->debug("CUID#%d - Interested in the peer", cuid);
|
||||
dispatcher->
|
||||
addMessageToQueue(BT_MESSAGE_FACTORY(btContext, peer)->
|
||||
createInterestedMessage());
|
||||
}
|
||||
} else {
|
||||
if(peer->amInterested) {
|
||||
logger->debug("CUID#%d - Not interested in the peer", cuid);
|
||||
dispatcher->
|
||||
addMessageToQueue(BT_MESSAGE_FACTORY(btContext, peer)->
|
||||
createNotInterestedMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DefaultBtInteractive::fillPiece(int maxPieceNum) {
|
||||
if(pieceStorage->hasMissingPiece(peer)) {
|
||||
if(peer->peerChoking) {
|
||||
dispatcher->doChokedAction();
|
||||
if(peer->isFastExtensionEnabled()) {
|
||||
while(btRequestFactory->countTargetPiece() < maxPieceNum) {
|
||||
PieceHandle piece = pieceStorage->getMissingFastPiece(peer);
|
||||
|
|
|
@ -129,14 +129,18 @@ void DefaultBtMessageDispatcher::doChokedAction()
|
|||
for(RequestSlots::iterator itr = requestSlots.begin();
|
||||
itr != requestSlots.end();) {
|
||||
RequestSlot& slot = *itr;
|
||||
logger->debug("CUID#%d - Deleting request slot index=%d, blockIndex=%d"
|
||||
" because localhost got choked.",
|
||||
cuid,
|
||||
slot.getIndex(),
|
||||
slot.getBlockIndex());
|
||||
PieceHandle piece = pieceStorage->getPiece(slot.getIndex());
|
||||
piece->cancelBlock(slot.getBlockIndex());
|
||||
itr = requestSlots.erase(itr);
|
||||
if(peer->isInPeerAllowedIndexSet(slot.getIndex())) {
|
||||
itr++;
|
||||
} else {
|
||||
logger->debug("CUID#%d - Deleting request slot index=%d, blockIndex=%d"
|
||||
" because localhost got choked.",
|
||||
cuid,
|
||||
slot.getIndex(),
|
||||
slot.getBlockIndex());
|
||||
PieceHandle piece = pieceStorage->getPiece(slot.getIndex());
|
||||
piece->cancelBlock(slot.getBlockIndex());
|
||||
itr = requestSlots.erase(itr);
|
||||
}
|
||||
}
|
||||
|
||||
BtChokedEventHandle event = new BtChokedEvent();
|
||||
|
|
|
@ -54,6 +54,20 @@ void DefaultBtRequestFactory::removeTargetPiece(const PieceHandle& piece) {
|
|||
pieceStorage->cancelPiece(piece);
|
||||
}
|
||||
|
||||
void DefaultBtRequestFactory::doChokedAction()
|
||||
{
|
||||
Pieces temp;
|
||||
for(Pieces::iterator itr = pieces.begin(); itr != pieces.end(); itr++) {
|
||||
PieceHandle& piece = *itr;
|
||||
if(peer->isInPeerAllowedIndexSet(piece->getIndex())) {
|
||||
temp.push_back(piece);
|
||||
} else {
|
||||
pieceStorage->cancelPiece(*itr);
|
||||
}
|
||||
}
|
||||
pieces = temp;
|
||||
}
|
||||
|
||||
void DefaultBtRequestFactory::removeAllTargetPiece() {
|
||||
for(Pieces::iterator itr = pieces.begin(); itr != pieces.end(); itr++) {
|
||||
dispatcher->doAbortOutstandingRequestAction(*itr);
|
||||
|
|
|
@ -82,6 +82,8 @@ public:
|
|||
|
||||
virtual void removeCompletedPiece();
|
||||
|
||||
virtual void doChokedAction();
|
||||
|
||||
virtual BtMessages createRequestMessages(uint32_t max);
|
||||
|
||||
virtual BtMessages createRequestMessagesOnEndGame(uint32_t max);
|
||||
|
|
|
@ -60,7 +60,7 @@ void DefaultDiskWriter::initAndOpenFile(const string& filename,
|
|||
fileAllocator->allocate(fd, totalLength);
|
||||
}
|
||||
}
|
||||
} catch(Exception *e) {
|
||||
} catch(RecoverableException *e) {
|
||||
throw new DlAbortEx(e, EX_FILE_WRITE, filename.c_str(), strerror(errno));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,12 +38,12 @@
|
|||
#include "AbstractSingleDiskAdaptor.h"
|
||||
|
||||
class DirectDiskAdaptor : public AbstractSingleDiskAdaptor {
|
||||
protected:
|
||||
virtual string getFilePath();
|
||||
public:
|
||||
DirectDiskAdaptor() {};
|
||||
virtual ~DirectDiskAdaptor() {};
|
||||
|
||||
virtual string getFilePath();
|
||||
|
||||
virtual void onDownloadComplete();
|
||||
};
|
||||
|
||||
|
|
|
@ -64,6 +64,10 @@ public:
|
|||
|
||||
virtual void onDownloadComplete() = 0;
|
||||
|
||||
virtual bool fileExists() = 0;
|
||||
|
||||
virtual string getFilePath() = 0;
|
||||
|
||||
void setFileEntries(const FileEntries& fileEntries) {
|
||||
this->fileEntries = fileEntries;
|
||||
}
|
||||
|
|
|
@ -34,20 +34,20 @@
|
|||
/* copyright --> */
|
||||
#ifndef _D_DL_ABORT_EX_H_
|
||||
#define _D_DL_ABORT_EX_H_
|
||||
#include "Exception.h"
|
||||
#include "RecoverableException.h"
|
||||
|
||||
class DlAbortEx:public Exception {
|
||||
class DlAbortEx : public RecoverableException {
|
||||
public:
|
||||
DlAbortEx(Exception* cause = 0):Exception(cause) {}
|
||||
DlAbortEx(Exception* cause = 0):RecoverableException(cause) {}
|
||||
|
||||
DlAbortEx(const char* msg, ...):Exception() {
|
||||
DlAbortEx(const char* msg, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, msg);
|
||||
setMsg(string(msg), ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
DlAbortEx(Exception* cause, const char* msg, ...):Exception(cause) {
|
||||
DlAbortEx(Exception* cause, const char* msg, ...):RecoverableException(cause) {
|
||||
va_list ap;
|
||||
va_start(ap, msg);
|
||||
setMsg(string(msg), ap);
|
||||
|
|
|
@ -34,20 +34,20 @@
|
|||
/* copyright --> */
|
||||
#ifndef _D_DL_RETRY_EX_H_
|
||||
#define _D_DL_RETRY_EX_H_
|
||||
#include "Exception.h"
|
||||
#include "RecoverableException.h"
|
||||
|
||||
class DlRetryEx:public Exception {
|
||||
class DlRetryEx : public RecoverableException {
|
||||
public:
|
||||
DlRetryEx(Exception* cause = 0):Exception(cause) {}
|
||||
DlRetryEx(Exception* cause = 0):RecoverableException(cause) {}
|
||||
|
||||
DlRetryEx(const char* msg, ...):Exception() {
|
||||
DlRetryEx(const char* msg, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, msg);
|
||||
setMsg(msg, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
DlRetryEx(Exception* cause, const char* msg, ...):Exception(cause) {
|
||||
DlRetryEx(Exception* cause, const char* msg, ...):RecoverableException(cause) {
|
||||
va_list ap;
|
||||
va_start(ap, msg);
|
||||
setMsg(msg, ap);
|
||||
|
|
|
@ -130,13 +130,6 @@ DownloadEngineFactory::newTorrentConsoleEngine(const BtContextHandle& btContext,
|
|||
te->setBtContext(btContext);
|
||||
// initialize file storage
|
||||
pieceStorage->initStorage();
|
||||
if(btProgressInfoFile->exists()) {
|
||||
// load .aria2 file if it exists.
|
||||
btProgressInfoFile->load();
|
||||
pieceStorage->getDiskAdaptor()->openExistingFile();
|
||||
} else {
|
||||
pieceStorage->getDiskAdaptor()->initAndOpenFile();
|
||||
}
|
||||
|
||||
Integers selectIndexes;
|
||||
Util::unfoldRange(op->get(PREF_SELECT_FILE), selectIndexes);
|
||||
|
|
|
@ -49,7 +49,7 @@ protected:
|
|||
Exception* cause;
|
||||
|
||||
void setMsg(const string& msgsrc, va_list ap) {
|
||||
char buf[256];
|
||||
char buf[1024];
|
||||
vsnprintf(buf, sizeof(buf), msgsrc.c_str(), ap);
|
||||
msg = buf;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
/* <!-- 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_FATAL_EXCEPTION_H_
|
||||
#define _D_FATAL_EXCEPTION_H_
|
||||
#include "Exception.h"
|
||||
|
||||
class FatalException : public Exception {
|
||||
public:
|
||||
FatalException(Exception* cause = 0):Exception(cause) {}
|
||||
|
||||
FatalException(const char* msg, ...):Exception() {
|
||||
va_list ap;
|
||||
va_start(ap, msg);
|
||||
setMsg(string(msg), ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
FatalException(Exception* cause, const char* msg, ...):Exception(cause) {
|
||||
va_list ap;
|
||||
va_start(ap, msg);
|
||||
setMsg(string(msg), ap);
|
||||
va_end(ap);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // _D_FATAL_EXCEPTION_EX_H_
|
|
@ -59,8 +59,9 @@ void FileAllocator::allocate(int fd, uint64_t totalLength)
|
|||
throw new DlAbortEx("Allocation failed: %s", strerror(errno));
|
||||
}
|
||||
if(cp.elapsedInMillis(500)) {
|
||||
fileAllocationMonitor->setCurrentValue(x*bufSize);
|
||||
fileAllocationMonitor->setCurrentValue(i*bufSize);
|
||||
fileAllocationMonitor->showProgress();
|
||||
cp.reset();
|
||||
}
|
||||
}
|
||||
fileAllocationMonitor->setCurrentValue(totalLength);
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "message.h"
|
||||
#include "prefs.h"
|
||||
#include "Util.h"
|
||||
#include "FatalException.h"
|
||||
|
||||
FtpNegotiationCommand::FtpNegotiationCommand(int cuid, const RequestHandle req,
|
||||
DownloadEngine* e,
|
||||
|
@ -188,6 +189,11 @@ bool FtpNegotiationCommand::recvSize() {
|
|||
e->segmentMan->totalSize);
|
||||
|
||||
e->segmentMan->filename = Util::urldecode(req->getFile());
|
||||
if(e->segmentMan->shouldCancelDownloadForSafety()) {
|
||||
throw new FatalException(EX_FILE_ALREADY_EXISTS,
|
||||
e->segmentMan->getFilePath().c_str(),
|
||||
e->segmentMan->getSegmentFilePath().c_str());
|
||||
}
|
||||
bool segFileExists = e->segmentMan->segmentFileExists();
|
||||
if(segFileExists) {
|
||||
e->segmentMan->load();
|
||||
|
|
|
@ -40,6 +40,8 @@
|
|||
#include "message.h"
|
||||
#include "Util.h"
|
||||
#include "prefs.h"
|
||||
#include "File.h"
|
||||
#include "FatalException.h"
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
@ -159,6 +161,11 @@ bool HttpResponseCommand::handleDefaultEncoding(const HttpHeader& headers) {
|
|||
// send request again to the server with Range header
|
||||
return prepareForRetry(0);
|
||||
} else {
|
||||
if(e->segmentMan->shouldCancelDownloadForSafety()) {
|
||||
throw new FatalException(EX_FILE_ALREADY_EXISTS,
|
||||
e->segmentMan->getFilePath().c_str(),
|
||||
e->segmentMan->getSegmentFilePath().c_str());
|
||||
}
|
||||
e->segmentMan->totalSize = size;
|
||||
e->segmentMan->initBitfield(e->option->getAsInt(PREF_SEGMENT_SIZE),
|
||||
e->segmentMan->totalSize);
|
||||
|
|
|
@ -30,6 +30,8 @@ SRCS = Socket.h\
|
|||
common.h\
|
||||
message.h\
|
||||
Exception.h\
|
||||
FatalException.h\
|
||||
RecoverableException.h\
|
||||
DlAbortEx.h\
|
||||
DlRetryEx.h\
|
||||
Logger.h\
|
||||
|
@ -187,9 +189,9 @@ libaria2c_a_SOURCES = $(SRCS)
|
|||
aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\
|
||||
@LIBGCRYPT_LIBS@ @OPENSSL_LIBS@ @XML_LIBS@ @LIBARES_LIBS@\
|
||||
@LIBCARES_LIBS@
|
||||
#aria2c_LDFLAGS = -pg
|
||||
aria2c_LDFLAGS = -pg
|
||||
AM_CPPFLAGS = -Wall\
|
||||
-I../lib -I../intl -I$(top_srcdir)/intl\
|
||||
@LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@ @XML_CPPFLAGS@\
|
||||
@LIBARES_CPPFLAGS@ @LIBCARES_CPPFLAGS@\
|
||||
-D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@ # -pg
|
||||
-D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@ -pg
|
|
@ -196,18 +196,18 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
|
|||
DownloadEngine.cc DownloadEngine.h ConsoleDownloadEngine.cc \
|
||||
ConsoleDownloadEngine.h Segment.cc Segment.h SegmentMan.cc \
|
||||
SegmentMan.h Util.cc Util.h Request.cc Request.h common.h \
|
||||
message.h Exception.h DlAbortEx.h DlRetryEx.h Logger.h \
|
||||
SimpleLogger.cc SimpleLogger.h TransferEncoding.h \
|
||||
ChunkedEncoding.cc ChunkedEncoding.h DiskWriter.h \
|
||||
AbstractDiskWriter.cc AbstractDiskWriter.h \
|
||||
DefaultDiskWriter.cc DefaultDiskWriter.h File.cc File.h \
|
||||
Option.cc Option.h Base64.cc Base64.h CookieBox.cc CookieBox.h \
|
||||
messageDigest.h LogFactory.cc LogFactory.h NullLogger.h \
|
||||
TimeA2.cc TimeA2.h SharedHandle.h HandleRegistry.h \
|
||||
FeatureConfig.cc FeatureConfig.h DownloadEngineFactory.cc \
|
||||
DownloadEngineFactory.h RequestInfo.h UrlRequestInfo.cc \
|
||||
UrlRequestInfo.h SpeedCalc.cc SpeedCalc.h PeerStat.h \
|
||||
BitfieldMan.cc BitfieldMan.h BitfieldManFactory.cc \
|
||||
message.h Exception.h FatalException.h RecoverableException.h \
|
||||
DlAbortEx.h DlRetryEx.h Logger.h SimpleLogger.cc \
|
||||
SimpleLogger.h TransferEncoding.h ChunkedEncoding.cc \
|
||||
ChunkedEncoding.h DiskWriter.h AbstractDiskWriter.cc \
|
||||
AbstractDiskWriter.h DefaultDiskWriter.cc DefaultDiskWriter.h \
|
||||
File.cc File.h Option.cc Option.h Base64.cc Base64.h \
|
||||
CookieBox.cc CookieBox.h messageDigest.h LogFactory.cc \
|
||||
LogFactory.h NullLogger.h TimeA2.cc TimeA2.h SharedHandle.h \
|
||||
HandleRegistry.h FeatureConfig.cc FeatureConfig.h \
|
||||
DownloadEngineFactory.cc DownloadEngineFactory.h RequestInfo.h \
|
||||
UrlRequestInfo.cc UrlRequestInfo.h SpeedCalc.cc SpeedCalc.h \
|
||||
PeerStat.h BitfieldMan.cc BitfieldMan.h BitfieldManFactory.cc \
|
||||
BitfieldManFactory.h Randomizer.h SimpleRandomizer.cc \
|
||||
SimpleRandomizer.h FileAllocator.cc FileAllocator.h \
|
||||
FileAllocationMonitor.cc FileAllocationMonitor.h \
|
||||
|
@ -566,18 +566,18 @@ SRCS = Socket.h SocketCore.cc SocketCore.h Command.cc Command.h \
|
|||
DownloadEngine.cc DownloadEngine.h ConsoleDownloadEngine.cc \
|
||||
ConsoleDownloadEngine.h Segment.cc Segment.h SegmentMan.cc \
|
||||
SegmentMan.h Util.cc Util.h Request.cc Request.h common.h \
|
||||
message.h Exception.h DlAbortEx.h DlRetryEx.h Logger.h \
|
||||
SimpleLogger.cc SimpleLogger.h TransferEncoding.h \
|
||||
ChunkedEncoding.cc ChunkedEncoding.h DiskWriter.h \
|
||||
AbstractDiskWriter.cc AbstractDiskWriter.h \
|
||||
DefaultDiskWriter.cc DefaultDiskWriter.h File.cc File.h \
|
||||
Option.cc Option.h Base64.cc Base64.h CookieBox.cc CookieBox.h \
|
||||
messageDigest.h LogFactory.cc LogFactory.h NullLogger.h \
|
||||
TimeA2.cc TimeA2.h SharedHandle.h HandleRegistry.h \
|
||||
FeatureConfig.cc FeatureConfig.h DownloadEngineFactory.cc \
|
||||
DownloadEngineFactory.h RequestInfo.h UrlRequestInfo.cc \
|
||||
UrlRequestInfo.h SpeedCalc.cc SpeedCalc.h PeerStat.h \
|
||||
BitfieldMan.cc BitfieldMan.h BitfieldManFactory.cc \
|
||||
message.h Exception.h FatalException.h RecoverableException.h \
|
||||
DlAbortEx.h DlRetryEx.h Logger.h SimpleLogger.cc \
|
||||
SimpleLogger.h TransferEncoding.h ChunkedEncoding.cc \
|
||||
ChunkedEncoding.h DiskWriter.h AbstractDiskWriter.cc \
|
||||
AbstractDiskWriter.h DefaultDiskWriter.cc DefaultDiskWriter.h \
|
||||
File.cc File.h Option.cc Option.h Base64.cc Base64.h \
|
||||
CookieBox.cc CookieBox.h messageDigest.h LogFactory.cc \
|
||||
LogFactory.h NullLogger.h TimeA2.cc TimeA2.h SharedHandle.h \
|
||||
HandleRegistry.h FeatureConfig.cc FeatureConfig.h \
|
||||
DownloadEngineFactory.cc DownloadEngineFactory.h RequestInfo.h \
|
||||
UrlRequestInfo.cc UrlRequestInfo.h SpeedCalc.cc SpeedCalc.h \
|
||||
PeerStat.h BitfieldMan.cc BitfieldMan.h BitfieldManFactory.cc \
|
||||
BitfieldManFactory.h Randomizer.h SimpleRandomizer.cc \
|
||||
SimpleRandomizer.h FileAllocator.cc FileAllocator.h \
|
||||
FileAllocationMonitor.cc FileAllocationMonitor.h \
|
||||
|
@ -589,12 +589,12 @@ aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\
|
|||
@LIBGCRYPT_LIBS@ @OPENSSL_LIBS@ @XML_LIBS@ @LIBARES_LIBS@\
|
||||
@LIBCARES_LIBS@
|
||||
|
||||
#aria2c_LDFLAGS = -pg
|
||||
aria2c_LDFLAGS = -pg
|
||||
AM_CPPFLAGS = -Wall\
|
||||
-I../lib -I../intl -I$(top_srcdir)/intl\
|
||||
@LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@ @XML_CPPFLAGS@\
|
||||
@LIBARES_CPPFLAGS@ @LIBCARES_CPPFLAGS@\
|
||||
-D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@ # -pg
|
||||
-D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@ -pg
|
||||
|
||||
all: all-am
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ MetaEntry* MetaFileUtil::parseMetaFile(const string& file) {
|
|||
MetaEntry* entry = bdecoding(buf, len);
|
||||
delete [] buf;
|
||||
return entry;
|
||||
} catch(Exception* ex) {
|
||||
} catch(RecoverableException* ex) {
|
||||
delete [] buf;
|
||||
if(fp != NULL) {
|
||||
fclose(fp);
|
||||
|
@ -121,7 +121,7 @@ Dictionary* MetaFileUtil::parseDictionaryTree(const char** pp, const char* end)
|
|||
dic->put(name, e);
|
||||
}
|
||||
return dic;
|
||||
} catch(Exception* ex) {
|
||||
} catch(RecoverableException* ex) {
|
||||
delete dic;
|
||||
throw;
|
||||
}
|
||||
|
@ -142,7 +142,7 @@ List* MetaFileUtil::parseListTree(const char** pp, const char* end) {
|
|||
lis->add(e);
|
||||
}
|
||||
return lis;
|
||||
} catch(Exception* ex) {
|
||||
} catch(RecoverableException* ex) {
|
||||
delete lis;
|
||||
throw;
|
||||
}
|
||||
|
|
|
@ -125,7 +125,7 @@ RequestInfos MetalinkRequestInfo::execute() {
|
|||
reqInfo->setChecksum(checksum);
|
||||
nextReqInfos.push_front(reqInfo);
|
||||
}
|
||||
} catch(Exception* ex) {
|
||||
} catch(RecoverableException* ex) {
|
||||
logger->error("Exception caught", ex);
|
||||
delete ex;
|
||||
fail = true;
|
||||
|
|
|
@ -117,7 +117,7 @@ void MultiDiskAdaptor::writeData(const unsigned char* data, uint32_t len,
|
|||
writing = true;
|
||||
fileOffset = 0;
|
||||
} else {
|
||||
fileOffset -= (*itr)->fileEntry->getLength();
|
||||
fileOffset -= (*itr)->getFileEntry()->getLength();
|
||||
}
|
||||
}
|
||||
if(!writing) {
|
||||
|
@ -128,8 +128,8 @@ void MultiDiskAdaptor::writeData(const unsigned char* data, uint32_t len,
|
|||
bool MultiDiskAdaptor::isInRange(const DiskWriterEntryHandle entry,
|
||||
int64_t offset) const
|
||||
{
|
||||
return entry->fileEntry->getOffset() <= offset &&
|
||||
offset < entry->fileEntry->getOffset()+entry->fileEntry->getLength();
|
||||
return entry->getFileEntry()->getOffset() <= offset &&
|
||||
offset < entry->getFileEntry()->getOffset()+entry->getFileEntry()->getLength();
|
||||
}
|
||||
|
||||
uint32_t MultiDiskAdaptor::calculateLength(const DiskWriterEntryHandle entry,
|
||||
|
@ -137,8 +137,8 @@ uint32_t MultiDiskAdaptor::calculateLength(const DiskWriterEntryHandle entry,
|
|||
uint32_t rem) const
|
||||
{
|
||||
uint32_t length;
|
||||
if(entry->fileEntry->getLength() < fileOffset+rem) {
|
||||
length = entry->fileEntry->getLength()-fileOffset;
|
||||
if(entry->getFileEntry()->getLength() < fileOffset+rem) {
|
||||
length = entry->getFileEntry()->getLength()-fileOffset;
|
||||
} else {
|
||||
length = rem;
|
||||
}
|
||||
|
@ -160,7 +160,7 @@ int MultiDiskAdaptor::readData(unsigned char* data, uint32_t len, int64_t offset
|
|||
reading = true;
|
||||
fileOffset = 0;
|
||||
} else {
|
||||
fileOffset -= (*itr)->fileEntry->getLength();
|
||||
fileOffset -= (*itr)->getFileEntry()->getLength();
|
||||
}
|
||||
}
|
||||
if(!reading) {
|
||||
|
@ -205,7 +205,7 @@ string MultiDiskAdaptor::sha1Sum(int64_t offset, uint64_t length) {
|
|||
reading = true;
|
||||
fileOffset = 0;
|
||||
} else {
|
||||
fileOffset -= (*itr)->fileEntry->getLength();
|
||||
fileOffset -= (*itr)->getFileEntry()->getLength();
|
||||
}
|
||||
}
|
||||
if(!reading) {
|
||||
|
@ -215,3 +215,14 @@ string MultiDiskAdaptor::sha1Sum(int64_t offset, uint64_t length) {
|
|||
ctx.digestFinal(hashValue);
|
||||
return Util::toHex(hashValue, 20);
|
||||
}
|
||||
|
||||
bool MultiDiskAdaptor::fileExists()
|
||||
{
|
||||
for(DiskWriterEntries::iterator itr = diskWriterEntries.begin();
|
||||
itr != diskWriterEntries.end(); itr++) {
|
||||
if((*itr)->fileExists(getTopDirPath())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -39,11 +39,11 @@
|
|||
#include "Option.h"
|
||||
#include "DiskWriter.h"
|
||||
#include "messageDigest.h"
|
||||
#include "File.h"
|
||||
|
||||
class DiskWriterEntry {
|
||||
public:
|
||||
FileEntryHandle fileEntry;
|
||||
private:
|
||||
FileEntryHandle fileEntry;
|
||||
DiskWriterHandle diskWriter;
|
||||
public:
|
||||
DiskWriterEntry(const FileEntryHandle& fileEntry):
|
||||
|
@ -77,6 +77,15 @@ public:
|
|||
diskWriter->closeFile();
|
||||
}
|
||||
|
||||
bool fileExists(const string& topDir)
|
||||
{
|
||||
return File(getFilePath(topDir)).exists();
|
||||
}
|
||||
|
||||
FileEntryHandle getFileEntry() const {
|
||||
return fileEntry;
|
||||
}
|
||||
|
||||
void setDiskWriter(const DiskWriterHandle& diskWriter) {
|
||||
this->diskWriter = diskWriter;
|
||||
}
|
||||
|
@ -139,6 +148,12 @@ public:
|
|||
|
||||
virtual string sha1Sum(int64_t offset, uint64_t length);
|
||||
|
||||
virtual bool fileExists();
|
||||
|
||||
virtual string getFilePath() {
|
||||
return getTopDirPath();
|
||||
}
|
||||
|
||||
void setTopDir(const string& topDir) {
|
||||
this->topDir = topDir;
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ bool PeerAbstractCommand::execute() {
|
|||
throw new DlRetryEx(EX_TIME_OUT);
|
||||
}
|
||||
return executeInternal();
|
||||
} catch(Exception* err) {
|
||||
} catch(RecoverableException* err) {
|
||||
logger->error(MSG_DOWNLOAD_ABORTED, err, cuid);
|
||||
logger->debug("CUID#%d - Peer %s:%d banned.",
|
||||
cuid, peer->ipaddr.c_str(), peer->port);
|
||||
|
@ -96,7 +96,7 @@ bool PeerAbstractCommand::prepareForRetry(int wait) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void PeerAbstractCommand::onAbort(Exception* ex) {
|
||||
void PeerAbstractCommand::onAbort(RecoverableException* ex) {
|
||||
if(peer->isSeeder()) {
|
||||
peer->error++;
|
||||
} else {
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "Request.h"
|
||||
#include "TorrentDownloadEngine.h"
|
||||
#include "TimeA2.h"
|
||||
#include "RecoverableException.h"
|
||||
|
||||
class PeerAbstractCommand : public BtContextAwareCommand {
|
||||
private:
|
||||
|
@ -52,7 +53,7 @@ protected:
|
|||
void setTimeout(int timeout) { this->timeout = timeout; }
|
||||
virtual bool prepareForNextPeer(int wait);
|
||||
virtual bool prepareForRetry(int wait);
|
||||
virtual void onAbort(Exception* ex);
|
||||
virtual void onAbort(RecoverableException* ex);
|
||||
virtual bool executeInternal() = 0;
|
||||
void setReadCheckSocket(const SocketHandle& socket);
|
||||
void setWriteCheckSocket(const SocketHandle& socket);
|
||||
|
|
|
@ -93,6 +93,9 @@ bool PeerConnection::receiveMessage(unsigned char* data, uint32_t& dataLength) {
|
|||
}
|
||||
currentPayloadLength = payloadLength;
|
||||
}
|
||||
if(!socket->isReadable(0)) {
|
||||
return false;
|
||||
}
|
||||
// we have currentPayloadLen-resbufLen bytes to read
|
||||
uint32_t remaining = currentPayloadLength-resbufLength;
|
||||
if(remaining > 0) {
|
||||
|
|
|
@ -204,7 +204,7 @@ bool PeerInteractionCommand::prepareForRetry(int wait) {
|
|||
return false;
|
||||
}
|
||||
|
||||
void PeerInteractionCommand::onAbort(Exception* ex) {
|
||||
void PeerInteractionCommand::onAbort(RecoverableException* ex) {
|
||||
btInteractive->cancelAllPiece();
|
||||
PeerAbstractCommand::onAbort(ex);
|
||||
}
|
||||
|
|
|
@ -43,10 +43,10 @@ private:
|
|||
int sequence;
|
||||
BtInteractiveHandle btInteractive;
|
||||
protected:
|
||||
bool executeInternal();
|
||||
bool prepareForRetry(int wait);
|
||||
bool prepareForNextPeer(int wait);
|
||||
void onAbort(Exception* ex);
|
||||
virtual bool executeInternal();
|
||||
virtual bool prepareForRetry(int wait);
|
||||
virtual bool prepareForNextPeer(int wait);
|
||||
virtual void onAbort(RecoverableException* ex);
|
||||
public:
|
||||
PeerInteractionCommand(int cuid,
|
||||
const PeerHandle& peer,
|
||||
|
|
|
@ -53,7 +53,7 @@ int PeerListenCommand::bindPort(int portRangeStart, int portRangeEnd) {
|
|||
logger->info("CUID#%d - using port %d for accepting new connections",
|
||||
cuid, port);
|
||||
return port;
|
||||
} catch(Exception* ex) {
|
||||
} catch(RecoverableException* ex) {
|
||||
logger->error("CUID#%d - an error occurred while binding port=%d",
|
||||
ex, cuid, port);
|
||||
socket->closeConnection();
|
||||
|
@ -92,7 +92,7 @@ bool PeerListenCommand::execute() {
|
|||
logger->debug("CUID#%d - incoming connection, adding new command CUID#%d", cuid, newCuid);
|
||||
}
|
||||
}
|
||||
} catch(Exception* ex) {
|
||||
} catch(RecoverableException* ex) {
|
||||
logger->error("CUID#%d - error in accepting connection", ex, cuid);
|
||||
delete ex;
|
||||
}
|
||||
|
|
|
@ -105,6 +105,10 @@ public:
|
|||
const unsigned char* getBitfield() const { return bitfield->getBitfield(); }
|
||||
void setBitfield(const unsigned char* bitfield, int len);
|
||||
|
||||
int getBitfieldLength() const {
|
||||
return bitfield->getBitfieldLength();
|
||||
}
|
||||
|
||||
void clearAllBlock();
|
||||
void setAllBlock();
|
||||
|
||||
|
|
|
@ -32,31 +32,27 @@
|
|||
* files in the program, then also delete it here.
|
||||
*/
|
||||
/* copyright --> */
|
||||
#ifndef _D_COMPACT_TRACKER_RESPONSE_PROCESSOR_H_
|
||||
#define _D_COMPACT_TRACKER_RESPONSE_PROCESSOR_H_
|
||||
#ifndef _D_RECOVERABLE_EXCEPTION_H_
|
||||
#define _D_RECOVERABLE_EXCEPTION_H_
|
||||
#include "Exception.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "ByteArrayDiskWriter.h"
|
||||
#include "Request.h"
|
||||
|
||||
class TorrentDownloadEngine;
|
||||
class Logger;
|
||||
|
||||
class CompactTrackerResponseProcessor {
|
||||
private:
|
||||
ByteArrayDiskWriter* diskWriter;
|
||||
TorrentDownloadEngine* e;
|
||||
Request* req;
|
||||
const Logger* logger;
|
||||
class RecoverableException : public Exception {
|
||||
public:
|
||||
CompactTrackerResponseProcessor(ByteArrayDiskWriter* diskWriter,
|
||||
TorrentDownloadEngine* e,
|
||||
Request* req);
|
||||
~CompactTrackerResponseProcessor();
|
||||
RecoverableException(Exception* cause = 0):Exception(cause) {}
|
||||
|
||||
bool isFeeded() const;
|
||||
void execute();
|
||||
void resetTrackerResponse();
|
||||
RecoverableException(const char* msg, ...):Exception() {
|
||||
va_list ap;
|
||||
va_start(ap, msg);
|
||||
setMsg(string(msg), ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
RecoverableException(Exception* cause, const char* msg, ...):Exception(cause) {
|
||||
va_list ap;
|
||||
va_start(ap, msg);
|
||||
setMsg(string(msg), ap);
|
||||
va_end(ap);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // _D_COMPACT_TRACKER_RESPONSE_PROCESSOR_H_
|
||||
#endif // _D_RECOVERABLE_EXCEPTION_EX_H_
|
|
@ -61,7 +61,7 @@ void RequestSlot::setDispatchedTime(time_t secFromEpoch) {
|
|||
}
|
||||
|
||||
bool RequestSlot::isTimeout(time_t timeoutSec) const {
|
||||
return dispatchedTime.differenceInMillis() > timeoutSec*1000;
|
||||
return dispatchedTime.elapsed(timeoutSec);
|
||||
}
|
||||
|
||||
int RequestSlot::getLatencyInMillis() const {
|
||||
|
|
|
@ -474,3 +474,12 @@ int SegmentMan::calculateDownloadSpeed() const {
|
|||
}
|
||||
return speed;
|
||||
}
|
||||
|
||||
bool SegmentMan::fileExists() {
|
||||
return File(getFilePath()).exists();
|
||||
}
|
||||
|
||||
bool SegmentMan::shouldCancelDownloadForSafety() {
|
||||
return fileExists() && !segmentFileExists() &&
|
||||
option->get(PREF_FORCE_TRUNCATE) != V_TRUE;
|
||||
}
|
||||
|
|
|
@ -255,6 +255,11 @@ public:
|
|||
* Returns current download speed in bytes per sec.
|
||||
*/
|
||||
int calculateDownloadSpeed() const;
|
||||
|
||||
bool fileExists();
|
||||
|
||||
bool shouldCancelDownloadForSafety();
|
||||
|
||||
};
|
||||
|
||||
#endif // _D_SEGMENT_MAN_H_
|
||||
|
|
|
@ -38,6 +38,9 @@
|
|||
#include "Util.h"
|
||||
#include "BtRegistry.h"
|
||||
#include "DefaultBtContext.h"
|
||||
#include "FatalException.h"
|
||||
#include "message.h"
|
||||
#include "RecoverableException.h"
|
||||
|
||||
extern volatile sig_atomic_t btHaltRequested;
|
||||
|
||||
|
@ -60,6 +63,21 @@ RequestInfos TorrentRequestInfo::execute() {
|
|||
op,
|
||||
targetFiles));
|
||||
|
||||
if(BT_PROGRESS_INFO_FILE(btContext)->exists()) {
|
||||
// load .aria2 file if it exists.
|
||||
BT_PROGRESS_INFO_FILE(btContext)->load();
|
||||
PIECE_STORAGE(btContext)->getDiskAdaptor()->openExistingFile();
|
||||
} else {
|
||||
if(PIECE_STORAGE(btContext)->getDiskAdaptor()->fileExists() &&
|
||||
op->get(PREF_FORCE_TRUNCATE) != V_TRUE) {
|
||||
throw new FatalException(EX_FILE_ALREADY_EXISTS,
|
||||
PIECE_STORAGE(btContext)->getDiskAdaptor()->getFilePath().c_str(),
|
||||
BT_PROGRESS_INFO_FILE(btContext)->getFilename().c_str());
|
||||
} else {
|
||||
PIECE_STORAGE(btContext)->getDiskAdaptor()->initAndOpenFile();
|
||||
}
|
||||
}
|
||||
|
||||
Util::setGlobalSignalHandler(SIGINT, torrentHandler, SA_RESETHAND);
|
||||
Util::setGlobalSignalHandler(SIGTERM, torrentHandler, SA_RESETHAND);
|
||||
|
||||
|
@ -68,7 +86,7 @@ RequestInfos TorrentRequestInfo::execute() {
|
|||
if(PIECE_STORAGE(btContext)->downloadFinished()) {
|
||||
printDownloadCompeleteMessage();
|
||||
}
|
||||
} catch(Exception* ex) {
|
||||
} catch(RecoverableException* ex) {
|
||||
logger->error("Exception caught", ex);
|
||||
fail = true;
|
||||
delete ex;
|
||||
|
|
|
@ -74,7 +74,7 @@ char* TrackerUpdateCommand::getTrackerResponse(size_t& trackerResponseLength) {
|
|||
}
|
||||
trackerResponseLength = bufLength;
|
||||
return buf;
|
||||
} catch(Exception* e) {
|
||||
} catch(RecoverableException* e) {
|
||||
delete [] buf;
|
||||
throw;
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ bool TrackerUpdateCommand::execute() {
|
|||
btAnnounce->announceSuccess();
|
||||
btAnnounce->resetAnnounce();
|
||||
e->segmentMan->init();
|
||||
} catch(Exception* err) {
|
||||
} catch(RecoverableException* err) {
|
||||
logger->error("CUID#%d - Error occurred while processing tracker response.", cuid, err);
|
||||
e->segmentMan->errors++;
|
||||
delete err;
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "MetalinkRequestInfo.h"
|
||||
#include "prefs.h"
|
||||
#include "DownloadEngineFactory.h"
|
||||
#include "RecoverableException.h"
|
||||
|
||||
extern volatile sig_atomic_t haltRequested;
|
||||
|
||||
|
@ -140,7 +141,7 @@ RequestInfos UrlRequestInfo::execute() {
|
|||
e->segmentMan->diskWriter->closeFile();
|
||||
printDownloadAbortMessage();
|
||||
}
|
||||
} catch(Exception *ex) {
|
||||
} catch(RecoverableException *ex) {
|
||||
logger->error("Exception caught", ex);
|
||||
delete ex;
|
||||
fail = true;
|
||||
|
|
|
@ -244,7 +244,9 @@ string Util::urlencode(const unsigned char* target, int len) {
|
|||
string Util::torrentUrlencode(const unsigned char* target, int len) {
|
||||
string dest;
|
||||
for(int i = 0; i < len; i++) {
|
||||
if(isalpha(target[i]) || isdigit(target[i])) {
|
||||
if('0' <= target[i] && target[i] <= '9' ||
|
||||
'A' <= target[i] && target[i] <= 'Z' ||
|
||||
'a' <= target[i] && target[i] <= 'z') {
|
||||
dest += target[i];
|
||||
} else {
|
||||
char temp[4];
|
||||
|
@ -339,7 +341,7 @@ void Util::rangedFileCopy(const string& dest, const string& src, long long int s
|
|||
close(destFd);
|
||||
srcFd = -1;
|
||||
destFd = -1;
|
||||
} catch(Exception* e) {
|
||||
} catch(RecoverableException* e) {
|
||||
if(srcFd != -1) {
|
||||
close(srcFd);
|
||||
}
|
||||
|
|
19
src/main.cc
19
src/main.cc
|
@ -176,6 +176,12 @@ void showUsage() {
|
|||
" This may take some time depending on the size of\n"
|
||||
" file.\n"
|
||||
" Default: 'none'") << endl;
|
||||
cout << _(" --force-truncate=true|false If this option set to false, aria2 doesn't download\n"
|
||||
" file which already exists in file system but\n"
|
||||
" its corresponding .aria2 file doesn't exist.\n"
|
||||
" Set this option to true if you want to download\n"
|
||||
" file all over again.\n"
|
||||
" Default: false") << endl;
|
||||
#ifdef ENABLE_BITTORRENT
|
||||
cout << _(" -T, --torrent-file=TORRENT_FILE The file path to .torrent file.") << endl;
|
||||
cout << _(" --follow-torrent=true|false Setting this option to false prevents aria2 to\n"
|
||||
|
@ -337,6 +343,7 @@ int main(int argc, char* argv[]) {
|
|||
op->put(PREF_STARTUP_IDLE_TIME, "10");
|
||||
op->put(PREF_TRACKER_MAX_TRIES, "10");
|
||||
op->put(PREF_FILE_ALLOCATION, V_NONE);
|
||||
op->put(PREF_FORCE_TRUNCATE, V_FALSE);
|
||||
while(1) {
|
||||
int optIndex = 0;
|
||||
int lopt;
|
||||
|
@ -366,6 +373,7 @@ int main(int argc, char* argv[]) {
|
|||
{ "lowest-speed-limit", required_argument, &lopt, 200 },
|
||||
{ "max-download-limit", required_argument, &lopt, 201 },
|
||||
{ "file-allocation", required_argument, 0, 'a' },
|
||||
{ "force-truncate", required_argument, &lopt, 202 },
|
||||
#ifdef ENABLE_BITTORRENT
|
||||
{ "torrent-file", required_argument, NULL, 'T' },
|
||||
{ "listen-port", required_argument, &lopt, 15 },
|
||||
|
@ -616,6 +624,17 @@ int main(int argc, char* argv[]) {
|
|||
op->put(PREF_MAX_DOWNLOAD_LIMIT, Util::itos(limit));
|
||||
break;
|
||||
}
|
||||
case 202: {
|
||||
if(string(optarg) == "true") {
|
||||
op->put(PREF_FORCE_TRUNCATE, V_TRUE);
|
||||
} else if(string(optarg) == "false") {
|
||||
op->put(PREF_FORCE_TRUNCATE, V_FALSE);
|
||||
} else {
|
||||
cerr << _("force-true must be either 'true' or 'false'.") << endl;
|
||||
showUsage();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -111,5 +111,6 @@
|
|||
#define EX_SOCKET_SEND _("Failed to send data, cause: %s")
|
||||
#define EX_SOCKET_RECV _("Failed to receive data, cause: %s")
|
||||
#define EX_SOCKET_PEEK _("Failed to peek data, cause: %s")
|
||||
#define EX_FILE_ALREADY_EXISTS _("File %s exists, but %s does not exist. The download was canceled in order to prevent your file from being truncated to 0. If you are sure to download file all over again, then delete it or add --force-truncate=true option and restart aria2.")
|
||||
|
||||
#endif // _D_MESSAGE_H_
|
||||
|
|
|
@ -84,6 +84,8 @@
|
|||
// value: prealloc | none
|
||||
#define PREF_FILE_ALLOCATION "file_allocation"
|
||||
# define V_PREALLOC "prealloc"
|
||||
// value: true | false
|
||||
#define PREF_FORCE_TRUNCATE "force_truncate"
|
||||
|
||||
/**
|
||||
* FTP related preferences
|
||||
|
|
Loading…
Reference in New Issue