Revert "Cleanup AbstractCommand"

This reverts commit 0465aa5455.
pull/235/head
Nils Maier 2014-05-29 18:21:49 +02:00
parent 0465aa5455
commit 6240345fd5
5 changed files with 479 additions and 566 deletions

View File

@ -74,12 +74,10 @@
namespace aria2 { namespace aria2 {
AbstractCommand::AbstractCommand( AbstractCommand::AbstractCommand(cuid_t cuid,
cuid_t cuid,
const std::shared_ptr<Request>& req, const std::shared_ptr<Request>& req,
const std::shared_ptr<FileEntry>& fileEntry, const std::shared_ptr<FileEntry>& fileEntry,
RequestGroup *requestGroup, RequestGroup* requestGroup, DownloadEngine* e,
DownloadEngine *e,
const std::shared_ptr<SocketCore>& s, const std::shared_ptr<SocketCore>& s,
const std::shared_ptr<SocketRecvBuffer>& socketRecvBuffer, const std::shared_ptr<SocketRecvBuffer>& socketRecvBuffer,
bool incNumConnection) bool incNumConnection)
@ -113,8 +111,7 @@ AbstractCommand::AbstractCommand(
#endif // ENABLE_ASYNC_DNS #endif // ENABLE_ASYNC_DNS
} }
AbstractCommand::~AbstractCommand() AbstractCommand::~AbstractCommand() {
{
disableReadCheckSocket(); disableReadCheckSocket();
disableWriteCheckSocket(); disableWriteCheckSocket();
#ifdef ENABLE_ASYNC_DNS #ifdef ENABLE_ASYNC_DNS
@ -127,8 +124,8 @@ AbstractCommand::~AbstractCommand()
} }
} }
void void AbstractCommand::useFasterRequest
AbstractCommand::useFasterRequest(const std::shared_ptr<Request> &fasterRequest) (const std::shared_ptr<Request>& fasterRequest)
{ {
A2_LOG_INFO(fmt("CUID#%" PRId64 " - Use faster Request hostname=%s, port=%u", A2_LOG_INFO(fmt("CUID#%" PRId64 " - Use faster Request hostname=%s, port=%u",
getCuid(), getCuid(),
@ -137,45 +134,13 @@ AbstractCommand::useFasterRequest(const std::shared_ptr<Request> &fasterRequest)
// Cancel current Request object and use faster one. // Cancel current Request object and use faster one.
fileEntry_->removeRequest(req_); fileEntry_->removeRequest(req_);
e_->setNoWait(true); e_->setNoWait(true);
e_->addCommand( e_->addCommand(InitiateConnectionCommandFactory::
InitiateConnectionCommandFactory::createInitiateConnectionCommand( createInitiateConnectionCommand
getCuid(), fasterRequest, fileEntry_, requestGroup_, e_)); (getCuid(), fasterRequest, fileEntry_, requestGroup_, e_));
} }
bool AbstractCommand::shouldCheck() const bool AbstractCommand::execute() {
{ A2_LOG_DEBUG(fmt("CUID#%" PRId64 " - socket: read:%d, write:%d, hup:%d, err:%d",
if (checkSocketIsReadable_) {
if (readEventEnabled()) {
return true;
}
if (socketRecvBuffer_ && !socketRecvBuffer_->bufferEmpty()) {
return true;
}
}
if (checkSocketIsWritable_ && writeEventEnabled()) {
return true;
}
#ifdef ENABLE_ASYNC_DNS
const auto resolverChecked = asyncNameResolverMan_->resolverChecked();
if (resolverChecked && asyncNameResolverMan_->getStatus() != 0) {
return true;
}
if (!checkSocketIsReadable_ && !checkSocketIsWritable_ && !resolverChecked) {
return true;
}
#endif // ENABLE_ASYNC_DNS
return noCheck();
}
bool AbstractCommand::execute()
{
A2_LOG_DEBUG(fmt("CUID#%" PRId64
" - socket: read:%d, write:%d, hup:%d, err:%d",
getCuid(), getCuid(),
readEventEnabled(), readEventEnabled(),
writeEventEnabled(), writeEventEnabled(),
@ -185,28 +150,20 @@ bool AbstractCommand::execute()
if(requestGroup_->downloadFinished() || requestGroup_->isHaltRequested()) { if(requestGroup_->downloadFinished() || requestGroup_->isHaltRequested()) {
return true; return true;
} }
if(req_ && req_->removalRequested()) { if(req_ && req_->removalRequested()) {
A2_LOG_DEBUG(fmt("CUID#%" PRId64 A2_LOG_DEBUG(fmt("CUID#%" PRId64 " - Discard original URI=%s because it is"
" - Discard original URI=%s because it is"
" requested.", " requested.",
getCuid(), getCuid(), req_->getUri().c_str()));
req_->getUri().c_str()));
return prepareForRetry(0); return prepareForRetry(0);
} }
auto sm = getSegmentMan();
if(getPieceStorage()) { if(getPieceStorage()) {
segments_.clear(); segments_.clear();
sm->getInFlightSegment(segments_, getCuid()); getSegmentMan()->getInFlightSegment(segments_, getCuid());
if(req_ && segments_.empty()) { if(req_ && segments_.empty()) {
// This command previously has assigned segments, but it is // This command previously has assigned segments, but it is
// canceled. So discard current request chain. Plus, if no // canceled. So discard current request chain. Plus, if no
// segment is available when http pipelining is used. // segment is available when http pipelining is used.
A2_LOG_DEBUG(fmt("CUID#%" PRId64 A2_LOG_DEBUG(fmt("CUID#%" PRId64 " - It seems previously assigned segments"
" - It seems previously assigned segments"
" are canceled. Restart.", " are canceled. Restart.",
getCuid())); getCuid()));
// Request::isPipeliningEnabled() == true means aria2 // Request::isPipeliningEnabled() == true means aria2
@ -217,12 +174,12 @@ bool AbstractCommand::execute()
} }
return prepareForRetry(0); return prepareForRetry(0);
} }
// TODO it is not needed to check other PeerStats every time. // TODO it is not needed to check other PeerStats every time.
// Find faster Request when no segment split is allowed. // Find faster Request when no segment split is allowed.
if(req_ && fileEntry_->countPooledRequest() > 0 && if(req_ && fileEntry_->countPooledRequest() > 0 &&
requestGroup_->getPendingLength() < calculateMinSplitSize() * 2) { requestGroup_->getTotalLength()-requestGroup_->getCompletedLength()
auto fasterRequest = fileEntry_->findFasterRequest(req_); < calculateMinSplitSize()*2) {
std::shared_ptr<Request> fasterRequest = fileEntry_->findFasterRequest(req_);
if(fasterRequest) { if(fasterRequest) {
useFasterRequest(fasterRequest); useFasterRequest(fasterRequest);
return true; return true;
@ -239,22 +196,31 @@ bool AbstractCommand::execute()
if(getOption()->getAsBool(PREF_SELECT_LEAST_USED_HOST)) { if(getOption()->getAsBool(PREF_SELECT_LEAST_USED_HOST)) {
getDownloadEngine()->getRequestGroupMan()->getUsedHosts(usedHosts); getDownloadEngine()->getRequestGroupMan()->getUsedHosts(usedHosts);
} }
auto fasterRequest = fileEntry_->findFasterRequest( std::shared_ptr<Request> fasterRequest =
req_, usedHosts, e_->getRequestGroupMan()->getServerStatMan()); fileEntry_->findFasterRequest
(req_, usedHosts, e_->getRequestGroupMan()->getServerStatMan());
if(fasterRequest) { if(fasterRequest) {
useFasterRequest(fasterRequest); useFasterRequest(fasterRequest);
return true; return true;
} }
} }
} }
if((checkSocketIsReadable_ &&
if (shouldCheck()) { (readEventEnabled() ||
(socketRecvBuffer_ && !socketRecvBuffer_->bufferEmpty()))) ||
(checkSocketIsWritable_ && writeEventEnabled()) ||
hupEventEnabled() ||
#ifdef ENABLE_ASYNC_DNS
(asyncNameResolverMan_->resolverChecked() &&
asyncNameResolverMan_->getStatus() != 0) ||
#endif // ENABLE_ASYNC_DNS
(!checkSocketIsReadable_ && !checkSocketIsWritable_
#ifdef ENABLE_ASYNC_DNS
&& !asyncNameResolverMan_->resolverChecked()
#endif // ENABLE_ASYNC_DNS
) || noCheck()) {
checkPoint_ = global::wallclock(); checkPoint_ = global::wallclock();
if(getPieceStorage()) {
if (!getPieceStorage()) {
return executeInternal();
}
if(!req_ || req_->getMaxPipelinedRequest() == 1 || if(!req_ || req_->getMaxPipelinedRequest() == 1 ||
// Why the following condition is necessary? That's because // Why the following condition is necessary? That's because
// For single file download, SegmentMan::getSegment(cuid) // For single file download, SegmentMan::getSegment(cuid)
@ -263,55 +229,55 @@ bool AbstractCommand::execute()
size_t maxSegments = req_?req_->getMaxPipelinedRequest():1; size_t maxSegments = req_?req_->getMaxPipelinedRequest():1;
size_t minSplitSize = calculateMinSplitSize(); size_t minSplitSize = calculateMinSplitSize();
while(segments_.size() < maxSegments) { while(segments_.size() < maxSegments) {
auto segment = sm->getSegment(getCuid(), minSplitSize); std::shared_ptr<Segment> segment =
getSegmentMan()->getSegment(getCuid(), minSplitSize);
if(!segment) { if(!segment) {
break; break;
} } else {
segments_.push_back(segment); segments_.push_back(segment);
} }
}
if(segments_.empty()) { if(segments_.empty()) {
// TODO socket could be pooled here if pipelining is // TODO socket could be pooled here if pipelining is
// enabled... Hmm, I don't think if pipelining is enabled // enabled... Hmm, I don't think if pipelining is enabled
// it does not go here. // it does not go here.
A2_LOG_INFO(fmt(MSG_NO_SEGMENT_AVAILABLE, getCuid())); A2_LOG_INFO(fmt(MSG_NO_SEGMENT_AVAILABLE,
getCuid()));
// When all segments are ignored in SegmentMan, there are // When all segments are ignored in SegmentMan, there are
// no URIs available, so don't retry. // no URIs available, so don't retry.
if (sm->allSegmentsIgnored()) { if(getSegmentMan()->allSegmentsIgnored()) {
A2_LOG_DEBUG("All segments are ignored."); A2_LOG_DEBUG("All segments are ignored.");
// This will execute other idle Commands and let them // This will execute other idle Commands and let them
// finish quickly. // finish quickly.
e_->setRefreshInterval(0); e_->setRefreshInterval(0);
return true; return true;
} } else {
return prepareForRetry(1); return prepareForRetry(1);
} }
} }
else { } else {
// For multi-file downloads // For multi-file downloads
size_t minSplitSize = calculateMinSplitSize(); size_t minSplitSize = calculateMinSplitSize();
size_t maxSegments = req_->getMaxPipelinedRequest(); size_t maxSegments = req_->getMaxPipelinedRequest();
if(segments_.size() < maxSegments) { if(segments_.size() < maxSegments) {
sm->getSegment( getSegmentMan()->getSegment
segments_, getCuid(), minSplitSize, fileEntry_, maxSegments); (segments_, getCuid(), minSplitSize, fileEntry_, maxSegments);
} }
if(segments_.empty()) { if(segments_.empty()) {
return prepareForRetry(0); return prepareForRetry(0);
} }
} }
}
return executeInternal(); return executeInternal();
} } else if(errorEventEnabled()) {
throw DL_RETRY_EX(fmt(MSG_NETWORK_PROBLEM,
if (errorEventEnabled()) { socket_->getSocketError().c_str()));
throw DL_RETRY_EX( } else {
fmt(MSG_NETWORK_PROBLEM, socket_->getSocketError().c_str()));
}
if(checkPoint_.difference(global::wallclock()) >= timeout_) { if(checkPoint_.difference(global::wallclock()) >= timeout_) {
// timeout triggers ServerStat error state. // timeout triggers ServerStat error state.
auto ss = e_->getRequestGroupMan()->getOrCreateServerStat( std::shared_ptr<ServerStat> ss =
req_->getHost(), req_->getProtocol()); e_->getRequestGroupMan()->getOrCreateServerStat(req_->getHost(),
req_->getProtocol());
ss->setError(); ss->setError();
// When DNS query was timeout, req_->getConnectedAddr() is // When DNS query was timeout, req_->getConnectedAddr() is
// empty. // empty.
@ -324,53 +290,56 @@ bool AbstractCommand::execute()
req_->getConnectedAddr(), req_->getConnectedAddr(),
req_->getConnectedPort()); req_->getConnectedPort());
} }
if (e_->findCachedIPAddress(req_->getConnectedHostname(), if(e_->findCachedIPAddress
req_->getConnectedPort()).empty()) { (req_->getConnectedHostname(), req_->getConnectedPort()).empty()) {
A2_LOG_DEBUG(fmt("CUID#%" PRId64 " - All IP addresses were marked bad." A2_LOG_DEBUG(fmt("CUID#%" PRId64 " - All IP addresses were marked bad."
" Removing Entry.", " Removing Entry.",
getCuid())); getCuid()));
e_->removeCachedIPAddress(req_->getConnectedHostname(), e_->removeCachedIPAddress
req_->getConnectedPort()); (req_->getConnectedHostname(), req_->getConnectedPort());
} }
throw DL_RETRY_EX2(EX_TIME_OUT, error_code::TIME_OUT); throw DL_RETRY_EX2(EX_TIME_OUT, error_code::TIME_OUT);
} }
addCommandSelf(); addCommandSelf();
return false; return false;
} }
catch (DlAbortEx &err) { } catch(DlAbortEx& err) {
requestGroup_->setLastErrorCode(err.getErrorCode()); requestGroup_->setLastErrorCode(err.getErrorCode());
if(req_) { if(req_) {
A2_LOG_ERROR_EX( A2_LOG_ERROR_EX(fmt(MSG_DOWNLOAD_ABORTED,
fmt(MSG_DOWNLOAD_ABORTED, getCuid(), req_->getUri().c_str()), getCuid(),
DL_ABORT_EX2(fmt("URI=%s", req_->getCurrentUri().c_str()), err)); req_->getUri().c_str()),
DL_ABORT_EX2(fmt("URI=%s", req_->getCurrentUri().c_str()),
err));
fileEntry_->addURIResult(req_->getUri(), err.getErrorCode()); fileEntry_->addURIResult(req_->getUri(), err.getErrorCode());
if(err.getErrorCode() == error_code::CANNOT_RESUME) { if(err.getErrorCode() == error_code::CANNOT_RESUME) {
requestGroup_->increaseResumeFailureCount(); requestGroup_->increaseResumeFailureCount();
} }
} } else {
else {
A2_LOG_DEBUG_EX(EX_EXCEPTION_CAUGHT, err); A2_LOG_DEBUG_EX(EX_EXCEPTION_CAUGHT, err);
} }
onAbort(); onAbort();
tryReserved(); tryReserved();
return true; return true;
} } catch(DlRetryEx& err) {
catch (DlRetryEx &err) {
assert(req_); assert(req_);
A2_LOG_INFO_EX( A2_LOG_INFO_EX(fmt(MSG_RESTARTING_DOWNLOAD,
fmt(MSG_RESTARTING_DOWNLOAD, getCuid(), req_->getUri().c_str()), getCuid(), req_->getUri().c_str()),
DL_RETRY_EX2(fmt("URI=%s", req_->getCurrentUri().c_str()), err)); DL_RETRY_EX2(fmt("URI=%s", req_->getCurrentUri().c_str()),
err));
req_->addTryCount(); req_->addTryCount();
req_->resetRedirectCount(); req_->resetRedirectCount();
req_->resetUri(); req_->resetUri();
const int maxTries = getOption()->getAsInt(PREF_MAX_TRIES); const int maxTries = getOption()->getAsInt(PREF_MAX_TRIES);
bool isAbort = maxTries != 0 && req_->getTryCount() >= maxTries; bool isAbort = maxTries != 0 && req_->getTryCount() >= maxTries;
if(isAbort) { if(isAbort) {
A2_LOG_INFO(fmt(MSG_MAX_TRY, getCuid(), req_->getTryCount())); A2_LOG_INFO(fmt(MSG_MAX_TRY,
A2_LOG_ERROR_EX( getCuid(),
fmt(MSG_DOWNLOAD_ABORTED, getCuid(), req_->getUri().c_str()), err); req_->getTryCount()));
A2_LOG_ERROR_EX(fmt(MSG_DOWNLOAD_ABORTED,
getCuid(),
req_->getUri().c_str()),
err);
fileEntry_->addURIResult(req_->getUri(), err.getErrorCode()); fileEntry_->addURIResult(req_->getUri(), err.getErrorCode());
requestGroup_->setLastErrorCode(err.getErrorCode()); requestGroup_->setLastErrorCode(err.getErrorCode());
if(err.getErrorCode() == error_code::CANNOT_RESUME) { if(err.getErrorCode() == error_code::CANNOT_RESUME) {
@ -379,19 +348,20 @@ bool AbstractCommand::execute()
onAbort(); onAbort();
tryReserved(); tryReserved();
return true; return true;
} } else {
Timer wakeTime(global::wallclock()); Timer wakeTime(global::wallclock());
wakeTime.advance(getOption()->getAsInt(PREF_RETRY_WAIT)); wakeTime.advance(getOption()->getAsInt(PREF_RETRY_WAIT));
req_->setWakeTime(wakeTime); req_->setWakeTime(wakeTime);
return prepareForRetry(0); return prepareForRetry(0);
} }
catch (DownloadFailureException &err) { } catch(DownloadFailureException& err) {
requestGroup_->setLastErrorCode(err.getErrorCode()); requestGroup_->setLastErrorCode(err.getErrorCode());
if(req_) { if(req_) {
A2_LOG_ERROR_EX( A2_LOG_ERROR_EX(fmt(MSG_DOWNLOAD_ABORTED,
fmt(MSG_DOWNLOAD_ABORTED, getCuid(), req_->getUri().c_str()), getCuid(),
DL_ABORT_EX2(fmt("URI=%s", req_->getCurrentUri().c_str()), err)); req_->getUri().c_str()),
DL_ABORT_EX2(fmt("URI=%s", req_->getCurrentUri().c_str()),
err));
fileEntry_->addURIResult(req_->getUri(), err.getErrorCode()); fileEntry_->addURIResult(req_->getUri(), err.getErrorCode());
} else { } else {
A2_LOG_ERROR_EX(EX_EXCEPTION_CAUGHT, err); A2_LOG_ERROR_EX(EX_EXCEPTION_CAUGHT, err);
@ -402,10 +372,10 @@ bool AbstractCommand::execute()
} }
} }
void AbstractCommand::tryReserved() void AbstractCommand::tryReserved() {
{
if(getDownloadContext()->getFileEntries().size() == 1) { if(getDownloadContext()->getFileEntries().size() == 1) {
const auto &entry = getDownloadContext()->getFirstFileEntry(); const std::shared_ptr<FileEntry>& entry =
getDownloadContext()->getFirstFileEntry();
// Don't create new command if currently file length is unknown // Don't create new command if currently file length is unknown
// and there are no URI left. Because file length is unknown, we // and there are no URI left. Because file length is unknown, we
// can assume that there are no in-flight request object. // can assume that there are no in-flight request object.
@ -417,16 +387,15 @@ void AbstractCommand::tryReserved()
return; return;
} }
} }
A2_LOG_DEBUG( A2_LOG_DEBUG(fmt("CUID#%" PRId64 " - Trying reserved/pooled request.",
fmt("CUID#%" PRId64 " - Trying reserved/pooled request.", getCuid())); getCuid()));
std::vector<std::unique_ptr<Command>> commands; std::vector<std::unique_ptr<Command>> commands;
requestGroup_->createNextCommand(commands, e_, 1); requestGroup_->createNextCommand(commands, e_, 1);
e_->setNoWait(true); e_->setNoWait(true);
e_->addCommand(std::move(commands)); e_->addCommand(std::move(commands));
} }
bool AbstractCommand::prepareForRetry(time_t wait) bool AbstractCommand::prepareForRetry(time_t wait) {
{
if(getPieceStorage()) { if(getPieceStorage()) {
getSegmentMan()->cancelSegment(getCuid()); getSegmentMan()->cancelSegment(getCuid());
} }
@ -439,19 +408,17 @@ bool AbstractCommand::prepareForRetry(time_t wait)
fileEntry_->poolRequest(req_); fileEntry_->poolRequest(req_);
A2_LOG_DEBUG(fmt("CUID#%" PRId64 " - Pooling request URI=%s", A2_LOG_DEBUG(fmt("CUID#%" PRId64 " - Pooling request URI=%s",
getCuid(), getCuid(), req_->getUri().c_str()));
req_->getUri().c_str()));
if(getSegmentMan()) { if(getSegmentMan()) {
getSegmentMan()->recognizeSegmentFor(fileEntry_); getSegmentMan()->recognizeSegmentFor(fileEntry_);
} }
} }
auto command = auto command = make_unique<CreateRequestCommand>(getCuid(),
make_unique<CreateRequestCommand>(getCuid(), requestGroup_, e_); requestGroup_, e_);
if(wait == 0) { if(wait == 0) {
e_->setNoWait(true); e_->setNoWait(true);
} } else {
else {
// We don't use wait so that Command can be executed by // We don't use wait so that Command can be executed by
// DownloadEngine::setRefreshInterval(0). // DownloadEngine::setRefreshInterval(0).
command->setStatus(Command::STATUS_INACTIVE); command->setStatus(Command::STATUS_INACTIVE);
@ -460,34 +427,26 @@ bool AbstractCommand::prepareForRetry(time_t wait)
return true; return true;
} }
void AbstractCommand::onAbort() void AbstractCommand::onAbort() {
{
if(req_) { if(req_) {
fileEntry_->removeIdenticalURI(req_->getUri()); fileEntry_->removeIdenticalURI(req_->getUri());
fileEntry_->removeRequest(req_); fileEntry_->removeRequest(req_);
} }
A2_LOG_DEBUG(fmt("CUID#%" PRId64 " - Aborting download",
A2_LOG_DEBUG(fmt("CUID#%" PRId64 " - Aborting download", getCuid())); getCuid()));
if (!getPieceStorage()) { if(getPieceStorage()) {
return;
}
getSegmentMan()->cancelSegment(getCuid()); getSegmentMan()->cancelSegment(getCuid());
// Don't do following process if BitTorrent is involved or files // Don't do following process if BitTorrent is involved or files
// in DownloadContext is more than 1. The latter condition is // in DownloadContext is more than 1. The latter condition is
// limitation of current implementation. // limitation of current implementation.
if (getOption()->getAsBool(PREF_ALWAYS_RESUME) || !fileEntry_ || if(!getOption()->getAsBool(PREF_ALWAYS_RESUME) &&
getDownloadContext()->getNetStat().getSessionDownloadLength() != 0 || fileEntry_ &&
requestGroup_->p2pInvolved() || getDownloadContext()->getNetStat().getSessionDownloadLength() == 0 &&
getDownloadContext()->getFileEntries().size() != 1) { !requestGroup_->p2pInvolved() &&
return; getDownloadContext()->getFileEntries().size() == 1) {
}
const int maxTries = getOption()->getAsInt(PREF_MAX_RESUME_FAILURE_TRIES); const int maxTries = getOption()->getAsInt(PREF_MAX_RESUME_FAILURE_TRIES);
if (!(maxTries > 0 && requestGroup_->getResumeFailureCount() >= maxTries) && if((maxTries > 0 && requestGroup_->getResumeFailureCount() >= maxTries)||
!fileEntry_->emptyRequestUri()) { fileEntry_->emptyRequestUri()) {
return;
}
// Local file exists, but given servers(or at least contacted // Local file exists, but given servers(or at least contacted
// ones) doesn't support resume. Let's restart download from // ones) doesn't support resume. Let's restart download from
// scratch. // scratch.
@ -502,18 +461,13 @@ void AbstractCommand::onAbort()
getOption()->put(PREF_ALWAYS_RESUME, A2_V_TRUE); getOption()->put(PREF_ALWAYS_RESUME, A2_V_TRUE);
std::deque<URIResult> res; std::deque<URIResult> res;
fileEntry_->extractURIResult(res, error_code::CANNOT_RESUME); fileEntry_->extractURIResult(res, error_code::CANNOT_RESUME);
if (res.empty()) { if(!res.empty()) {
return;
}
getSegmentMan()->cancelAllSegments(); getSegmentMan()->cancelAllSegments();
getSegmentMan()->eraseSegmentWrittenLengthMemo(); getSegmentMan()->eraseSegmentWrittenLengthMemo();
getPieceStorage()->markPiecesDone(0); getPieceStorage()->markPiecesDone(0);
std::vector<std::string> uris; std::vector<std::string> uris;
uris.reserve(res.size()); uris.reserve(res.size());
std::transform(res.begin(), std::transform(res.begin(), res.end(), std::back_inserter(uris),
res.end(),
std::back_inserter(uris),
std::mem_fn(&URIResult::getURI)); std::mem_fn(&URIResult::getURI));
A2_LOG_DEBUG(fmt("CUID#%" PRId64 " - %lu URIs found.", A2_LOG_DEBUG(fmt("CUID#%" PRId64 " - %lu URIs found.",
getCuid(), getCuid(),
@ -521,94 +475,84 @@ void AbstractCommand::onAbort()
fileEntry_->addUris(uris.begin(), uris.end()); fileEntry_->addUris(uris.begin(), uris.end());
getSegmentMan()->recognizeSegmentFor(fileEntry_); getSegmentMan()->recognizeSegmentFor(fileEntry_);
} }
}
void AbstractCommand::disableReadCheckSocket() }
{ }
if (!checkSocketIsReadable_) {
return;
} }
void AbstractCommand::disableReadCheckSocket() {
if(checkSocketIsReadable_) {
e_->deleteSocketForReadCheck(readCheckTarget_, this); e_->deleteSocketForReadCheck(readCheckTarget_, this);
checkSocketIsReadable_ = false; checkSocketIsReadable_ = false;
readCheckTarget_.reset(); readCheckTarget_.reset();
} }
void
AbstractCommand::setReadCheckSocket(const std::shared_ptr<SocketCore> &socket)
{
if (!socket->isOpen()) {
disableReadCheckSocket();
return;
} }
void AbstractCommand::setReadCheckSocket
(const std::shared_ptr<SocketCore>& socket) {
if(!socket->isOpen()) {
disableReadCheckSocket();
} else {
if(checkSocketIsReadable_) { if(checkSocketIsReadable_) {
if(*readCheckTarget_ != *socket) { if(*readCheckTarget_ != *socket) {
e_->deleteSocketForReadCheck(readCheckTarget_, this); e_->deleteSocketForReadCheck(readCheckTarget_, this);
e_->addSocketForReadCheck(socket, this); e_->addSocketForReadCheck(socket, this);
readCheckTarget_ = socket; readCheckTarget_ = socket;
} }
return; } else {
}
e_->addSocketForReadCheck(socket, this); e_->addSocketForReadCheck(socket, this);
checkSocketIsReadable_ = true; checkSocketIsReadable_ = true;
readCheckTarget_ = socket; readCheckTarget_ = socket;
} }
}
}
void void AbstractCommand::setReadCheckSocketIf
AbstractCommand::setReadCheckSocketIf(const std::shared_ptr<SocketCore> &socket, (const std::shared_ptr<SocketCore>& socket, bool pred)
bool pred)
{ {
if(pred) { if(pred) {
setReadCheckSocket(socket); setReadCheckSocket(socket);
return; } else {
}
disableReadCheckSocket(); disableReadCheckSocket();
} }
void AbstractCommand::disableWriteCheckSocket()
{
if (!checkSocketIsWritable_) {
return;
} }
void AbstractCommand::disableWriteCheckSocket() {
if(checkSocketIsWritable_) {
e_->deleteSocketForWriteCheck(writeCheckTarget_, this); e_->deleteSocketForWriteCheck(writeCheckTarget_, this);
checkSocketIsWritable_ = false; checkSocketIsWritable_ = false;
writeCheckTarget_.reset(); writeCheckTarget_.reset();
} }
void
AbstractCommand::setWriteCheckSocket(const std::shared_ptr<SocketCore> &socket)
{
if (!socket->isOpen()) {
disableWriteCheckSocket();
return;
} }
void AbstractCommand::setWriteCheckSocket
(const std::shared_ptr<SocketCore>& socket) {
if(!socket->isOpen()) {
disableWriteCheckSocket();
} else {
if(checkSocketIsWritable_) { if(checkSocketIsWritable_) {
if(*writeCheckTarget_ != *socket) { if(*writeCheckTarget_ != *socket) {
e_->deleteSocketForWriteCheck(writeCheckTarget_, this); e_->deleteSocketForWriteCheck(writeCheckTarget_, this);
e_->addSocketForWriteCheck(socket, this); e_->addSocketForWriteCheck(socket, this);
writeCheckTarget_ = socket; writeCheckTarget_ = socket;
} }
return; } else {
}
e_->addSocketForWriteCheck(socket, this); e_->addSocketForWriteCheck(socket, this);
checkSocketIsWritable_ = true; checkSocketIsWritable_ = true;
writeCheckTarget_ = socket; writeCheckTarget_ = socket;
} }
}
}
void AbstractCommand::setWriteCheckSocketIf( void AbstractCommand::setWriteCheckSocketIf
const std::shared_ptr<SocketCore> &socket, bool pred) (const std::shared_ptr<SocketCore>& socket, bool pred)
{ {
if(pred) { if(pred) {
setWriteCheckSocket(socket); setWriteCheckSocket(socket);
return; } else {
}
disableWriteCheckSocket(); disableWriteCheckSocket();
} }
}
void AbstractCommand::swapSocket(std::shared_ptr<SocketCore>& socket) void AbstractCommand::swapSocket(std::shared_ptr<SocketCore>& socket)
{ {
@ -620,15 +564,14 @@ void AbstractCommand::swapSocket(std::shared_ptr<SocketCore> &socket)
namespace { namespace {
// Constructs proxy URI, merging username and password if they are // Constructs proxy URI, merging username and password if they are
// defined. // defined.
std::string makeProxyUri(PrefPtr proxyPref, std::string makeProxyUri
(PrefPtr proxyPref,
PrefPtr proxyUser, PrefPtr proxyUser,
PrefPtr proxyPasswd, PrefPtr proxyPasswd,
const Option* option) const Option* option)
{ {
uri::UriStruct us; uri::UriStruct us;
if (!uri::parse(us, option->get(proxyPref))) { if(uri::parse(us, option->get(proxyPref))) {
return "";
}
if(option->defined(proxyUser)) { if(option->defined(proxyUser)) {
us.username = option->get(proxyUser); us.username = option->get(proxyUser);
} }
@ -637,55 +580,60 @@ std::string makeProxyUri(PrefPtr proxyPref,
us.hasPassword = true; us.hasPassword = true;
} }
return uri::construct(us); return uri::construct(us);
} else {
return "";
}
} }
} // namespace } // namespace
namespace { namespace {
// Returns proxy option value for the given protocol. // Returns proxy option value for the given protocol.
std::string getProxyOptionFor(PrefPtr proxyPref, std::string getProxyOptionFor
(PrefPtr proxyPref,
PrefPtr proxyUser, PrefPtr proxyUser,
PrefPtr proxyPasswd, PrefPtr proxyPasswd,
const Option* option) const Option* option)
{ {
std::string uri = makeProxyUri(proxyPref, proxyUser, proxyPasswd, option); std::string uri = makeProxyUri(proxyPref, proxyUser, proxyPasswd, option);
if(uri.empty()) { if(uri.empty()) {
return makeProxyUri( return makeProxyUri(PREF_ALL_PROXY, PREF_ALL_PROXY_USER,
PREF_ALL_PROXY, PREF_ALL_PROXY_USER, PREF_ALL_PROXY_PASSWD, option); PREF_ALL_PROXY_PASSWD, option);
} } else {
return uri; return uri;
} }
}
} // namespace } // namespace
// Returns proxy URI for given protocol. If no proxy URI is defined, // Returns proxy URI for given protocol. If no proxy URI is defined,
// then returns an empty string. // then returns an empty string.
std::string getProxyUri(const std::string &protocol, const Option *option) std::string getProxyUri
(const std::string& protocol, const Option* option)
{ {
if(protocol == "http") { if(protocol == "http") {
return getProxyOptionFor( return getProxyOptionFor(PREF_HTTP_PROXY,
PREF_HTTP_PROXY, PREF_HTTP_PROXY_USER, PREF_HTTP_PROXY_PASSWD, option); PREF_HTTP_PROXY_USER,
} PREF_HTTP_PROXY_PASSWD,
option);
if (protocol == "https") { } else if(protocol == "https") {
return getProxyOptionFor(PREF_HTTPS_PROXY, return getProxyOptionFor(PREF_HTTPS_PROXY,
PREF_HTTPS_PROXY_USER, PREF_HTTPS_PROXY_USER,
PREF_HTTPS_PROXY_PASSWD, PREF_HTTPS_PROXY_PASSWD,
option); option);
} } else if(protocol == "ftp") {
return getProxyOptionFor(PREF_FTP_PROXY,
if (protocol == "ftp") { PREF_FTP_PROXY_USER,
return getProxyOptionFor( PREF_FTP_PROXY_PASSWD,
PREF_FTP_PROXY, PREF_FTP_PROXY_USER, PREF_FTP_PROXY_PASSWD, option); option);
} } else {
return A2STR::NIL; return A2STR::NIL;
} }
}
namespace { namespace {
// Returns true if proxy is defined for the given protocol. Otherwise // Returns true if proxy is defined for the given protocol. Otherwise
// returns false. // returns false.
bool isProxyRequest(const std::string &protocol, bool isProxyRequest
const std::shared_ptr<Option> &option) (const std::string& protocol, const std::shared_ptr<Option>& option)
{ {
std::string proxyUri = getProxyUri(protocol, option.get()); std::string proxyUri = getProxyUri(protocol, option.get());
return !proxyUri.empty(); return !proxyUri.empty();
@ -693,36 +641,39 @@ bool isProxyRequest(const std::string &protocol,
} // namespace } // namespace
namespace { namespace {
bool inNoProxy(const std::shared_ptr<Request> &req, const std::string &noProxy) bool inNoProxy(const std::shared_ptr<Request>& req,
const std::string& noProxy)
{ {
std::vector<Scip> entries; std::vector<Scip> entries;
util::splitIter( util::splitIter(noProxy.begin(), noProxy.end(), std::back_inserter(entries),
noProxy.begin(), noProxy.end(), std::back_inserter(entries), ',', true); ',', true);
if(entries.empty()) { if(entries.empty()) {
return false; return false;
} }
for(std::vector<Scip>::const_iterator i = entries.begin(),
for (const auto &e : entries) { eoi = entries.end(); i != eoi; ++i) {
const auto slashpos = std::find(e.first, e.second, '/'); std::string::const_iterator slashpos =
if (slashpos == e.second) { std::find((*i).first, (*i).second, '/');
if (util::noProxyDomainMatch(req->getHost(), if(slashpos == (*i).second) {
std::string(e.first, e.second))) { if(util::noProxyDomainMatch
(req->getHost(), std::string((*i).first, (*i).second))) {
return true; return true;
} }
} } else {
// TODO We don't resolve hostname here. More complete // TODO We don't resolve hostname here. More complete
// implementation is that we should first resolve // implementation is that we should first resolve
// hostname(which may result in several IP addresses) and // hostname(which may result in several IP addresses) and
// evaluates against all of them // evaluates against all of them
std::string ip(e.first, slashpos); std::string ip((*i).first, slashpos);
uint32_t bits; uint32_t bits;
if (!util::parseUIntNoThrow(bits, std::string(slashpos + 1, e.second))) { if(!util::parseUIntNoThrow(bits, std::string(slashpos+1, (*i).second))) {
continue; continue;
} }
if(util::inSameCidrBlock(ip, req->getHost(), bits)) { if(util::inSameCidrBlock(ip, req->getHost(), bits)) {
return true; return true;
} }
} }
}
return false; return false;
} }
} // namespace } // namespace
@ -739,42 +690,30 @@ std::shared_ptr<Request> AbstractCommand::createProxyRequest() const
if(inNoProxy(req_, getOption()->get(PREF_NO_PROXY))) { if(inNoProxy(req_, getOption()->get(PREF_NO_PROXY))) {
return proxyRequest; return proxyRequest;
} }
std::string proxy = getProxyUri(req_->getProtocol(), getOption().get()); std::string proxy = getProxyUri(req_->getProtocol(), getOption().get());
if(!proxy.empty()) { if(!proxy.empty()) {
proxyRequest.reset(new Request()); proxyRequest.reset(new Request());
if(proxyRequest->setUri(proxy)) { if(proxyRequest->setUri(proxy)) {
A2_LOG_DEBUG(fmt("CUID#%" PRId64 " - Using proxy", getCuid())); A2_LOG_DEBUG(fmt("CUID#%" PRId64 " - Using proxy", getCuid()));
} } else {
else { A2_LOG_DEBUG(fmt("CUID#%" PRId64 " - Failed to parse proxy string",
A2_LOG_DEBUG( getCuid()));
fmt("CUID#%" PRId64 " - Failed to parse proxy string", getCuid()));
proxyRequest.reset(); proxyRequest.reset();
} }
} }
return proxyRequest; return proxyRequest;
} }
std::string AbstractCommand::resolveHostname(std::vector<std::string> &addrs, std::string AbstractCommand::resolveHostname
const std::string &hostname, (std::vector<std::string>& addrs, const std::string& hostname, uint16_t port)
uint16_t port)
{ {
if(util::isNumericHost(hostname)) { if(util::isNumericHost(hostname)) {
addrs.push_back(hostname); addrs.push_back(hostname);
return hostname; return hostname;
} }
e_->findAllCachedIPAddresses(std::back_inserter(addrs), hostname, port); e_->findAllCachedIPAddresses(std::back_inserter(addrs), hostname, port);
if (!addrs.empty()) {
auto ipaddr = addrs.front();
A2_LOG_INFO(fmt(MSG_DNS_CACHE_HIT,
getCuid(),
hostname.c_str(),
strjoin(addrs.begin(), addrs.end(), ", ").c_str()));
return ipaddr;
}
std::string ipaddr; std::string ipaddr;
if(addrs.empty()) {
#ifdef ENABLE_ASYNC_DNS #ifdef ENABLE_ASYNC_DNS
if(getOption()->getAsBool(PREF_ASYNC_DNS)) { if(getOption()->getAsBool(PREF_ASYNC_DNS)) {
if(!asyncNameResolverMan_->started()) { if(!asyncNameResolverMan_->started()) {
@ -783,31 +722,26 @@ std::string AbstractCommand::resolveHostname(std::vector<std::string> &addrs,
switch(asyncNameResolverMan_->getStatus()) { switch(asyncNameResolverMan_->getStatus()) {
case -1: case -1:
if(!isProxyRequest(req_->getProtocol(), getOption())) { if(!isProxyRequest(req_->getProtocol(), getOption())) {
e_->getRequestGroupMan() e_->getRequestGroupMan()->getOrCreateServerStat
->getOrCreateServerStat(req_->getHost(), req_->getProtocol()) (req_->getHost(), req_->getProtocol())->setError();
->setError();
} }
throw DL_ABORT_EX2(fmt(MSG_NAME_RESOLUTION_FAILED, throw DL_ABORT_EX2
getCuid(), (fmt(MSG_NAME_RESOLUTION_FAILED, getCuid(), hostname.c_str(),
hostname.c_str(),
asyncNameResolverMan_->getLastError().c_str()), asyncNameResolverMan_->getLastError().c_str()),
error_code::NAME_RESOLVE_ERROR); error_code::NAME_RESOLVE_ERROR);
case 0: case 0:
return A2STR::NIL; return A2STR::NIL;
case 1: case 1:
asyncNameResolverMan_->getResolvedAddress(addrs); asyncNameResolverMan_->getResolvedAddress(addrs);
if(addrs.empty()) { if(addrs.empty()) {
throw DL_ABORT_EX2(fmt(MSG_NAME_RESOLUTION_FAILED, throw DL_ABORT_EX2
getCuid(), (fmt(MSG_NAME_RESOLUTION_FAILED, getCuid(), hostname.c_str(),
hostname.c_str(),
"No address returned"), "No address returned"),
error_code::NAME_RESOLVE_ERROR); error_code::NAME_RESOLVE_ERROR);
} }
break; break;
} }
} } else
else
#endif // ENABLE_ASYNC_DNS #endif // ENABLE_ASYNC_DNS
{ {
NameResolver res; NameResolver res;
@ -821,67 +755,74 @@ std::string AbstractCommand::resolveHostname(std::vector<std::string> &addrs,
getCuid(), getCuid(),
hostname.c_str(), hostname.c_str(),
strjoin(addrs.begin(), addrs.end(), ", ").c_str())); strjoin(addrs.begin(), addrs.end(), ", ").c_str()));
for (const auto &addr: addrs) { for(std::vector<std::string>::const_iterator i = addrs.begin(),
e_->cacheIPAddress(hostname, addr, port); eoi = addrs.end(); i != eoi; ++i) {
e_->cacheIPAddress(hostname, *i, port);
} }
ipaddr = e_->findCachedIPAddress(hostname, port); ipaddr = e_->findCachedIPAddress(hostname, port);
} else {
ipaddr = addrs.front();
A2_LOG_INFO(fmt(MSG_DNS_CACHE_HIT,
getCuid(),
hostname.c_str(),
strjoin(addrs.begin(), addrs.end(), ", ").c_str()));
}
return ipaddr; return ipaddr;
} }
void AbstractCommand::prepareForNextAction( void AbstractCommand::prepareForNextAction
std::unique_ptr<CheckIntegrityEntry> checkEntry) (std::unique_ptr<CheckIntegrityEntry> checkEntry)
{ {
std::vector<std::unique_ptr<Command>> commands; std::vector<std::unique_ptr<Command>> commands;
requestGroup_->processCheckIntegrityEntry( requestGroup_->processCheckIntegrityEntry(commands, std::move(checkEntry),
commands, std::move(checkEntry), e_); e_);
e_->addCommand(std::move(commands)); e_->addCommand(std::move(commands));
e_->setNoWait(true); e_->setNoWait(true);
} }
bool AbstractCommand::checkIfConnectionEstablished( bool AbstractCommand::checkIfConnectionEstablished
const std::shared_ptr<SocketCore> &socket, (const std::shared_ptr<SocketCore>& socket,
const std::string& connectedHostname, const std::string& connectedHostname,
const std::string& connectedAddr, const std::string& connectedAddr,
uint16_t connectedPort) uint16_t connectedPort)
{ {
std::string error = socket->getSocketError(); std::string error = socket->getSocketError();
if (error.empty()) { if(!error.empty()) {
return true;
}
// See also InitiateConnectionCommand::executeInternal() // See also InitiateConnectionCommand::executeInternal()
e_->markBadIPAddress(connectedHostname, connectedAddr, connectedPort); e_->markBadIPAddress(connectedHostname, connectedAddr, connectedPort);
if (e_->findCachedIPAddress(connectedHostname, connectedPort).empty()) { if(!e_->findCachedIPAddress(connectedHostname, connectedPort).empty()) {
A2_LOG_INFO(fmt(MSG_CONNECT_FAILED_AND_RETRY,
getCuid(),
connectedAddr.c_str(), connectedPort));
e_->setNoWait(true);
e_->addCommand(InitiateConnectionCommandFactory::
createInitiateConnectionCommand
(getCuid(), req_, fileEntry_, requestGroup_, e_));
return false;
}
e_->removeCachedIPAddress(connectedHostname, connectedPort); e_->removeCachedIPAddress(connectedHostname, connectedPort);
// Don't set error if proxy server is used and its method is GET. // Don't set error if proxy server is used and its method is GET.
if(resolveProxyMethod(req_->getProtocol()) != V_GET || if(resolveProxyMethod(req_->getProtocol()) != V_GET ||
!isProxyRequest(req_->getProtocol(), getOption())) { !isProxyRequest(req_->getProtocol(), getOption())) {
e_->getRequestGroupMan() e_->getRequestGroupMan()->getOrCreateServerStat
->getOrCreateServerStat(req_->getHost(), req_->getProtocol()) (req_->getHost(), req_->getProtocol())->setError();
->setError();
} }
throw DL_RETRY_EX(fmt(MSG_ESTABLISHING_CONNECTION_FAILED, error.c_str())); throw DL_RETRY_EX
(fmt(MSG_ESTABLISHING_CONNECTION_FAILED, error.c_str()));
}
return true;
} }
A2_LOG_INFO(fmt(MSG_CONNECT_FAILED_AND_RETRY, const std::string& AbstractCommand::resolveProxyMethod
getCuid(), (const std::string& protocol) const
connectedAddr.c_str(),
connectedPort));
e_->setNoWait(true);
e_->addCommand(
InitiateConnectionCommandFactory::createInitiateConnectionCommand(
getCuid(), req_, fileEntry_, requestGroup_, e_));
return false;
}
const std::string&
AbstractCommand::resolveProxyMethod(const std::string &protocol) const
{ {
if (getOption()->get(PREF_PROXY_METHOD) == V_TUNNEL || protocol == "https") { if(getOption()->get(PREF_PROXY_METHOD) == V_TUNNEL ||
protocol == "https") {
return V_TUNNEL; return V_TUNNEL;
} } else {
return V_GET; return V_GET;
} }
}
const std::shared_ptr<Option>& AbstractCommand::getOption() const const std::shared_ptr<Option>& AbstractCommand::getOption() const
{ {
@ -897,10 +838,10 @@ int32_t AbstractCommand::calculateMinSplitSize() const
{ {
if(req_ && req_->isPipeliningEnabled()) { if(req_ && req_->isPipeliningEnabled()) {
return getDownloadContext()->getPieceLength(); return getDownloadContext()->getPieceLength();
} } else {
return getOption()->getAsInt(PREF_MIN_SPLIT_SIZE); return getOption()->getAsInt(PREF_MIN_SPLIT_SIZE);
} }
}
void AbstractCommand::setRequest(const std::shared_ptr<Request>& request) void AbstractCommand::setRequest(const std::shared_ptr<Request>& request)
{ {
@ -922,8 +863,7 @@ void AbstractCommand::setSocket(const std::shared_ptr<SocketCore>& s)
socket_ = s; socket_ = s;
} }
const std::shared_ptr<DownloadContext>& const std::shared_ptr<DownloadContext>& AbstractCommand::getDownloadContext() const
AbstractCommand::getDownloadContext() const
{ {
return requestGroup_->getDownloadContext(); return requestGroup_->getDownloadContext();
} }
@ -940,13 +880,11 @@ const std::shared_ptr<PieceStorage>& AbstractCommand::getPieceStorage() const
void AbstractCommand::checkSocketRecvBuffer() void AbstractCommand::checkSocketRecvBuffer()
{ {
if (socketRecvBuffer_->bufferEmpty()) { if(!socketRecvBuffer_->bufferEmpty()) {
return;
}
setStatus(Command::STATUS_ONESHOT_REALTIME); setStatus(Command::STATUS_ONESHOT_REALTIME);
e_->setNoWait(true); e_->setNoWait(true);
} }
}
void AbstractCommand::addCommandSelf() void AbstractCommand::addCommandSelf()
{ {

View File

@ -43,8 +43,7 @@
#include "TimerA2.h" #include "TimerA2.h"
namespace aria2 namespace aria2 {
{
class FileEntry; class FileEntry;
class RequestGroup; class RequestGroup;
@ -63,8 +62,7 @@ class AsyncNameResolver;
class AsyncNameResolverMan; class AsyncNameResolverMan;
#endif // ENABLE_ASYNC_DNS #endif // ENABLE_ASYNC_DNS
class AbstractCommand : public Command class AbstractCommand : public Command {
{
private: private:
std::shared_ptr<Request> req_; std::shared_ptr<Request> req_;
std::shared_ptr<FileEntry> fileEntry_; std::shared_ptr<FileEntry> fileEntry_;
@ -92,11 +90,8 @@ private:
bool incNumConnection_; bool incNumConnection_;
int32_t calculateMinSplitSize() const; int32_t calculateMinSplitSize() const;
void useFasterRequest(const std::shared_ptr<Request>& fasterRequest); void useFasterRequest(const std::shared_ptr<Request>& fasterRequest);
bool shouldCheck() const;
public: public:
RequestGroup* getRequestGroup() const RequestGroup* getRequestGroup() const
{ {
@ -155,32 +150,26 @@ public:
// return empty string. In this case, call this function with same // return empty string. In this case, call this function with same
// arguments until resolved address is returned. Exception is // arguments until resolved address is returned. Exception is
// thrown on error. port is used for retrieving cached addresses. // thrown on error. port is used for retrieving cached addresses.
std::string resolveHostname(std::vector<std::string> &addrs, std::string resolveHostname
const std::string &hostname, (std::vector<std::string>& addrs, const std::string& hostname, uint16_t port);
uint16_t port);
void tryReserved(); void tryReserved();
void setReadCheckSocket(const std::shared_ptr<SocketCore>& socket); void setReadCheckSocket(const std::shared_ptr<SocketCore>& socket);
void setWriteCheckSocket(const std::shared_ptr<SocketCore>& socket); void setWriteCheckSocket(const std::shared_ptr<SocketCore>& socket);
void disableReadCheckSocket(); void disableReadCheckSocket();
void disableWriteCheckSocket(); void disableWriteCheckSocket();
/** /**
* If pred == true, calls setReadCheckSocket(socket). Otherwise, calls * If pred == true, calls setReadCheckSocket(socket). Otherwise, calls
* disableReadCheckSocket(). * disableReadCheckSocket().
*/ */
void setReadCheckSocketIf(const std::shared_ptr<SocketCore> &socket, void setReadCheckSocketIf(const std::shared_ptr<SocketCore>& socket, bool pred);
bool pred);
/** /**
* If pred == true, calls setWriteCheckSocket(socket). Otherwise, calls * If pred == true, calls setWriteCheckSocket(socket). Otherwise, calls
* disableWriteCheckSocket(). * disableWriteCheckSocket().
*/ */
void setWriteCheckSocketIf(const std::shared_ptr<SocketCore> &socket, void setWriteCheckSocketIf(const std::shared_ptr<SocketCore>& socket, bool pred);
bool pred);
// Swaps socket_ with socket. This disables current read and write // Swaps socket_ with socket. This disables current read and write
// check. // check.
@ -191,10 +180,7 @@ public:
return timeout_; return timeout_;
} }
void setTimeout(time_t timeout) void setTimeout(time_t timeout) { timeout_ = timeout; }
{
timeout_ = timeout;
}
void prepareForNextAction(std::unique_ptr<CheckIntegrityEntry> checkEntry); void prepareForNextAction(std::unique_ptr<CheckIntegrityEntry> checkEntry);
@ -203,7 +189,8 @@ public:
// InitiateConnectionCommandFactory and it is pushed to // InitiateConnectionCommandFactory and it is pushed to
// DownloadEngine and returns false. If no addresses left, DlRetryEx // DownloadEngine and returns false. If no addresses left, DlRetryEx
// exception is thrown. // exception is thrown.
bool checkIfConnectionEstablished(const std::shared_ptr<SocketCore> &socket, bool checkIfConnectionEstablished
(const std::shared_ptr<SocketCore>& socket,
const std::string& connectedHostname, const std::string& connectedHostname,
const std::string& connectedAddr, const std::string& connectedAddr,
uint16_t connectedPort); uint16_t connectedPort);
@ -238,40 +225,33 @@ public:
void checkSocketRecvBuffer(); void checkSocketRecvBuffer();
void addCommandSelf(); void addCommandSelf();
protected: protected:
virtual bool prepareForRetry(time_t wait); virtual bool prepareForRetry(time_t wait);
virtual void onAbort(); virtual void onAbort();
virtual bool executeInternal() = 0; virtual bool executeInternal() = 0;
// Returns true if the derived class wants to execute // Returns true if the derived class wants to execute
// executeInternal() unconditionally // executeInternal() unconditionally
virtual bool noCheck() const virtual bool noCheck()
{ {
return false; return false;
} }
public: public:
AbstractCommand(cuid_t cuid, AbstractCommand(cuid_t cuid, const std::shared_ptr<Request>& req,
const std::shared_ptr<Request> &req,
const std::shared_ptr<FileEntry>& fileEntry, const std::shared_ptr<FileEntry>& fileEntry,
RequestGroup *requestGroup, RequestGroup* requestGroup, DownloadEngine* e,
DownloadEngine *e,
const std::shared_ptr<SocketCore>& s = nullptr, const std::shared_ptr<SocketCore>& s = nullptr,
const std::shared_ptr<SocketRecvBuffer> &socketRecvBuffer = const std::shared_ptr<SocketRecvBuffer>& socketRecvBuffer = nullptr,
nullptr,
bool incNumConnection = true); bool incNumConnection = true);
virtual ~AbstractCommand(); virtual ~AbstractCommand();
virtual bool execute() CXX11_OVERRIDE; virtual bool execute() CXX11_OVERRIDE;
}; };
// Returns proxy URI for given protocol. If no proxy URI is defined, // Returns proxy URI for given protocol. If no proxy URI is defined,
// then returns an empty string. // then returns an empty string.
std::string getProxyUri(const std::string &protocol, const Option *option); std::string getProxyUri
(const std::string& protocol, const Option* option);
} // namespace aria2 } // namespace aria2

View File

@ -115,7 +115,7 @@ bool ConnectCommand::executeInternal()
return true; return true;
} }
bool ConnectCommand::noCheck() const bool ConnectCommand::noCheck()
{ {
return backupConnectionInfo_ && !backupConnectionInfo_->ipaddr.empty(); return backupConnectionInfo_ && !backupConnectionInfo_->ipaddr.empty();
} }

View File

@ -58,7 +58,7 @@ public:
const std::shared_ptr<Request>& getProxyRequest() const; const std::shared_ptr<Request>& getProxyRequest() const;
protected: protected:
virtual bool executeInternal() CXX11_OVERRIDE; virtual bool executeInternal() CXX11_OVERRIDE;
virtual bool noCheck() const CXX11_OVERRIDE; virtual bool noCheck() CXX11_OVERRIDE;
private: private:
std::shared_ptr<Request> proxyRequest_; std::shared_ptr<Request> proxyRequest_;
std::shared_ptr<BackupConnectInfo> backupConnectionInfo_; std::shared_ptr<BackupConnectInfo> backupConnectionInfo_;

View File

@ -241,11 +241,6 @@ public:
int64_t getCompletedLength() const; int64_t getCompletedLength() const;
inline int64_t getPendingLength() const
{
return getTotalLength() - getCompletedLength();
}
/** /**
* Compares expected filename with specified actualFilename. * Compares expected filename with specified actualFilename.
* The expected filename refers to FileEntry::getBasename() of the first * The expected filename refers to FileEntry::getBasename() of the first