mirror of https://github.com/aria2/aria2
2010-07-30 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Added FTP EPSV and EPRT command support. aria2 issues these commands when address family of local socket is AF_INET6. * src/FtpConnection.cc * src/FtpConnection.h * src/FtpNegotiationCommand.cc * src/FtpNegotiationCommand.h * src/SocketCore.cc * src/SocketCore.h * test/FtpConnectionTest.ccpull/1/head
parent
20b7c8cd0e
commit
7958ce4366
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
||||||
|
2010-07-30 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||||
|
|
||||||
|
Added FTP EPSV and EPRT command support. aria2 issues these
|
||||||
|
commands when address family of local socket is AF_INET6.
|
||||||
|
* src/FtpConnection.cc
|
||||||
|
* src/FtpConnection.h
|
||||||
|
* src/FtpNegotiationCommand.cc
|
||||||
|
* src/FtpNegotiationCommand.h
|
||||||
|
* src/SocketCore.cc
|
||||||
|
* src/SocketCore.h
|
||||||
|
* test/FtpConnectionTest.cc
|
||||||
|
|
||||||
2010-07-30 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
2010-07-30 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||||
|
|
||||||
Fixed the bug that if hostname is numeric,
|
Fixed the bug that if hostname is numeric,
|
||||||
|
|
|
@ -190,6 +190,20 @@ bool FtpConnection::sendSize()
|
||||||
return socketBuffer_.sendBufferIsEmpty();
|
return socketBuffer_.sendBufferIsEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FtpConnection::sendEpsv()
|
||||||
|
{
|
||||||
|
if(socketBuffer_.sendBufferIsEmpty()) {
|
||||||
|
static const std::string request("EPSV\r\n");
|
||||||
|
if(logger_->info()) {
|
||||||
|
logger_->info(MSG_SENDING_REQUEST,
|
||||||
|
util::itos(cuid_).c_str(), request.c_str());
|
||||||
|
}
|
||||||
|
socketBuffer_.pushStr(request);
|
||||||
|
}
|
||||||
|
socketBuffer_.send();
|
||||||
|
return socketBuffer_.sendBufferIsEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
bool FtpConnection::sendPasv()
|
bool FtpConnection::sendPasv()
|
||||||
{
|
{
|
||||||
if(socketBuffer_.sendBufferIsEmpty()) {
|
if(socketBuffer_.sendBufferIsEmpty()) {
|
||||||
|
@ -206,13 +220,41 @@ bool FtpConnection::sendPasv()
|
||||||
|
|
||||||
SharedHandle<SocketCore> FtpConnection::createServerSocket()
|
SharedHandle<SocketCore> FtpConnection::createServerSocket()
|
||||||
{
|
{
|
||||||
|
std::pair<std::string, uint16_t> addrinfo;
|
||||||
|
socket_->getAddrInfo(addrinfo);
|
||||||
SharedHandle<SocketCore> serverSocket(new SocketCore());
|
SharedHandle<SocketCore> serverSocket(new SocketCore());
|
||||||
serverSocket->bind(0);
|
serverSocket->bind(addrinfo.first, 0);
|
||||||
serverSocket->beginListen();
|
serverSocket->beginListen();
|
||||||
serverSocket->setNonBlockingMode();
|
serverSocket->setNonBlockingMode();
|
||||||
return serverSocket;
|
return serverSocket;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FtpConnection::sendEprt(const SharedHandle<SocketCore>& serverSocket)
|
||||||
|
{
|
||||||
|
if(socketBuffer_.sendBufferIsEmpty()) {
|
||||||
|
struct sockaddr_storage sockaddr;
|
||||||
|
socklen_t len = sizeof(sockaddr);
|
||||||
|
serverSocket->getAddrInfo(sockaddr, len);
|
||||||
|
std::pair<std::string, uint16_t> addrinfo = util::getNumericNameInfo
|
||||||
|
(reinterpret_cast<const struct sockaddr*>(&sockaddr), len);
|
||||||
|
std::string request = "EPRT ";
|
||||||
|
request += "|";
|
||||||
|
request += util::itos(sockaddr.ss_family == AF_INET?1:2);
|
||||||
|
request += "|";
|
||||||
|
request += addrinfo.first;
|
||||||
|
request += "|";
|
||||||
|
request += util::uitos(addrinfo.second);
|
||||||
|
request += "|\r\n";
|
||||||
|
if(logger_->info()) {
|
||||||
|
logger_->info(MSG_SENDING_REQUEST,
|
||||||
|
util::itos(cuid_).c_str(), request.c_str());
|
||||||
|
}
|
||||||
|
socketBuffer_.pushStr(request);
|
||||||
|
}
|
||||||
|
socketBuffer_.send();
|
||||||
|
return socketBuffer_.sendBufferIsEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
bool FtpConnection::sendPort(const SharedHandle<SocketCore>& serverSocket)
|
bool FtpConnection::sendPort(const SharedHandle<SocketCore>& serverSocket)
|
||||||
{
|
{
|
||||||
if(socketBuffer_.sendBufferIsEmpty()) {
|
if(socketBuffer_.sendBufferIsEmpty()) {
|
||||||
|
@ -453,6 +495,34 @@ unsigned int FtpConnection::receiveMdtmResponse(Time& time)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int FtpConnection::receiveEpsvResponse(uint16_t& port)
|
||||||
|
{
|
||||||
|
std::pair<unsigned int, std::string> response;
|
||||||
|
if(bulkReceiveResponse(response)) {
|
||||||
|
if(response.first == 229) {
|
||||||
|
port = 0;
|
||||||
|
std::string::size_type leftParen = response.second.find("(");
|
||||||
|
std::string::size_type rightParen = response.second.find(")");
|
||||||
|
if(leftParen == std::string::npos || rightParen == std::string::npos ||
|
||||||
|
leftParen > rightParen) {
|
||||||
|
return response.first;
|
||||||
|
}
|
||||||
|
std::vector<std::string> rd;
|
||||||
|
util::split(response.second.substr(leftParen+1, rightParen-(leftParen+1)),
|
||||||
|
std::back_inserter(rd), "|", true, true);
|
||||||
|
uint32_t portTemp = 0;
|
||||||
|
if(rd.size() == 5 && util::parseUIntNoThrow(portTemp, rd[3])) {
|
||||||
|
if(0 < portTemp && portTemp <= UINT16_MAX) {
|
||||||
|
port = portTemp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return response.first;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int FtpConnection::receivePasvResponse
|
unsigned int FtpConnection::receivePasvResponse
|
||||||
(std::pair<std::string, uint16_t>& dest)
|
(std::pair<std::string, uint16_t>& dest)
|
||||||
{
|
{
|
||||||
|
|
|
@ -95,8 +95,10 @@ public:
|
||||||
bool sendCwd(const std::string& dir);
|
bool sendCwd(const std::string& dir);
|
||||||
bool sendMdtm();
|
bool sendMdtm();
|
||||||
bool sendSize();
|
bool sendSize();
|
||||||
|
bool sendEpsv();
|
||||||
bool sendPasv();
|
bool sendPasv();
|
||||||
SharedHandle<SocketCore> createServerSocket();
|
SharedHandle<SocketCore> createServerSocket();
|
||||||
|
bool sendEprt(const SharedHandle<SocketCore>& serverSocket);
|
||||||
bool sendPort(const SharedHandle<SocketCore>& serverSocket);
|
bool sendPort(const SharedHandle<SocketCore>& serverSocket);
|
||||||
bool sendRest(const SharedHandle<Segment>& segment);
|
bool sendRest(const SharedHandle<Segment>& segment);
|
||||||
bool sendRetr();
|
bool sendRetr();
|
||||||
|
@ -110,6 +112,7 @@ public:
|
||||||
// date cannot be parsed, then assign Time::null() to given time.
|
// date cannot be parsed, then assign Time::null() to given time.
|
||||||
// If reply is not received yet, returns 0.
|
// If reply is not received yet, returns 0.
|
||||||
unsigned int receiveMdtmResponse(Time& time);
|
unsigned int receiveMdtmResponse(Time& time);
|
||||||
|
unsigned int receiveEpsvResponse(uint16_t& port);
|
||||||
unsigned int receivePasvResponse(std::pair<std::string, uint16_t>& dest);
|
unsigned int receivePasvResponse(std::pair<std::string, uint16_t>& dest);
|
||||||
unsigned int receivePwdResponse(std::string& pwd);
|
unsigned int receivePwdResponse(std::string& pwd);
|
||||||
|
|
||||||
|
|
|
@ -126,9 +126,9 @@ bool FtpNegotiationCommand::executeInternal() {
|
||||||
return true;
|
return true;
|
||||||
} else if(sequence_ == SEQ_FILE_PREPARATION) {
|
} else if(sequence_ == SEQ_FILE_PREPARATION) {
|
||||||
if(getOption()->getAsBool(PREF_FTP_PASV)) {
|
if(getOption()->getAsBool(PREF_FTP_PASV)) {
|
||||||
sequence_ = SEQ_SEND_PASV;
|
sequence_ = SEQ_PREPARE_PASV;
|
||||||
} else {
|
} else {
|
||||||
sequence_ = SEQ_PREPARE_SERVER_SOCKET;
|
sequence_ = SEQ_PREPARE_PORT;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
} else if(sequence_ == SEQ_EXIT) {
|
} else if(sequence_ == SEQ_EXIT) {
|
||||||
|
@ -391,9 +391,9 @@ bool FtpNegotiationCommand::onFileSizeDetermined(uint64_t totalLength)
|
||||||
if(totalLength == 0) {
|
if(totalLength == 0) {
|
||||||
|
|
||||||
if(getOption()->getAsBool(PREF_FTP_PASV)) {
|
if(getOption()->getAsBool(PREF_FTP_PASV)) {
|
||||||
sequence_ = SEQ_SEND_PASV;
|
sequence_ = SEQ_PREPARE_PASV;
|
||||||
} else {
|
} else {
|
||||||
sequence_ = SEQ_PREPARE_SERVER_SOCKET;
|
sequence_ = SEQ_PREPARE_PORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(getOption()->getAsBool(PREF_DRY_RUN)) {
|
if(getOption()->getAsBool(PREF_DRY_RUN)) {
|
||||||
|
@ -514,9 +514,9 @@ bool FtpNegotiationCommand::recvSize() {
|
||||||
// wrong file to be downloaded if user-specified URL is wrong.
|
// wrong file to be downloaded if user-specified URL is wrong.
|
||||||
}
|
}
|
||||||
if(getOption()->getAsBool(PREF_FTP_PASV)) {
|
if(getOption()->getAsBool(PREF_FTP_PASV)) {
|
||||||
sequence_ = SEQ_SEND_PASV;
|
sequence_ = SEQ_PREPARE_PASV;
|
||||||
} else {
|
} else {
|
||||||
sequence_ = SEQ_PREPARE_SERVER_SOCKET;
|
sequence_ = SEQ_PREPARE_PORT;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -526,6 +526,22 @@ void FtpNegotiationCommand::afterFileAllocation()
|
||||||
setReadCheckSocket(getSocket());
|
setReadCheckSocket(getSocket());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FtpNegotiationCommand::preparePort() {
|
||||||
|
afterFileAllocation();
|
||||||
|
if(getSocket()->getAddressFamily() == AF_INET6) {
|
||||||
|
sequence_ = SEQ_PREPARE_SERVER_SOCKET_EPRT;
|
||||||
|
} else {
|
||||||
|
sequence_ = SEQ_PREPARE_SERVER_SOCKET;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FtpNegotiationCommand::prepareServerSocketEprt() {
|
||||||
|
serverSocket_ = ftp_->createServerSocket();
|
||||||
|
sequence_ = SEQ_SEND_EPRT;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool FtpNegotiationCommand::prepareServerSocket()
|
bool FtpNegotiationCommand::prepareServerSocket()
|
||||||
{
|
{
|
||||||
serverSocket_ = ftp_->createServerSocket();
|
serverSocket_ = ftp_->createServerSocket();
|
||||||
|
@ -533,8 +549,30 @@ bool FtpNegotiationCommand::prepareServerSocket()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FtpNegotiationCommand::sendEprt() {
|
||||||
|
if(ftp_->sendEprt(serverSocket_)) {
|
||||||
|
disableWriteCheckSocket();
|
||||||
|
sequence_ = SEQ_RECV_EPRT;
|
||||||
|
} else {
|
||||||
|
setWriteCheckSocket(getSocket());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FtpNegotiationCommand::recvEprt() {
|
||||||
|
unsigned int status = ftp_->receiveResponse();
|
||||||
|
if(status == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(status == 200) {
|
||||||
|
sequence_ = SEQ_SEND_REST;
|
||||||
|
} else {
|
||||||
|
sequence_ = SEQ_PREPARE_SERVER_SOCKET;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool FtpNegotiationCommand::sendPort() {
|
bool FtpNegotiationCommand::sendPort() {
|
||||||
afterFileAllocation();
|
|
||||||
if(ftp_->sendPort(serverSocket_)) {
|
if(ftp_->sendPort(serverSocket_)) {
|
||||||
disableWriteCheckSocket();
|
disableWriteCheckSocket();
|
||||||
sequence_ = SEQ_RECV_PORT;
|
sequence_ = SEQ_RECV_PORT;
|
||||||
|
@ -556,8 +594,45 @@ bool FtpNegotiationCommand::recvPort() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FtpNegotiationCommand::sendPasv() {
|
bool FtpNegotiationCommand::preparePasv() {
|
||||||
afterFileAllocation();
|
afterFileAllocation();
|
||||||
|
if(getSocket()->getAddressFamily() == AF_INET6) {
|
||||||
|
sequence_ = SEQ_SEND_EPSV;
|
||||||
|
} else {
|
||||||
|
sequence_ = SEQ_SEND_PASV;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FtpNegotiationCommand::sendEpsv() {
|
||||||
|
if(ftp_->sendEpsv()) {
|
||||||
|
disableWriteCheckSocket();
|
||||||
|
sequence_ = SEQ_RECV_EPSV;
|
||||||
|
} else {
|
||||||
|
setWriteCheckSocket(getSocket());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FtpNegotiationCommand::recvEpsv() {
|
||||||
|
uint16_t port;
|
||||||
|
unsigned int status = ftp_->receiveEpsvResponse(port);
|
||||||
|
if(status == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(status == 229) {
|
||||||
|
std::pair<std::string, uint16_t> peerInfo;
|
||||||
|
getSocket()->getPeerInfo(peerInfo);
|
||||||
|
peerInfo.second = port;
|
||||||
|
dataConnAddr_ = peerInfo;
|
||||||
|
return preparePasvConnect();
|
||||||
|
} else {
|
||||||
|
sequence_ = SEQ_SEND_PASV;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FtpNegotiationCommand::sendPasv() {
|
||||||
if(ftp_->sendPasv()) {
|
if(ftp_->sendPasv()) {
|
||||||
disableWriteCheckSocket();
|
disableWriteCheckSocket();
|
||||||
sequence_ = SEQ_RECV_PASV;
|
sequence_ = SEQ_RECV_PASV;
|
||||||
|
@ -576,20 +651,26 @@ bool FtpNegotiationCommand::recvPasv() {
|
||||||
if(status != 227) {
|
if(status != 227) {
|
||||||
throw DL_ABORT_EX(StringFormat(EX_BAD_STATUS, status).str());
|
throw DL_ABORT_EX(StringFormat(EX_BAD_STATUS, status).str());
|
||||||
}
|
}
|
||||||
// TODO Should we check to see that dest.first is not in noProxy list?
|
dataConnAddr_ = dest;
|
||||||
|
|
||||||
|
return preparePasvConnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FtpNegotiationCommand::preparePasvConnect() {
|
||||||
|
// TODO Should we check to see that dataConnAddr_.first is not in
|
||||||
|
// noProxy list?
|
||||||
if(isProxyDefined()) {
|
if(isProxyDefined()) {
|
||||||
dataConnAddr_ = dest;
|
|
||||||
sequence_ = SEQ_RESOLVE_PROXY;
|
sequence_ = SEQ_RESOLVE_PROXY;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
// make a data connection to the server.
|
// make a data connection to the server.
|
||||||
if(getLogger()->info()) {
|
if(getLogger()->info()) {
|
||||||
getLogger()->info(MSG_CONNECTING_TO_SERVER, util::itos(getCuid()).c_str(),
|
getLogger()->info(MSG_CONNECTING_TO_SERVER, util::itos(getCuid()).c_str(),
|
||||||
dest.first.c_str(),
|
dataConnAddr_.first.c_str(),
|
||||||
dest.second);
|
dataConnAddr_.second);
|
||||||
}
|
}
|
||||||
dataSocket_.reset(new SocketCore());
|
dataSocket_.reset(new SocketCore());
|
||||||
dataSocket_->establishConnection(dest.first, dest.second);
|
dataSocket_->establishConnection(dataConnAddr_.first, dataConnAddr_.second);
|
||||||
disableReadCheckSocket();
|
disableReadCheckSocket();
|
||||||
setWriteCheckSocket(dataSocket_);
|
setWriteCheckSocket(dataSocket_);
|
||||||
sequence_ = SEQ_SEND_REST_PASV;
|
sequence_ = SEQ_SEND_REST_PASV;
|
||||||
|
@ -691,6 +772,12 @@ bool FtpNegotiationCommand::recvTunnelResponse()
|
||||||
|
|
||||||
bool FtpNegotiationCommand::sendRestPasv(const SharedHandle<Segment>& segment) {
|
bool FtpNegotiationCommand::sendRestPasv(const SharedHandle<Segment>& segment) {
|
||||||
//dataSocket_->setBlockingMode();
|
//dataSocket_->setBlockingMode();
|
||||||
|
// Check connection is made properly
|
||||||
|
if(dataSocket_->isReadable(0)) {
|
||||||
|
std::string error = dataSocket_->getSocketError();
|
||||||
|
throw DL_ABORT_EX
|
||||||
|
(StringFormat(MSG_ESTABLISHING_CONNECTION_FAILED, error.c_str()).str());
|
||||||
|
}
|
||||||
setReadCheckSocket(getSocket());
|
setReadCheckSocket(getSocket());
|
||||||
disableWriteCheckSocket();
|
disableWriteCheckSocket();
|
||||||
return sendRest(segment);
|
return sendRest(segment);
|
||||||
|
@ -803,12 +890,26 @@ bool FtpNegotiationCommand::processSequence
|
||||||
return sendSize();
|
return sendSize();
|
||||||
case SEQ_RECV_SIZE:
|
case SEQ_RECV_SIZE:
|
||||||
return recvSize();
|
return recvSize();
|
||||||
|
case SEQ_PREPARE_PORT:
|
||||||
|
return preparePort();
|
||||||
|
case SEQ_PREPARE_SERVER_SOCKET_EPRT:
|
||||||
|
return prepareServerSocketEprt();
|
||||||
|
case SEQ_SEND_EPRT:
|
||||||
|
return sendEprt();
|
||||||
|
case SEQ_RECV_EPRT:
|
||||||
|
return recvEprt();
|
||||||
case SEQ_PREPARE_SERVER_SOCKET:
|
case SEQ_PREPARE_SERVER_SOCKET:
|
||||||
return prepareServerSocket();
|
return prepareServerSocket();
|
||||||
case SEQ_SEND_PORT:
|
case SEQ_SEND_PORT:
|
||||||
return sendPort();
|
return sendPort();
|
||||||
case SEQ_RECV_PORT:
|
case SEQ_RECV_PORT:
|
||||||
return recvPort();
|
return recvPort();
|
||||||
|
case SEQ_PREPARE_PASV:
|
||||||
|
return preparePasv();
|
||||||
|
case SEQ_SEND_EPSV:
|
||||||
|
return sendEpsv();
|
||||||
|
case SEQ_RECV_EPSV:
|
||||||
|
return recvEpsv();
|
||||||
case SEQ_SEND_PASV:
|
case SEQ_SEND_PASV:
|
||||||
return sendPasv();
|
return sendPasv();
|
||||||
case SEQ_RECV_PASV:
|
case SEQ_RECV_PASV:
|
||||||
|
|
|
@ -62,9 +62,16 @@ public:
|
||||||
SEQ_RECV_MDTM,
|
SEQ_RECV_MDTM,
|
||||||
SEQ_SEND_SIZE,
|
SEQ_SEND_SIZE,
|
||||||
SEQ_RECV_SIZE,
|
SEQ_RECV_SIZE,
|
||||||
|
SEQ_PREPARE_PORT,
|
||||||
|
SEQ_PREPARE_SERVER_SOCKET_EPRT,
|
||||||
|
SEQ_SEND_EPRT,
|
||||||
|
SEQ_RECV_EPRT,
|
||||||
SEQ_PREPARE_SERVER_SOCKET,
|
SEQ_PREPARE_SERVER_SOCKET,
|
||||||
SEQ_SEND_PORT,
|
SEQ_SEND_PORT,
|
||||||
SEQ_RECV_PORT,
|
SEQ_RECV_PORT,
|
||||||
|
SEQ_PREPARE_PASV,
|
||||||
|
SEQ_SEND_EPSV,
|
||||||
|
SEQ_RECV_EPSV,
|
||||||
SEQ_SEND_PASV,
|
SEQ_SEND_PASV,
|
||||||
SEQ_RECV_PASV,
|
SEQ_RECV_PASV,
|
||||||
SEQ_RESOLVE_PROXY,
|
SEQ_RESOLVE_PROXY,
|
||||||
|
@ -100,11 +107,19 @@ private:
|
||||||
bool recvMdtm();
|
bool recvMdtm();
|
||||||
bool sendSize();
|
bool sendSize();
|
||||||
bool recvSize();
|
bool recvSize();
|
||||||
|
bool preparePort();
|
||||||
|
bool prepareServerSocketEprt();
|
||||||
|
bool sendEprt();
|
||||||
|
bool recvEprt();
|
||||||
bool prepareServerSocket();
|
bool prepareServerSocket();
|
||||||
bool sendPort();
|
bool sendPort();
|
||||||
bool recvPort();
|
bool recvPort();
|
||||||
|
bool preparePasv();
|
||||||
|
bool sendEpsv();
|
||||||
|
bool recvEpsv();
|
||||||
bool sendPasv();
|
bool sendPasv();
|
||||||
bool recvPasv();
|
bool recvPasv();
|
||||||
|
bool preparePasvConnect();
|
||||||
bool resolveProxy();
|
bool resolveProxy();
|
||||||
bool sendTunnelRequest();
|
bool sendTunnelRequest();
|
||||||
bool recvTunnelResponse();
|
bool recvTunnelResponse();
|
||||||
|
|
|
@ -341,11 +341,26 @@ void SocketCore::getAddrInfo(std::pair<std::string, uint16_t>& addrinfo) const
|
||||||
{
|
{
|
||||||
struct sockaddr_storage sockaddr;
|
struct sockaddr_storage sockaddr;
|
||||||
socklen_t len = sizeof(sockaddr);
|
socklen_t len = sizeof(sockaddr);
|
||||||
|
getAddrInfo(sockaddr, len);
|
||||||
|
addrinfo = util::getNumericNameInfo
|
||||||
|
(reinterpret_cast<const struct sockaddr*>(&sockaddr), len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocketCore::getAddrInfo
|
||||||
|
(struct sockaddr_storage& sockaddr, socklen_t& len) const
|
||||||
|
{
|
||||||
struct sockaddr* addrp = reinterpret_cast<struct sockaddr*>(&sockaddr);
|
struct sockaddr* addrp = reinterpret_cast<struct sockaddr*>(&sockaddr);
|
||||||
if(getsockname(sockfd_, addrp, &len) == -1) {
|
if(getsockname(sockfd_, addrp, &len) == -1) {
|
||||||
throw DL_ABORT_EX(StringFormat(EX_SOCKET_GET_NAME, errorMsg()).str());
|
throw DL_ABORT_EX(StringFormat(EX_SOCKET_GET_NAME, errorMsg()).str());
|
||||||
}
|
}
|
||||||
addrinfo = util::getNumericNameInfo(addrp, len);
|
}
|
||||||
|
|
||||||
|
int SocketCore::getAddressFamily() const
|
||||||
|
{
|
||||||
|
struct sockaddr_storage sockaddr;
|
||||||
|
socklen_t len = sizeof(sockaddr);
|
||||||
|
getAddrInfo(sockaddr, len);
|
||||||
|
return sockaddr.ss_family;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SocketCore::getPeerInfo(std::pair<std::string, uint16_t>& peerinfo) const
|
void SocketCore::getPeerInfo(std::pair<std::string, uint16_t>& peerinfo) const
|
||||||
|
|
|
@ -159,6 +159,21 @@ public:
|
||||||
*/
|
*/
|
||||||
void getAddrInfo(std::pair<std::string, uint16_t>& addrinfo) const;
|
void getAddrInfo(std::pair<std::string, uint16_t>& addrinfo) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores address of this socket to sockaddr. len must be
|
||||||
|
* initialized to the size of sockaddr. On success, address data is
|
||||||
|
* stored in sockaddr and actual size of address structure is stored
|
||||||
|
* in len.
|
||||||
|
*/
|
||||||
|
void getAddrInfo
|
||||||
|
(struct sockaddr_storage& sockaddr, socklen_t& len) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns address family of this socket.
|
||||||
|
* The socket must be connected or bounded to address.
|
||||||
|
*/
|
||||||
|
int getAddressFamily() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores peer's address and port to peerinfo.
|
* Stores peer's address and port to peerinfo.
|
||||||
* @param peerinfo placeholder to store peer's address and port.
|
* @param peerinfo placeholder to store peer's address and port.
|
||||||
|
|
|
@ -32,6 +32,7 @@ class FtpConnectionTest:public CppUnit::TestFixture {
|
||||||
CPPUNIT_TEST(testSendSize);
|
CPPUNIT_TEST(testSendSize);
|
||||||
CPPUNIT_TEST(testReceiveSizeResponse);
|
CPPUNIT_TEST(testReceiveSizeResponse);
|
||||||
CPPUNIT_TEST(testSendRetr);
|
CPPUNIT_TEST(testSendRetr);
|
||||||
|
CPPUNIT_TEST(testReceiveEpsvResponse);
|
||||||
CPPUNIT_TEST_SUITE_END();
|
CPPUNIT_TEST_SUITE_END();
|
||||||
private:
|
private:
|
||||||
SharedHandle<SocketCore> serverSocket_;
|
SharedHandle<SocketCore> serverSocket_;
|
||||||
|
@ -85,6 +86,7 @@ public:
|
||||||
void testSendSize();
|
void testSendSize();
|
||||||
void testReceiveSizeResponse();
|
void testReceiveSizeResponse();
|
||||||
void testSendRetr();
|
void testSendRetr();
|
||||||
|
void testReceiveEpsvResponse();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -299,4 +301,33 @@ void FtpConnectionTest::testSendRetr()
|
||||||
std::string(&data[0], &data[len]));
|
std::string(&data[0], &data[len]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FtpConnectionTest::testReceiveEpsvResponse()
|
||||||
|
{
|
||||||
|
serverSocket_->writeData("229 Success (|||12000|)\r\n");
|
||||||
|
waitRead(clientSocket_);
|
||||||
|
uint16_t port = 0;
|
||||||
|
CPPUNIT_ASSERT_EQUAL((unsigned int)229, ftp_->receiveEpsvResponse(port));
|
||||||
|
CPPUNIT_ASSERT_EQUAL((uint16_t)12000, port);
|
||||||
|
|
||||||
|
serverSocket_->writeData("229 Success |||12000|)\r\n");
|
||||||
|
CPPUNIT_ASSERT_EQUAL((unsigned int)229, ftp_->receiveEpsvResponse(port));
|
||||||
|
CPPUNIT_ASSERT_EQUAL((uint16_t)0, port);
|
||||||
|
|
||||||
|
serverSocket_->writeData("229 Success (|||12000|\r\n");
|
||||||
|
CPPUNIT_ASSERT_EQUAL((unsigned int)229, ftp_->receiveEpsvResponse(port));
|
||||||
|
CPPUNIT_ASSERT_EQUAL((uint16_t)0, port);
|
||||||
|
|
||||||
|
serverSocket_->writeData("229 Success ()|||12000|\r\n");
|
||||||
|
CPPUNIT_ASSERT_EQUAL((unsigned int)229, ftp_->receiveEpsvResponse(port));
|
||||||
|
CPPUNIT_ASSERT_EQUAL((uint16_t)0, port);
|
||||||
|
|
||||||
|
serverSocket_->writeData("229 Success )(|||12000|)\r\n");
|
||||||
|
CPPUNIT_ASSERT_EQUAL((unsigned int)229, ftp_->receiveEpsvResponse(port));
|
||||||
|
CPPUNIT_ASSERT_EQUAL((uint16_t)0, port);
|
||||||
|
|
||||||
|
serverSocket_->writeData("229 Success )(||12000|)\r\n");
|
||||||
|
CPPUNIT_ASSERT_EQUAL((unsigned int)229, ftp_->receiveEpsvResponse(port));
|
||||||
|
CPPUNIT_ASSERT_EQUAL((uint16_t)0, port);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
Loading…
Reference in New Issue