trunk: backport fixes for FTPClientSession

This commit is contained in:
Marian Krivos 2012-02-04 17:39:15 +00:00
parent 8b70c37260
commit 73426e13e7
2 changed files with 273 additions and 264 deletions

View File

@ -110,8 +110,13 @@ public:
Poco::Timespan getTimeout() const;
/// Returns the timeout for socket operations.
void setPassive(bool flag);
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.

View File

@ -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;
@ -94,16 +94,16 @@ FTPClientSession::FTPClientSession(const std::string& host,
_serverReady(false),
_isLoggedIn(false),
_timeout(DEFAULT_TIMEOUT)
{
{
if (!username.empty())
login(username, password);
else
_pControlSocket->setReceiveTimeout(_timeout);
}
}
FTPClientSession::~FTPClientSession()
{
{
try { close(); }
catch (...) { }
}
@ -125,9 +125,10 @@ Poco::Timespan FTPClientSession::getTimeout() const
}
void FTPClientSession::setPassive(bool flag)
void FTPClientSession::setPassive(bool flag, bool useRFC1738)
{
_passiveMode = flag;
_supports1738 = useRFC1738;
}
@ -170,7 +171,7 @@ void FTPClientSession::login(const std::string& username, const std::string& pas
{
status = _pControlSocket->receiveStatusMessage(response);
if (!isPositiveCompletion(status))
throw FTPException("Cannot login to server", response);
throw FTPException("Cannot login to server", response, status);
_serverReady = true;
}
@ -179,7 +180,7 @@ void FTPClientSession::login(const std::string& username, const std::string& pas
if (isPositiveIntermediate(status))
status = sendCommand("PASS", password, response);
if (!isPositiveCompletion(status))
throw FTPException("Login denied", response);
throw FTPException("Login denied", response, status);
setFileType(_fileType);
_isLoggedIn = true;
@ -187,7 +188,7 @@ void FTPClientSession::login(const std::string& username, const std::string& pas
void FTPClientSession::logout()
{
{
if (!isOpen())
throw FTPException("Connection is closed.");
@ -216,7 +217,7 @@ void FTPClientSession::setFileType(FTPClientSession::FileType type)
{
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,7 +235,7 @@ 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);
}
@ -243,7 +244,7 @@ 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);
throw FTPException("Cannot change directory", response, status);
}
@ -254,7 +255,7 @@ 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);
}
@ -263,7 +264,7 @@ void FTPClientSession::cdup()
std::string response;
int status = sendCommand("CDUP", response);
if (!isPositiveCompletion(status))
throw FTPException("Cannot change directory", response);
throw FTPException("Cannot change directory", response, status);
}
@ -272,10 +273,10 @@ 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);
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);
throw FTPException(std::string("Cannot rename to ") + newName, response, status);
}
@ -284,7 +285,7 @@ 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);
throw FTPException(std::string("Cannot remove " + path), response, status);
}
@ -293,7 +294,7 @@ 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);
throw FTPException(std::string("Cannot create directory ") + path, response, status);
}
@ -302,7 +303,7 @@ 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);
throw FTPException(std::string("Cannot remove directory ") + path, response, status);
}
@ -371,7 +372,8 @@ void FTPClientSession::abort()
int status = sendCommand("ABOR", response);
if (status == 426)
status = _pControlSocket->receiveStatusMessage(response);
if (status != 226) throw FTPException("Cannot abort transfer", response);
if (status != 226)
throw FTPException("Cannot abort transfer", response, status);
}
@ -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++;
}
@ -436,7 +438,8 @@ StreamSocket FTPClientSession::activeDataConnection(const std::string& command,
sendPortCommand(server.address());
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);
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);
}
}