mirror of https://github.com/aria2/aria2
Implement simple Happy Eyeballs for HTTP/FTP downloads
parent
d671d8bf36
commit
597e1a5c1b
|
@ -225,7 +225,7 @@ bool AbstractCommand::execute() {
|
||||||
#ifdef ENABLE_ASYNC_DNS
|
#ifdef ENABLE_ASYNC_DNS
|
||||||
&& !asyncNameResolverMan_->resolverChecked()
|
&& !asyncNameResolverMan_->resolverChecked()
|
||||||
#endif // ENABLE_ASYNC_DNS
|
#endif // ENABLE_ASYNC_DNS
|
||||||
)) {
|
) || noCheck()) {
|
||||||
checkPoint_ = global::wallclock();
|
checkPoint_ = global::wallclock();
|
||||||
if(getPieceStorage()) {
|
if(getPieceStorage()) {
|
||||||
if(!req_ || req_->getMaxPipelinedRequest() == 1 ||
|
if(!req_ || req_->getMaxPipelinedRequest() == 1 ||
|
||||||
|
|
|
@ -123,6 +123,11 @@ protected:
|
||||||
return socket_;
|
return socket_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SharedHandle<SocketCore>& getSocket()
|
||||||
|
{
|
||||||
|
return socket_;
|
||||||
|
}
|
||||||
|
|
||||||
void setSocket(const SharedHandle<SocketCore>& s);
|
void setSocket(const SharedHandle<SocketCore>& s);
|
||||||
|
|
||||||
void createSocket();
|
void createSocket();
|
||||||
|
@ -215,6 +220,13 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkSocketRecvBuffer();
|
void checkSocketRecvBuffer();
|
||||||
|
|
||||||
|
// Returns true if the derived class wants to execute
|
||||||
|
// executeInternal() unconditionally
|
||||||
|
virtual bool noCheck()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
public:
|
public:
|
||||||
AbstractCommand
|
AbstractCommand
|
||||||
(cuid_t cuid, const SharedHandle<Request>& req,
|
(cuid_t cuid, const SharedHandle<Request>& req,
|
||||||
|
|
|
@ -44,6 +44,9 @@
|
||||||
#include "SocketCore.h"
|
#include "SocketCore.h"
|
||||||
#include "DownloadContext.h"
|
#include "DownloadContext.h"
|
||||||
#include "SocketRecvBuffer.h"
|
#include "SocketRecvBuffer.h"
|
||||||
|
#include "BackupIPv4ConnectCommand.h"
|
||||||
|
#include "fmt.h"
|
||||||
|
#include "LogFactory.h"
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
|
@ -67,16 +70,48 @@ AbstractProxyRequestCommand::AbstractProxyRequestCommand
|
||||||
setWriteCheckSocket(getSocket());
|
setWriteCheckSocket(getSocket());
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractProxyRequestCommand::~AbstractProxyRequestCommand() {}
|
AbstractProxyRequestCommand::~AbstractProxyRequestCommand()
|
||||||
|
{
|
||||||
|
if(backupConnectionInfo_) {
|
||||||
|
backupConnectionInfo_->cancel = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AbstractProxyRequestCommand::noCheck() {
|
||||||
|
return backupConnectionInfo_ && !backupConnectionInfo_->ipaddr.empty();
|
||||||
|
}
|
||||||
|
|
||||||
bool AbstractProxyRequestCommand::executeInternal() {
|
bool AbstractProxyRequestCommand::executeInternal() {
|
||||||
//socket->setBlockingMode();
|
//socket->setBlockingMode();
|
||||||
if(httpConnection_->sendBufferIsEmpty()) {
|
if(httpConnection_->sendBufferIsEmpty()) {
|
||||||
|
if(backupConnectionInfo_ && !backupConnectionInfo_->ipaddr.empty()) {
|
||||||
|
A2_LOG_INFO(fmt("CUID#%"PRId64" - Use backup connection address %s",
|
||||||
|
getCuid(), backupConnectionInfo_->ipaddr.c_str()));
|
||||||
|
getDownloadEngine()->markBadIPAddress
|
||||||
|
(getRequest()->getConnectedHostname(),
|
||||||
|
getRequest()->getConnectedAddr(),
|
||||||
|
getRequest()->getConnectedPort());
|
||||||
|
|
||||||
|
getRequest()->setConnectedAddrInfo(getRequest()->getConnectedHostname(),
|
||||||
|
backupConnectionInfo_->ipaddr,
|
||||||
|
getRequest()->getConnectedPort());
|
||||||
|
|
||||||
|
Command* c = createSelf(backupConnectionInfo_->socket);
|
||||||
|
c->setStatus(STATUS_ONESHOT_REALTIME);
|
||||||
|
getDownloadEngine()->setNoWait(true);
|
||||||
|
getDownloadEngine()->addCommand(c);
|
||||||
|
backupConnectionInfo_.reset();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if(!checkIfConnectionEstablished
|
if(!checkIfConnectionEstablished
|
||||||
(getSocket(), getRequest()->getConnectedHostname(),
|
(getSocket(), getRequest()->getConnectedHostname(),
|
||||||
getRequest()->getConnectedAddr(), getRequest()->getConnectedPort())) {
|
getRequest()->getConnectedAddr(), getRequest()->getConnectedPort())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if(backupConnectionInfo_) {
|
||||||
|
backupConnectionInfo_->cancel = true;
|
||||||
|
backupConnectionInfo_.reset();
|
||||||
|
}
|
||||||
SharedHandle<HttpRequest> httpRequest(new HttpRequest());
|
SharedHandle<HttpRequest> httpRequest(new HttpRequest());
|
||||||
httpRequest->setUserAgent(getOption()->get(PREF_USER_AGENT));
|
httpRequest->setUserAgent(getOption()->get(PREF_USER_AGENT));
|
||||||
httpRequest->setRequest(getRequest());
|
httpRequest->setRequest(getRequest());
|
||||||
|
@ -96,4 +131,10 @@ bool AbstractProxyRequestCommand::executeInternal() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AbstractProxyRequestCommand::setBackupConnectInfo
|
||||||
|
(const SharedHandle<BackupConnectInfo>& info)
|
||||||
|
{
|
||||||
|
backupConnectionInfo_ = info;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -41,19 +41,28 @@ namespace aria2 {
|
||||||
|
|
||||||
class HttpConnection;
|
class HttpConnection;
|
||||||
class SocketCore;
|
class SocketCore;
|
||||||
|
class BackupConnectInfo;
|
||||||
|
|
||||||
class AbstractProxyRequestCommand : public AbstractCommand {
|
class AbstractProxyRequestCommand : public AbstractCommand {
|
||||||
private:
|
private:
|
||||||
SharedHandle<Request> proxyRequest_;
|
SharedHandle<Request> proxyRequest_;
|
||||||
|
|
||||||
SharedHandle<HttpConnection> httpConnection_;
|
SharedHandle<HttpConnection> httpConnection_;
|
||||||
|
|
||||||
|
SharedHandle<BackupConnectInfo> backupConnectionInfo_;
|
||||||
protected:
|
protected:
|
||||||
virtual bool executeInternal();
|
virtual bool executeInternal();
|
||||||
|
virtual bool noCheck();
|
||||||
|
|
||||||
const SharedHandle<HttpConnection>& getHttpConnection() const
|
const SharedHandle<HttpConnection>& getHttpConnection() const
|
||||||
{
|
{
|
||||||
return httpConnection_;
|
return httpConnection_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const SharedHandle<Request>& getProxyRequest() const
|
||||||
|
{
|
||||||
|
return proxyRequest_;
|
||||||
|
}
|
||||||
public:
|
public:
|
||||||
AbstractProxyRequestCommand(cuid_t cuid,
|
AbstractProxyRequestCommand(cuid_t cuid,
|
||||||
const SharedHandle<Request>& req,
|
const SharedHandle<Request>& req,
|
||||||
|
@ -66,6 +75,8 @@ public:
|
||||||
virtual ~AbstractProxyRequestCommand();
|
virtual ~AbstractProxyRequestCommand();
|
||||||
|
|
||||||
virtual Command* getNextCommand() = 0;
|
virtual Command* getNextCommand() = 0;
|
||||||
|
virtual Command* createSelf(const SharedHandle<SocketCore>& socket) = 0;
|
||||||
|
void setBackupConnectInfo(const SharedHandle<BackupConnectInfo>& info);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -0,0 +1,140 @@
|
||||||
|
/* <!-- copyright */
|
||||||
|
/*
|
||||||
|
* aria2 - The high speed download utility
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Tatsuhiro Tsujikawa
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the copyright holders give
|
||||||
|
* permission to link the code of portions of this program with the
|
||||||
|
* OpenSSL library under certain conditions as described in each
|
||||||
|
* individual source file, and distribute linked combinations
|
||||||
|
* including the two.
|
||||||
|
* You must obey the GNU General Public License in all respects
|
||||||
|
* for all of the code used other than OpenSSL. If you modify
|
||||||
|
* file(s) with this exception, you may extend this exception to your
|
||||||
|
* version of the file(s), but you are not obligated to do so. If you
|
||||||
|
* do not wish to do so, delete this exception statement from your
|
||||||
|
* version. If you delete this exception statement from all source
|
||||||
|
* files in the program, then also delete it here.
|
||||||
|
*/
|
||||||
|
/* copyright --> */
|
||||||
|
#include "BackupIPv4ConnectCommand.h"
|
||||||
|
#include "RequestGroup.h"
|
||||||
|
#include "DownloadEngine.h"
|
||||||
|
#include "SocketCore.h"
|
||||||
|
#include "wallclock.h"
|
||||||
|
#include "RecoverableException.h"
|
||||||
|
#include "fmt.h"
|
||||||
|
#include "LogFactory.h"
|
||||||
|
#include "prefs.h"
|
||||||
|
#include "Option.h"
|
||||||
|
|
||||||
|
namespace aria2 {
|
||||||
|
|
||||||
|
BackupConnectInfo::BackupConnectInfo()
|
||||||
|
: cancel(false)
|
||||||
|
{}
|
||||||
|
|
||||||
|
BackupIPv4ConnectCommand::BackupIPv4ConnectCommand
|
||||||
|
(cuid_t cuid, const std::string& ipaddr, uint16_t port,
|
||||||
|
const SharedHandle<BackupConnectInfo>& info, Command* mainCommand,
|
||||||
|
RequestGroup* requestGroup, DownloadEngine* e)
|
||||||
|
: Command(cuid),
|
||||||
|
ipaddr_(ipaddr),
|
||||||
|
port_(port),
|
||||||
|
info_(info),
|
||||||
|
mainCommand_(mainCommand),
|
||||||
|
requestGroup_(requestGroup),
|
||||||
|
e_(e),
|
||||||
|
startTime_(global::wallclock()),
|
||||||
|
timeoutCheck_(global::wallclock()),
|
||||||
|
timeout_(requestGroup_->getOption()->getAsInt(PREF_CONNECT_TIMEOUT))
|
||||||
|
{
|
||||||
|
requestGroup_->increaseStreamCommand();
|
||||||
|
requestGroup_->increaseNumCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
BackupIPv4ConnectCommand::~BackupIPv4ConnectCommand()
|
||||||
|
{
|
||||||
|
requestGroup_->decreaseNumCommand();
|
||||||
|
requestGroup_->decreaseStreamCommand();
|
||||||
|
if(socket_) {
|
||||||
|
e_->deleteSocketForWriteCheck(socket_, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BackupIPv4ConnectCommand::execute()
|
||||||
|
{
|
||||||
|
bool retval = false;
|
||||||
|
if(requestGroup_->downloadFinished() || requestGroup_->isHaltRequested()) {
|
||||||
|
retval = true;
|
||||||
|
} else if(info_->cancel) {
|
||||||
|
A2_LOG_INFO(fmt("CUID#%"PRId64" - Backup connection canceled", getCuid()));
|
||||||
|
retval = true;
|
||||||
|
} else if(socket_) {
|
||||||
|
if(writeEventEnabled()) {
|
||||||
|
try {
|
||||||
|
std::string error = socket_->getSocketError();
|
||||||
|
if(error.empty()) {
|
||||||
|
A2_LOG_INFO(fmt("CUID#%"PRId64" - Backup connection to %s "
|
||||||
|
"established", getCuid(), ipaddr_.c_str()));
|
||||||
|
info_->ipaddr = ipaddr_;
|
||||||
|
e_->deleteSocketForWriteCheck(socket_, this);
|
||||||
|
info_->socket.swap(socket_);
|
||||||
|
mainCommand_->setStatus(STATUS_ONESHOT_REALTIME);
|
||||||
|
e_->setNoWait(true);
|
||||||
|
retval = true;
|
||||||
|
} else {
|
||||||
|
A2_LOG_INFO(fmt("CUID#%"PRId64" - Backup connection failed: %s",
|
||||||
|
getCuid(), error.c_str()));
|
||||||
|
retval = true;
|
||||||
|
}
|
||||||
|
} catch(RecoverableException& e) {
|
||||||
|
A2_LOG_INFO_EX(fmt("CUID#%"PRId64" - Backup connection failed",
|
||||||
|
getCuid()), e);
|
||||||
|
retval = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if(!socket_) {
|
||||||
|
// TODO Although we check 300ms initial timeout as described in
|
||||||
|
// RFC 6555, the interval will be much longer and around 1 second
|
||||||
|
// due to the refresh interval mechanism in DownloadEngine.
|
||||||
|
if(startTime_.differenceInMillis(global::wallclock()) >= 300) {
|
||||||
|
socket_.reset(new SocketCore());
|
||||||
|
try {
|
||||||
|
socket_->establishConnection(ipaddr_, port_);
|
||||||
|
e_->addSocketForWriteCheck(socket_, this);
|
||||||
|
timeoutCheck_ = global::wallclock();
|
||||||
|
} catch(RecoverableException& e) {
|
||||||
|
A2_LOG_INFO_EX(fmt("CUID#%"PRId64" - Backup connection failed",
|
||||||
|
getCuid()), e);
|
||||||
|
socket_.reset();
|
||||||
|
retval = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if(timeoutCheck_.difference(global::wallclock()) >= timeout_) {
|
||||||
|
A2_LOG_INFO(fmt("CUID#%"PRId64" - Backup connection command timeout",
|
||||||
|
getCuid()));
|
||||||
|
retval = true;
|
||||||
|
}
|
||||||
|
if(!retval) {
|
||||||
|
e_->addCommand(this);
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace aria2
|
|
@ -0,0 +1,89 @@
|
||||||
|
/* <!-- copyright */
|
||||||
|
/*
|
||||||
|
* aria2 - The high speed download utility
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Tatsuhiro Tsujikawa
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the copyright holders give
|
||||||
|
* permission to link the code of portions of this program with the
|
||||||
|
* OpenSSL library under certain conditions as described in each
|
||||||
|
* individual source file, and distribute linked combinations
|
||||||
|
* including the two.
|
||||||
|
* You must obey the GNU General Public License in all respects
|
||||||
|
* for all of the code used other than OpenSSL. If you modify
|
||||||
|
* file(s) with this exception, you may extend this exception to your
|
||||||
|
* version of the file(s), but you are not obligated to do so. If you
|
||||||
|
* do not wish to do so, delete this exception statement from your
|
||||||
|
* version. If you delete this exception statement from all source
|
||||||
|
* files in the program, then also delete it here.
|
||||||
|
*/
|
||||||
|
/* copyright --> */
|
||||||
|
#ifndef BACKUP_IPV4_CONNECT_COMMAND_H
|
||||||
|
#define BACKUP_IPV4_CONNECT_COMMAND_H
|
||||||
|
|
||||||
|
#include "Command.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "SharedHandle.h"
|
||||||
|
#include "TimerA2.h"
|
||||||
|
|
||||||
|
namespace aria2 {
|
||||||
|
|
||||||
|
class RequestGroup;
|
||||||
|
class DownloadEngine;
|
||||||
|
class SocketCore;
|
||||||
|
|
||||||
|
// Used to communicate mainCommand and backup IPv4 connection command.
|
||||||
|
// When backup connection succeeds, ipaddr is filled with connected
|
||||||
|
// IPv4 address and socket is a socket connected to the ipaddr. If
|
||||||
|
// mainCommand wants to cancel backup connection command, cancel
|
||||||
|
// member becomes true.
|
||||||
|
struct BackupConnectInfo {
|
||||||
|
std::string ipaddr;
|
||||||
|
SharedHandle<SocketCore> socket;
|
||||||
|
bool cancel;
|
||||||
|
BackupConnectInfo();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Make backup connection to IPv4 address. This is a simplest RFC 6555
|
||||||
|
// "Happy Eyeballs" implementation.
|
||||||
|
class BackupIPv4ConnectCommand : public Command {
|
||||||
|
public:
|
||||||
|
BackupIPv4ConnectCommand(cuid_t cuid,
|
||||||
|
const std::string& ipaddr, uint16_t port,
|
||||||
|
const SharedHandle<BackupConnectInfo>& info,
|
||||||
|
Command* mainCommand,
|
||||||
|
RequestGroup* requestGroup, DownloadEngine* e);
|
||||||
|
~BackupIPv4ConnectCommand();
|
||||||
|
virtual bool execute();
|
||||||
|
private:
|
||||||
|
std::string ipaddr_;
|
||||||
|
uint16_t port_;
|
||||||
|
SharedHandle<SocketCore> socket_;
|
||||||
|
SharedHandle<BackupConnectInfo> info_;
|
||||||
|
Command* mainCommand_;
|
||||||
|
RequestGroup* requestGroup_;
|
||||||
|
DownloadEngine* e_;
|
||||||
|
Timer startTime_;
|
||||||
|
Timer timeoutCheck_;
|
||||||
|
time_t timeout_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace aria2
|
||||||
|
|
||||||
|
#endif // BACKUP_IPV4_CONNECT_COMMAND_H
|
|
@ -56,6 +56,7 @@
|
||||||
#include "AuthConfig.h"
|
#include "AuthConfig.h"
|
||||||
#include "fmt.h"
|
#include "fmt.h"
|
||||||
#include "SocketRecvBuffer.h"
|
#include "SocketRecvBuffer.h"
|
||||||
|
#include "BackupIPv4ConnectCommand.h"
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
|
@ -110,12 +111,22 @@ Command* FtpInitiateConnectionCommand::createNextCommand
|
||||||
getRequestGroup(), hc, getDownloadEngine(),
|
getRequestGroup(), hc, getDownloadEngine(),
|
||||||
getSocket());
|
getSocket());
|
||||||
c->setProxyRequest(proxyRequest);
|
c->setProxyRequest(proxyRequest);
|
||||||
|
SharedHandle<BackupConnectInfo> backupConnectInfo
|
||||||
|
= createBackupIPv4ConnectCommand(hostname, addr, port, c);
|
||||||
|
if(backupConnectInfo) {
|
||||||
|
c->setBackupConnectInfo(backupConnectInfo);
|
||||||
|
}
|
||||||
command = c;
|
command = c;
|
||||||
} else if(proxyMethod == V_TUNNEL) {
|
} else if(proxyMethod == V_TUNNEL) {
|
||||||
FtpTunnelRequestCommand* c =
|
FtpTunnelRequestCommand* c =
|
||||||
new FtpTunnelRequestCommand(getCuid(), getRequest(), getFileEntry(),
|
new FtpTunnelRequestCommand(getCuid(), getRequest(), getFileEntry(),
|
||||||
getRequestGroup(), getDownloadEngine(),
|
getRequestGroup(), getDownloadEngine(),
|
||||||
proxyRequest, getSocket());
|
proxyRequest, getSocket());
|
||||||
|
SharedHandle<BackupConnectInfo> backupConnectInfo
|
||||||
|
= createBackupIPv4ConnectCommand(hostname, addr, port, c);
|
||||||
|
if(backupConnectInfo) {
|
||||||
|
c->setBackupConnectInfo(backupConnectInfo);
|
||||||
|
}
|
||||||
command = c;
|
command = c;
|
||||||
} else {
|
} else {
|
||||||
// TODO
|
// TODO
|
||||||
|
@ -163,11 +174,16 @@ Command* FtpInitiateConnectionCommand::createNextCommand
|
||||||
getCuid(), addr.c_str(), port));
|
getCuid(), addr.c_str(), port));
|
||||||
createSocket();
|
createSocket();
|
||||||
getSocket()->establishConnection(addr, port);
|
getSocket()->establishConnection(addr, port);
|
||||||
|
getRequest()->setConnectedAddrInfo(hostname, addr, port);
|
||||||
FtpNegotiationCommand* c =
|
FtpNegotiationCommand* c =
|
||||||
new FtpNegotiationCommand(getCuid(), getRequest(), getFileEntry(),
|
new FtpNegotiationCommand(getCuid(), getRequest(), getFileEntry(),
|
||||||
getRequestGroup(), getDownloadEngine(),
|
getRequestGroup(), getDownloadEngine(),
|
||||||
getSocket());
|
getSocket());
|
||||||
getRequest()->setConnectedAddrInfo(hostname, addr, port);
|
SharedHandle<BackupConnectInfo> backupConnectInfo
|
||||||
|
= createBackupIPv4ConnectCommand(hostname, addr, port, c);
|
||||||
|
if(backupConnectInfo) {
|
||||||
|
c->setBackupConnectInfo(backupConnectInfo);
|
||||||
|
}
|
||||||
command = c;
|
command = c;
|
||||||
} else {
|
} else {
|
||||||
// options contains "baseWorkingDir"
|
// options contains "baseWorkingDir"
|
||||||
|
|
|
@ -74,6 +74,7 @@
|
||||||
#include "CheckIntegrityEntry.h"
|
#include "CheckIntegrityEntry.h"
|
||||||
#include "error_code.h"
|
#include "error_code.h"
|
||||||
#include "SocketRecvBuffer.h"
|
#include "SocketRecvBuffer.h"
|
||||||
|
#include "BackupIPv4ConnectCommand.h"
|
||||||
#ifdef ENABLE_MESSAGE_DIGEST
|
#ifdef ENABLE_MESSAGE_DIGEST
|
||||||
# include "ChecksumCheckIntegrityEntry.h"
|
# include "ChecksumCheckIntegrityEntry.h"
|
||||||
#endif // ENABLE_MESSAGE_DIGEST
|
#endif // ENABLE_MESSAGE_DIGEST
|
||||||
|
@ -105,7 +106,16 @@ FtpNegotiationCommand::FtpNegotiationCommand
|
||||||
setWriteCheckSocket(getSocket());
|
setWriteCheckSocket(getSocket());
|
||||||
}
|
}
|
||||||
|
|
||||||
FtpNegotiationCommand::~FtpNegotiationCommand() {}
|
FtpNegotiationCommand::~FtpNegotiationCommand()
|
||||||
|
{
|
||||||
|
if(backupConnectionInfo_) {
|
||||||
|
backupConnectionInfo_->cancel = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FtpNegotiationCommand::noCheck() {
|
||||||
|
return backupConnectionInfo_ && !backupConnectionInfo_->ipaddr.empty();
|
||||||
|
}
|
||||||
|
|
||||||
bool FtpNegotiationCommand::executeInternal() {
|
bool FtpNegotiationCommand::executeInternal() {
|
||||||
while(processSequence(getSegments().front()));
|
while(processSequence(getSegments().front()));
|
||||||
|
@ -145,12 +155,38 @@ bool FtpNegotiationCommand::executeInternal() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FtpNegotiationCommand::recvGreeting() {
|
bool FtpNegotiationCommand::recvGreeting() {
|
||||||
|
if(backupConnectionInfo_ && !backupConnectionInfo_->ipaddr.empty()) {
|
||||||
|
A2_LOG_INFO(fmt("CUID#%"PRId64" - Use backup connection address %s",
|
||||||
|
getCuid(), backupConnectionInfo_->ipaddr.c_str()));
|
||||||
|
getDownloadEngine()->markBadIPAddress
|
||||||
|
(getRequest()->getConnectedHostname(),
|
||||||
|
getRequest()->getConnectedAddr(),
|
||||||
|
getRequest()->getConnectedPort());
|
||||||
|
|
||||||
|
getRequest()->setConnectedAddrInfo(getRequest()->getConnectedHostname(),
|
||||||
|
backupConnectionInfo_->ipaddr,
|
||||||
|
getRequest()->getConnectedPort());
|
||||||
|
|
||||||
|
FtpNegotiationCommand* c =
|
||||||
|
new FtpNegotiationCommand(getCuid(), getRequest(), getFileEntry(),
|
||||||
|
getRequestGroup(), getDownloadEngine(),
|
||||||
|
backupConnectionInfo_->socket);
|
||||||
|
c->setStatus(STATUS_ONESHOT_REALTIME);
|
||||||
|
getDownloadEngine()->setNoWait(true);
|
||||||
|
getDownloadEngine()->addCommand(c);
|
||||||
|
backupConnectionInfo_.reset();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if(!checkIfConnectionEstablished
|
if(!checkIfConnectionEstablished
|
||||||
(getSocket(), getRequest()->getConnectedHostname(),
|
(getSocket(), getRequest()->getConnectedHostname(),
|
||||||
getRequest()->getConnectedAddr(), getRequest()->getConnectedPort())) {
|
getRequest()->getConnectedAddr(), getRequest()->getConnectedPort())) {
|
||||||
sequence_ = SEQ_EXIT;
|
sequence_ = SEQ_EXIT;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if(backupConnectionInfo_) {
|
||||||
|
backupConnectionInfo_->cancel = true;
|
||||||
|
backupConnectionInfo_.reset();
|
||||||
|
}
|
||||||
setTimeout(getRequestGroup()->getTimeout());
|
setTimeout(getRequestGroup()->getTimeout());
|
||||||
//socket->setBlockingMode();
|
//socket->setBlockingMode();
|
||||||
disableWriteCheckSocket();
|
disableWriteCheckSocket();
|
||||||
|
@ -973,4 +1009,10 @@ void FtpNegotiationCommand::onDryRunFileFound()
|
||||||
sequence_ = SEQ_HEAD_OK;
|
sequence_ = SEQ_HEAD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FtpNegotiationCommand::setBackupConnectInfo
|
||||||
|
(const SharedHandle<BackupConnectInfo>& info)
|
||||||
|
{
|
||||||
|
backupConnectionInfo_ = info;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -44,6 +44,7 @@ namespace aria2 {
|
||||||
class FtpConnection;
|
class FtpConnection;
|
||||||
class SocketCore;
|
class SocketCore;
|
||||||
class HttpConnection;
|
class HttpConnection;
|
||||||
|
class BackupConnectInfo;
|
||||||
|
|
||||||
class FtpNegotiationCommand : public AbstractCommand {
|
class FtpNegotiationCommand : public AbstractCommand {
|
||||||
public:
|
public:
|
||||||
|
@ -153,8 +154,11 @@ private:
|
||||||
std::string proxyAddr_;
|
std::string proxyAddr_;
|
||||||
|
|
||||||
std::deque<std::string> cwdDirs_;
|
std::deque<std::string> cwdDirs_;
|
||||||
|
|
||||||
|
SharedHandle<BackupConnectInfo> backupConnectionInfo_;
|
||||||
protected:
|
protected:
|
||||||
virtual bool executeInternal();
|
virtual bool executeInternal();
|
||||||
|
virtual bool noCheck();
|
||||||
public:
|
public:
|
||||||
FtpNegotiationCommand(cuid_t cuid,
|
FtpNegotiationCommand(cuid_t cuid,
|
||||||
const SharedHandle<Request>& req,
|
const SharedHandle<Request>& req,
|
||||||
|
@ -165,6 +169,7 @@ public:
|
||||||
Seq seq = SEQ_RECV_GREETING,
|
Seq seq = SEQ_RECV_GREETING,
|
||||||
const std::string& baseWorkingDir = "/");
|
const std::string& baseWorkingDir = "/");
|
||||||
virtual ~FtpNegotiationCommand();
|
virtual ~FtpNegotiationCommand();
|
||||||
|
void setBackupConnectInfo(const SharedHandle<BackupConnectInfo>& info);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -63,4 +63,12 @@ Command* FtpTunnelRequestCommand::getNextCommand()
|
||||||
getHttpConnection(), getDownloadEngine(), getSocket());
|
getHttpConnection(), getDownloadEngine(), getSocket());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Command* FtpTunnelRequestCommand::createSelf
|
||||||
|
(const SharedHandle<SocketCore>& socket)
|
||||||
|
{
|
||||||
|
return new FtpTunnelRequestCommand(getCuid(), getRequest(), getFileEntry(),
|
||||||
|
getRequestGroup(), getDownloadEngine(),
|
||||||
|
getProxyRequest(), socket);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -53,6 +53,8 @@ public:
|
||||||
virtual ~FtpTunnelRequestCommand();
|
virtual ~FtpTunnelRequestCommand();
|
||||||
|
|
||||||
virtual Command* getNextCommand();
|
virtual Command* getNextCommand();
|
||||||
|
|
||||||
|
virtual Command* createSelf(const SharedHandle<SocketCore>& socket);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "fmt.h"
|
#include "fmt.h"
|
||||||
#include "SocketRecvBuffer.h"
|
#include "SocketRecvBuffer.h"
|
||||||
|
#include "BackupIPv4ConnectCommand.h"
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
|
@ -93,6 +94,11 @@ Command* HttpInitiateConnectionCommand::createNextCommand
|
||||||
getDownloadEngine(),
|
getDownloadEngine(),
|
||||||
proxyRequest,
|
proxyRequest,
|
||||||
getSocket());
|
getSocket());
|
||||||
|
SharedHandle<BackupConnectInfo> backupConnectionInfo
|
||||||
|
= createBackupIPv4ConnectCommand(hostname, addr, port, c);
|
||||||
|
if(backupConnectionInfo) {
|
||||||
|
c->setBackupConnectInfo(backupConnectionInfo);
|
||||||
|
}
|
||||||
command = c;
|
command = c;
|
||||||
} else if(proxyMethod == V_GET) {
|
} else if(proxyMethod == V_GET) {
|
||||||
SharedHandle<SocketRecvBuffer> socketRecvBuffer
|
SharedHandle<SocketRecvBuffer> socketRecvBuffer
|
||||||
|
@ -107,6 +113,11 @@ Command* HttpInitiateConnectionCommand::createNextCommand
|
||||||
getDownloadEngine(),
|
getDownloadEngine(),
|
||||||
getSocket());
|
getSocket());
|
||||||
c->setProxyRequest(proxyRequest);
|
c->setProxyRequest(proxyRequest);
|
||||||
|
SharedHandle<BackupConnectInfo> backupConnectionInfo
|
||||||
|
= createBackupIPv4ConnectCommand(hostname, addr, port, c);
|
||||||
|
if(backupConnectionInfo) {
|
||||||
|
c->setBackupConnectInfo(backupConnectionInfo);
|
||||||
|
}
|
||||||
command = c;
|
command = c;
|
||||||
} else {
|
} else {
|
||||||
// TODO
|
// TODO
|
||||||
|
@ -131,6 +142,7 @@ Command* HttpInitiateConnectionCommand::createNextCommand
|
||||||
command = c;
|
command = c;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
bool connectRequired = false;
|
||||||
SharedHandle<SocketCore> pooledSocket =
|
SharedHandle<SocketCore> pooledSocket =
|
||||||
getDownloadEngine()->popPooledSocket
|
getDownloadEngine()->popPooledSocket
|
||||||
(resolvedAddresses, getRequest()->getPort());
|
(resolvedAddresses, getRequest()->getPort());
|
||||||
|
@ -141,6 +153,7 @@ Command* HttpInitiateConnectionCommand::createNextCommand
|
||||||
getSocket()->establishConnection(addr, port);
|
getSocket()->establishConnection(addr, port);
|
||||||
|
|
||||||
getRequest()->setConnectedAddrInfo(hostname, addr, port);
|
getRequest()->setConnectedAddrInfo(hostname, addr, port);
|
||||||
|
connectRequired = true;
|
||||||
} else {
|
} else {
|
||||||
setSocket(pooledSocket);
|
setSocket(pooledSocket);
|
||||||
setConnectedAddrInfo(getRequest(), hostname, pooledSocket);
|
setConnectedAddrInfo(getRequest(), hostname, pooledSocket);
|
||||||
|
@ -155,6 +168,14 @@ Command* HttpInitiateConnectionCommand::createNextCommand
|
||||||
httpConnection,
|
httpConnection,
|
||||||
getDownloadEngine(),
|
getDownloadEngine(),
|
||||||
getSocket());
|
getSocket());
|
||||||
|
if(connectRequired) {
|
||||||
|
SharedHandle<BackupConnectInfo> backupConnectInfo
|
||||||
|
= createBackupIPv4ConnectCommand(hostname, addr, port, c);
|
||||||
|
if(backupConnectInfo) {
|
||||||
|
c->setBackupConnectInfo(backupConnectInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
command = c;
|
command = c;
|
||||||
}
|
}
|
||||||
return command;
|
return command;
|
||||||
|
|
|
@ -62,4 +62,16 @@ Command* HttpProxyRequestCommand::getNextCommand()
|
||||||
getHttpConnection(), getDownloadEngine(), getSocket());
|
getHttpConnection(), getDownloadEngine(), getSocket());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Command* HttpProxyRequestCommand::createSelf
|
||||||
|
(const SharedHandle<SocketCore>& socket)
|
||||||
|
{
|
||||||
|
return new HttpProxyRequestCommand(getCuid(),
|
||||||
|
getRequest(),
|
||||||
|
getFileEntry(),
|
||||||
|
getRequestGroup(),
|
||||||
|
getDownloadEngine(),
|
||||||
|
getProxyRequest(),
|
||||||
|
socket);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -53,6 +53,8 @@ public:
|
||||||
virtual ~HttpProxyRequestCommand();
|
virtual ~HttpProxyRequestCommand();
|
||||||
|
|
||||||
virtual Command* getNextCommand();
|
virtual Command* getNextCommand();
|
||||||
|
|
||||||
|
virtual Command* createSelf(const SharedHandle<SocketCore>& socket);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -59,6 +59,7 @@
|
||||||
#include "LogFactory.h"
|
#include "LogFactory.h"
|
||||||
#include "fmt.h"
|
#include "fmt.h"
|
||||||
#include "SocketRecvBuffer.h"
|
#include "SocketRecvBuffer.h"
|
||||||
|
#include "BackupIPv4ConnectCommand.h"
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
|
@ -79,7 +80,12 @@ HttpRequestCommand::HttpRequestCommand
|
||||||
setWriteCheckSocket(getSocket());
|
setWriteCheckSocket(getSocket());
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpRequestCommand::~HttpRequestCommand() {}
|
HttpRequestCommand::~HttpRequestCommand()
|
||||||
|
{
|
||||||
|
if(backupConnectionInfo_) {
|
||||||
|
backupConnectionInfo_->cancel = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
SharedHandle<HttpRequest>
|
SharedHandle<HttpRequest>
|
||||||
|
@ -122,14 +128,52 @@ createHttpRequest(const SharedHandle<Request>& req,
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
bool HttpRequestCommand::noCheck() {
|
||||||
|
return backupConnectionInfo_ && !backupConnectionInfo_->ipaddr.empty();
|
||||||
|
}
|
||||||
|
|
||||||
bool HttpRequestCommand::executeInternal() {
|
bool HttpRequestCommand::executeInternal() {
|
||||||
//socket->setBlockingMode();
|
//socket->setBlockingMode();
|
||||||
if(httpConnection_->sendBufferIsEmpty()) {
|
if(httpConnection_->sendBufferIsEmpty()) {
|
||||||
|
if(backupConnectionInfo_ && !backupConnectionInfo_->ipaddr.empty()) {
|
||||||
|
A2_LOG_INFO(fmt("CUID#%"PRId64" - Use backup connection address %s",
|
||||||
|
getCuid(), backupConnectionInfo_->ipaddr.c_str()));
|
||||||
|
getDownloadEngine()->markBadIPAddress
|
||||||
|
(getRequest()->getConnectedHostname(),
|
||||||
|
getRequest()->getConnectedAddr(),
|
||||||
|
getRequest()->getConnectedPort());
|
||||||
|
|
||||||
|
getRequest()->setConnectedAddrInfo(getRequest()->getConnectedHostname(),
|
||||||
|
backupConnectionInfo_->ipaddr,
|
||||||
|
getRequest()->getConnectedPort());
|
||||||
|
|
||||||
|
SharedHandle<SocketRecvBuffer> socketRecvBuffer
|
||||||
|
(new SocketRecvBuffer(backupConnectionInfo_->socket));
|
||||||
|
SharedHandle<HttpConnection> httpConnection
|
||||||
|
(new HttpConnection(getCuid(), backupConnectionInfo_->socket,
|
||||||
|
socketRecvBuffer));
|
||||||
|
HttpRequestCommand* c =
|
||||||
|
new HttpRequestCommand(getCuid(), getRequest(), getFileEntry(),
|
||||||
|
getRequestGroup(),
|
||||||
|
httpConnection,
|
||||||
|
getDownloadEngine(),
|
||||||
|
backupConnectionInfo_->socket);
|
||||||
|
c->setProxyRequest(proxyRequest_);
|
||||||
|
c->setStatus(STATUS_ONESHOT_REALTIME);
|
||||||
|
getDownloadEngine()->setNoWait(true);
|
||||||
|
getDownloadEngine()->addCommand(c);
|
||||||
|
backupConnectionInfo_.reset();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if(!checkIfConnectionEstablished
|
if(!checkIfConnectionEstablished
|
||||||
(getSocket(), getRequest()->getConnectedHostname(),
|
(getSocket(), getRequest()->getConnectedHostname(),
|
||||||
getRequest()->getConnectedAddr(), getRequest()->getConnectedPort())) {
|
getRequest()->getConnectedAddr(), getRequest()->getConnectedPort())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if(backupConnectionInfo_) {
|
||||||
|
backupConnectionInfo_->cancel = true;
|
||||||
|
backupConnectionInfo_.reset();
|
||||||
|
}
|
||||||
#ifdef ENABLE_SSL
|
#ifdef ENABLE_SSL
|
||||||
if(getRequest()->getProtocol() == "https") {
|
if(getRequest()->getProtocol() == "https") {
|
||||||
if(!getSocket()->tlsConnect(getRequest()->getHost())) {
|
if(!getSocket()->tlsConnect(getRequest()->getHost())) {
|
||||||
|
@ -235,4 +279,10 @@ void HttpRequestCommand::setProxyRequest
|
||||||
proxyRequest_ = proxyRequest;
|
proxyRequest_ = proxyRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HttpRequestCommand::setBackupConnectInfo
|
||||||
|
(const SharedHandle<BackupConnectInfo>& info)
|
||||||
|
{
|
||||||
|
backupConnectionInfo_ = info;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -41,6 +41,7 @@ namespace aria2 {
|
||||||
|
|
||||||
class HttpConnection;
|
class HttpConnection;
|
||||||
class SocketCore;
|
class SocketCore;
|
||||||
|
class BackupConnectInfo;
|
||||||
|
|
||||||
// HttpRequestCommand sends HTTP request header to remote server.
|
// HttpRequestCommand sends HTTP request header to remote server.
|
||||||
// Because network I/O is non-blocking, execute() returns false if all
|
// Because network I/O is non-blocking, execute() returns false if all
|
||||||
|
@ -53,8 +54,11 @@ private:
|
||||||
SharedHandle<Request> proxyRequest_;
|
SharedHandle<Request> proxyRequest_;
|
||||||
|
|
||||||
SharedHandle<HttpConnection> httpConnection_;
|
SharedHandle<HttpConnection> httpConnection_;
|
||||||
|
|
||||||
|
SharedHandle<BackupConnectInfo> backupConnectionInfo_;
|
||||||
protected:
|
protected:
|
||||||
virtual bool executeInternal();
|
virtual bool executeInternal();
|
||||||
|
virtual bool noCheck();
|
||||||
public:
|
public:
|
||||||
HttpRequestCommand(cuid_t cuid,
|
HttpRequestCommand(cuid_t cuid,
|
||||||
const SharedHandle<Request>& req,
|
const SharedHandle<Request>& req,
|
||||||
|
@ -66,6 +70,7 @@ public:
|
||||||
virtual ~HttpRequestCommand();
|
virtual ~HttpRequestCommand();
|
||||||
|
|
||||||
void setProxyRequest(const SharedHandle<Request>& proxyRequest);
|
void setProxyRequest(const SharedHandle<Request>& proxyRequest);
|
||||||
|
void setBackupConnectInfo(const SharedHandle<BackupConnectInfo>& info);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
#include "RecoverableException.h"
|
#include "RecoverableException.h"
|
||||||
#include "fmt.h"
|
#include "fmt.h"
|
||||||
#include "SocketRecvBuffer.h"
|
#include "SocketRecvBuffer.h"
|
||||||
|
#include "BackupIPv4ConnectCommand.h"
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
|
@ -127,4 +128,36 @@ void InitiateConnectionCommand::setConnectedAddrInfo
|
||||||
req->setConnectedAddrInfo(hostname, peerAddr.first, peerAddr.second);
|
req->setConnectedAddrInfo(hostname, peerAddr.first, peerAddr.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SharedHandle<BackupConnectInfo>
|
||||||
|
InitiateConnectionCommand::createBackupIPv4ConnectCommand
|
||||||
|
(const std::string& hostname, const std::string& ipaddr, uint16_t port,
|
||||||
|
Command* mainCommand)
|
||||||
|
{
|
||||||
|
// Prepare IPv4 backup connection attemp in "Happy Eyeballs"
|
||||||
|
// fashion.
|
||||||
|
SharedHandle<BackupConnectInfo> info;
|
||||||
|
char buf[sizeof(in6_addr)];
|
||||||
|
if(inetPton(AF_INET6, ipaddr.c_str(), &buf) == -1) {
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
A2_LOG_INFO("Searching IPv4 address for backup connection attempt");
|
||||||
|
std::vector<std::string> addrs;
|
||||||
|
getDownloadEngine()->findAllCachedIPAddresses(std::back_inserter(addrs),
|
||||||
|
hostname, port);
|
||||||
|
for(std::vector<std::string>::const_iterator i = addrs.begin(),
|
||||||
|
eoi = addrs.end(); i != eoi; ++i) {
|
||||||
|
if(inetPton(AF_INET, (*i).c_str(), &buf) == 0) {
|
||||||
|
info.reset(new BackupConnectInfo());
|
||||||
|
BackupIPv4ConnectCommand* command = new BackupIPv4ConnectCommand
|
||||||
|
(getDownloadEngine()->newCUID(), *i, port, info, mainCommand,
|
||||||
|
getRequestGroup(), getDownloadEngine());
|
||||||
|
A2_LOG_INFO(fmt("Issue backup connection command CUID#%"PRId64
|
||||||
|
", addr=%s", command->getCuid(), (*i).c_str()));
|
||||||
|
getDownloadEngine()->addCommand(command);
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -39,6 +39,8 @@
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
|
class BackupConnectInfo;
|
||||||
|
|
||||||
class InitiateConnectionCommand : public AbstractCommand {
|
class InitiateConnectionCommand : public AbstractCommand {
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
|
@ -64,6 +66,10 @@ protected:
|
||||||
(const SharedHandle<Request>& req,
|
(const SharedHandle<Request>& req,
|
||||||
const std::string& hostname,
|
const std::string& hostname,
|
||||||
const SharedHandle<SocketCore>& socket);
|
const SharedHandle<SocketCore>& socket);
|
||||||
|
|
||||||
|
SharedHandle<BackupConnectInfo> createBackupIPv4ConnectCommand
|
||||||
|
(const std::string& hostname, const std::string& ipaddr, uint16_t port,
|
||||||
|
Command* mainCommand);
|
||||||
public:
|
public:
|
||||||
InitiateConnectionCommand(cuid_t cuid, const SharedHandle<Request>& req,
|
InitiateConnectionCommand(cuid_t cuid, const SharedHandle<Request>& req,
|
||||||
const SharedHandle<FileEntry>& fileEntry,
|
const SharedHandle<FileEntry>& fileEntry,
|
||||||
|
|
|
@ -245,7 +245,8 @@ SRCS = SocketCore.cc SocketCore.h\
|
||||||
WrDiskCacheEntry.cc WrDiskCacheEntry.h\
|
WrDiskCacheEntry.cc WrDiskCacheEntry.h\
|
||||||
GroupId.cc GroupId.h\
|
GroupId.cc GroupId.h\
|
||||||
IndexedList.h\
|
IndexedList.h\
|
||||||
SaveSessionCommand.h SaveSessionCommand.cc
|
SaveSessionCommand.h SaveSessionCommand.cc\
|
||||||
|
BackupIPv4ConnectCommand.h BackupIPv4ConnectCommand.cc
|
||||||
|
|
||||||
if MINGW_BUILD
|
if MINGW_BUILD
|
||||||
SRCS += WinConsoleFile.cc WinConsoleFile.h
|
SRCS += WinConsoleFile.cc WinConsoleFile.h
|
||||||
|
|
Loading…
Reference in New Issue