mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-23 00:07:59 +02:00
Merge branch 'develop' of https://github.com/pocoproject/poco into develop
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
//
|
||||
// FTPClientSession.cpp
|
||||
//
|
||||
// $Id: //poco/1.4/Net/src/FTPClientSession.cpp#1 $
|
||||
// $Id: //poco/svn/Net/src/FTPClientSession.cpp#2 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: FTP
|
||||
@@ -50,48 +50,72 @@ namespace Poco {
|
||||
namespace Net {
|
||||
|
||||
|
||||
FTPClientSession::FTPClientSession(const StreamSocket& socket):
|
||||
_controlSocket(socket),
|
||||
FTPClientSession::FTPClientSession():
|
||||
_port(0),
|
||||
_pControlSocket(0),
|
||||
_pDataStream(0),
|
||||
_passiveMode(true),
|
||||
_fileType(TYPE_BINARY),
|
||||
_supports1738(true),
|
||||
_isOpen(true),
|
||||
_serverReady(false),
|
||||
_isLoggedIn(false),
|
||||
_timeout(DEFAULT_TIMEOUT)
|
||||
{
|
||||
_controlSocket.setReceiveTimeout(_timeout);
|
||||
}
|
||||
|
||||
|
||||
FTPClientSession::FTPClientSession(const std::string& host, Poco::UInt16 port):
|
||||
_controlSocket(SocketAddress(host, port)),
|
||||
FTPClientSession::FTPClientSession(const StreamSocket& socket):
|
||||
_host(socket.address().host().toString()),
|
||||
_port(socket.address().port()),
|
||||
_pControlSocket(new DialogSocket(socket)),
|
||||
_pDataStream(0),
|
||||
_passiveMode(true),
|
||||
_fileType(TYPE_BINARY),
|
||||
_supports1738(true),
|
||||
_isOpen(true),
|
||||
_serverReady(false),
|
||||
_isLoggedIn(false),
|
||||
_timeout(DEFAULT_TIMEOUT)
|
||||
{
|
||||
_controlSocket.setReceiveTimeout(_timeout);
|
||||
_pControlSocket->setReceiveTimeout(_timeout);
|
||||
}
|
||||
|
||||
|
||||
FTPClientSession::FTPClientSession(const std::string& host,
|
||||
Poco::UInt16 port,
|
||||
const std::string& username,
|
||||
const std::string& password):
|
||||
_host(host),
|
||||
_port(port),
|
||||
_pControlSocket(new DialogSocket(SocketAddress(host, port))),
|
||||
_pDataStream(0),
|
||||
_passiveMode(true),
|
||||
_fileType(TYPE_BINARY),
|
||||
_supports1738(true),
|
||||
_serverReady(false),
|
||||
_isLoggedIn(false),
|
||||
_timeout(DEFAULT_TIMEOUT)
|
||||
{
|
||||
if (!username.empty())
|
||||
login(username, password);
|
||||
else
|
||||
_pControlSocket->setReceiveTimeout(_timeout);
|
||||
}
|
||||
|
||||
|
||||
FTPClientSession::~FTPClientSession()
|
||||
{
|
||||
try
|
||||
{
|
||||
close();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
try { close(); }
|
||||
catch (...) { }
|
||||
}
|
||||
|
||||
|
||||
void FTPClientSession::setTimeout(const Poco::Timespan& timeout)
|
||||
{
|
||||
if (!isOpen())
|
||||
throw FTPException("Connection is closed.");
|
||||
|
||||
_timeout = timeout;
|
||||
_controlSocket.setReceiveTimeout(timeout);
|
||||
_pControlSocket->setReceiveTimeout(timeout);
|
||||
}
|
||||
|
||||
|
||||
@@ -114,35 +138,78 @@ bool FTPClientSession::getPassive() const
|
||||
}
|
||||
|
||||
|
||||
void FTPClientSession::open(const std::string& host,
|
||||
Poco::UInt16 port,
|
||||
const std::string& username,
|
||||
const std::string& password)
|
||||
{
|
||||
_host = host;
|
||||
_port = port;
|
||||
if (!username.empty())
|
||||
login(username, password);
|
||||
else
|
||||
{
|
||||
_pControlSocket = new DialogSocket(SocketAddress(_host, _port));
|
||||
_pControlSocket->setReceiveTimeout(_timeout);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FTPClientSession::login(const std::string& username, const std::string& password)
|
||||
{
|
||||
if (_isLoggedIn) logout();
|
||||
|
||||
int status = FTP_POSITIVE_COMPLETION * 100;
|
||||
std::string response;
|
||||
int status = _controlSocket.receiveStatusMessage(response);
|
||||
if (!isPositiveCompletion(status)) throw FTPException("Cannot login to server", response, status);
|
||||
if (!_pControlSocket)
|
||||
{
|
||||
_pControlSocket = new DialogSocket(SocketAddress(_host, _port));
|
||||
_pControlSocket->setReceiveTimeout(_timeout);
|
||||
}
|
||||
|
||||
if (!_serverReady)
|
||||
{
|
||||
status = _pControlSocket->receiveStatusMessage(response);
|
||||
if (!isPositiveCompletion(status))
|
||||
throw FTPException("Cannot login to server", response, status);
|
||||
|
||||
_serverReady = true;
|
||||
}
|
||||
|
||||
status = sendCommand("USER", username, response);
|
||||
if (isPositiveIntermediate(status))
|
||||
status = sendCommand("PASS", password, response);
|
||||
if (!isPositiveCompletion(status)) throw FTPException("Login denied", response, status);
|
||||
if (!isPositiveCompletion(status))
|
||||
throw FTPException("Login denied", response, status);
|
||||
|
||||
setFileType(_fileType);
|
||||
_isLoggedIn = true;
|
||||
}
|
||||
|
||||
|
||||
void FTPClientSession::logout()
|
||||
{
|
||||
if (!isOpen())
|
||||
throw FTPException("Connection is closed.");
|
||||
|
||||
if (_isLoggedIn)
|
||||
{
|
||||
try { endTransfer(); }
|
||||
catch (...) { }
|
||||
std::string response;
|
||||
sendCommand("QUIT", response);
|
||||
_isLoggedIn = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FTPClientSession::close()
|
||||
{
|
||||
if (_isOpen)
|
||||
{
|
||||
try
|
||||
{
|
||||
endTransfer();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
std::string response;
|
||||
sendCommand("QUIT", response);
|
||||
_controlSocket.close();
|
||||
_isOpen = false;
|
||||
}
|
||||
logout();
|
||||
_pControlSocket->close();
|
||||
delete _pControlSocket;
|
||||
_pControlSocket = 0;
|
||||
_serverReady = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -176,7 +243,8 @@ void FTPClientSession::setWorkingDirectory(const std::string& path)
|
||||
{
|
||||
std::string response;
|
||||
int status = sendCommand("CWD", path, response);
|
||||
if (!isPositiveCompletion(status)) throw FTPException("Cannot change directory", response, status);
|
||||
if (!isPositiveCompletion(status))
|
||||
throw FTPException("Cannot change directory", response, status);
|
||||
}
|
||||
|
||||
|
||||
@@ -195,7 +263,8 @@ void FTPClientSession::cdup()
|
||||
{
|
||||
std::string response;
|
||||
int status = sendCommand("CDUP", response);
|
||||
if (!isPositiveCompletion(status)) throw FTPException("Cannot change directory", response, status);
|
||||
if (!isPositiveCompletion(status))
|
||||
throw FTPException("Cannot change directory", response, status);
|
||||
}
|
||||
|
||||
|
||||
@@ -203,9 +272,11 @@ void FTPClientSession::rename(const std::string& oldName, const std::string& new
|
||||
{
|
||||
std::string response;
|
||||
int status = sendCommand("RNFR", oldName, response);
|
||||
if (!isPositiveIntermediate(status)) throw FTPException(std::string("Cannot rename ") + oldName, response, status);
|
||||
if (!isPositiveIntermediate(status))
|
||||
throw FTPException(std::string("Cannot rename ") + oldName, response, status);
|
||||
status = sendCommand("RNTO", newName, response);
|
||||
if (!isPositiveCompletion(status)) throw FTPException(std::string("Cannot rename to ") + newName, response, status);
|
||||
if (!isPositiveCompletion(status))
|
||||
throw FTPException(std::string("Cannot rename to ") + newName, response, status);
|
||||
}
|
||||
|
||||
|
||||
@@ -213,7 +284,8 @@ void FTPClientSession::remove(const std::string& path)
|
||||
{
|
||||
std::string response;
|
||||
int status = sendCommand("DELE", path, response);
|
||||
if (!isPositiveCompletion(status)) throw FTPException(std::string("Cannot remove " + path), response, status);
|
||||
if (!isPositiveCompletion(status))
|
||||
throw FTPException(std::string("Cannot remove " + path), response, status);
|
||||
}
|
||||
|
||||
|
||||
@@ -221,7 +293,8 @@ void FTPClientSession::createDirectory(const std::string& path)
|
||||
{
|
||||
std::string response;
|
||||
int status = sendCommand("MKD", path, response);
|
||||
if (!isPositiveCompletion(status)) throw FTPException(std::string("Cannot create directory ") + path, response, status);
|
||||
if (!isPositiveCompletion(status))
|
||||
throw FTPException(std::string("Cannot create directory ") + path, response, status);
|
||||
}
|
||||
|
||||
|
||||
@@ -229,12 +302,16 @@ void FTPClientSession::removeDirectory(const std::string& path)
|
||||
{
|
||||
std::string response;
|
||||
int status = sendCommand("RMD", path, response);
|
||||
if (!isPositiveCompletion(status)) throw FTPException(std::string("Cannot remove directory ") + path, response, status);
|
||||
if (!isPositiveCompletion(status))
|
||||
throw FTPException(std::string("Cannot remove directory ") + path, response, status);
|
||||
}
|
||||
|
||||
|
||||
std::istream& FTPClientSession::beginDownload(const std::string& path)
|
||||
{
|
||||
if (!isOpen())
|
||||
throw FTPException("Connection is closed.");
|
||||
|
||||
delete _pDataStream;
|
||||
_pDataStream = 0;
|
||||
_pDataStream = new SocketStream(establishDataConnection("RETR", path));
|
||||
@@ -250,6 +327,9 @@ void FTPClientSession::endDownload()
|
||||
|
||||
std::ostream& FTPClientSession::beginUpload(const std::string& path)
|
||||
{
|
||||
if (!isOpen())
|
||||
throw FTPException("Connection is closed.");
|
||||
|
||||
delete _pDataStream;
|
||||
_pDataStream = 0;
|
||||
_pDataStream = new SocketStream(establishDataConnection("STOR", path));
|
||||
@@ -265,6 +345,9 @@ void FTPClientSession::endUpload()
|
||||
|
||||
std::istream& FTPClientSession::beginList(const std::string& path, bool extended)
|
||||
{
|
||||
if (!isOpen())
|
||||
throw FTPException("Connection is closed.");
|
||||
|
||||
delete _pDataStream;
|
||||
_pDataStream = 0;
|
||||
_pDataStream = new SocketStream(establishDataConnection(extended ? "LIST" : "NLST", path));
|
||||
@@ -280,27 +363,37 @@ void FTPClientSession::endList()
|
||||
|
||||
void FTPClientSession::abort()
|
||||
{
|
||||
_controlSocket.sendByte(DialogSocket::TELNET_IP);
|
||||
_controlSocket.synch();
|
||||
if (!isOpen())
|
||||
throw FTPException("Connection is closed.");
|
||||
|
||||
_pControlSocket->sendByte(DialogSocket::TELNET_IP);
|
||||
_pControlSocket->synch();
|
||||
std::string response;
|
||||
int status = sendCommand("ABOR", response);
|
||||
if (status == 426)
|
||||
status = _controlSocket.receiveStatusMessage(response);
|
||||
if (status != 226) throw FTPException("Cannot abort transfer", response, status);
|
||||
status = _pControlSocket->receiveStatusMessage(response);
|
||||
if (status != 226)
|
||||
throw FTPException("Cannot abort transfer", response, status);
|
||||
}
|
||||
|
||||
|
||||
int FTPClientSession::sendCommand(const std::string& command, std::string& response)
|
||||
{
|
||||
_controlSocket.sendMessage(command);
|
||||
return _controlSocket.receiveStatusMessage(response);
|
||||
if (!isOpen())
|
||||
throw FTPException("Connection is closed.");
|
||||
|
||||
_pControlSocket->sendMessage(command);
|
||||
return _pControlSocket->receiveStatusMessage(response);
|
||||
}
|
||||
|
||||
|
||||
int FTPClientSession::sendCommand(const std::string& command, const std::string& arg, std::string& response)
|
||||
{
|
||||
_controlSocket.sendMessage(command, arg);
|
||||
return _controlSocket.receiveStatusMessage(response);
|
||||
if (!isOpen())
|
||||
throw FTPException("Connection is closed.");
|
||||
|
||||
_pControlSocket->sendMessage(command, arg);
|
||||
return _pControlSocket->receiveStatusMessage(response);
|
||||
}
|
||||
|
||||
|
||||
@@ -329,23 +422,24 @@ std::string FTPClientSession::extractPath(const std::string& response)
|
||||
|
||||
StreamSocket FTPClientSession::establishDataConnection(const std::string& command, const std::string& arg)
|
||||
{
|
||||
StreamSocket ss;
|
||||
if (_passiveMode)
|
||||
ss = passiveDataConnection(command, arg);
|
||||
return passiveDataConnection(command, arg);
|
||||
else
|
||||
ss = activeDataConnection(command, arg);
|
||||
ss.setReceiveTimeout(_timeout);
|
||||
return ss;
|
||||
return activeDataConnection(command, arg);
|
||||
}
|
||||
|
||||
|
||||
StreamSocket FTPClientSession::activeDataConnection(const std::string& command, const std::string& arg)
|
||||
{
|
||||
ServerSocket server(SocketAddress(_controlSocket.address().host(), 0));
|
||||
if (!isOpen())
|
||||
throw FTPException("Connection is closed.");
|
||||
|
||||
ServerSocket server(SocketAddress(_pControlSocket->address().host(), 0));
|
||||
sendPortCommand(server.address());
|
||||
std::string response;
|
||||
int status = sendCommand(command, arg, response);
|
||||
if (!isPositivePreliminary(status)) throw FTPException(command + " command failed", response, status);
|
||||
if (!isPositivePreliminary(status))
|
||||
throw FTPException(command + " command failed", response, status);
|
||||
if (server.poll(_timeout, Socket::SELECT_READ))
|
||||
return server.acceptConnection();
|
||||
else
|
||||
@@ -359,7 +453,8 @@ StreamSocket FTPClientSession::passiveDataConnection(const std::string& command,
|
||||
StreamSocket sock(sa);
|
||||
std::string response;
|
||||
int status = sendCommand(command, arg, response);
|
||||
if (!isPositivePreliminary(status)) throw FTPException(command + " command failed", response, status);
|
||||
if (!isPositivePreliminary(status))
|
||||
throw FTPException(command + " command failed", response, status);
|
||||
return sock;
|
||||
}
|
||||
|
||||
@@ -426,7 +521,8 @@ void FTPClientSession::sendPORT(const SocketAddress& addr)
|
||||
arg += NumberFormatter::format(port % 256);
|
||||
std::string response;
|
||||
int status = sendCommand("PORT", arg, response);
|
||||
if (!isPositiveCompletion(status)) throw FTPException("PORT command failed", response, status);
|
||||
if (!isPositiveCompletion(status))
|
||||
throw FTPException("PORT command failed", response, status);
|
||||
}
|
||||
|
||||
|
||||
@@ -451,7 +547,8 @@ void FTPClientSession::sendPASV(SocketAddress& addr)
|
||||
{
|
||||
std::string response;
|
||||
int status = sendCommand("PASV", response);
|
||||
if (!isPositiveCompletion(status)) throw FTPException("PASV command failed", response, status);
|
||||
if (!isPositiveCompletion(status))
|
||||
throw FTPException("PASV command failed", response, status);
|
||||
parseAddress(response, addr);
|
||||
}
|
||||
|
||||
@@ -492,7 +589,7 @@ void FTPClientSession::parseExtAddress(const std::string& str, SocketAddress& ad
|
||||
if (it != end && *it == delim) ++it;
|
||||
Poco::UInt16 port = 0;
|
||||
while (it != end && Poco::Ascii::isDigit(*it)) { port *= 10; port += *it++ - '0'; }
|
||||
addr = SocketAddress(_controlSocket.peerAddress().host(), port);
|
||||
addr = SocketAddress(_pControlSocket->peerAddress().host(), port);
|
||||
}
|
||||
|
||||
|
||||
@@ -503,8 +600,9 @@ void FTPClientSession::endTransfer()
|
||||
delete _pDataStream;
|
||||
_pDataStream = 0;
|
||||
std::string response;
|
||||
int status = _controlSocket.receiveStatusMessage(response);
|
||||
if (!isPositiveCompletion(status)) throw FTPException("Data transfer failed", response, status);
|
||||
int status = _pControlSocket->receiveStatusMessage(response);
|
||||
if (!isPositiveCompletion(status))
|
||||
throw FTPException("Data transfer failed", response, status);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -233,6 +233,12 @@ SocketAddress::SocketAddress(const IPAddress& addr, Poco::UInt16 port)
|
||||
}
|
||||
|
||||
|
||||
SocketAddress::SocketAddress(Poco::UInt16 port)
|
||||
{
|
||||
init(IPAddress(), port);
|
||||
}
|
||||
|
||||
|
||||
SocketAddress::SocketAddress(const std::string& addr, Poco::UInt16 port)
|
||||
{
|
||||
init(addr, port);
|
||||
|
||||
Reference in New Issue
Block a user