mirror of
https://github.com/pocoproject/poco.git
synced 2024-12-13 18:45:10 +01:00
trunk: backport fixes for FTPClientSession
This commit is contained in:
parent
8b70c37260
commit
73426e13e7
@ -77,67 +77,72 @@ public:
|
||||
enum FileType
|
||||
{
|
||||
TYPE_TEXT, // TYPE A (ASCII)
|
||||
TYPE_BINARY // TYPE I (Image)
|
||||
};
|
||||
|
||||
FTPClientSession();
|
||||
/// Creates an FTPClientSession.
|
||||
///
|
||||
/// Passive mode will be used for data transfers.
|
||||
TYPE_BINARY // TYPE I (Image)
|
||||
};
|
||||
|
||||
FTPClientSession();
|
||||
/// Creates an FTPClientSession.
|
||||
///
|
||||
/// Passive mode will be used for data transfers.
|
||||
|
||||
explicit FTPClientSession(const StreamSocket& socket);
|
||||
/// Creates an FTPClientSession using the given
|
||||
/// connected socket for the control connection.
|
||||
///
|
||||
/// Passive mode will be used for data transfers.
|
||||
|
||||
FTPClientSession(const std::string& host,
|
||||
Poco::UInt16 port = FTP_PORT,
|
||||
const std::string& username = "",
|
||||
const std::string& password = "");
|
||||
/// Creates an FTPClientSession using a socket connected
|
||||
/// to the given host and port. If username is supplied,
|
||||
/// login is attempted.
|
||||
///
|
||||
/// Passive mode will be used for data transfers.
|
||||
|
||||
explicit FTPClientSession(const StreamSocket& socket);
|
||||
/// Creates an FTPClientSession using the given
|
||||
/// connected socket for the control connection.
|
||||
///
|
||||
/// Passive mode will be used for data transfers.
|
||||
|
||||
FTPClientSession(const std::string& host,
|
||||
Poco::UInt16 port = FTP_PORT,
|
||||
const std::string& username = "",
|
||||
const std::string& password = "");
|
||||
/// Creates an FTPClientSession using a socket connected
|
||||
/// to the given host and port. If username is supplied,
|
||||
/// login is attempted.
|
||||
///
|
||||
/// Passive mode will be used for data transfers.
|
||||
|
||||
virtual ~FTPClientSession();
|
||||
/// Destroys the FTPClientSession.
|
||||
|
||||
void setTimeout(const Poco::Timespan& timeout);
|
||||
/// Sets the timeout for socket operations.
|
||||
|
||||
Poco::Timespan getTimeout() const;
|
||||
/// Returns the timeout for socket operations.
|
||||
Poco::Timespan getTimeout() const;
|
||||
/// Returns the timeout for socket operations.
|
||||
|
||||
void setPassive(bool flag);
|
||||
/// Enables (default) or disables FTP passive mode for this session.
|
||||
|
||||
bool getPassive() const;
|
||||
/// Returns true iff passive mode is enabled for this connection.
|
||||
|
||||
void open(const std::string& host,
|
||||
Poco::UInt16 port,
|
||||
const std::string& username = "",
|
||||
const std::string& password = "");
|
||||
/// Opens the FTP connection to the given host and port.
|
||||
/// If username is supplied, login is attempted.
|
||||
void setPassive(bool flag, bool useRFC1738 = true);
|
||||
/// Enables (default) or disables FTP passive mode for this session.
|
||||
///
|
||||
/// If useRFC1738 is true (the default), the RFC 1738
|
||||
/// EPSV command is used (with a fallback to PASV if EPSV fails)
|
||||
/// for switching to passive mode. The same applies to
|
||||
/// EPRT and PORT for active connections.
|
||||
|
||||
bool getPassive() const;
|
||||
/// Returns true iff passive mode is enabled for this connection.
|
||||
|
||||
void open(const std::string& host,
|
||||
Poco::UInt16 port,
|
||||
const std::string& username = "",
|
||||
const std::string& password = "");
|
||||
/// Opens the FTP connection to the given host and port.
|
||||
/// If username is supplied, login is attempted.
|
||||
|
||||
void login(const std::string& username, const std::string& password);
|
||||
/// Authenticates the user against the FTP server. Must be
|
||||
/// called before any other commands (except QUIT) can be sent.
|
||||
void login(const std::string& username, const std::string& password);
|
||||
/// Authenticates the user against the FTP server. Must be
|
||||
/// called before any other commands (except QUIT) can be sent.
|
||||
///
|
||||
/// Sends a USER command followed by a PASS command with the
|
||||
/// respective arguments to the server.
|
||||
///
|
||||
/// Throws a FTPException in case of a FTP-specific error, or a
|
||||
/// NetException in case of a general network communication failure.
|
||||
/// Throws a FTPException in case of a FTP-specific error, or a
|
||||
/// NetException in case of a general network communication failure.
|
||||
|
||||
void logout();
|
||||
void logout();
|
||||
|
||||
void close();
|
||||
/// Sends a QUIT command and closes the connection to the server.
|
||||
///
|
||||
void close();
|
||||
/// Sends a QUIT command and closes the connection to the server.
|
||||
///
|
||||
/// Throws a FTPException in case of a FTP-specific error, or a
|
||||
/// NetException in case of a general network communication failure.
|
||||
|
||||
@ -310,18 +315,18 @@ public:
|
||||
/// and waits for a response.
|
||||
|
||||
int sendCommand(const std::string& command, const std::string& arg, std::string& response);
|
||||
/// Sends the given command verbatim to the server
|
||||
/// and waits for a response.
|
||||
/// Sends the given command verbatim to the server
|
||||
/// and waits for a response.
|
||||
|
||||
bool isOpen() const;
|
||||
/// Returns true if the connection with FTP server is opened.
|
||||
bool isOpen() const;
|
||||
/// Returns true if the connection with FTP server is opened.
|
||||
|
||||
bool isLoggedIn() const;
|
||||
/// Returns true if the session is logged in.
|
||||
bool isLoggedIn() const;
|
||||
/// Returns true if the session is logged in.
|
||||
|
||||
protected:
|
||||
enum StatusClass
|
||||
{
|
||||
enum StatusClass
|
||||
{
|
||||
FTP_POSITIVE_PRELIMINARY = 1,
|
||||
FTP_POSITIVE_COMPLETION = 2,
|
||||
FTP_POSITIVE_INTERMEDIATE = 3,
|
||||
@ -350,22 +355,22 @@ protected:
|
||||
void sendPASV(SocketAddress& addr);
|
||||
void parseAddress(const std::string& str, SocketAddress& addr);
|
||||
void parseExtAddress(const std::string& str, SocketAddress& addr);
|
||||
void endTransfer();
|
||||
|
||||
void endTransfer();
|
||||
|
||||
private:
|
||||
FTPClientSession(const FTPClientSession&);
|
||||
FTPClientSession& operator = (const FTPClientSession&);
|
||||
|
||||
std::string _host;
|
||||
Poco::UInt16 _port;
|
||||
DialogSocket* _pControlSocket;
|
||||
SocketStream* _pDataStream;
|
||||
bool _passiveMode;
|
||||
FileType _fileType;
|
||||
bool _supports1738;
|
||||
bool _serverReady;
|
||||
bool _isLoggedIn;
|
||||
Poco::Timespan _timeout;
|
||||
FTPClientSession(const FTPClientSession&);
|
||||
FTPClientSession& operator = (const FTPClientSession&);
|
||||
|
||||
std::string _host;
|
||||
Poco::UInt16 _port;
|
||||
DialogSocket* _pControlSocket;
|
||||
SocketStream* _pDataStream;
|
||||
bool _passiveMode;
|
||||
FileType _fileType;
|
||||
bool _supports1738;
|
||||
bool _serverReady;
|
||||
bool _isLoggedIn;
|
||||
Poco::Timespan _timeout;
|
||||
};
|
||||
|
||||
|
||||
@ -404,13 +409,13 @@ inline bool FTPClientSession::isPermanentNegative(int status)
|
||||
|
||||
inline bool FTPClientSession::isOpen() const
|
||||
{
|
||||
return _pControlSocket != 0;
|
||||
return _pControlSocket != 0;
|
||||
}
|
||||
|
||||
|
||||
inline bool FTPClientSession::isLoggedIn() const
|
||||
{
|
||||
return _isLoggedIn;
|
||||
return _isLoggedIn;
|
||||
}
|
||||
|
||||
|
||||
|
@ -40,7 +40,7 @@
|
||||
#include "Poco/Net/ServerSocket.h"
|
||||
#include "Poco/Net/NetException.h"
|
||||
#include "Poco/NumberFormatter.h"
|
||||
#include <cctype>
|
||||
#include "Poco/Ascii.h"
|
||||
|
||||
|
||||
using Poco::NumberFormatter;
|
||||
@ -51,83 +51,84 @@ namespace Net {
|
||||
|
||||
|
||||
FTPClientSession::FTPClientSession():
|
||||
_port(0),
|
||||
_pControlSocket(0),
|
||||
_pDataStream(0),
|
||||
_passiveMode(true),
|
||||
_fileType(TYPE_BINARY),
|
||||
_supports1738(true),
|
||||
_serverReady(false),
|
||||
_isLoggedIn(false),
|
||||
_timeout(DEFAULT_TIMEOUT)
|
||||
_port(0),
|
||||
_pControlSocket(0),
|
||||
_pDataStream(0),
|
||||
_passiveMode(true),
|
||||
_fileType(TYPE_BINARY),
|
||||
_supports1738(true),
|
||||
_serverReady(false),
|
||||
_isLoggedIn(false),
|
||||
_timeout(DEFAULT_TIMEOUT)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
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),
|
||||
_serverReady(false),
|
||||
_isLoggedIn(false),
|
||||
_timeout(DEFAULT_TIMEOUT)
|
||||
_host(socket.address().host().toString()),
|
||||
_port(socket.address().port()),
|
||||
_pControlSocket(new DialogSocket(socket)),
|
||||
_pDataStream(0),
|
||||
_passiveMode(true),
|
||||
_fileType(TYPE_BINARY),
|
||||
_supports1738(true),
|
||||
_serverReady(false),
|
||||
_isLoggedIn(false),
|
||||
_timeout(DEFAULT_TIMEOUT)
|
||||
{
|
||||
_pControlSocket->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);
|
||||
}
|
||||
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.");
|
||||
if (!isOpen())
|
||||
throw FTPException("Connection is closed.");
|
||||
|
||||
_timeout = timeout;
|
||||
_pControlSocket->setReceiveTimeout(timeout);
|
||||
_timeout = timeout;
|
||||
_pControlSocket->setReceiveTimeout(timeout);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Poco::Timespan FTPClientSession::getTimeout() const
|
||||
{
|
||||
return _timeout;
|
||||
}
|
||||
|
||||
|
||||
void FTPClientSession::setPassive(bool flag)
|
||||
void FTPClientSession::setPassive(bool flag, bool useRFC1738)
|
||||
{
|
||||
_passiveMode = flag;
|
||||
_passiveMode = flag;
|
||||
_supports1738 = useRFC1738;
|
||||
}
|
||||
|
||||
|
||||
@ -138,85 +139,85 @@ bool FTPClientSession::getPassive() const
|
||||
|
||||
|
||||
void FTPClientSession::open(const std::string& host,
|
||||
Poco::UInt16 port,
|
||||
const std::string& username,
|
||||
const std::string& password)
|
||||
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);
|
||||
}
|
||||
_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();
|
||||
if (_isLoggedIn) logout();
|
||||
|
||||
int status = FTP_POSITIVE_COMPLETION * 100;
|
||||
std::string response;
|
||||
if (!_pControlSocket)
|
||||
{
|
||||
_pControlSocket = new DialogSocket(SocketAddress(_host, _port));
|
||||
_pControlSocket->setReceiveTimeout(_timeout);
|
||||
}
|
||||
int status = FTP_POSITIVE_COMPLETION * 100;
|
||||
std::string response;
|
||||
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);
|
||||
if (!_serverReady)
|
||||
{
|
||||
status = _pControlSocket->receiveStatusMessage(response);
|
||||
if (!isPositiveCompletion(status))
|
||||
throw FTPException("Cannot login to server", response, status);
|
||||
|
||||
_serverReady = true;
|
||||
}
|
||||
_serverReady = true;
|
||||
}
|
||||
|
||||
status = sendCommand("USER", username, response);
|
||||
if (isPositiveIntermediate(status))
|
||||
status = sendCommand("PASS", password, response);
|
||||
if (!isPositiveCompletion(status))
|
||||
throw FTPException("Login denied", response);
|
||||
status = sendCommand("USER", username, response);
|
||||
if (isPositiveIntermediate(status))
|
||||
status = sendCommand("PASS", password, response);
|
||||
if (!isPositiveCompletion(status))
|
||||
throw FTPException("Login denied", response, status);
|
||||
|
||||
setFileType(_fileType);
|
||||
_isLoggedIn = true;
|
||||
setFileType(_fileType);
|
||||
_isLoggedIn = true;
|
||||
}
|
||||
|
||||
|
||||
void FTPClientSession::logout()
|
||||
{
|
||||
if (!isOpen())
|
||||
throw FTPException("Connection is closed.");
|
||||
{
|
||||
if (!isOpen())
|
||||
throw FTPException("Connection is closed.");
|
||||
|
||||
if (_isLoggedIn)
|
||||
{
|
||||
try { endTransfer(); }
|
||||
catch (...) { }
|
||||
std::string response;
|
||||
sendCommand("QUIT", response);
|
||||
_isLoggedIn = false;
|
||||
}
|
||||
if (_isLoggedIn)
|
||||
{
|
||||
try { endTransfer(); }
|
||||
catch (...) { }
|
||||
std::string response;
|
||||
sendCommand("QUIT", response);
|
||||
_isLoggedIn = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FTPClientSession::close()
|
||||
{
|
||||
logout();
|
||||
_pControlSocket->close();
|
||||
delete _pControlSocket;
|
||||
_pControlSocket = 0;
|
||||
_serverReady = false;
|
||||
logout();
|
||||
_pControlSocket->close();
|
||||
delete _pControlSocket;
|
||||
_pControlSocket = 0;
|
||||
_serverReady = false;
|
||||
}
|
||||
|
||||
|
||||
void FTPClientSession::setFileType(FTPClientSession::FileType type)
|
||||
{
|
||||
std::string response;
|
||||
std::string response;
|
||||
int status = sendCommand("TYPE", (type == TYPE_TEXT ? "A" : "I"), response);
|
||||
if (!isPositiveCompletion(status)) throw FTPException("Cannot set file type", response);
|
||||
if (!isPositiveCompletion(status)) throw FTPException("Cannot set file type", response, status);
|
||||
_fileType = type;
|
||||
}
|
||||
|
||||
@ -234,16 +235,16 @@ std::string FTPClientSession::systemType()
|
||||
if (isPositiveCompletion(status))
|
||||
return response.substr(4);
|
||||
else
|
||||
throw FTPException("Cannot get remote system type", response);
|
||||
throw FTPException("Cannot get remote system type", response, status);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
std::string response;
|
||||
int status = sendCommand("CWD", path, response);
|
||||
if (!isPositiveCompletion(status))
|
||||
throw FTPException("Cannot change directory", response, status);
|
||||
}
|
||||
|
||||
|
||||
@ -254,66 +255,66 @@ std::string FTPClientSession::getWorkingDirectory()
|
||||
if (isPositiveCompletion(status))
|
||||
return extractPath(response);
|
||||
else
|
||||
throw FTPException("Cannot get current working directory", response);
|
||||
throw FTPException("Cannot get current working directory", response, status);
|
||||
}
|
||||
|
||||
|
||||
void FTPClientSession::cdup()
|
||||
{
|
||||
std::string response;
|
||||
int status = sendCommand("CDUP", response);
|
||||
if (!isPositiveCompletion(status))
|
||||
throw FTPException("Cannot change directory", response);
|
||||
std::string response;
|
||||
int status = sendCommand("CDUP", response);
|
||||
if (!isPositiveCompletion(status))
|
||||
throw FTPException("Cannot change directory", response, status);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FTPClientSession::rename(const std::string& oldName, const std::string& newName)
|
||||
{
|
||||
std::string response;
|
||||
int status = sendCommand("RNFR", oldName, response);
|
||||
if (!isPositiveIntermediate(status))
|
||||
throw FTPException(std::string("Cannot rename ") + oldName, response);
|
||||
status = sendCommand("RNTO", newName, response);
|
||||
if (!isPositiveCompletion(status))
|
||||
throw FTPException(std::string("Cannot rename to ") + newName, response);
|
||||
std::string response;
|
||||
int status = sendCommand("RNFR", oldName, response);
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
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);
|
||||
std::string response;
|
||||
int status = sendCommand("DELE", path, response);
|
||||
if (!isPositiveCompletion(status))
|
||||
throw FTPException(std::string("Cannot remove " + path), response, status);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
std::string response;
|
||||
int status = sendCommand("MKD", path, response);
|
||||
if (!isPositiveCompletion(status))
|
||||
throw FTPException(std::string("Cannot create directory ") + path, response, status);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
std::string response;
|
||||
int status = sendCommand("RMD", path, response);
|
||||
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.");
|
||||
if (!isOpen())
|
||||
throw FTPException("Connection is closed.");
|
||||
|
||||
delete _pDataStream;
|
||||
_pDataStream = 0;
|
||||
_pDataStream = new SocketStream(establishDataConnection("RETR", path));
|
||||
delete _pDataStream;
|
||||
_pDataStream = 0;
|
||||
_pDataStream = new SocketStream(establishDataConnection("RETR", path));
|
||||
return *_pDataStream;
|
||||
}
|
||||
|
||||
@ -323,15 +324,15 @@ void FTPClientSession::endDownload()
|
||||
endTransfer();
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::ostream& FTPClientSession::beginUpload(const std::string& path)
|
||||
{
|
||||
if (!isOpen())
|
||||
throw FTPException("Connection is closed.");
|
||||
if (!isOpen())
|
||||
throw FTPException("Connection is closed.");
|
||||
|
||||
delete _pDataStream;
|
||||
_pDataStream = 0;
|
||||
_pDataStream = new SocketStream(establishDataConnection("STOR", path));
|
||||
delete _pDataStream;
|
||||
_pDataStream = 0;
|
||||
_pDataStream = new SocketStream(establishDataConnection("STOR", path));
|
||||
return *_pDataStream;
|
||||
}
|
||||
|
||||
@ -344,12 +345,12 @@ void FTPClientSession::endUpload()
|
||||
|
||||
std::istream& FTPClientSession::beginList(const std::string& path, bool extended)
|
||||
{
|
||||
if (!isOpen())
|
||||
throw FTPException("Connection is closed.");
|
||||
if (!isOpen())
|
||||
throw FTPException("Connection is closed.");
|
||||
|
||||
delete _pDataStream;
|
||||
_pDataStream = 0;
|
||||
_pDataStream = new SocketStream(establishDataConnection(extended ? "LIST" : "NLST", path));
|
||||
delete _pDataStream;
|
||||
_pDataStream = 0;
|
||||
_pDataStream = new SocketStream(establishDataConnection(extended ? "LIST" : "NLST", path));
|
||||
return *_pDataStream;
|
||||
}
|
||||
|
||||
@ -359,39 +360,40 @@ void FTPClientSession::endList()
|
||||
endTransfer();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FTPClientSession::abort()
|
||||
{
|
||||
if (!isOpen())
|
||||
throw FTPException("Connection is closed.");
|
||||
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 = _pControlSocket->receiveStatusMessage(response);
|
||||
if (status != 226) throw FTPException("Cannot abort transfer", response);
|
||||
_pControlSocket->sendByte(DialogSocket::TELNET_IP);
|
||||
_pControlSocket->synch();
|
||||
std::string response;
|
||||
int status = sendCommand("ABOR", response);
|
||||
if (status == 426)
|
||||
status = _pControlSocket->receiveStatusMessage(response);
|
||||
if (status != 226)
|
||||
throw FTPException("Cannot abort transfer", response, status);
|
||||
}
|
||||
|
||||
|
||||
int FTPClientSession::sendCommand(const std::string& command, std::string& response)
|
||||
{
|
||||
if (!isOpen())
|
||||
throw FTPException("Connection is closed.");
|
||||
if (!isOpen())
|
||||
throw FTPException("Connection is closed.");
|
||||
|
||||
_pControlSocket->sendMessage(command);
|
||||
return _pControlSocket->receiveStatusMessage(response);
|
||||
_pControlSocket->sendMessage(command);
|
||||
return _pControlSocket->receiveStatusMessage(response);
|
||||
}
|
||||
|
||||
|
||||
int FTPClientSession::sendCommand(const std::string& command, const std::string& arg, std::string& response)
|
||||
{
|
||||
if (!isOpen())
|
||||
throw FTPException("Connection is closed.");
|
||||
if (!isOpen())
|
||||
throw FTPException("Connection is closed.");
|
||||
|
||||
_pControlSocket->sendMessage(command, arg);
|
||||
return _pControlSocket->receiveStatusMessage(response);
|
||||
_pControlSocket->sendMessage(command, arg);
|
||||
return _pControlSocket->receiveStatusMessage(response);
|
||||
}
|
||||
|
||||
|
||||
@ -409,7 +411,7 @@ std::string FTPClientSession::extractPath(const std::string& response)
|
||||
if (*it == '"')
|
||||
{
|
||||
++it;
|
||||
if (it != end && *it != '"') break;
|
||||
if (it == end || (it != end && *it != '"')) break;
|
||||
}
|
||||
path += *it++;
|
||||
}
|
||||
@ -429,14 +431,15 @@ StreamSocket FTPClientSession::establishDataConnection(const std::string& comman
|
||||
|
||||
StreamSocket FTPClientSession::activeDataConnection(const std::string& command, const std::string& arg)
|
||||
{
|
||||
if (!isOpen())
|
||||
throw FTPException("Connection is closed.");
|
||||
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);
|
||||
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 (server.poll(_timeout, Socket::SELECT_READ))
|
||||
return server.acceptConnection();
|
||||
else
|
||||
@ -450,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);
|
||||
if (!isPositivePreliminary(status))
|
||||
throw FTPException(command + " command failed", response, status);
|
||||
return sock;
|
||||
}
|
||||
|
||||
@ -499,7 +503,7 @@ bool FTPClientSession::sendEPRT(const SocketAddress& addr)
|
||||
else if (isPermanentNegative(status))
|
||||
return false;
|
||||
else
|
||||
throw FTPException("EPRT command failed", response);
|
||||
throw FTPException("EPRT command failed", response, status);
|
||||
}
|
||||
|
||||
|
||||
@ -517,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);
|
||||
if (!isPositiveCompletion(status))
|
||||
throw FTPException("PORT command failed", response, status);
|
||||
}
|
||||
|
||||
|
||||
@ -534,7 +539,7 @@ bool FTPClientSession::sendEPSV(SocketAddress& addr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else throw FTPException("EPSV command failed", response);
|
||||
else throw FTPException("EPSV command failed", response, status);
|
||||
}
|
||||
|
||||
|
||||
@ -542,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);
|
||||
if (!isPositiveCompletion(status))
|
||||
throw FTPException("PASV command failed", response, status);
|
||||
parseAddress(response, addr);
|
||||
}
|
||||
|
||||
@ -554,19 +560,19 @@ void FTPClientSession::parseAddress(const std::string& str, SocketAddress& addr)
|
||||
while (it != end && *it != '(') ++it;
|
||||
if (it != end) ++it;
|
||||
std::string host;
|
||||
while (it != end && std::isdigit(*it)) host += *it++;
|
||||
while (it != end && Poco::Ascii::isDigit(*it)) host += *it++;
|
||||
if (it != end && *it == ',') { host += '.'; ++it; }
|
||||
while (it != end && std::isdigit(*it)) host += *it++;
|
||||
while (it != end && Poco::Ascii::isDigit(*it)) host += *it++;
|
||||
if (it != end && *it == ',') { host += '.'; ++it; }
|
||||
while (it != end && std::isdigit(*it)) host += *it++;
|
||||
while (it != end && Poco::Ascii::isDigit(*it)) host += *it++;
|
||||
if (it != end && *it == ',') { host += '.'; ++it; }
|
||||
while (it != end && std::isdigit(*it)) host += *it++;
|
||||
while (it != end && Poco::Ascii::isDigit(*it)) host += *it++;
|
||||
if (it != end && *it == ',') ++it;
|
||||
Poco::UInt16 portHi = 0;
|
||||
while (it != end && std::isdigit(*it)) { portHi *= 10; portHi += *it++ - '0'; }
|
||||
while (it != end && Poco::Ascii::isDigit(*it)) { portHi *= 10; portHi += *it++ - '0'; }
|
||||
if (it != end && *it == ',') ++it;
|
||||
Poco::UInt16 portLo = 0;
|
||||
while (it != end && std::isdigit(*it)) { portLo *= 10; portLo += *it++ - '0'; }
|
||||
while (it != end && Poco::Ascii::isDigit(*it)) { portLo *= 10; portLo += *it++ - '0'; }
|
||||
addr = SocketAddress(host, portHi*256 + portLo);
|
||||
}
|
||||
|
||||
@ -582,23 +588,21 @@ void FTPClientSession::parseExtAddress(const std::string& str, SocketAddress& ad
|
||||
if (it != end && *it == delim) ++it;
|
||||
if (it != end && *it == delim) ++it;
|
||||
Poco::UInt16 port = 0;
|
||||
while (it != end && std::isdigit(*it)) { port *= 10; port += *it++ - '0'; }
|
||||
while (it != end && Poco::Ascii::isDigit(*it)) { port *= 10; port += *it++ - '0'; }
|
||||
addr = SocketAddress(_pControlSocket->peerAddress().host(), port);
|
||||
}
|
||||
|
||||
|
||||
void FTPClientSession::endTransfer()
|
||||
{
|
||||
if (!isOpen())
|
||||
throw FTPException("Connection is closed.");
|
||||
|
||||
if (_pDataStream)
|
||||
{
|
||||
delete _pDataStream;
|
||||
_pDataStream = 0;
|
||||
std::string response;
|
||||
int status = _pControlSocket->receiveStatusMessage(response);
|
||||
if (!isPositiveCompletion(status)) throw FTPException("Data transfer failed", response);
|
||||
if (!isPositiveCompletion(status))
|
||||
throw FTPException("Data transfer failed", response, status);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user