2010-06-09 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

Made protected member variable private. Added accessor funcs.
	* src/AbstractCommand.cc
	* src/AbstractCommand.h
	* src/AbstractProxyRequestCommand.cc
	* src/AbstractProxyRequestCommand.h
	* src/AbstractProxyResponseCommand.cc
	* src/AbstractProxyResponseCommand.h
	* src/CreateRequestCommand.cc
	* src/DownloadCommand.cc
	* src/DownloadCommand.h
	* src/FtpDownloadCommand.cc
	* src/FtpDownloadCommand.h
	* src/FtpFinishDownloadCommand.cc
	* src/FtpInitiateConnectionCommand.cc
	* src/FtpNegotiationCommand.cc
	* src/FtpNegotiationCommand.h
	* src/FtpTunnelRequestCommand.cc
	* src/FtpTunnelResponseCommand.cc
	* src/HttpDownloadCommand.cc
	* src/HttpInitiateConnectionCommand.cc
	* src/HttpProxyRequestCommand.cc
	* src/HttpProxyResponseCommand.cc
	* src/HttpRequestCommand.cc
	* src/HttpResponseCommand.cc
	* src/HttpResponseCommand.h
	* src/HttpSkipResponseCommand.cc
	* src/InitiateConnectionCommand.cc
pull/1/head
Tatsuhiro Tsujikawa 2010-06-09 12:43:44 +00:00
parent 9afc36152a
commit 970e7f95a6
27 changed files with 823 additions and 668 deletions

View File

@ -1,3 +1,33 @@
2010-06-09 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Made protected member variable private. Added accessor funcs.
* src/AbstractCommand.cc
* src/AbstractCommand.h
* src/AbstractProxyRequestCommand.cc
* src/AbstractProxyRequestCommand.h
* src/AbstractProxyResponseCommand.cc
* src/AbstractProxyResponseCommand.h
* src/CreateRequestCommand.cc
* src/DownloadCommand.cc
* src/DownloadCommand.h
* src/FtpDownloadCommand.cc
* src/FtpDownloadCommand.h
* src/FtpFinishDownloadCommand.cc
* src/FtpInitiateConnectionCommand.cc
* src/FtpNegotiationCommand.cc
* src/FtpNegotiationCommand.h
* src/FtpTunnelRequestCommand.cc
* src/FtpTunnelResponseCommand.cc
* src/HttpDownloadCommand.cc
* src/HttpInitiateConnectionCommand.cc
* src/HttpProxyRequestCommand.cc
* src/HttpProxyResponseCommand.cc
* src/HttpRequestCommand.cc
* src/HttpResponseCommand.cc
* src/HttpResponseCommand.h
* src/HttpSkipResponseCommand.cc
* src/InitiateConnectionCommand.cc
2010-06-09 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Made protected member variables of Command private. Added accessor

View File

@ -77,15 +77,16 @@ AbstractCommand::AbstractCommand(cuid_t cuid,
RequestGroup* requestGroup,
DownloadEngine* e,
const SocketHandle& s):
Command(cuid), checkPoint(global::wallclock), _requestGroup(requestGroup),
req(req), _fileEntry(fileEntry), e(e), socket(s),
checkSocketIsReadable(false), checkSocketIsWritable(false),
nameResolverCheck(false)
Command(cuid), _checkPoint(global::wallclock),
_timeout(requestGroup->getTimeout()),
_requestGroup(requestGroup),
_req(req), _fileEntry(fileEntry), _e(e), _socket(s),
_checkSocketIsReadable(false), _checkSocketIsWritable(false),
_nameResolverCheck(false)
{
if(!socket.isNull() && socket->isOpen()) {
setReadCheckSocket(socket);
if(!_socket.isNull() && _socket->isOpen()) {
setReadCheckSocket(_socket);
}
timeout = _requestGroup->getTimeout();
_requestGroup->increaseStreamConnection();
_requestGroup->increaseNumCommand();
}
@ -113,19 +114,19 @@ bool AbstractCommand::execute() {
if(_requestGroup->downloadFinished() || _requestGroup->isHaltRequested()) {
return true;
}
if(!req.isNull() && req->removalRequested()) {
if(!_req.isNull() && _req->removalRequested()) {
if(getLogger()->debug()) {
getLogger()->debug
("CUID#%s - Discard original URI=%s because it is requested.",
util::itos(getCuid()).c_str(), req->getUri().c_str());
util::itos(getCuid()).c_str(), _req->getUri().c_str());
}
return prepareForRetry(0);
}
// TODO it is not needed to check other PeerStats every time.
// Find faster Request when no segment is available.
if(!req.isNull() && _fileEntry->countPooledRequest() > 0 &&
!_requestGroup->getPieceStorage()->hasMissingUnusedPiece()) {
SharedHandle<Request> fasterRequest = _fileEntry->findFasterRequest(req);
if(!_req.isNull() && _fileEntry->countPooledRequest() > 0 &&
!getPieceStorage()->hasMissingUnusedPiece()) {
SharedHandle<Request> fasterRequest = _fileEntry->findFasterRequest(_req);
if(!fasterRequest.isNull()) {
if(getLogger()->info()) {
getLogger()->info("CUID#%s - Use faster Request hostname=%s, port=%u",
@ -134,29 +135,28 @@ bool AbstractCommand::execute() {
fasterRequest->getPort());
}
// Cancel current Request object and use faster one.
_fileEntry->removeRequest(req);
_fileEntry->removeRequest(_req);
Command* command =
InitiateConnectionCommandFactory::createInitiateConnectionCommand
(getCuid(), fasterRequest, _fileEntry, _requestGroup, e);
e->setNoWait(true);
e->addCommand(command);
(getCuid(), fasterRequest, _fileEntry, _requestGroup, _e);
_e->setNoWait(true);
_e->addCommand(command);
return true;
}
}
if((checkSocketIsReadable && readEventEnabled()) ||
(checkSocketIsWritable && writeEventEnabled()) ||
if((_checkSocketIsReadable && readEventEnabled()) ||
(_checkSocketIsWritable && writeEventEnabled()) ||
hupEventEnabled() ||
#ifdef ENABLE_ASYNC_DNS
(nameResolverCheck && nameResolveFinished()) ||
(_nameResolverCheck && nameResolveFinished()) ||
#endif // ENABLE_ASYNC_DNS
(!checkSocketIsReadable && !checkSocketIsWritable &&
!nameResolverCheck)) {
checkPoint = global::wallclock;
if(!_requestGroup->getPieceStorage().isNull()) {
(!_checkSocketIsReadable && !_checkSocketIsWritable &&
!_nameResolverCheck)) {
_checkPoint = global::wallclock;
if(!getPieceStorage().isNull()) {
_segments.clear();
_requestGroup->getSegmentMan()->getInFlightSegment
(_segments, getCuid());
if(!req.isNull() && _segments.empty()) {
getSegmentMan()->getInFlightSegment(_segments, getCuid());
if(!_req.isNull() && _segments.empty()) {
// This command previously has assigned segments, but it is
// canceled. So discard current request chain.
if(getLogger()->debug()) {
@ -166,11 +166,11 @@ bool AbstractCommand::execute() {
}
return prepareForRetry(0);
}
if(req.isNull() || req->getMaxPipelinedRequest() == 1 ||
if(_req.isNull() || _req->getMaxPipelinedRequest() == 1 ||
_requestGroup->getDownloadContext()->getFileEntries().size() == 1) {
if(_segments.empty()) {
SharedHandle<Segment> segment =
_requestGroup->getSegmentMan()->getSegment(getCuid());
getSegmentMan()->getSegment(getCuid());
if(!segment.isNull()) {
_segments.push_back(segment);
}
@ -183,7 +183,7 @@ bool AbstractCommand::execute() {
}
// When all segments are ignored in SegmentMan, there are
// no URIs available, so don't retry.
if(_requestGroup->getSegmentMan()->allSegmentsIgnored()) {
if(getSegmentMan()->allSegmentsIgnored()) {
if(getLogger()->debug()) {
getLogger()->debug("All segments are ignored.");
}
@ -193,9 +193,9 @@ bool AbstractCommand::execute() {
}
}
} else {
size_t maxSegments = req->getMaxPipelinedRequest();
size_t maxSegments = _req->getMaxPipelinedRequest();
if(_segments.size() < maxSegments) {
_requestGroup->getSegmentMan()->getSegment
getSegmentMan()->getSegment
(_segments, getCuid(), _fileEntry, maxSegments);
}
if(_segments.empty()) {
@ -207,23 +207,23 @@ bool AbstractCommand::execute() {
} else if(errorEventEnabled()) {
throw DL_RETRY_EX
(StringFormat(MSG_NETWORK_PROBLEM,
socket->getSocketError().c_str()).str());
_socket->getSocketError().c_str()).str());
} else {
if(checkPoint.difference(global::wallclock) >= timeout) {
if(_checkPoint.difference(global::wallclock) >= _timeout) {
// timeout triggers ServerStat error state.
SharedHandle<ServerStat> ss =
e->getRequestGroupMan()->getOrCreateServerStat(req->getHost(),
req->getProtocol());
_e->getRequestGroupMan()->getOrCreateServerStat(_req->getHost(),
_req->getProtocol());
ss->setError();
throw DL_RETRY_EX2(EX_TIME_OUT, downloadresultcode::TIME_OUT);
}
e->addCommand(this);
_e->addCommand(this);
return false;
}
} catch(DlAbortEx& err) {
if(req.isNull()) {
if(_req.isNull()) {
if(getLogger()->debug()) {
getLogger()->debug(EX_EXCEPTION_CAUGHT, err);
}
@ -231,10 +231,10 @@ bool AbstractCommand::execute() {
getLogger()->error
(MSG_DOWNLOAD_ABORTED,
DL_ABORT_EX2(StringFormat
("URI=%s", req->getCurrentUri().c_str()).str(),err),
util::itos(getCuid()).c_str(), req->getUri().c_str());
_fileEntry->addURIResult(req->getUri(), err.getCode());
_requestGroup->setLastUriResult(req->getUri(), err.getCode());
("URI=%s", _req->getCurrentUri().c_str()).str(),err),
util::itos(getCuid()).c_str(), _req->getUri().c_str());
_fileEntry->addURIResult(_req->getUri(), err.getCode());
_requestGroup->setLastUriResult(_req->getUri(), err.getCode());
if(err.getCode() == downloadresultcode::CANNOT_RESUME) {
_requestGroup->increaseResumeFailureCount();
}
@ -243,29 +243,29 @@ bool AbstractCommand::execute() {
tryReserved();
return true;
} catch(DlRetryEx& err) {
assert(!req.isNull());
assert(!_req.isNull());
if(getLogger()->info()) {
getLogger()->info
(MSG_RESTARTING_DOWNLOAD,
DL_RETRY_EX2(StringFormat
("URI=%s", req->getCurrentUri().c_str()).str(),
("URI=%s", _req->getCurrentUri().c_str()).str(),
err),
util::itos(getCuid()).c_str(), req->getUri().c_str());
util::itos(getCuid()).c_str(), _req->getUri().c_str());
}
req->addTryCount();
req->resetRedirectCount();
_req->addTryCount();
_req->resetRedirectCount();
const unsigned int maxTries = getOption()->getAsInt(PREF_MAX_TRIES);
bool isAbort = maxTries != 0 && req->getTryCount() >= maxTries;
bool isAbort = maxTries != 0 && _req->getTryCount() >= maxTries;
if(isAbort) {
if(getLogger()->info()) {
getLogger()->info(MSG_MAX_TRY,
util::itos(getCuid()).c_str(), req->getTryCount());
util::itos(getCuid()).c_str(), _req->getTryCount());
}
getLogger()->error(MSG_DOWNLOAD_ABORTED, err,
util::itos(getCuid()).c_str(),
req->getUri().c_str());
_fileEntry->addURIResult(req->getUri(), err.getCode());
_requestGroup->setLastUriResult(req->getUri(), err.getCode());
_req->getUri().c_str());
_fileEntry->addURIResult(_req->getUri(), err.getCode());
_requestGroup->setLastUriResult(_req->getUri(), err.getCode());
if(err.getCode() == downloadresultcode::CANNOT_RESUME) {
_requestGroup->increaseResumeFailureCount();
}
@ -277,9 +277,9 @@ bool AbstractCommand::execute() {
}
} catch(DownloadFailureException& err) {
getLogger()->error(EX_EXCEPTION_CAUGHT, err);
if(!req.isNull()) {
_fileEntry->addURIResult(req->getUri(), err.getCode());
_requestGroup->setLastUriResult(req->getUri(), err.getCode());
if(!_req.isNull()) {
_fileEntry->addURIResult(_req->getUri(), err.getCode());
_requestGroup->setLastUriResult(_req->getUri(), err.getCode());
}
_requestGroup->setHaltRequested(true);
return true;
@ -308,59 +308,58 @@ void AbstractCommand::tryReserved() {
util::itos(getCuid()).c_str());
}
std::vector<Command*> commands;
_requestGroup->createNextCommand(commands, e, 1);
e->setNoWait(true);
e->addCommand(commands);
_requestGroup->createNextCommand(commands, _e, 1);
_e->setNoWait(true);
_e->addCommand(commands);
}
bool AbstractCommand::prepareForRetry(time_t wait) {
if(!_requestGroup->getPieceStorage().isNull()) {
_requestGroup->getSegmentMan()->cancelSegment(getCuid());
if(!getPieceStorage().isNull()) {
getSegmentMan()->cancelSegment(getCuid());
}
if(!req.isNull()) {
_fileEntry->poolRequest(req);
if(!_req.isNull()) {
_fileEntry->poolRequest(_req);
if(getLogger()->debug()) {
getLogger()->debug("CUID#%s - Pooling request URI=%s",
util::itos(getCuid()).c_str(), req->getUri().c_str());
util::itos(getCuid()).c_str(), _req->getUri().c_str());
}
if(!_requestGroup->getSegmentMan().isNull()) {
_requestGroup->getSegmentMan()->recognizeSegmentFor(_fileEntry);
if(!getSegmentMan().isNull()) {
getSegmentMan()->recognizeSegmentFor(_fileEntry);
}
}
Command* command = new CreateRequestCommand(getCuid(), _requestGroup, e);
Command* command = new CreateRequestCommand(getCuid(), _requestGroup, _e);
if(wait == 0) {
e->setNoWait(true);
e->addCommand(command);
_e->setNoWait(true);
_e->addCommand(command);
} else {
SleepCommand* scom = new SleepCommand(getCuid(), e, _requestGroup,
SleepCommand* scom = new SleepCommand(getCuid(), _e, _requestGroup,
command, wait);
e->addCommand(scom);
_e->addCommand(scom);
}
return true;
}
void AbstractCommand::onAbort() {
if(!req.isNull()) {
if(!_req.isNull()) {
// TODO This might be a problem if the failure is caused by proxy.
e->getRequestGroupMan()->getOrCreateServerStat
(req->getHost(), req->getProtocol())->setError();
_fileEntry->removeIdenticalURI(req->getUri());
_fileEntry->removeRequest(req);
_e->getRequestGroupMan()->getOrCreateServerStat
(_req->getHost(), _req->getProtocol())->setError();
_fileEntry->removeIdenticalURI(_req->getUri());
_fileEntry->removeRequest(_req);
}
if(getLogger()->debug()) {
getLogger()->debug("CUID#%s - Aborting download",
util::itos(getCuid()).c_str());
}
if(!_requestGroup->getPieceStorage().isNull()) {
SharedHandle<SegmentMan> segmentMan = _requestGroup->getSegmentMan();
segmentMan->cancelSegment(getCuid());
if(!getPieceStorage().isNull()) {
getSegmentMan()->cancelSegment(getCuid());
// Don't do following process if BitTorrent is involved or files
// in DownloadContext is more than 1. The latter condition is
// limitation of current implementation.
if(!getOption()->getAsBool(PREF_ALWAYS_RESUME) &&
!_fileEntry.isNull() &&
segmentMan->calculateSessionDownloadLength() == 0 &&
getSegmentMan()->calculateSessionDownloadLength() == 0 &&
!_requestGroup->p2pInvolved() &&
_requestGroup->getDownloadContext()->getFileEntries().size() == 1) {
const int maxTries = getOption()->getAsInt(PREF_MAX_RESUME_FAILURE_TRIES);
@ -383,9 +382,9 @@ void AbstractCommand::onAbort() {
std::deque<URIResult> res;
_fileEntry->extractURIResult(res, downloadresultcode::CANNOT_RESUME);
if(!res.empty()) {
segmentMan->cancelAllSegments();
segmentMan->eraseSegmentWrittenLengthMemo();
_requestGroup->getPieceStorage()->markPiecesDone(0);
getSegmentMan()->cancelAllSegments();
getSegmentMan()->eraseSegmentWrittenLengthMemo();
getPieceStorage()->markPiecesDone(0);
std::vector<std::string> uris;
uris.reserve(res.size());
std::transform(res.begin(), res.end(), std::back_inserter(uris),
@ -396,7 +395,7 @@ void AbstractCommand::onAbort() {
static_cast<unsigned long int>(uris.size()));
}
_fileEntry->addUris(uris.begin(), uris.end());
segmentMan->recognizeSegmentFor(_fileEntry);
getSegmentMan()->recognizeSegmentFor(_fileEntry);
}
}
}
@ -404,10 +403,10 @@ void AbstractCommand::onAbort() {
}
void AbstractCommand::disableReadCheckSocket() {
if(checkSocketIsReadable) {
e->deleteSocketForReadCheck(readCheckTarget, this);
checkSocketIsReadable = false;
readCheckTarget = SocketHandle();
if(_checkSocketIsReadable) {
_e->deleteSocketForReadCheck(_readCheckTarget, this);
_checkSocketIsReadable = false;
_readCheckTarget.reset();
}
}
@ -415,16 +414,16 @@ void AbstractCommand::setReadCheckSocket(const SocketHandle& socket) {
if(!socket->isOpen()) {
disableReadCheckSocket();
} else {
if(checkSocketIsReadable) {
if(readCheckTarget != socket) {
e->deleteSocketForReadCheck(readCheckTarget, this);
e->addSocketForReadCheck(socket, this);
readCheckTarget = socket;
if(_checkSocketIsReadable) {
if(_readCheckTarget != socket) {
_e->deleteSocketForReadCheck(_readCheckTarget, this);
_e->addSocketForReadCheck(socket, this);
_readCheckTarget = socket;
}
} else {
e->addSocketForReadCheck(socket, this);
checkSocketIsReadable = true;
readCheckTarget = socket;
_e->addSocketForReadCheck(socket, this);
_checkSocketIsReadable = true;
_readCheckTarget = socket;
}
}
}
@ -440,10 +439,10 @@ void AbstractCommand::setReadCheckSocketIf
}
void AbstractCommand::disableWriteCheckSocket() {
if(checkSocketIsWritable) {
e->deleteSocketForWriteCheck(writeCheckTarget, this);
checkSocketIsWritable = false;
writeCheckTarget = SocketHandle();
if(_checkSocketIsWritable) {
_e->deleteSocketForWriteCheck(_writeCheckTarget, this);
_checkSocketIsWritable = false;
_writeCheckTarget.reset();
}
}
@ -451,16 +450,16 @@ void AbstractCommand::setWriteCheckSocket(const SocketHandle& socket) {
if(!socket->isOpen()) {
disableWriteCheckSocket();
} else {
if(checkSocketIsWritable) {
if(writeCheckTarget != socket) {
e->deleteSocketForWriteCheck(writeCheckTarget, this);
e->addSocketForWriteCheck(socket, this);
writeCheckTarget = socket;
if(_checkSocketIsWritable) {
if(_writeCheckTarget != socket) {
_e->deleteSocketForWriteCheck(_writeCheckTarget, this);
_e->addSocketForWriteCheck(socket, this);
_writeCheckTarget = socket;
}
} else {
e->addSocketForWriteCheck(socket, this);
checkSocketIsWritable = true;
writeCheckTarget = socket;
_e->addSocketForWriteCheck(socket, this);
_checkSocketIsWritable = true;
_writeCheckTarget = socket;
}
}
}
@ -570,17 +569,17 @@ static bool inNoProxy(const SharedHandle<Request>& req,
bool AbstractCommand::isProxyDefined() const
{
return isProxyRequest(req->getProtocol(), getOption()) &&
!inNoProxy(req, getOption()->get(PREF_NO_PROXY));
return isProxyRequest(_req->getProtocol(), getOption()) &&
!inNoProxy(_req, getOption()->get(PREF_NO_PROXY));
}
SharedHandle<Request> AbstractCommand::createProxyRequest() const
{
SharedHandle<Request> proxyRequest;
if(inNoProxy(req, getOption()->get(PREF_NO_PROXY))) {
if(inNoProxy(_req, getOption()->get(PREF_NO_PROXY))) {
return proxyRequest;
}
std::string proxy = getProxyUri(req->getProtocol(), getOption());
std::string proxy = getProxyUri(_req->getProtocol(), getOption());
if(!proxy.empty()) {
proxyRequest.reset(new Request());
if(proxyRequest->setUri(proxy)) {
@ -625,9 +624,9 @@ bool AbstractCommand::asyncResolveHostname()
return true;
case AsyncNameResolver::STATUS_ERROR:
disableNameResolverCheck(_asyncNameResolver);
if(!isProxyRequest(req->getProtocol(), getOption())) {
e->getRequestGroupMan()->getOrCreateServerStat
(req->getHost(), req->getProtocol())->setError();
if(!isProxyRequest(_req->getProtocol(), getOption())) {
_e->getRequestGroupMan()->getOrCreateServerStat
(_req->getHost(), _req->getProtocol())->setError();
}
throw DL_ABORT_EX
(StringFormat(MSG_NAME_RESOLUTION_FAILED,
@ -647,16 +646,16 @@ const std::vector<std::string>& AbstractCommand::getResolvedAddresses()
void AbstractCommand::setNameResolverCheck
(const SharedHandle<AsyncNameResolver>& resolver) {
if(!resolver.isNull()) {
nameResolverCheck = true;
e->addNameResolverCheck(resolver, this);
_nameResolverCheck = true;
_e->addNameResolverCheck(resolver, this);
}
}
void AbstractCommand::disableNameResolverCheck
(const SharedHandle<AsyncNameResolver>& resolver) {
if(!resolver.isNull()) {
nameResolverCheck = false;
e->deleteNameResolverCheck(resolver, this);
_nameResolverCheck = false;
_e->deleteNameResolverCheck(resolver, this);
}
}
@ -670,7 +669,7 @@ bool AbstractCommand::nameResolveFinished() const {
std::string AbstractCommand::resolveHostname
(std::vector<std::string>& addrs, const std::string& hostname, uint16_t port)
{
e->findAllCachedIPAddresses(std::back_inserter(addrs), hostname, port);
_e->findAllCachedIPAddresses(std::back_inserter(addrs), hostname, port);
std::string ipaddr;
if(addrs.empty()) {
#ifdef ENABLE_ASYNC_DNS
@ -688,7 +687,7 @@ std::string AbstractCommand::resolveHostname
{
NameResolver res;
res.setSocktype(SOCK_STREAM);
if(e->getOption()->getAsBool(PREF_DISABLE_IPV6)) {
if(_e->getOption()->getAsBool(PREF_DISABLE_IPV6)) {
res.setFamily(AF_INET);
}
res.resolve(addrs, hostname);
@ -701,9 +700,9 @@ std::string AbstractCommand::resolveHostname
}
for(std::vector<std::string>::const_iterator i = addrs.begin(),
eoi = addrs.end(); i != eoi; ++i) {
e->cacheIPAddress(hostname, *i, port);
_e->cacheIPAddress(hostname, *i, port);
}
ipaddr = e->findCachedIPAddress(hostname, port);
ipaddr = _e->findCachedIPAddress(hostname, port);
} else {
ipaddr = addrs.front();
if(getLogger()->info()) {
@ -725,13 +724,13 @@ void AbstractCommand::prepareForNextAction(Command* nextCommand)
std::vector<Command*> commands;
try {
_requestGroup->processCheckIntegrityEntry(commands, entry, e);
_requestGroup->processCheckIntegrityEntry(commands, entry, _e);
} catch(RecoverableException& e) {
std::for_each(commands.begin(), commands.end(), Deleter());
throw;
}
e->addCommand(commands);
e->setNoWait(true);
_e->addCommand(commands);
_e->setNoWait(true);
}
bool AbstractCommand::checkIfConnectionEstablished
@ -744,8 +743,8 @@ bool AbstractCommand::checkIfConnectionEstablished
std::string error = socket->getSocketError();
if(!error.empty()) {
// See also InitiateConnectionCommand::executeInternal()
e->markBadIPAddress(connectedHostname, connectedAddr, connectedPort);
if(!e->findCachedIPAddress(connectedHostname, connectedPort).empty()) {
_e->markBadIPAddress(connectedHostname, connectedAddr, connectedPort);
if(!_e->findCachedIPAddress(connectedHostname, connectedPort).empty()) {
if(getLogger()->info()) {
getLogger()->info(MSG_CONNECT_FAILED_AND_RETRY,
util::itos(getCuid()).c_str(),
@ -753,17 +752,17 @@ bool AbstractCommand::checkIfConnectionEstablished
}
Command* command =
InitiateConnectionCommandFactory::createInitiateConnectionCommand
(getCuid(), req, _fileEntry, _requestGroup, e);
e->setNoWait(true);
e->addCommand(command);
(getCuid(), _req, _fileEntry, _requestGroup, _e);
_e->setNoWait(true);
_e->addCommand(command);
return false;
}
e->removeCachedIPAddress(connectedHostname, connectedPort);
_e->removeCachedIPAddress(connectedHostname, connectedPort);
// Don't set error if proxy server is used and its method is GET.
if(resolveProxyMethod(req->getProtocol()) != V_GET ||
!isProxyRequest(req->getProtocol(), getOption())) {
e->getRequestGroupMan()->getOrCreateServerStat
(req->getHost(), req->getProtocol())->setError();
if(resolveProxyMethod(_req->getProtocol()) != V_GET ||
!isProxyRequest(_req->getProtocol(), getOption())) {
_e->getRequestGroupMan()->getOrCreateServerStat
(_req->getHost(), _req->getProtocol())->setError();
}
throw DL_RETRY_EX
(StringFormat(MSG_ESTABLISHING_CONNECTION_FAILED, error.c_str()).str());
@ -788,4 +787,9 @@ const SharedHandle<Option>& AbstractCommand::getOption() const
return _requestGroup->getOption();
}
void AbstractCommand::createSocket()
{
_socket.reset(new SocketCore());
}
} // namespace aria2

View File

@ -55,19 +55,83 @@ class AsyncNameResolver;
class AbstractCommand : public Command {
private:
Timer checkPoint;
time_t timeout;
protected:
Timer _checkPoint;
time_t _timeout;
RequestGroup* _requestGroup;
SharedHandle<Request> req;
SharedHandle<Request> _req;
SharedHandle<FileEntry> _fileEntry;
DownloadEngine* e;
SharedHandle<SocketCore> socket;
DownloadEngine* _e;
SharedHandle<SocketCore> _socket;
std::vector<SharedHandle<Segment> > _segments;
#ifdef ENABLE_ASYNC_DNS
SharedHandle<AsyncNameResolver> _asyncNameResolver;
#endif // ENABLE_ASYNC_DNS
bool _checkSocketIsReadable;
bool _checkSocketIsWritable;
SharedHandle<SocketCore> _readCheckTarget;
SharedHandle<SocketCore> _writeCheckTarget;
bool _nameResolverCheck;
#ifdef ENABLE_ASYNC_DNS
void setNameResolverCheck(const SharedHandle<AsyncNameResolver>& resolver);
void disableNameResolverCheck
(const SharedHandle<AsyncNameResolver>& resolver);
bool nameResolveFinished() const;
#endif // ENABLE_ASYNC_DNS
protected:
RequestGroup* getRequestGroup() const
{
return _requestGroup;
}
const SharedHandle<Request>& getRequest() const
{
return _req;
}
void setRequest(const SharedHandle<Request>& request)
{
_req = request;
}
const SharedHandle<FileEntry>& getFileEntry() const
{
return _fileEntry;
}
void setFileEntry(const SharedHandle<FileEntry>& fileEntry)
{
_fileEntry = fileEntry;
}
DownloadEngine* getDownloadEngine() const
{
return _e;
}
const SharedHandle<SocketCore>& getSocket() const
{
return _socket;
}
void setSocket(const SharedHandle<SocketCore>& s)
{
_socket = s;
}
void createSocket();
const std::vector<SharedHandle<Segment> >& getSegments() const
{
return _segments;
}
#ifdef ENABLE_ASYNC_DNS
bool isAsyncNameResolverInitialized() const;
void initAsyncNameResolver(const std::string& hostname);
@ -106,7 +170,7 @@ protected:
*/
void setWriteCheckSocketIf(const SharedHandle<SocketCore>& socket, bool pred);
void setTimeout(time_t timeout) { this->timeout = timeout; }
void setTimeout(time_t timeout) { _timeout = timeout; }
void prepareForNextAction(Command* nextCommand = 0);
@ -143,20 +207,16 @@ protected:
{
return _requestGroup->getDownloadContext();
}
private:
bool checkSocketIsReadable;
bool checkSocketIsWritable;
SharedHandle<SocketCore> readCheckTarget;
SharedHandle<SocketCore> writeCheckTarget;
bool nameResolverCheck;
#ifdef ENABLE_ASYNC_DNS
const SharedHandle<SegmentMan>& getSegmentMan() const
{
return _requestGroup->getSegmentMan();
}
void setNameResolverCheck(const SharedHandle<AsyncNameResolver>& resolver);
void disableNameResolverCheck(const SharedHandle<AsyncNameResolver>& resolver);
bool nameResolveFinished() const;
#endif // ENABLE_ASYNC_DNS
const SharedHandle<PieceStorage>& getPieceStorage() const
{
return _requestGroup->getPieceStorage();
}
public:
AbstractCommand(cuid_t cuid, const SharedHandle<Request>& req,
const SharedHandle<FileEntry>& fileEntry,

View File

@ -64,37 +64,37 @@ AbstractProxyRequestCommand::AbstractProxyRequestCommand
:
AbstractCommand(cuid, req, fileEntry, requestGroup, e, s),
_proxyRequest(proxyRequest),
httpConnection(new HttpConnection(cuid, s, getOption().get()))
_httpConnection(new HttpConnection(cuid, s, getOption().get()))
{
setTimeout(getOption()->getAsInt(PREF_CONNECT_TIMEOUT));
disableReadCheckSocket();
setWriteCheckSocket(socket);
setWriteCheckSocket(getSocket());
}
AbstractProxyRequestCommand::~AbstractProxyRequestCommand() {}
bool AbstractProxyRequestCommand::executeInternal() {
//socket->setBlockingMode();
if(httpConnection->sendBufferIsEmpty()) {
if(_httpConnection->sendBufferIsEmpty()) {
if(!checkIfConnectionEstablished
(socket, _connectedHostname, _connectedAddr, _connectedPort)) {
(getSocket(), _connectedHostname, _connectedAddr, _connectedPort)) {
return true;
}
SharedHandle<HttpRequest> httpRequest(new HttpRequest());
httpRequest->setUserAgent(getOption()->get(PREF_USER_AGENT));
httpRequest->setRequest(req);
httpRequest->setRequest(getRequest());
httpRequest->setProxyRequest(_proxyRequest);
httpConnection->sendProxyRequest(httpRequest);
_httpConnection->sendProxyRequest(httpRequest);
} else {
httpConnection->sendPendingData();
_httpConnection->sendPendingData();
}
if(httpConnection->sendBufferIsEmpty()) {
e->addCommand(getNextCommand());
if(_httpConnection->sendBufferIsEmpty()) {
getDownloadEngine()->addCommand(getNextCommand());
return true;
} else {
setWriteCheckSocket(socket);
e->addCommand(this);
setWriteCheckSocket(getSocket());
getDownloadEngine()->addCommand(this);
return false;
}
}

View File

@ -43,16 +43,21 @@ class HttpConnection;
class SocketCore;
class AbstractProxyRequestCommand : public AbstractCommand {
protected:
private:
SharedHandle<Request> _proxyRequest;
SharedHandle<HttpConnection> httpConnection;
SharedHandle<HttpConnection> _httpConnection;
std::string _connectedHostname;
std::string _connectedAddr;
uint16_t _connectedPort;
protected:
virtual bool executeInternal();
const SharedHandle<HttpConnection>& getHttpConnection() const
{
return _httpConnection;
}
public:
AbstractProxyRequestCommand(cuid_t cuid,
const SharedHandle<Request>& req,

View File

@ -62,21 +62,21 @@ AbstractProxyResponseCommand::AbstractProxyResponseCommand
DownloadEngine* e,
const SocketHandle& s)
:AbstractCommand(cuid, req, fileEntry, requestGroup, e, s),
httpConnection(httpConnection) {}
_httpConnection(httpConnection) {}
AbstractProxyResponseCommand::~AbstractProxyResponseCommand() {}
bool AbstractProxyResponseCommand::executeInternal() {
SharedHandle<HttpResponse> httpResponse = httpConnection->receiveResponse();
SharedHandle<HttpResponse> httpResponse = _httpConnection->receiveResponse();
if(httpResponse.isNull()) {
// the server has not responded our request yet.
e->addCommand(this);
getDownloadEngine()->addCommand(this);
return false;
}
if(httpResponse->getResponseStatus() != HttpHeader::S200) {
throw DL_RETRY_EX(EX_PROXY_CONNECTION_FAILED);
}
e->addCommand(getNextCommand());
getDownloadEngine()->addCommand(getNextCommand());
return true;
}

View File

@ -43,10 +43,15 @@ class HttpConnection;
class SocketCore;
class AbstractProxyResponseCommand : public AbstractCommand {
private:
SharedHandle<HttpConnection> _httpConnection;
protected:
SharedHandle<HttpConnection> httpConnection;
virtual bool executeInternal();
const SharedHandle<HttpConnection>& getHttpConnection() const
{
return _httpConnection;
}
public:
AbstractProxyResponseCommand
(cuid_t cuid,

View File

@ -67,39 +67,41 @@ CreateRequestCommand::CreateRequestCommand(cuid_t cuid,
bool CreateRequestCommand::executeInternal()
{
if(_segments.empty()) {
_fileEntry = _requestGroup->getDownloadContext()->findFileEntryByOffset(0);
if(getSegments().empty()) {
setFileEntry(getDownloadContext()->findFileEntryByOffset(0));
} else {
// We assume all segments belongs to same file.
_fileEntry = _requestGroup->getDownloadContext()->findFileEntryByOffset
(_segments.front()->getPositionToWrite());
setFileEntry(getDownloadContext()->findFileEntryByOffset
(getSegments().front()->getPositionToWrite()));
}
if(_fileEntry->getRemainingUris().empty() &&
if(getFileEntry()->getRemainingUris().empty() &&
getOption()->getAsBool(PREF_REUSE_URI) &&
_fileEntry->countPooledRequest() == 0) {
_fileEntry->reuseUri(_requestGroup->getNumConcurrentCommand());
getFileEntry()->countPooledRequest() == 0) {
getFileEntry()->reuseUri(getRequestGroup()->getNumConcurrentCommand());
}
req = _fileEntry->getRequest(_requestGroup->getURISelector(),
getOption()->get(PREF_REFERER),
// Don't use HEAD request when file
// size is known.
// Use HEAD for dry-run mode.
(_fileEntry->getLength() == 0 &&
getOption()->getAsBool(PREF_USE_HEAD)) ||
getOption()->getAsBool(PREF_DRY_RUN)?
Request::METHOD_HEAD:Request::METHOD_GET);
if(req.isNull()) {
if(!_requestGroup->getSegmentMan().isNull()) {
_requestGroup->getSegmentMan()->ignoreSegmentFor(_fileEntry);
setRequest
(getFileEntry()->getRequest(getRequestGroup()->getURISelector(),
getOption()->get(PREF_REFERER),
// Don't use HEAD request when file
// size is known.
// Use HEAD for dry-run mode.
(getFileEntry()->getLength() == 0 &&
getOption()->getAsBool(PREF_USE_HEAD)) ||
getOption()->getAsBool(PREF_DRY_RUN)?
Request::METHOD_HEAD:Request::METHOD_GET));
if(getRequest().isNull()) {
if(!getSegmentMan().isNull()) {
getSegmentMan()->ignoreSegmentFor(getFileEntry());
}
throw DL_ABORT_EX("No URI available.");
}
Command* command =
InitiateConnectionCommandFactory::createInitiateConnectionCommand
(getCuid(), req, _fileEntry, _requestGroup, e);
e->setNoWait(true);
e->addCommand(command);
(getCuid(), getRequest(), getFileEntry(), getRequestGroup(),
getDownloadEngine());
getDownloadEngine()->setNoWait(true);
getDownloadEngine()->addCommand(command);
return true;
}
@ -113,16 +115,16 @@ bool CreateRequestCommand::prepareForRetry(time_t wait)
// called repeatedly. This means that newly created
// CreateRequestCommand is deleted one second later: This is not
// efficient. For this reason, reuse current CreateRequestCommand.
if(!_requestGroup->getPieceStorage().isNull()) {
_requestGroup->getSegmentMan()->cancelSegment(getCuid());
if(!getPieceStorage().isNull()) {
getSegmentMan()->cancelSegment(getCuid());
}
if(getLogger()->debug()) {
getLogger()->debug("CUID#%s - Reusing CreateRequestCommand",
util::itos(getCuid()).c_str());
}
SleepCommand* scom = new SleepCommand
(getCuid(), e, _requestGroup, this, wait);
e->addCommand(scom);
(getCuid(), getDownloadEngine(), getRequestGroup(), this, wait);
getDownloadEngine()->addCommand(scom);
return false;
}

View File

@ -76,7 +76,9 @@ DownloadCommand::DownloadCommand(cuid_t cuid,
DownloadEngine* e,
const SocketHandle& s):
AbstractCommand(cuid, req, fileEntry, requestGroup, e, s),
_buf(new unsigned char[BUFSIZE])
_buf(new unsigned char[BUFSIZE]),
_startupIdleTime(10),
_lowestDownloadSpeedLimit(0)
#ifdef ENABLE_MESSAGE_DIGEST
, _pieceHashValidationEnabled(false)
#endif // ENABLE_MESSAGE_DIGEST
@ -84,8 +86,7 @@ DownloadCommand::DownloadCommand(cuid_t cuid,
#ifdef ENABLE_MESSAGE_DIGEST
{
if(getOption()->getAsBool(PREF_REALTIME_CHUNK_CHECKSUM)) {
std::string algo =
_requestGroup->getDownloadContext()->getPieceHashAlgo();
const std::string& algo = getDownloadContext()->getPieceHashAlgo();
if(MessageDigestContext::supports(algo)) {
_messageDigestContext.reset(new MessageDigestContext());
_messageDigestContext->trySetAlgo(algo);
@ -97,46 +98,47 @@ DownloadCommand::DownloadCommand(cuid_t cuid,
}
#endif // ENABLE_MESSAGE_DIGEST
peerStat = req->initPeerStat();
peerStat->downloadStart();
_requestGroup->getSegmentMan()->registerPeerStat(peerStat);
_peerStat = req->initPeerStat();
_peerStat->downloadStart();
getSegmentMan()->registerPeerStat(_peerStat);
}
DownloadCommand::~DownloadCommand() {
peerStat->downloadStop();
_requestGroup->getSegmentMan()->updateFastestPeerStat(peerStat);
_peerStat->downloadStop();
getSegmentMan()->updateFastestPeerStat(_peerStat);
delete [] _buf;
}
bool DownloadCommand::executeInternal() {
if(e->getRequestGroupMan()->doesOverallDownloadSpeedExceed() ||
_requestGroup->doesDownloadSpeedExceed()) {
e->addCommand(this);
if(getDownloadEngine()->getRequestGroupMan()->doesOverallDownloadSpeedExceed()
|| getRequestGroup()->doesDownloadSpeedExceed()) {
getDownloadEngine()->addCommand(this);
disableReadCheckSocket();
return false;
}
setReadCheckSocket(socket);
SharedHandle<Segment> segment = _segments.front();
setReadCheckSocket(getSocket());
SharedHandle<Segment> segment = getSegments().front();
size_t bufSize;
if(segment->getLength() > 0) {
if(static_cast<uint64_t>(segment->getPosition()+segment->getLength()) <=
static_cast<uint64_t>(_fileEntry->getLastOffset())) {
static_cast<uint64_t>(getFileEntry()->getLastOffset())) {
bufSize = std::min(segment->getLength()-segment->getWrittenLength(),
BUFSIZE);
} else {
bufSize =
std::min(static_cast<size_t>
(_fileEntry->getLastOffset()-segment->getPositionToWrite()),
BUFSIZE);
std::min
(static_cast<size_t>
(getFileEntry()->getLastOffset()-segment->getPositionToWrite()),
BUFSIZE);
}
} else {
bufSize = BUFSIZE;
}
socket->readData(_buf, bufSize);
getSocket()->readData(_buf, bufSize);
const SharedHandle<DiskAdaptor>& diskAdaptor =
_requestGroup->getPieceStorage()->getDiskAdaptor();
getPieceStorage()->getDiskAdaptor();
const unsigned char* bufFinal;
size_t bufSizeFinal;
@ -173,24 +175,21 @@ bool DownloadCommand::executeInternal() {
if(bufSizeFinal > 0) {
segment->updateWrittenLength(bufSizeFinal);
}
peerStat->updateDownloadLength(bufSize);
_requestGroup->getSegmentMan()->updateDownloadSpeedFor(peerStat);
_peerStat->updateDownloadLength(bufSize);
getSegmentMan()->updateDownloadSpeedFor(_peerStat);
bool segmentPartComplete = false;
// Note that GrowSegment::complete() always returns false.
if(_transferEncodingDecoder.isNull() && _contentEncodingDecoder.isNull()) {
if(segment->complete() ||
segment->getPositionToWrite() == _fileEntry->getLastOffset()) {
segment->getPositionToWrite() == getFileEntry()->getLastOffset()) {
segmentPartComplete = true;
} else if(segment->getLength() == 0 && bufSize == 0 &&
!socket->wantRead() && !socket->wantWrite()) {
!getSocket()->wantRead() && !getSocket()->wantWrite()) {
segmentPartComplete = true;
}
} else if(!_transferEncodingDecoder.isNull() &&
(segment->complete() ||
segment->getPositionToWrite() == _fileEntry->getLastOffset())) {
segment->getPositionToWrite() == getFileEntry()->getLastOffset())){
// In this case, transferEncodingDecoder is used and
// Content-Length is known.
segmentPartComplete = true;
@ -202,7 +201,7 @@ bool DownloadCommand::executeInternal() {
}
if(!segmentPartComplete && bufSize == 0 &&
!socket->wantRead() && !socket->wantWrite()) {
!getSocket()->wantRead() && !getSocket()->wantWrite()) {
throw DL_RETRY_EX(EX_GOT_EOF);
}
@ -219,8 +218,7 @@ bool DownloadCommand::executeInternal() {
{
const std::string& expectedPieceHash =
_requestGroup->getDownloadContext()->getPieceHash
(segment->getIndex());
getDownloadContext()->getPieceHash(segment->getIndex());
if(_pieceHashValidationEnabled && !expectedPieceHash.empty()) {
if(segment->isHashCalculated()) {
if(getLogger()->debug()) {
@ -236,31 +234,31 @@ bool DownloadCommand::executeInternal() {
(segment, expectedPieceHash,
MessageDigestHelper::digest
(_messageDigestContext.get(),
_requestGroup->getPieceStorage()->getDiskAdaptor(),
getPieceStorage()->getDiskAdaptor(),
segment->getPosition(),
segment->getLength()));
}
} else {
_requestGroup->getSegmentMan()->completeSegment(getCuid(), segment);
getSegmentMan()->completeSegment(getCuid(), segment);
}
}
#else // !ENABLE_MESSAGE_DIGEST
_requestGroup->getSegmentMan()->completeSegment(getCuid(), segment);
getSegmentMan()->completeSegment(getCuid(), segment);
#endif // !ENABLE_MESSAGE_DIGEST
} else {
// If segment is not canceled here, in the next pipelining
// request, aria2 requests bad range
// [FileEntry->getLastOffset(), FileEntry->getLastOffset())
_requestGroup->getSegmentMan()->cancelSegment(getCuid(), segment);
getSegmentMan()->cancelSegment(getCuid(), segment);
}
checkLowestDownloadSpeed();
// this unit is going to download another segment.
return prepareForNextSegment();
} else {
checkLowestDownloadSpeed();
setWriteCheckSocketIf(socket, socket->wantWrite());
e->addCommand(this);
setWriteCheckSocketIf(getSocket(), getSocket()->wantWrite());
getDownloadEngine()->addCommand(this);
return false;
}
}
@ -268,67 +266,62 @@ bool DownloadCommand::executeInternal() {
void DownloadCommand::checkLowestDownloadSpeed() const
{
// calculate downloading speed
if(peerStat->getDownloadStartTime().difference(global::wallclock) >=
startupIdleTime) {
unsigned int nowSpeed = peerStat->calculateDownloadSpeed();
if(lowestDownloadSpeedLimit > 0 && nowSpeed <= lowestDownloadSpeedLimit) {
if(_peerStat->getDownloadStartTime().difference(global::wallclock) >=
_startupIdleTime) {
unsigned int nowSpeed = _peerStat->calculateDownloadSpeed();
if(_lowestDownloadSpeedLimit > 0 && nowSpeed <= _lowestDownloadSpeedLimit) {
throw DL_ABORT_EX2(StringFormat(EX_TOO_SLOW_DOWNLOAD_SPEED,
nowSpeed,
lowestDownloadSpeedLimit,
req->getHost().c_str()).str(),
_lowestDownloadSpeedLimit,
getRequest()->getHost().c_str()).str(),
downloadresultcode::TOO_SLOW_DOWNLOAD_SPEED);
}
}
}
bool DownloadCommand::prepareForNextSegment() {
if(_requestGroup->downloadFinished()) {
const SharedHandle<DownloadContext>& dctx =
_requestGroup->getDownloadContext();
if(getRequestGroup()->downloadFinished()) {
// Remove in-flight request here.
_fileEntry->poolRequest(req);
getFileEntry()->poolRequest(getRequest());
// If this is a single file download, and file size becomes known
// just after downloading, set total length to FileEntry object
// here.
if(dctx->getFileEntries().size() == 1) {
const SharedHandle<FileEntry>& fileEntry = dctx->getFirstFileEntry();
if(fileEntry->getLength() == 0) {
fileEntry->setLength
(_requestGroup->getPieceStorage()->getCompletedLength());
if(getDownloadContext()->getFileEntries().size() == 1) {
if(getFileEntry()->getLength() == 0) {
getFileEntry()->setLength(getPieceStorage()->getCompletedLength());
}
}
#ifdef ENABLE_MESSAGE_DIGEST
if(dctx->getPieceHashAlgo().empty()) {
if(getDownloadContext()->getPieceHashAlgo().empty()) {
SharedHandle<CheckIntegrityEntry> entry
(new ChecksumCheckIntegrityEntry(_requestGroup));
(new ChecksumCheckIntegrityEntry(getRequestGroup()));
if(entry->isValidationReady()) {
entry->initValidator();
// TODO do we need cuttrailinggarbage here?
e->getCheckIntegrityMan()->pushEntry(entry);
getDownloadEngine()->getCheckIntegrityMan()->pushEntry(entry);
}
}
// Following 2lines are needed for DownloadEngine to detect
// completed RequestGroups without 1sec delay.
e->setNoWait(true);
e->setRefreshInterval(0);
getDownloadEngine()->setNoWait(true);
getDownloadEngine()->setRefreshInterval(0);
#endif // ENABLE_MESSAGE_DIGEST
return true;
} else {
// The number of segments should be 1 in order to pass through the next
// segment.
if(_segments.size() == 1) {
SharedHandle<Segment> tempSegment = _segments.front();
if(getSegments().size() == 1) {
SharedHandle<Segment> tempSegment = getSegments().front();
if(!tempSegment->complete()) {
return prepareForRetry(0);
}
SharedHandle<SegmentMan> segmentMan = _requestGroup->getSegmentMan();
SharedHandle<Segment> nextSegment =
segmentMan->getCleanSegmentIfOwnerIsIdle
getSegmentMan()->getCleanSegmentIfOwnerIsIdle
(getCuid(), tempSegment->getIndex()+1);
if(nextSegment.isNull()) {
return prepareForRetry(0);
} else {
e->addCommand(this);
getDownloadEngine()->addCommand(this);
return false;
}
} else {
@ -345,7 +338,7 @@ void DownloadCommand::validatePieceHash(const SharedHandle<Segment>& segment,
{
if(actualPieceHash == expectedPieceHash) {
getLogger()->info(MSG_GOOD_CHUNK_CHECKSUM, actualPieceHash.c_str());
_requestGroup->getSegmentMan()->completeSegment(getCuid(), segment);
getSegmentMan()->completeSegment(getCuid(), segment);
} else {
getLogger()->info(EX_INVALID_CHUNK_CHECKSUM,
segment->getIndex(),
@ -353,7 +346,7 @@ void DownloadCommand::validatePieceHash(const SharedHandle<Segment>& segment,
expectedPieceHash.c_str(),
actualPieceHash.c_str());
segment->clear();
_requestGroup->getSegmentMan()->cancelSegment(getCuid());
getSegmentMan()->cancelSegment(getCuid());
throw DL_RETRY_EX
(StringFormat("Invalid checksum index=%d", segment->getIndex()).str());
}

View File

@ -49,9 +49,9 @@ class DownloadCommand : public AbstractCommand {
private:
unsigned char* _buf;
time_t startupIdleTime;
unsigned int lowestDownloadSpeedLimit;
SharedHandle<PeerStat> peerStat;
time_t _startupIdleTime;
unsigned int _lowestDownloadSpeedLimit;
SharedHandle<PeerStat> _peerStat;
#ifdef ENABLE_MESSAGE_DIGEST
@ -66,15 +66,14 @@ private:
const std::string& actualPieceHash);
void checkLowestDownloadSpeed() const;
protected:
SharedHandle<Decoder> _transferEncodingDecoder;
SharedHandle<Decoder> _contentEncodingDecoder;
protected:
virtual bool executeInternal();
virtual bool prepareForNextSegment();
public:
DownloadCommand(cuid_t cuid,
const SharedHandle<Request>& req,
@ -84,16 +83,28 @@ public:
const SharedHandle<SocketCore>& s);
virtual ~DownloadCommand();
const SharedHandle<Decoder>& getTransferEncodingDecoder() const
{
return _transferEncodingDecoder;
}
void setTransferEncodingDecoder(const SharedHandle<Decoder>& decoder);
const SharedHandle<Decoder>& getContentEncodingDecoder() const
{
return _contentEncodingDecoder;
}
void setContentEncodingDecoder(const SharedHandle<Decoder>& decoder);
void setStartupIdleTime(time_t startupIdleTime) {
this->startupIdleTime = startupIdleTime;
void setStartupIdleTime(time_t startupIdleTime)
{
_startupIdleTime = startupIdleTime;
}
void setLowestDownloadSpeedLimit(unsigned int lowestDownloadSpeedLimit) {
this->lowestDownloadSpeedLimit = lowestDownloadSpeedLimit;
void setLowestDownloadSpeedLimit(unsigned int lowestDownloadSpeedLimit)
{
_lowestDownloadSpeedLimit = lowestDownloadSpeedLimit;
}
};

View File

@ -62,7 +62,7 @@ FtpDownloadCommand::FtpDownloadCommand
const SocketHandle& ctrlSocket)
:DownloadCommand(cuid, req, fileEntry, requestGroup, e, dataSocket),
_ftpConnection(ftpConnection),
ctrlSocket(ctrlSocket) {}
_ctrlSocket(ctrlSocket) {}
FtpDownloadCommand::~FtpDownloadCommand() {}
@ -71,14 +71,14 @@ bool FtpDownloadCommand::prepareForNextSegment()
{
if(getOption()->getAsBool(PREF_FTP_REUSE_CONNECTION) &&
static_cast<uint64_t>
(_fileEntry->gtoloff(_segments.front()->getPositionToWrite())) ==
_fileEntry->getLength()) {
(getFileEntry()->gtoloff(getSegments().front()->getPositionToWrite())) ==
getFileEntry()->getLength()) {
Command* command = new FtpFinishDownloadCommand
(getCuid(), req, _fileEntry, _requestGroup, _ftpConnection, e,
ctrlSocket);
e->addCommand(command);
(getCuid(), getRequest(), getFileEntry(), getRequestGroup(),
_ftpConnection, getDownloadEngine(), _ctrlSocket);
getDownloadEngine()->addCommand(command);
if(_requestGroup->downloadFinished()) {
if(getRequestGroup()->downloadFinished()) {
// To run checksum checking, we had to call following function here.
DownloadCommand::prepareForNextSegment();
}

View File

@ -45,7 +45,7 @@ class FtpDownloadCommand : public DownloadCommand {
private:
SharedHandle<FtpConnection> _ftpConnection;
SharedHandle<SocketCore> ctrlSocket;
SharedHandle<SocketCore> _ctrlSocket;
protected:
virtual bool prepareForNextSegment();
public:

View File

@ -71,13 +71,13 @@ FtpFinishDownloadCommand::FtpFinishDownloadCommand
// AbstractCommand::_segments is empty.
bool FtpFinishDownloadCommand::execute()
{
if(_requestGroup->isHaltRequested()) {
if(getRequestGroup()->isHaltRequested()) {
return true;
}
try {
unsigned int status = _ftpConnection->receiveResponse();
if(status == 0) {
e->addCommand(this);
getDownloadEngine()->addCommand(this);
return false;
}
if(status != 226) {
@ -86,13 +86,14 @@ bool FtpFinishDownloadCommand::execute()
if(getOption()->getAsBool(PREF_FTP_REUSE_CONNECTION)) {
std::map<std::string, std::string> options;
options["baseWorkingDir"] = _ftpConnection->getBaseWorkingDir();
e->poolSocket(req, _ftpConnection->getUser(), createProxyRequest(),
socket, options);
getDownloadEngine()->poolSocket
(getRequest(), _ftpConnection->getUser(), createProxyRequest(),
getSocket(), options);
}
} catch(RecoverableException& e) {
getLogger()->info(EX_EXCEPTION_CAUGHT, e);
}
if(_requestGroup->downloadFinished()) {
if(getRequestGroup()->downloadFinished()) {
return true;
} else {
return prepareForRetry(0);

View File

@ -80,16 +80,16 @@ Command* FtpInitiateConnectionCommand::createNextCommand
if(!proxyRequest.isNull()) {
std::map<std::string, std::string> options;
SharedHandle<SocketCore> pooledSocket;
std::string proxyMethod = resolveProxyMethod(req->getProtocol());
std::string proxyMethod = resolveProxyMethod(getRequest()->getProtocol());
if(proxyMethod == V_GET) {
pooledSocket = e->popPooledSocket
(req->getHost(), req->getPort(),
pooledSocket = getDownloadEngine()->popPooledSocket
(getRequest()->getHost(), getRequest()->getPort(),
proxyRequest->getHost(), proxyRequest->getPort());
} else {
pooledSocket = e->popPooledSocket
(options, req->getHost(), req->getPort(),
e->getAuthConfigFactory()->createAuthConfig
(req, getOption().get())->getUser(),
pooledSocket = getDownloadEngine()->popPooledSocket
(options, getRequest()->getHost(), getRequest()->getPort(),
getDownloadEngine()->getAuthConfigFactory()->createAuthConfig
(getRequest(), getOption().get())->getUser(),
proxyRequest->getHost(), proxyRequest->getPort());
}
if(pooledSocket.isNull()) {
@ -97,26 +97,27 @@ Command* FtpInitiateConnectionCommand::createNextCommand
getLogger()->info(MSG_CONNECTING_TO_SERVER,
util::itos(getCuid()).c_str(), addr.c_str(), port);
}
socket.reset(new SocketCore());
socket->establishConnection(addr, port);
createSocket();
getSocket()->establishConnection(addr, port);
if(proxyMethod == V_GET) {
// Use GET for FTP via HTTP proxy.
req->setMethod(Request::METHOD_GET);
getRequest()->setMethod(Request::METHOD_GET);
SharedHandle<HttpConnection> hc
(new HttpConnection(getCuid(), socket, getOption().get()));
(new HttpConnection(getCuid(), getSocket(), getOption().get()));
HttpRequestCommand* c =
new HttpRequestCommand(getCuid(), req, _fileEntry,
_requestGroup, hc, e, socket);
new HttpRequestCommand(getCuid(), getRequest(), getFileEntry(),
getRequestGroup(), hc, getDownloadEngine(),
getSocket());
c->setConnectedAddr(hostname, addr, port);
c->setProxyRequest(proxyRequest);
command = c;
} else if(proxyMethod == V_TUNNEL) {
FtpTunnelRequestCommand* c =
new FtpTunnelRequestCommand(getCuid(), req, _fileEntry,
_requestGroup, e,
proxyRequest, socket);
new FtpTunnelRequestCommand(getCuid(), getRequest(), getFileEntry(),
getRequestGroup(), getDownloadEngine(),
proxyRequest, getSocket());
c->setConnectedAddr(hostname, addr, port);
command = c;
} else {
@ -126,19 +127,21 @@ Command* FtpInitiateConnectionCommand::createNextCommand
} else {
if(proxyMethod == V_TUNNEL) {
command =
new FtpNegotiationCommand(getCuid(), req, _fileEntry,
_requestGroup, e, pooledSocket,
new FtpNegotiationCommand(getCuid(), getRequest(), getFileEntry(),
getRequestGroup(), getDownloadEngine(),
pooledSocket,
FtpNegotiationCommand::SEQ_SEND_CWD,
options["baseWorkingDir"]);
} else if(proxyMethod == V_GET) {
// Use GET for FTP via HTTP proxy.
req->setMethod(Request::METHOD_GET);
getRequest()->setMethod(Request::METHOD_GET);
SharedHandle<HttpConnection> hc
(new HttpConnection(getCuid(), pooledSocket, getOption().get()));
HttpRequestCommand* c =
new HttpRequestCommand(getCuid(), req, _fileEntry,
_requestGroup, hc, e, pooledSocket);
new HttpRequestCommand(getCuid(), getRequest(), getFileEntry(),
getRequestGroup(), hc, getDownloadEngine(),
pooledSocket);
c->setProxyRequest(proxyRequest);
command = c;
} else {
@ -149,25 +152,29 @@ Command* FtpInitiateConnectionCommand::createNextCommand
} else {
std::map<std::string, std::string> options;
SharedHandle<SocketCore> pooledSocket =
e->popPooledSocket(options, resolvedAddresses, req->getPort(),
e->getAuthConfigFactory()->createAuthConfig
(req, getOption().get())->getUser());
getDownloadEngine()->popPooledSocket
(options, resolvedAddresses,
getRequest()->getPort(),
getDownloadEngine()->getAuthConfigFactory()->createAuthConfig
(getRequest(), getOption().get())->getUser());
if(pooledSocket.isNull()) {
if(getLogger()->info()) {
getLogger()->info(MSG_CONNECTING_TO_SERVER,
util::itos(getCuid()).c_str(), addr.c_str(), port);
}
socket.reset(new SocketCore());
socket->establishConnection(addr, port);
createSocket();
getSocket()->establishConnection(addr, port);
FtpNegotiationCommand* c =
new FtpNegotiationCommand(getCuid(), req, _fileEntry,
_requestGroup, e, socket);
new FtpNegotiationCommand(getCuid(), getRequest(), getFileEntry(),
getRequestGroup(), getDownloadEngine(),
getSocket());
c->setConnectedAddr(hostname, addr, port);
command = c;
} else {
command =
new FtpNegotiationCommand(getCuid(), req, _fileEntry,
_requestGroup, e, pooledSocket,
new FtpNegotiationCommand(getCuid(), getRequest(), getFileEntry(),
getRequestGroup(), getDownloadEngine(),
pooledSocket,
FtpNegotiationCommand::SEQ_SEND_CWD,
options["baseWorkingDir"]);
}

View File

@ -83,104 +83,105 @@ FtpNegotiationCommand::FtpNegotiationCommand
const SharedHandle<FileEntry>& fileEntry,
RequestGroup* requestGroup,
DownloadEngine* e,
const SocketHandle& s,
const SocketHandle& socket,
Seq seq,
const std::string& baseWorkingDir):
AbstractCommand(cuid, req, fileEntry, requestGroup, e, s), sequence(seq),
ftp(new FtpConnection(cuid, socket, req,
AbstractCommand(cuid, req, fileEntry, requestGroup, e, socket), _sequence(seq),
_ftp(new FtpConnection(cuid, socket, req,
e->getAuthConfigFactory()->createAuthConfig
(req, requestGroup->getOption().get()),
getOption().get()))
{
ftp->setBaseWorkingDir(baseWorkingDir);
_ftp->setBaseWorkingDir(baseWorkingDir);
if(seq == SEQ_RECV_GREETING) {
setTimeout(getOption()->getAsInt(PREF_CONNECT_TIMEOUT));
}
disableReadCheckSocket();
setWriteCheckSocket(socket);
setWriteCheckSocket(getSocket());
}
FtpNegotiationCommand::~FtpNegotiationCommand() {}
bool FtpNegotiationCommand::executeInternal() {
while(processSequence(_segments.front()));
if(sequence == SEQ_RETRY) {
while(processSequence(getSegments().front()));
if(_sequence == SEQ_RETRY) {
return prepareForRetry(0);
} else if(sequence == SEQ_NEGOTIATION_COMPLETED) {
} else if(_sequence == SEQ_NEGOTIATION_COMPLETED) {
FtpDownloadCommand* command =
new FtpDownloadCommand
(getCuid(), req, _fileEntry, _requestGroup, ftp, e, dataSocket, socket);
(getCuid(), getRequest(), getFileEntry(), getRequestGroup(), _ftp,
getDownloadEngine(), _dataSocket, getSocket());
command->setStartupIdleTime(getOption()->getAsInt(PREF_STARTUP_IDLE_TIME));
command->setLowestDownloadSpeedLimit
(getOption()->getAsInt(PREF_LOWEST_SPEED_LIMIT));
if(!_fileEntry->isSingleHostMultiConnectionEnabled()) {
_fileEntry->removeURIWhoseHostnameIs(req->getHost());
if(!getFileEntry()->isSingleHostMultiConnectionEnabled()) {
getFileEntry()->removeURIWhoseHostnameIs(getRequest()->getHost());
}
_requestGroup->getURISelector()->tuneDownloadCommand
(_fileEntry->getRemainingUris(), command);
e->addCommand(command);
getRequestGroup()->getURISelector()->tuneDownloadCommand
(getFileEntry()->getRemainingUris(), command);
getDownloadEngine()->addCommand(command);
return true;
} else if(sequence == SEQ_HEAD_OK ||
sequence == SEQ_DOWNLOAD_ALREADY_COMPLETED) {
} else if(_sequence == SEQ_HEAD_OK ||
_sequence == SEQ_DOWNLOAD_ALREADY_COMPLETED) {
return true;
} else if(sequence == SEQ_FILE_PREPARATION) {
} else if(_sequence == SEQ_FILE_PREPARATION) {
if(getOption()->getAsBool(PREF_FTP_PASV)) {
sequence = SEQ_SEND_PASV;
_sequence = SEQ_SEND_PASV;
} else {
sequence = SEQ_PREPARE_SERVER_SOCKET;
_sequence = SEQ_PREPARE_SERVER_SOCKET;
}
return false;
} else if(sequence == SEQ_EXIT) {
} else if(_sequence == SEQ_EXIT) {
return true;
} else {
e->addCommand(this);
getDownloadEngine()->addCommand(this);
return false;
}
}
bool FtpNegotiationCommand::recvGreeting() {
if(!checkIfConnectionEstablished
(socket, _connectedHostname, _connectedAddr, _connectedPort)) {
sequence = SEQ_EXIT;
(getSocket(), _connectedHostname, _connectedAddr, _connectedPort)) {
_sequence = SEQ_EXIT;
return false;
}
setTimeout(_requestGroup->getTimeout());
setTimeout(getRequestGroup()->getTimeout());
//socket->setBlockingMode();
disableWriteCheckSocket();
setReadCheckSocket(socket);
setReadCheckSocket(getSocket());
unsigned int status = ftp->receiveResponse();
unsigned int status = _ftp->receiveResponse();
if(status == 0) {
return false;
}
if(status != 220) {
throw DL_ABORT_EX(EX_CONNECTION_FAILED);
}
sequence = SEQ_SEND_USER;
_sequence = SEQ_SEND_USER;
return true;
}
bool FtpNegotiationCommand::sendUser() {
if(ftp->sendUser()) {
if(_ftp->sendUser()) {
disableWriteCheckSocket();
sequence = SEQ_RECV_USER;
_sequence = SEQ_RECV_USER;
} else {
setWriteCheckSocket(socket);
setWriteCheckSocket(getSocket());
}
return false;
}
bool FtpNegotiationCommand::recvUser() {
unsigned int status = ftp->receiveResponse();
unsigned int status = _ftp->receiveResponse();
switch(status) {
case 0:
return false;
case 230:
sequence = SEQ_SEND_TYPE;
_sequence = SEQ_SEND_TYPE;
break;
case 331:
sequence = SEQ_SEND_PASS;
_sequence = SEQ_SEND_PASS;
break;
default:
throw DL_ABORT_EX(StringFormat(EX_BAD_STATUS, status).str());
@ -189,56 +190,56 @@ bool FtpNegotiationCommand::recvUser() {
}
bool FtpNegotiationCommand::sendPass() {
if(ftp->sendPass()) {
if(_ftp->sendPass()) {
disableWriteCheckSocket();
sequence = SEQ_RECV_PASS;
_sequence = SEQ_RECV_PASS;
} else {
setWriteCheckSocket(socket);
setWriteCheckSocket(getSocket());
}
return false;
}
bool FtpNegotiationCommand::recvPass() {
unsigned int status = ftp->receiveResponse();
unsigned int status = _ftp->receiveResponse();
if(status == 0) {
return false;
}
if(status != 230) {
throw DL_ABORT_EX(StringFormat(EX_BAD_STATUS, status).str());
}
sequence = SEQ_SEND_TYPE;
_sequence = SEQ_SEND_TYPE;
return true;
}
bool FtpNegotiationCommand::sendType() {
if(ftp->sendType()) {
if(_ftp->sendType()) {
disableWriteCheckSocket();
sequence = SEQ_RECV_TYPE;
_sequence = SEQ_RECV_TYPE;
} else {
setWriteCheckSocket(socket);
setWriteCheckSocket(getSocket());
}
return false;
}
bool FtpNegotiationCommand::recvType() {
unsigned int status = ftp->receiveResponse();
unsigned int status = _ftp->receiveResponse();
if(status == 0) {
return false;
}
if(status != 200) {
throw DL_ABORT_EX(StringFormat(EX_BAD_STATUS, status).str());
}
sequence = SEQ_SEND_PWD;
_sequence = SEQ_SEND_PWD;
return true;
}
bool FtpNegotiationCommand::sendPwd()
{
if(ftp->sendPwd()) {
if(_ftp->sendPwd()) {
disableWriteCheckSocket();
sequence = SEQ_RECV_PWD;
_sequence = SEQ_RECV_PWD;
} else {
setWriteCheckSocket(socket);
setWriteCheckSocket(getSocket());
}
return false;
}
@ -246,42 +247,42 @@ bool FtpNegotiationCommand::sendPwd()
bool FtpNegotiationCommand::recvPwd()
{
std::string pwd;
unsigned int status = ftp->receivePwdResponse(pwd);
unsigned int status = _ftp->receivePwdResponse(pwd);
if(status == 0) {
return false;
}
if(status != 257) {
throw DL_ABORT_EX(StringFormat(EX_BAD_STATUS, status).str());
}
ftp->setBaseWorkingDir(pwd);
_ftp->setBaseWorkingDir(pwd);
if(getLogger()->info()) {
getLogger()->info("CUID#%s - base working directory is '%s'",
util::itos(getCuid()).c_str(), pwd.c_str());
}
sequence = SEQ_SEND_CWD;
_sequence = SEQ_SEND_CWD;
return true;
}
bool FtpNegotiationCommand::sendCwd() {
// Calling setReadCheckSocket() is needed when the socket is reused,
setReadCheckSocket(socket);
if(ftp->sendCwd()) {
setReadCheckSocket(getSocket());
if(_ftp->sendCwd()) {
disableWriteCheckSocket();
sequence = SEQ_RECV_CWD;
_sequence = SEQ_RECV_CWD;
} else {
setWriteCheckSocket(socket);
setWriteCheckSocket(getSocket());
}
return false;
}
bool FtpNegotiationCommand::recvCwd() {
unsigned int status = ftp->receiveResponse();
unsigned int status = _ftp->receiveResponse();
if(status == 0) {
return false;
}
if(status != 250) {
poolConnection();
_requestGroup->increaseAndValidateFileNotFoundCount();
getRequestGroup()->increaseAndValidateFileNotFoundCount();
if (status == 550)
throw DL_ABORT_EX2(MSG_RESOURCE_NOT_FOUND,
downloadresultcode::RESOURCE_NOT_FOUND);
@ -289,20 +290,20 @@ bool FtpNegotiationCommand::recvCwd() {
throw DL_ABORT_EX(StringFormat(EX_BAD_STATUS, status).str());
}
if(getOption()->getAsBool(PREF_REMOTE_TIME)) {
sequence = SEQ_SEND_MDTM;
_sequence = SEQ_SEND_MDTM;
} else {
sequence = SEQ_SEND_SIZE;
_sequence = SEQ_SEND_SIZE;
}
return true;
}
bool FtpNegotiationCommand::sendMdtm()
{
if(ftp->sendMdtm()) {
if(_ftp->sendMdtm()) {
disableWriteCheckSocket();
sequence = SEQ_RECV_MDTM;
_sequence = SEQ_RECV_MDTM;
} else {
setWriteCheckSocket(socket);
setWriteCheckSocket(getSocket());
}
return false;
}
@ -310,13 +311,13 @@ bool FtpNegotiationCommand::sendMdtm()
bool FtpNegotiationCommand::recvMdtm()
{
Time lastModifiedTime = Time::null();
unsigned int status = ftp->receiveMdtmResponse(lastModifiedTime);
unsigned int status = _ftp->receiveMdtmResponse(lastModifiedTime);
if(status == 0) {
return false;
}
if(status == 213) {
if(lastModifiedTime.good()) {
_requestGroup->updateLastModifiedTime(lastModifiedTime);
getRequestGroup()->updateLastModifiedTime(lastModifiedTime);
time_t t = lastModifiedTime.getTime();
struct tm* tms = gmtime(&t); // returned struct is statically allocated.
if(tms) {
@ -340,84 +341,87 @@ bool FtpNegotiationCommand::recvMdtm()
util::itos(getCuid()).c_str());
}
}
sequence = SEQ_SEND_SIZE;
_sequence = SEQ_SEND_SIZE;
return true;
}
bool FtpNegotiationCommand::sendSize() {
if(ftp->sendSize()) {
if(_ftp->sendSize()) {
disableWriteCheckSocket();
sequence = SEQ_RECV_SIZE;
_sequence = SEQ_RECV_SIZE;
} else {
setWriteCheckSocket(socket);
setWriteCheckSocket(getSocket());
}
return false;
}
bool FtpNegotiationCommand::onFileSizeDetermined(uint64_t totalLength)
{
_fileEntry->setLength(totalLength);
if(_fileEntry->getPath().empty()) {
_fileEntry->setPath
getFileEntry()->setLength(totalLength);
if(getFileEntry()->getPath().empty()) {
getFileEntry()->setPath
(util::applyDir
(getDownloadContext()->getDir(),
util::fixTaintedBasename(util::percentDecode(req->getFile()))));
util::fixTaintedBasename
(util::percentDecode(getRequest()->getFile()))));
}
_requestGroup->preDownloadProcessing();
if(e->getRequestGroupMan()->isSameFileBeingDownloaded(_requestGroup)) {
getRequestGroup()->preDownloadProcessing();
if(getDownloadEngine()->getRequestGroupMan()->
isSameFileBeingDownloaded(getRequestGroup())) {
throw DOWNLOAD_FAILURE_EXCEPTION
(StringFormat(EX_DUPLICATE_FILE_DOWNLOAD,
_requestGroup->getFirstFilePath().c_str()).str());
getRequestGroup()->getFirstFilePath().c_str()).str());
}
if(totalLength == 0) {
if(getOption()->getAsBool(PREF_FTP_PASV)) {
sequence = SEQ_SEND_PASV;
_sequence = SEQ_SEND_PASV;
} else {
sequence = SEQ_PREPARE_SERVER_SOCKET;
_sequence = SEQ_PREPARE_SERVER_SOCKET;
}
if(getOption()->getAsBool(PREF_DRY_RUN)) {
_requestGroup->initPieceStorage();
getRequestGroup()->initPieceStorage();
onDryRunFileFound();
return false;
}
if(_requestGroup->downloadFinishedByFileLength()) {
_requestGroup->initPieceStorage();
_requestGroup->getPieceStorage()->markAllPiecesDone();
sequence = SEQ_DOWNLOAD_ALREADY_COMPLETED;
if(getRequestGroup()->downloadFinishedByFileLength()) {
getRequestGroup()->initPieceStorage();
getPieceStorage()->markAllPiecesDone();
_sequence = SEQ_DOWNLOAD_ALREADY_COMPLETED;
getLogger()->notice(MSG_DOWNLOAD_ALREADY_COMPLETED,
util::itos(_requestGroup->getGID()).c_str(),
_requestGroup->getFirstFilePath().c_str());
util::itos(getRequestGroup()->getGID()).c_str(),
getRequestGroup()->getFirstFilePath().c_str());
poolConnection();
return false;
}
_requestGroup->shouldCancelDownloadForSafety();
_requestGroup->initPieceStorage();
_requestGroup->getPieceStorage()->getDiskAdaptor()->initAndOpenFile();
getRequestGroup()->shouldCancelDownloadForSafety();
getRequestGroup()->initPieceStorage();
getPieceStorage()->getDiskAdaptor()->initAndOpenFile();
if(getDownloadContext()->knowsTotalLength()) {
sequence = SEQ_DOWNLOAD_ALREADY_COMPLETED;
_sequence = SEQ_DOWNLOAD_ALREADY_COMPLETED;
poolConnection();
return false;
}
// We have to make sure that command that has Request object must
// have segment after PieceStorage is initialized. See
// AbstractCommand::execute()
_requestGroup->getSegmentMan()->getSegment(getCuid(), 0);
getSegmentMan()->getSegment(getCuid(), 0);
return true;
} else {
_requestGroup->adjustFilename
(SharedHandle<BtProgressInfoFile>(new DefaultBtProgressInfoFile
(_requestGroup->getDownloadContext(),
SharedHandle<PieceStorage>(),
getOption().get())));
_requestGroup->initPieceStorage();
getRequestGroup()->adjustFilename
(SharedHandle<BtProgressInfoFile>
(new DefaultBtProgressInfoFile
(getDownloadContext(),
SharedHandle<PieceStorage>(),
getOption().get())));
getRequestGroup()->initPieceStorage();
if(getOption()->getAsBool(PREF_DRY_RUN)) {
onDryRunFileFound();
@ -425,27 +429,28 @@ bool FtpNegotiationCommand::onFileSizeDetermined(uint64_t totalLength)
}
BtProgressInfoFileHandle infoFile
(new DefaultBtProgressInfoFile(_requestGroup->getDownloadContext(),
_requestGroup->getPieceStorage(),
(new DefaultBtProgressInfoFile(getDownloadContext(),
getPieceStorage(),
getOption().get()));
if(!infoFile->exists() && _requestGroup->downloadFinishedByFileLength()) {
_requestGroup->getPieceStorage()->markAllPiecesDone();
if(!infoFile->exists() &&
getRequestGroup()->downloadFinishedByFileLength()) {
getPieceStorage()->markAllPiecesDone();
sequence = SEQ_DOWNLOAD_ALREADY_COMPLETED;
_sequence = SEQ_DOWNLOAD_ALREADY_COMPLETED;
getLogger()->notice(MSG_DOWNLOAD_ALREADY_COMPLETED,
util::itos(_requestGroup->getGID()).c_str(),
_requestGroup->getFirstFilePath().c_str());
util::itos(getRequestGroup()->getGID()).c_str(),
getRequestGroup()->getFirstFilePath().c_str());
poolConnection();
return false;
}
_requestGroup->loadAndOpenFile(infoFile);
getRequestGroup()->loadAndOpenFile(infoFile);
// We have to make sure that command that has Request object must
// have segment after PieceStorage is initialized. See
// AbstractCommand::execute()
_requestGroup->getSegmentMan()->getSegment(getCuid(), 0);
getSegmentMan()->getSegment(getCuid(), 0);
prepareForNextAction(this);
@ -456,7 +461,7 @@ bool FtpNegotiationCommand::onFileSizeDetermined(uint64_t totalLength)
bool FtpNegotiationCommand::recvSize() {
uint64_t size = 0;
unsigned int status = ftp->receiveSizeResponse(size);
unsigned int status = _ftp->receiveSizeResponse(size);
if(status == 0) {
return false;
}
@ -467,13 +472,13 @@ bool FtpNegotiationCommand::recvSize() {
(StringFormat(EX_TOO_LARGE_FILE,
util::uitos(size, true).c_str()).str());
}
if(_requestGroup->getPieceStorage().isNull()) {
if(getPieceStorage().isNull()) {
sequence = SEQ_FILE_PREPARATION;
_sequence = SEQ_FILE_PREPARATION;
return onFileSizeDetermined(size);
} else {
_requestGroup->validateTotalLength(_fileEntry->getLength(), size);
getRequestGroup()->validateTotalLength(getFileEntry()->getLength(), size);
}
} else {
@ -484,7 +489,7 @@ bool FtpNegotiationCommand::recvSize() {
// Even if one of the other servers waiting in the queue supports SIZE
// command, resuming and segmented downloading are disabled when the first
// contacted FTP server doesn't support it.
if(_requestGroup->getPieceStorage().isNull()) {
if(getPieceStorage().isNull()) {
getDownloadContext()->markTotalLengthIsUnknown();
return onFileSizeDetermined(0);
@ -493,62 +498,62 @@ bool FtpNegotiationCommand::recvSize() {
// wrong file to be downloaded if user-specified URL is wrong.
}
if(getOption()->getAsBool(PREF_FTP_PASV)) {
sequence = SEQ_SEND_PASV;
_sequence = SEQ_SEND_PASV;
} else {
sequence = SEQ_PREPARE_SERVER_SOCKET;
_sequence = SEQ_PREPARE_SERVER_SOCKET;
}
return true;
}
void FtpNegotiationCommand::afterFileAllocation()
{
setReadCheckSocket(socket);
setReadCheckSocket(getSocket());
}
bool FtpNegotiationCommand::prepareServerSocket()
{
serverSocket = ftp->createServerSocket();
sequence = SEQ_SEND_PORT;
_serverSocket = _ftp->createServerSocket();
_sequence = SEQ_SEND_PORT;
return true;
}
bool FtpNegotiationCommand::sendPort() {
afterFileAllocation();
if(ftp->sendPort(serverSocket)) {
if(_ftp->sendPort(_serverSocket)) {
disableWriteCheckSocket();
sequence = SEQ_RECV_PORT;
_sequence = SEQ_RECV_PORT;
} else {
setWriteCheckSocket(socket);
setWriteCheckSocket(getSocket());
}
return false;
}
bool FtpNegotiationCommand::recvPort() {
unsigned int status = ftp->receiveResponse();
unsigned int status = _ftp->receiveResponse();
if(status == 0) {
return false;
}
if(status != 200) {
throw DL_ABORT_EX(StringFormat(EX_BAD_STATUS, status).str());
}
sequence = SEQ_SEND_REST;
_sequence = SEQ_SEND_REST;
return true;
}
bool FtpNegotiationCommand::sendPasv() {
afterFileAllocation();
if(ftp->sendPasv()) {
if(_ftp->sendPasv()) {
disableWriteCheckSocket();
sequence = SEQ_RECV_PASV;
_sequence = SEQ_RECV_PASV;
} else {
setWriteCheckSocket(socket);
setWriteCheckSocket(getSocket());
}
return false;
}
bool FtpNegotiationCommand::recvPasv() {
std::pair<std::string, uint16_t> dest;
unsigned int status = ftp->receivePasvResponse(dest);
unsigned int status = _ftp->receivePasvResponse(dest);
if(status == 0) {
return false;
}
@ -558,7 +563,7 @@ bool FtpNegotiationCommand::recvPasv() {
// TODO Should we check to see that dest.first is not in noProxy list?
if(isProxyDefined()) {
_dataConnAddr = dest;
sequence = SEQ_RESOLVE_PROXY;
_sequence = SEQ_RESOLVE_PROXY;
return true;
} else {
// make a data connection to the server.
@ -567,11 +572,11 @@ bool FtpNegotiationCommand::recvPasv() {
dest.first.c_str(),
dest.second);
}
dataSocket.reset(new SocketCore());
dataSocket->establishConnection(dest.first, dest.second);
_dataSocket.reset(new SocketCore());
_dataSocket->establishConnection(dest.first, dest.second);
disableReadCheckSocket();
setWriteCheckSocket(dataSocket);
sequence = SEQ_SEND_REST_PASV;
setWriteCheckSocket(_dataSocket);
_sequence = SEQ_SEND_REST_PASV;
return false;
}
}
@ -589,27 +594,29 @@ bool FtpNegotiationCommand::resolveProxy()
getLogger()->info(MSG_CONNECTING_TO_SERVER, util::itos(getCuid()).c_str(),
_proxyAddr.c_str(), proxyReq->getPort());
}
dataSocket.reset(new SocketCore());
dataSocket->establishConnection(_proxyAddr, proxyReq->getPort());
_dataSocket.reset(new SocketCore());
_dataSocket->establishConnection(_proxyAddr, proxyReq->getPort());
disableReadCheckSocket();
setWriteCheckSocket(dataSocket);
_http.reset(new HttpConnection(getCuid(), dataSocket, getOption().get()));
sequence = SEQ_SEND_TUNNEL_REQUEST;
setWriteCheckSocket(_dataSocket);
_http.reset(new HttpConnection(getCuid(), _dataSocket, getOption().get()));
_sequence = SEQ_SEND_TUNNEL_REQUEST;
return false;
}
bool FtpNegotiationCommand::sendTunnelRequest()
{
if(_http->sendBufferIsEmpty()) {
if(dataSocket->isReadable(0)) {
std::string error = socket->getSocketError();
if(_dataSocket->isReadable(0)) {
std::string error = getSocket()->getSocketError();
if(!error.empty()) {
SharedHandle<Request> proxyReq = createProxyRequest();
e->markBadIPAddress(proxyReq->getHost(),_proxyAddr,proxyReq->getPort());
std::string nextProxyAddr = e->findCachedIPAddress
getDownloadEngine()->markBadIPAddress(proxyReq->getHost(),
_proxyAddr,proxyReq->getPort());
std::string nextProxyAddr = getDownloadEngine()->findCachedIPAddress
(proxyReq->getHost(), proxyReq->getPort());
if(nextProxyAddr.empty()) {
e->removeCachedIPAddress(proxyReq->getHost(), proxyReq->getPort());
getDownloadEngine()->removeCachedIPAddress(proxyReq->getHost(),
proxyReq->getPort());
throw DL_RETRY_EX
(StringFormat(MSG_ESTABLISHING_CONNECTION_FAILED,
error.c_str()).str());
@ -625,7 +632,7 @@ bool FtpNegotiationCommand::sendTunnelRequest()
util::itos(getCuid()).c_str(),
_proxyAddr.c_str(), proxyReq->getPort());
}
dataSocket->establishConnection(_proxyAddr, proxyReq->getPort());
_dataSocket->establishConnection(_proxyAddr, proxyReq->getPort());
return false;
}
}
@ -644,11 +651,11 @@ bool FtpNegotiationCommand::sendTunnelRequest()
}
if(_http->sendBufferIsEmpty()) {
disableWriteCheckSocket();
setReadCheckSocket(dataSocket);
sequence = SEQ_RECV_TUNNEL_RESPONSE;
setReadCheckSocket(_dataSocket);
_sequence = SEQ_RECV_TUNNEL_RESPONSE;
return false;
} else {
setWriteCheckSocket(dataSocket);
setWriteCheckSocket(_dataSocket);
return false;
}
}
@ -662,29 +669,29 @@ bool FtpNegotiationCommand::recvTunnelResponse()
if(httpResponse->getResponseStatus() != HttpHeader::S200) {
throw DL_RETRY_EX(EX_PROXY_CONNECTION_FAILED);
}
sequence = SEQ_SEND_REST_PASV;
_sequence = SEQ_SEND_REST_PASV;
return true;
}
bool FtpNegotiationCommand::sendRestPasv(const SharedHandle<Segment>& segment) {
//dataSocket->setBlockingMode();
setReadCheckSocket(socket);
//_dataSocket->setBlockingMode();
setReadCheckSocket(getSocket());
disableWriteCheckSocket();
return sendRest(segment);
}
bool FtpNegotiationCommand::sendRest(const SharedHandle<Segment>& segment) {
if(ftp->sendRest(segment)) {
if(_ftp->sendRest(segment)) {
disableWriteCheckSocket();
sequence = SEQ_RECV_REST;
_sequence = SEQ_RECV_REST;
} else {
setWriteCheckSocket(socket);
setWriteCheckSocket(getSocket());
}
return false;
}
bool FtpNegotiationCommand::recvRest(const SharedHandle<Segment>& segment) {
unsigned int status = ftp->receiveResponse();
unsigned int status = _ftp->receiveResponse();
if(status == 0) {
return false;
}
@ -696,27 +703,27 @@ bool FtpNegotiationCommand::recvRest(const SharedHandle<Segment>& segment) {
downloadresultcode::CANNOT_RESUME);
}
}
sequence = SEQ_SEND_RETR;
_sequence = SEQ_SEND_RETR;
return true;
}
bool FtpNegotiationCommand::sendRetr() {
if(ftp->sendRetr()) {
if(_ftp->sendRetr()) {
disableWriteCheckSocket();
sequence = SEQ_RECV_RETR;
_sequence = SEQ_RECV_RETR;
} else {
setWriteCheckSocket(socket);
setWriteCheckSocket(getSocket());
}
return false;
}
bool FtpNegotiationCommand::recvRetr() {
unsigned int status = ftp->receiveResponse();
unsigned int status = _ftp->receiveResponse();
if(status == 0) {
return false;
}
if(status != 150 && status != 125) {
_requestGroup->increaseAndValidateFileNotFoundCount();
getRequestGroup()->increaseAndValidateFileNotFoundCount();
if (status == 550)
throw DL_ABORT_EX2(MSG_RESOURCE_NOT_FOUND,
downloadresultcode::RESOURCE_NOT_FOUND);
@ -724,12 +731,12 @@ bool FtpNegotiationCommand::recvRetr() {
throw DL_ABORT_EX(StringFormat(EX_BAD_STATUS, status).str());
}
if(getOption()->getAsBool(PREF_FTP_PASV)) {
sequence = SEQ_NEGOTIATION_COMPLETED;
_sequence = SEQ_NEGOTIATION_COMPLETED;
return false;
} else {
disableReadCheckSocket();
setReadCheckSocket(serverSocket);
sequence = SEQ_WAIT_CONNECTION;
setReadCheckSocket(_serverSocket);
_sequence = SEQ_WAIT_CONNECTION;
return false;
}
}
@ -737,17 +744,17 @@ bool FtpNegotiationCommand::recvRetr() {
bool FtpNegotiationCommand::waitConnection()
{
disableReadCheckSocket();
setReadCheckSocket(socket);
dataSocket.reset(serverSocket->acceptConnection());
dataSocket->setNonBlockingMode();
sequence = SEQ_NEGOTIATION_COMPLETED;
setReadCheckSocket(getSocket());
_dataSocket.reset(_serverSocket->acceptConnection());
_dataSocket->setNonBlockingMode();
_sequence = SEQ_NEGOTIATION_COMPLETED;
return false;
}
bool FtpNegotiationCommand::processSequence
(const SharedHandle<Segment>& segment) {
bool doNextSequence = true;
switch(sequence) {
switch(_sequence) {
case SEQ_RECV_GREETING:
return recvGreeting();
case SEQ_SEND_USER:
@ -816,16 +823,17 @@ void FtpNegotiationCommand::poolConnection() const
{
if(getOption()->getAsBool(PREF_FTP_REUSE_CONNECTION)) {
std::map<std::string, std::string> options;
options["baseWorkingDir"] = ftp->getBaseWorkingDir();
e->poolSocket(req, ftp->getUser(), createProxyRequest(), socket, options);
options["baseWorkingDir"] = _ftp->getBaseWorkingDir();
getDownloadEngine()->poolSocket(getRequest(), _ftp->getUser(),
createProxyRequest(), getSocket(), options);
}
}
void FtpNegotiationCommand::onDryRunFileFound()
{
_requestGroup->getPieceStorage()->markAllPiecesDone();
getPieceStorage()->markAllPiecesDone();
poolConnection();
sequence = SEQ_HEAD_OK;
_sequence = SEQ_HEAD_OK;
}
} // namespace aria2

View File

@ -122,10 +122,10 @@ private:
void onDryRunFileFound();
SharedHandle<SocketCore> dataSocket;
SharedHandle<SocketCore> serverSocket;
Seq sequence;
SharedHandle<FtpConnection> ftp;
SharedHandle<SocketCore> _dataSocket;
SharedHandle<SocketCore> _serverSocket;
Seq _sequence;
SharedHandle<FtpConnection> _ftp;
// For tunneling
SharedHandle<HttpConnection> _http;
// IP, Port pair in pasv response

View File

@ -58,7 +58,8 @@ FtpTunnelRequestCommand::~FtpTunnelRequestCommand() {}
Command* FtpTunnelRequestCommand::getNextCommand()
{
return new FtpTunnelResponseCommand
(getCuid(), req, _fileEntry, _requestGroup, httpConnection, e, socket);
(getCuid(), getRequest(), getFileEntry(), getRequestGroup(),
getHttpConnection(), getDownloadEngine(), getSocket());
}
} // namespace aria2

View File

@ -59,8 +59,9 @@ FtpTunnelResponseCommand::~FtpTunnelResponseCommand() {}
Command* FtpTunnelResponseCommand::getNextCommand()
{
return new FtpNegotiationCommand(getCuid(), req, _fileEntry,
_requestGroup, e, socket);
return new FtpNegotiationCommand(getCuid(), getRequest(), getFileEntry(),
getRequestGroup(), getDownloadEngine(),
getSocket());
}
} // namespace aria2

View File

@ -71,29 +71,29 @@ HttpDownloadCommand::HttpDownloadCommand
HttpDownloadCommand::~HttpDownloadCommand() {}
bool HttpDownloadCommand::prepareForNextSegment() {
bool downloadFinished = _requestGroup->downloadFinished();
if(req->isPipeliningEnabled() && !downloadFinished) {
bool downloadFinished = getRequestGroup()->downloadFinished();
if(getRequest()->isPipeliningEnabled() && !downloadFinished) {
HttpRequestCommand* command =
new HttpRequestCommand(getCuid(), req, _fileEntry,
_requestGroup, _httpConnection, e,
socket);
new HttpRequestCommand(getCuid(), getRequest(), getFileEntry(),
getRequestGroup(), _httpConnection,
getDownloadEngine(), getSocket());
// Set proxy request here. aria2 sends the HTTP request specialized for
// proxy.
if(resolveProxyMethod(req->getProtocol()) == V_GET) {
if(resolveProxyMethod(getRequest()->getProtocol()) == V_GET) {
command->setProxyRequest(createProxyRequest());
}
e->addCommand(command);
getDownloadEngine()->addCommand(command);
return true;
} else {
if(req->isPipeliningEnabled() ||
(req->isKeepAliveEnabled() &&
if(getRequest()->isPipeliningEnabled() ||
(getRequest()->isKeepAliveEnabled() &&
(
((!_transferEncodingDecoder.isNull() &&
_transferEncodingDecoder->finished()) ||
(!_contentEncodingDecoder.isNull() &&
_contentEncodingDecoder->finished())) ||
_fileEntry->getLastOffset() ==
_segments.front()->getPositionToWrite()
((!getTransferEncodingDecoder().isNull() &&
getTransferEncodingDecoder()->finished()) ||
(!getContentEncodingDecoder().isNull() &&
getContentEncodingDecoder()->finished())) ||
getFileEntry()->getLastOffset() ==
getSegments().front()->getPositionToWrite()
)
)
) {
@ -102,20 +102,23 @@ bool HttpDownloadCommand::prepareForNextSegment() {
// pool terminated socket. In HTTP/1.1, keep-alive is default,
// so closing connection without Connection: close header means
// that server is broken or not configured properly.
e->poolSocket(req, createProxyRequest(), socket);
getDownloadEngine()->poolSocket
(getRequest(), createProxyRequest(), getSocket());
}
// The request was sent assuming that server supported pipelining, but
// it turned out that server didn't support it.
// We detect this situation by comparing the end byte in range header
// of the response with the end byte of segment.
// If it is the same, HTTP negotiation is necessary for the next request.
if(!req->isPipeliningEnabled() && req->isPipeliningHint() &&
if(!getRequest()->isPipeliningEnabled() &&
getRequest()->isPipeliningHint() &&
!downloadFinished) {
const SharedHandle<Segment>& segment = _segments.front();
const SharedHandle<Segment>& segment = getSegments().front();
off_t lastOffset =_fileEntry->gtoloff
(std::min(static_cast<off_t>(segment->getPosition()+segment->getLength()),
_fileEntry->getLastOffset()));
off_t lastOffset =getFileEntry()->gtoloff
(std::min(static_cast<off_t>
(segment->getPosition()+segment->getLength()),
getFileEntry()->getLastOffset()));
if(lastOffset ==
_httpResponse->getHttpHeader()->getRange()->getEndByte()+1) {

View File

@ -73,32 +73,39 @@ Command* HttpInitiateConnectionCommand::createNextCommand
Command* command;
if(!proxyRequest.isNull()) {
SharedHandle<SocketCore> pooledSocket =
e->popPooledSocket(req->getHost(), req->getPort(),
proxyRequest->getHost(), proxyRequest->getPort());
std::string proxyMethod = resolveProxyMethod(req->getProtocol());
getDownloadEngine()->popPooledSocket
(getRequest()->getHost(), getRequest()->getPort(),
proxyRequest->getHost(), proxyRequest->getPort());
std::string proxyMethod = resolveProxyMethod(getRequest()->getProtocol());
if(pooledSocket.isNull()) {
if(getLogger()->info()) {
getLogger()->info(MSG_CONNECTING_TO_SERVER,
util::itos(getCuid()).c_str(), addr.c_str(), port);
}
socket.reset(new SocketCore());
socket->establishConnection(addr, port);
createSocket();
getSocket()->establishConnection(addr, port);
if(proxyMethod == V_TUNNEL) {
HttpProxyRequestCommand* c =
new HttpProxyRequestCommand(getCuid(), req, _fileEntry,
_requestGroup, e,
proxyRequest, socket);
new HttpProxyRequestCommand(getCuid(),
getRequest(),
getFileEntry(),
getRequestGroup(),
getDownloadEngine(),
proxyRequest,
getSocket());
c->setConnectedAddr(hostname, addr, port);
command = c;
} else if(proxyMethod == V_GET) {
SharedHandle<HttpConnection> httpConnection
(new HttpConnection(getCuid(), socket, getOption().get()));
HttpRequestCommand* c = new HttpRequestCommand(getCuid(), req,
_fileEntry,
_requestGroup,
httpConnection, e,
socket);
(new HttpConnection(getCuid(), getSocket(), getOption().get()));
HttpRequestCommand* c = new HttpRequestCommand(getCuid(),
getRequest(),
getFileEntry(),
getRequestGroup(),
httpConnection,
getDownloadEngine(),
getSocket());
c->setConnectedAddr(hostname, addr, port);
c->setProxyRequest(proxyRequest);
command = c;
@ -109,10 +116,12 @@ Command* HttpInitiateConnectionCommand::createNextCommand
} else {
SharedHandle<HttpConnection> httpConnection
(new HttpConnection(getCuid(), pooledSocket, getOption().get()));
HttpRequestCommand* c = new HttpRequestCommand(getCuid(), req,
_fileEntry,
_requestGroup,
httpConnection, e,
HttpRequestCommand* c = new HttpRequestCommand(getCuid(),
getRequest(),
getFileEntry(),
getRequestGroup(),
httpConnection,
getDownloadEngine(),
pooledSocket);
if(proxyMethod == V_GET) {
c->setProxyRequest(proxyRequest);
@ -121,22 +130,26 @@ Command* HttpInitiateConnectionCommand::createNextCommand
}
} else {
SharedHandle<SocketCore> pooledSocket =
e->popPooledSocket(resolvedAddresses, req->getPort());
getDownloadEngine()->popPooledSocket
(resolvedAddresses, getRequest()->getPort());
if(pooledSocket.isNull()) {
if(getLogger()->info()) {
getLogger()->info(MSG_CONNECTING_TO_SERVER,
util::itos(getCuid()).c_str(), addr.c_str(), port);
}
socket.reset(new SocketCore());
socket->establishConnection(addr, port);
createSocket();
getSocket()->establishConnection(addr, port);
} else {
socket = pooledSocket;
setSocket(pooledSocket);
}
SharedHandle<HttpConnection> httpConnection
(new HttpConnection(getCuid(), socket, getOption().get()));
(new HttpConnection(getCuid(), getSocket(), getOption().get()));
HttpRequestCommand* c =
new HttpRequestCommand(getCuid(), req, _fileEntry, _requestGroup,
httpConnection, e, socket);
new HttpRequestCommand(getCuid(), getRequest(), getFileEntry(),
getRequestGroup(),
httpConnection,
getDownloadEngine(),
getSocket());
if(pooledSocket.isNull()) {
c->setConnectedAddr(hostname, addr, port);
}

View File

@ -58,7 +58,8 @@ HttpProxyRequestCommand::~HttpProxyRequestCommand() {}
Command* HttpProxyRequestCommand::getNextCommand()
{
return new HttpProxyResponseCommand
(getCuid(), req, _fileEntry, _requestGroup, httpConnection, e, socket);
(getCuid(), getRequest(), getFileEntry(), getRequestGroup(),
getHttpConnection(), getDownloadEngine(), getSocket());
}
} // namespace aria2

View File

@ -59,8 +59,9 @@ HttpProxyResponseCommand::~HttpProxyResponseCommand() {}
Command* HttpProxyResponseCommand::getNextCommand()
{
return new HttpRequestCommand(getCuid(), req, _fileEntry,
_requestGroup, httpConnection, e, socket);
return new HttpRequestCommand(getCuid(), getRequest(), getFileEntry(),
getRequestGroup(), getHttpConnection(),
getDownloadEngine(), getSocket());
}
} // namespace aria2

View File

@ -73,7 +73,7 @@ HttpRequestCommand::HttpRequestCommand
{
setTimeout(getOption()->getAsInt(PREF_CONNECT_TIMEOUT));
disableReadCheckSocket();
setWriteCheckSocket(socket);
setWriteCheckSocket(getSocket());
}
HttpRequestCommand::~HttpRequestCommand() {}
@ -115,47 +115,48 @@ createHttpRequest(const SharedHandle<Request>& req,
bool HttpRequestCommand::executeInternal() {
//socket->setBlockingMode();
if(req->getProtocol() == Request::PROTO_HTTPS) {
socket->prepareSecureConnection();
if(!socket->initiateSecureConnection(req->getHost())) {
setReadCheckSocketIf(socket, socket->wantRead());
setWriteCheckSocketIf(socket, socket->wantWrite());
e->addCommand(this);
if(getRequest()->getProtocol() == Request::PROTO_HTTPS) {
getSocket()->prepareSecureConnection();
if(!getSocket()->initiateSecureConnection(getRequest()->getHost())) {
setReadCheckSocketIf(getSocket(), getSocket()->wantRead());
setWriteCheckSocketIf(getSocket(), getSocket()->wantWrite());
getDownloadEngine()->addCommand(this);
return false;
}
}
if(_httpConnection->sendBufferIsEmpty()) {
if(!checkIfConnectionEstablished
(socket, _connectedHostname, _connectedAddr, _connectedPort)) {
(getSocket(), _connectedHostname, _connectedAddr, _connectedPort)) {
return true;
}
if(_segments.empty()) {
if(getSegments().empty()) {
SharedHandle<HttpRequest> httpRequest
(createHttpRequest(req,
_fileEntry,
(createHttpRequest(getRequest(),
getFileEntry(),
SharedHandle<Segment>(),
_requestGroup->getTotalLength(),
getRequestGroup()->getTotalLength(),
getOption(),
_requestGroup,
e->getCookieStorage(),
e->getAuthConfigFactory(),
getRequestGroup(),
getDownloadEngine()->getCookieStorage(),
getDownloadEngine()->getAuthConfigFactory(),
_proxyRequest));
_httpConnection->sendRequest(httpRequest);
} else {
for(std::vector<SharedHandle<Segment> >::const_iterator itr =
_segments.begin(), eoi = _segments.end(); itr != eoi; ++itr) {
getSegments().begin(), eoi = getSegments().end();
itr != eoi; ++itr) {
const SharedHandle<Segment>& segment = *itr;
if(!_httpConnection->isIssued(segment)) {
SharedHandle<HttpRequest> httpRequest
(createHttpRequest(req,
_fileEntry,
(createHttpRequest(getRequest(),
getFileEntry(),
segment,
_requestGroup->getTotalLength(),
getRequestGroup()->getTotalLength(),
getOption(),
_requestGroup,
e->getCookieStorage(),
e->getAuthConfigFactory(),
getRequestGroup(),
getDownloadEngine()->getCookieStorage(),
getDownloadEngine()->getAuthConfigFactory(),
_proxyRequest));
_httpConnection->sendRequest(httpRequest);
}
@ -165,15 +166,19 @@ bool HttpRequestCommand::executeInternal() {
_httpConnection->sendPendingData();
}
if(_httpConnection->sendBufferIsEmpty()) {
Command* command = new HttpResponseCommand(getCuid(), req, _fileEntry,
_requestGroup,
_httpConnection, e, socket);
e->addCommand(command);
Command* command = new HttpResponseCommand(getCuid(),
getRequest(),
getFileEntry(),
getRequestGroup(),
_httpConnection,
getDownloadEngine(),
getSocket());
getDownloadEngine()->addCommand(command);
return true;
} else {
setReadCheckSocketIf(socket, socket->wantRead());
setWriteCheckSocketIf(socket, socket->wantWrite());
e->addCommand(this);
setReadCheckSocketIf(getSocket(), getSocket()->wantRead());
setWriteCheckSocketIf(getSocket(), getSocket()->wantWrite());
getDownloadEngine()->addCommand(this);
return false;
}
}

View File

@ -87,21 +87,21 @@ HttpResponseCommand::HttpResponseCommand
DownloadEngine* e,
const SocketHandle& s)
:AbstractCommand(cuid, req, fileEntry, requestGroup, e, s),
httpConnection(httpConnection)
_httpConnection(httpConnection)
{}
HttpResponseCommand::~HttpResponseCommand() {}
bool HttpResponseCommand::executeInternal()
{
SharedHandle<HttpRequest> httpRequest = httpConnection->getFirstHttpRequest();
SharedHandle<HttpResponse> httpResponse = httpConnection->receiveResponse();
SharedHandle<HttpRequest> httpRequest =_httpConnection->getFirstHttpRequest();
SharedHandle<HttpResponse> httpResponse = _httpConnection->receiveResponse();
if(httpResponse.isNull()) {
// The server has not responded to our request yet.
// For socket->wantRead() == true, setReadCheckSocket(socket) is already
// done in the constructor.
setWriteCheckSocketIf(socket, socket->wantWrite());
e->addCommand(this);
setWriteCheckSocketIf(getSocket(), getSocket()->wantWrite());
getDownloadEngine()->addCommand(this);
return false;
}
// check HTTP status number
@ -112,39 +112,40 @@ bool HttpResponseCommand::executeInternal()
// Disable persistent connection if:
// Connection: close is received or the remote server is not HTTP/1.1.
// We don't care whether non-HTTP/1.1 server returns Connection: keep-alive.
req->supportsPersistentConnection
getRequest()->supportsPersistentConnection
(httpResponse->supportsPersistentConnection());
if(req->isPipeliningEnabled()) {
req->setMaxPipelinedRequest
if(getRequest()->isPipeliningEnabled()) {
getRequest()->setMaxPipelinedRequest
(getOption()->getAsInt(PREF_MAX_HTTP_PIPELINING));
}
if(httpResponse->getResponseStatus() >= HttpHeader::S300) {
if(httpResponse->getResponseStatus() == HttpHeader::S404) {
_requestGroup->increaseAndValidateFileNotFoundCount();
getRequestGroup()->increaseAndValidateFileNotFoundCount();
}
return skipResponseBody(httpResponse);
}
if(!_fileEntry->isSingleHostMultiConnectionEnabled()) {
if(!getFileEntry()->isSingleHostMultiConnectionEnabled()) {
// TODO redirection should be considered here. We need to parse
// original URI to get hostname.
_fileEntry->removeURIWhoseHostnameIs(req->getHost());
getFileEntry()->removeURIWhoseHostnameIs(getRequest()->getHost());
}
if(_requestGroup->getPieceStorage().isNull()) {
if(getPieceStorage().isNull()) {
uint64_t totalLength = httpResponse->getEntityLength();
_fileEntry->setLength(totalLength);
if(_fileEntry->getPath().empty()) {
_fileEntry->setPath
getFileEntry()->setLength(totalLength);
if(getFileEntry()->getPath().empty()) {
getFileEntry()->setPath
(util::applyDir
(getDownloadContext()->getDir(),
util::fixTaintedBasename(httpResponse->determinFilename())));
}
_fileEntry->setContentType(httpResponse->getContentType());
_requestGroup->preDownloadProcessing();
if(e->getRequestGroupMan()->isSameFileBeingDownloaded(_requestGroup)) {
getFileEntry()->setContentType(httpResponse->getContentType());
getRequestGroup()->preDownloadProcessing();
if(getDownloadEngine()->getRequestGroupMan()->
isSameFileBeingDownloaded(getRequestGroup())) {
throw DOWNLOAD_FAILURE_EXCEPTION
(StringFormat(EX_DUPLICATE_FILE_DOWNLOAD,
_requestGroup->getFirstFilePath().c_str()).str());
getRequestGroup()->getFirstFilePath().c_str()).str());
}
// update last modified time
updateLastModifiedTime(httpResponse->getLastModifiedTime());
@ -153,8 +154,8 @@ bool HttpResponseCommand::executeInternal()
// assume we can do segmented downloading
if(totalLength == 0 || shouldInflateContentEncoding(httpResponse)) {
// we ignore content-length when inflate is required
_fileEntry->setLength(0);
if(req->getMethod() == Request::METHOD_GET &&
getFileEntry()->setLength(0);
if(getRequest()->getMethod() == Request::METHOD_GET &&
(totalLength != 0 ||
!httpResponse->getHttpHeader()->defined(HttpHeader::CONTENT_LENGTH))){
// DownloadContext::knowsTotalLength() == true only when
@ -167,22 +168,22 @@ bool HttpResponseCommand::executeInternal()
}
} else {
// validate totalsize
_requestGroup->validateTotalLength(_fileEntry->getLength(),
getRequestGroup()->validateTotalLength(getFileEntry()->getLength(),
httpResponse->getEntityLength());
// update last modified time
updateLastModifiedTime(httpResponse->getLastModifiedTime());
if(_requestGroup->getTotalLength() == 0) {
if(getRequestGroup()->getTotalLength() == 0) {
// Since total length is unknown, the file size in previously
// failed download could be larger than the size this time.
// Also we can't resume in this case too. So truncate the file
// anyway.
_requestGroup->getPieceStorage()->getDiskAdaptor()->truncate(0);
e->addCommand
getPieceStorage()->getDiskAdaptor()->truncate(0);
getDownloadEngine()->addCommand
(createHttpDownloadCommand(httpResponse,
getTransferEncodingDecoder(httpResponse),
getContentEncodingDecoder(httpResponse)));
} else {
e->addCommand(createHttpDownloadCommand
getDownloadEngine()->addCommand(createHttpDownloadCommand
(httpResponse, getTransferEncodingDecoder(httpResponse)));
}
return true;
@ -192,7 +193,7 @@ bool HttpResponseCommand::executeInternal()
void HttpResponseCommand::updateLastModifiedTime(const Time& lastModified)
{
if(getOption()->getAsBool(PREF_REMOTE_TIME)) {
_requestGroup->updateLastModifiedTime(lastModified);
getRequestGroup()->updateLastModifiedTime(lastModified);
}
}
@ -215,12 +216,12 @@ bool HttpResponseCommand::handleDefaultEncoding
(const SharedHandle<HttpResponse>& httpResponse)
{
SharedHandle<HttpRequest> httpRequest = httpResponse->getHttpRequest();
_requestGroup->adjustFilename
getRequestGroup()->adjustFilename
(SharedHandle<BtProgressInfoFile>(new DefaultBtProgressInfoFile
(_requestGroup->getDownloadContext(),
(getDownloadContext(),
SharedHandle<PieceStorage>(),
getOption().get())));
_requestGroup->initPieceStorage();
getRequestGroup()->initPieceStorage();
if(getOption()->getAsBool(PREF_DRY_RUN)) {
onDryRunFileFound();
@ -228,47 +229,44 @@ bool HttpResponseCommand::handleDefaultEncoding
}
BtProgressInfoFileHandle infoFile
(new DefaultBtProgressInfoFile(_requestGroup->getDownloadContext(),
_requestGroup->getPieceStorage(),
(new DefaultBtProgressInfoFile(getDownloadContext(),
getPieceStorage(),
getOption().get()));
if(!infoFile->exists() && _requestGroup->downloadFinishedByFileLength()) {
_requestGroup->getPieceStorage()->markAllPiecesDone();
if(!infoFile->exists() && getRequestGroup()->downloadFinishedByFileLength()) {
getPieceStorage()->markAllPiecesDone();
getLogger()->notice(MSG_DOWNLOAD_ALREADY_COMPLETED,
util::itos(_requestGroup->getGID()).c_str(),
_requestGroup->getFirstFilePath().c_str());
util::itos(getRequestGroup()->getGID()).c_str(),
getRequestGroup()->getFirstFilePath().c_str());
return true;
}
_requestGroup->loadAndOpenFile(infoFile);
File file(_requestGroup->getFirstFilePath());
getRequestGroup()->loadAndOpenFile(infoFile);
File file(getRequestGroup()->getFirstFilePath());
// We have to make sure that command that has Request object must
// have segment after PieceStorage is initialized. See
// AbstractCommand::execute()
SharedHandle<Segment> segment =
_requestGroup->getSegmentMan()->getSegment(getCuid(), 0);
SharedHandle<Segment> segment = getSegmentMan()->getSegment(getCuid(), 0);
// pipelining requires implicit range specified. But the request for
// this response most likely dones't contains range header. This means
// we can't continue to use this socket because server sends all entity
// body instead of a segment.
// Therefore, we shutdown the socket here if pipelining is enabled.
DownloadCommand* command = 0;
if(req->getMethod() == Request::METHOD_GET &&
if(getRequest()->getMethod() == Request::METHOD_GET &&
!segment.isNull() && segment->getPositionToWrite() == 0 &&
!req->isPipeliningEnabled()) {
!getRequest()->isPipeliningEnabled()) {
command = createHttpDownloadCommand
(httpResponse, getTransferEncodingDecoder(httpResponse));
} else {
_requestGroup->getSegmentMan()->cancelSegment(getCuid());
_fileEntry->poolRequest(req);
getSegmentMan()->cancelSegment(getCuid());
getFileEntry()->poolRequest(getRequest());
}
// After command is passed to prepareForNextAction(), it is managed
// by CheckIntegrityEntry.
prepareForNextAction(command);
command = 0;
if(req->getMethod() == Request::METHOD_HEAD) {
if(getRequest()->getMethod() == Request::METHOD_HEAD) {
poolConnection();
req->setMethod(Request::METHOD_GET);
getRequest()->setMethod(Request::METHOD_GET);
}
return true;
}
@ -314,47 +312,43 @@ bool HttpResponseCommand::handleOtherEncoding
SharedHandle<HttpRequest> httpRequest = httpResponse->getHttpRequest();
if(getOption()->getAsBool(PREF_DRY_RUN)) {
_requestGroup->initPieceStorage();
getRequestGroup()->initPieceStorage();
onDryRunFileFound();
return true;
}
if(req->getMethod() == Request::METHOD_HEAD) {
if(getRequest()->getMethod() == Request::METHOD_HEAD) {
poolConnection();
req->setMethod(Request::METHOD_GET);
getRequest()->setMethod(Request::METHOD_GET);
return prepareForRetry(0);
}
// For zero-length file, check existing file comparing its size
if(_requestGroup->downloadFinishedByFileLength()) {
_requestGroup->initPieceStorage();
_requestGroup->getPieceStorage()->markAllPiecesDone();
if(getRequestGroup()->downloadFinishedByFileLength()) {
getRequestGroup()->initPieceStorage();
getPieceStorage()->markAllPiecesDone();
getLogger()->notice(MSG_DOWNLOAD_ALREADY_COMPLETED,
util::itos(_requestGroup->getGID()).c_str(),
_requestGroup->getFirstFilePath().c_str());
util::itos(getRequestGroup()->getGID()).c_str(),
getRequestGroup()->getFirstFilePath().c_str());
poolConnection();
return true;
}
_requestGroup->shouldCancelDownloadForSafety();
_requestGroup->initPieceStorage();
_requestGroup->getPieceStorage()->getDiskAdaptor()->initAndOpenFile();
getRequestGroup()->shouldCancelDownloadForSafety();
getRequestGroup()->initPieceStorage();
getPieceStorage()->getDiskAdaptor()->initAndOpenFile();
// In this context, knowsTotalLength() is true only when the file is
// really zero-length.
if(_requestGroup->getDownloadContext()->knowsTotalLength()) {
if(getDownloadContext()->knowsTotalLength()) {
poolConnection();
return true;
}
// We have to make sure that command that has Request object must
// have segment after PieceStorage is initialized. See
// AbstractCommand::execute()
_requestGroup->getSegmentMan()->getSegment(getCuid(), 0);
getSegmentMan()->getSegment(getCuid(), 0);
e->addCommand
getDownloadEngine()->addCommand
(createHttpDownloadCommand(httpResponse,
getTransferEncodingDecoder(httpResponse),
getContentEncodingDecoder(httpResponse)));
@ -369,22 +363,23 @@ bool HttpResponseCommand::skipResponseBody
// thrown away.
HttpSkipResponseCommand* command = new HttpSkipResponseCommand
(getCuid(), req, _fileEntry, _requestGroup, httpConnection, httpResponse,
e, socket);
(getCuid(), getRequest(), getFileEntry(), getRequestGroup(),
_httpConnection, httpResponse,
getDownloadEngine(), getSocket());
command->setTransferEncodingDecoder(decoder);
// If request method is HEAD or the response body is zero-length,
// set command's status to real time so that avoid read check blocking
if(req->getMethod() == Request::METHOD_HEAD ||
if(getRequest()->getMethod() == Request::METHOD_HEAD ||
(httpResponse->getEntityLength() == 0 &&
!httpResponse->isTransferEncodingSpecified())) {
command->setStatusRealtime();
// If entity length == 0, then socket read/write check must be disabled.
command->disableSocketCheck();
e->setNoWait(true);
getDownloadEngine()->setNoWait(true);
}
e->addCommand(command);
getDownloadEngine()->addCommand(command);
return true;
}
@ -395,8 +390,10 @@ HttpDownloadCommand* HttpResponseCommand::createHttpDownloadCommand
{
HttpDownloadCommand* command =
new HttpDownloadCommand(getCuid(), req, _fileEntry, _requestGroup,
httpResponse, httpConnection, e, socket);
new HttpDownloadCommand(getCuid(), getRequest(), getFileEntry(),
getRequestGroup(),
httpResponse, _httpConnection,
getDownloadEngine(), getSocket());
command->setStartupIdleTime(getOption()->getAsInt(PREF_STARTUP_IDLE_TIME));
command->setLowestDownloadSpeedLimit
(getOption()->getAsInt(PREF_LOWEST_SPEED_LIMIT));
@ -407,25 +404,26 @@ HttpDownloadCommand* HttpResponseCommand::createHttpDownloadCommand
// Since the compressed file's length are returned in the response header
// and the decompressed file size is unknown at this point, disable file
// allocation here.
_requestGroup->setFileAllocationEnabled(false);
getRequestGroup()->setFileAllocationEnabled(false);
}
_requestGroup->getURISelector()->tuneDownloadCommand
(_fileEntry->getRemainingUris(), command);
getRequestGroup()->getURISelector()->tuneDownloadCommand
(getFileEntry()->getRemainingUris(), command);
return command;
}
void HttpResponseCommand::poolConnection()
{
if(req->supportsPersistentConnection()) {
e->poolSocket(req, createProxyRequest(), socket);
if(getRequest()->supportsPersistentConnection()) {
getDownloadEngine()->poolSocket(getRequest(), createProxyRequest(),
getSocket());
}
}
void HttpResponseCommand::onDryRunFileFound()
{
_requestGroup->getPieceStorage()->markAllPiecesDone();
getPieceStorage()->markAllPiecesDone();
poolConnection();
}

View File

@ -48,7 +48,7 @@ class SocketCore;
class HttpResponseCommand : public AbstractCommand {
private:
SharedHandle<HttpConnection> httpConnection;
SharedHandle<HttpConnection> _httpConnection;
bool handleDefaultEncoding(const SharedHandle<HttpResponse>& httpResponse);
bool handleOtherEncoding(const SharedHandle<HttpResponse>& httpResponse);

View File

@ -87,13 +87,13 @@ void HttpSkipResponseCommand::setTransferEncodingDecoder
bool HttpSkipResponseCommand::executeInternal()
{
if(req->getMethod() == Request::METHOD_HEAD ||
if(getRequest()->getMethod() == Request::METHOD_HEAD ||
(_totalLength == 0 && _transferEncodingDecoder.isNull())) {
// If request method is HEAD or content-length header is present and
// it's value is 0, then pool socket for reuse.
// If content-length header is not present, then EOF is expected in the end.
// In this case, the content is thrown away and socket cannot be pooled.
if(req->getMethod() == Request::METHOD_HEAD ||
if(getRequest()->getMethod() == Request::METHOD_HEAD ||
_httpResponse->getHttpHeader()->defined(HttpHeader::CONTENT_LENGTH)) {
poolConnection();
}
@ -104,7 +104,7 @@ bool HttpSkipResponseCommand::executeInternal()
size_t bufSize = BUFSIZE;
try {
socket->readData(buf, bufSize);
getSocket()->readData(buf, bufSize);
if(_transferEncodingDecoder.isNull()) {
_receivedBytes += bufSize;
@ -114,7 +114,7 @@ bool HttpSkipResponseCommand::executeInternal()
_transferEncodingDecoder->decode(buf, bufSize);
}
if(_totalLength != 0 && bufSize == 0 &&
!socket->wantRead() && !socket->wantWrite()) {
!getSocket()->wantRead() && !getSocket()->wantWrite()) {
throw DL_RETRY_EX(EX_GOT_EOF);
}
} catch(RecoverableException& e) {
@ -127,7 +127,7 @@ bool HttpSkipResponseCommand::executeInternal()
bool finished = false;
if(_transferEncodingDecoder.isNull()) {
if(bufSize == 0) {
if(!socket->wantRead() && !socket->wantWrite()) {
if(!getSocket()->wantRead() && !getSocket()->wantWrite()) {
return processResponse();
}
} else {
@ -140,16 +140,17 @@ bool HttpSkipResponseCommand::executeInternal()
poolConnection();
return processResponse();
} else {
setWriteCheckSocketIf(socket, socket->wantWrite());
e->addCommand(this);
setWriteCheckSocketIf(getSocket(), getSocket()->wantWrite());
getDownloadEngine()->addCommand(this);
return false;
}
}
void HttpSkipResponseCommand::poolConnection() const
{
if(req->supportsPersistentConnection()) {
e->poolSocket(req, createProxyRequest(), socket);
if(getRequest()->supportsPersistentConnection()) {
getDownloadEngine()->poolSocket
(getRequest(), createProxyRequest(), getSocket());
}
}
@ -159,7 +160,8 @@ bool HttpSkipResponseCommand::processResponse()
unsigned int rnum =
_httpResponse->getHttpRequest()->getRequest()->getRedirectCount();
if(rnum >= Request::MAX_REDIRECT) {
throw DL_ABORT_EX(StringFormat("Too many redirects: count=%u", rnum).str());
throw DL_ABORT_EX
(StringFormat("Too many redirects: count=%u", rnum).str());
}
_httpResponse->processRedirect();
return prepareForRetry(0);
@ -167,8 +169,8 @@ bool HttpSkipResponseCommand::processResponse()
if(_httpResponse->getResponseStatus() == HttpHeader::S401) {
if(getOption()->getAsBool(PREF_HTTP_AUTH_CHALLENGE) &&
!_httpResponse->getHttpRequest()->authenticationUsed() &&
e->getAuthConfigFactory()->activateBasicCred
(req->getHost(), req->getDir(), getOption().get())) {
getDownloadEngine()->getAuthConfigFactory()->activateBasicCred
(getRequest()->getHost(), getRequest()->getDir(), getOption().get())) {
return prepareForRetry(0);
} else {
throw DL_ABORT_EX(EX_AUTH_FAILED);
@ -177,7 +179,10 @@ bool HttpSkipResponseCommand::processResponse()
throw DL_ABORT_EX2(MSG_RESOURCE_NOT_FOUND,
downloadresultcode::RESOURCE_NOT_FOUND);
} else {
throw DL_ABORT_EX(StringFormat(EX_BAD_STATUS, util::parseUInt(_httpResponse->getResponseStatus())).str());
throw DL_ABORT_EX
(StringFormat
(EX_BAD_STATUS,
util::parseUInt(_httpResponse->getResponseStatus())).str());
}
} else {
return prepareForRetry(0);

View File

@ -77,8 +77,8 @@ bool InitiateConnectionCommand::executeInternal() {
uint16_t port;
SharedHandle<Request> proxyRequest = createProxyRequest();
if(proxyRequest.isNull()) {
hostname = req->getHost();
port = req->getPort();
hostname = getRequest()->getHost();
port = getRequest()->getPort();
} else {
hostname = proxyRequest->getHost();
port = proxyRequest->getPort();
@ -86,21 +86,21 @@ bool InitiateConnectionCommand::executeInternal() {
std::vector<std::string> addrs;
std::string ipaddr = resolveHostname(addrs, hostname, port);
if(ipaddr.empty()) {
e->addCommand(this);
getDownloadEngine()->addCommand(this);
return false;
}
try {
Command* command = createNextCommand(hostname, ipaddr, port,
addrs, proxyRequest);
e->addCommand(command);
getDownloadEngine()->addCommand(command);
return true;
} catch(RecoverableException& ex) {
// Catch exception and retry another address.
// See also AbstractCommand::checkIfConnectionEstablished
// TODO ipaddr might not be used if pooled sockt was found.
e->markBadIPAddress(hostname, ipaddr, port);
if(!e->findCachedIPAddress(hostname, port).empty()) {
getDownloadEngine()->markBadIPAddress(hostname, ipaddr, port);
if(!getDownloadEngine()->findCachedIPAddress(hostname, port).empty()) {
if(getLogger()->info()) {
getLogger()->info(EX_EXCEPTION_CAUGHT, ex);
getLogger()->info(MSG_CONNECT_FAILED_AND_RETRY,
@ -108,12 +108,13 @@ bool InitiateConnectionCommand::executeInternal() {
}
Command* command =
InitiateConnectionCommandFactory::createInitiateConnectionCommand
(getCuid(), req, _fileEntry, _requestGroup, e);
e->setNoWait(true);
e->addCommand(command);
(getCuid(), getRequest(), getFileEntry(), getRequestGroup(),
getDownloadEngine());
getDownloadEngine()->setNoWait(true);
getDownloadEngine()->addCommand(command);
return true;
}
e->removeCachedIPAddress(hostname, port);
getDownloadEngine()->removeCachedIPAddress(hostname, port);
throw;
}
}