mirror of
https://github.com/pocoproject/poco.git
synced 2025-02-22 23:11:00 +01:00
merge FTPSClientSession from develop-experimental
This commit is contained in:
parent
958ce15bb5
commit
5d481ff493
@ -63,7 +63,7 @@ public:
|
||||
///
|
||||
/// Passive mode will be used for data transfers.
|
||||
|
||||
explicit FTPClientSession(const StreamSocket& socket);
|
||||
explicit FTPClientSession(const StreamSocket& socket, bool readWelcomeMessage = true);
|
||||
/// Creates an FTPClientSession using the given
|
||||
/// connected socket for the control connection.
|
||||
///
|
||||
@ -99,14 +99,14 @@ public:
|
||||
bool getPassive() const;
|
||||
/// Returns true iff passive mode is enabled for this connection.
|
||||
|
||||
void open(const std::string& host,
|
||||
virtual 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);
|
||||
virtual 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.
|
||||
///
|
||||
@ -302,7 +302,16 @@ public:
|
||||
bool isLoggedIn() const;
|
||||
/// Returns true if the session is logged in.
|
||||
|
||||
bool isSecure() const;
|
||||
/// Returns true if the session is FTPS.
|
||||
|
||||
const std::string& welcomeMessage();
|
||||
/// Returns welcome message.
|
||||
|
||||
protected:
|
||||
virtual void receiveServerReadyReply();
|
||||
/// Function that read server welcome message after connetion
|
||||
|
||||
enum StatusClass
|
||||
{
|
||||
FTP_POSITIVE_PRELIMINARY = 1,
|
||||
@ -335,20 +344,23 @@ protected:
|
||||
void parseExtAddress(const std::string& str, SocketAddress& addr);
|
||||
void endTransfer();
|
||||
|
||||
DialogSocket* _pControlSocket = nullptr;
|
||||
SocketStream* _pDataStream = nullptr;
|
||||
|
||||
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;
|
||||
std::string _host;
|
||||
Poco::UInt16 _port = 0;
|
||||
bool _passiveMode = true;
|
||||
FileType _fileType = TYPE_BINARY;
|
||||
bool _supports1738 = true;
|
||||
bool _serverReady = false;
|
||||
bool _isLoggedIn = false;
|
||||
Poco::Timespan _timeout = DEFAULT_TIMEOUT;
|
||||
std::string _welcomeMessage;
|
||||
Poco::FastMutex _wmMutex;
|
||||
};
|
||||
|
||||
|
||||
@ -397,6 +409,19 @@ inline bool FTPClientSession::isLoggedIn() const
|
||||
}
|
||||
|
||||
|
||||
inline bool FTPClientSession::isSecure() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
inline const std::string& FTPClientSession::welcomeMessage()
|
||||
{
|
||||
Poco::FastMutex::ScopedLock lock(_wmMutex);
|
||||
return _welcomeMessage;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
||||
|
||||
|
||||
|
@ -29,9 +29,9 @@ namespace Net {
|
||||
|
||||
|
||||
FTPClientSession::FTPClientSession():
|
||||
_port(0),
|
||||
_pControlSocket(0),
|
||||
_pDataStream(0),
|
||||
_port(0),
|
||||
_passiveMode(true),
|
||||
_fileType(TYPE_BINARY),
|
||||
_supports1738(true),
|
||||
@ -42,11 +42,11 @@ FTPClientSession::FTPClientSession():
|
||||
}
|
||||
|
||||
|
||||
FTPClientSession::FTPClientSession(const StreamSocket& socket):
|
||||
_host(socket.address().host().toString()),
|
||||
_port(socket.address().port()),
|
||||
FTPClientSession::FTPClientSession(const StreamSocket& socket, bool readWelcomeMessage):
|
||||
_pControlSocket(new DialogSocket(socket)),
|
||||
_pDataStream(0),
|
||||
_host(socket.address().host().toString()),
|
||||
_port(socket.address().port()),
|
||||
_passiveMode(true),
|
||||
_fileType(TYPE_BINARY),
|
||||
_supports1738(true),
|
||||
@ -55,6 +55,14 @@ FTPClientSession::FTPClientSession(const StreamSocket& socket):
|
||||
_timeout(DEFAULT_TIMEOUT)
|
||||
{
|
||||
_pControlSocket->setReceiveTimeout(_timeout);
|
||||
if (readWelcomeMessage)
|
||||
{
|
||||
receiveServerReadyReply();
|
||||
}
|
||||
else
|
||||
{
|
||||
_serverReady = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -62,10 +70,10 @@ 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),
|
||||
_host(host),
|
||||
_port(port),
|
||||
_passiveMode(true),
|
||||
_fileType(TYPE_BINARY),
|
||||
_supports1738(true),
|
||||
@ -73,10 +81,9 @@ FTPClientSession::FTPClientSession(const std::string& host,
|
||||
_isLoggedIn(false),
|
||||
_timeout(DEFAULT_TIMEOUT)
|
||||
{
|
||||
_pControlSocket->setReceiveTimeout(_timeout);
|
||||
if (!username.empty())
|
||||
login(username, password);
|
||||
else
|
||||
_pControlSocket->setReceiveTimeout(_timeout);
|
||||
}
|
||||
|
||||
|
||||
@ -134,12 +141,32 @@ void FTPClientSession::open(const std::string& host,
|
||||
}
|
||||
else
|
||||
{
|
||||
_pControlSocket = new DialogSocket(SocketAddress(_host, _port));
|
||||
_pControlSocket->setReceiveTimeout(_timeout);
|
||||
if (!_pControlSocket)
|
||||
{
|
||||
_pControlSocket = new DialogSocket(SocketAddress(_host, _port));
|
||||
_pControlSocket->setReceiveTimeout(_timeout);
|
||||
}
|
||||
receiveServerReadyReply();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FTPClientSession::receiveServerReadyReply()
|
||||
{
|
||||
if (_serverReady) return;
|
||||
std::string response;
|
||||
int status = _pControlSocket->receiveStatusMessage(response);
|
||||
if (!isPositiveCompletion(status))
|
||||
throw FTPException("Cannot receive status message", response, status);
|
||||
|
||||
{
|
||||
Poco::FastMutex::ScopedLock lock(_wmMutex);
|
||||
_welcomeMessage = response;
|
||||
}
|
||||
_serverReady = true;
|
||||
}
|
||||
|
||||
|
||||
void FTPClientSession::login(const std::string& username, const std::string& password)
|
||||
{
|
||||
if (_isLoggedIn) logout();
|
||||
@ -151,15 +178,7 @@ void FTPClientSession::login(const std::string& username, const std::string& pas
|
||||
_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;
|
||||
}
|
||||
receiveServerReadyReply();
|
||||
|
||||
status = sendCommand("USER", username, response);
|
||||
if (isPositiveIntermediate(status))
|
||||
@ -190,8 +209,13 @@ void FTPClientSession::logout()
|
||||
|
||||
void FTPClientSession::close()
|
||||
{
|
||||
try { logout(); }
|
||||
catch (...) {}
|
||||
try
|
||||
{
|
||||
logout();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
_serverReady = false;
|
||||
if (_pControlSocket)
|
||||
{
|
||||
|
@ -16,10 +16,11 @@ objects = AcceptCertificateHandler RejectCertificateHandler ConsoleCertificateHa
|
||||
PrivateKeyPassphraseHandler SecureServerSocket SecureServerSocketImpl \
|
||||
SecureSocketImpl SecureStreamSocket SecureStreamSocketImpl \
|
||||
SSLException SSLManager Utility VerificationErrorArgs \
|
||||
X509Certificate Session SecureSMTPClientSession
|
||||
X509Certificate Session SecureSMTPClientSession \
|
||||
FTPSClientSession
|
||||
|
||||
target = PocoNetSSL
|
||||
target_version = $(LIBVERSION)
|
||||
target_libs = PocoNet PocoCrypto PocoUtil PocoFoundation
|
||||
target_libs = PocoNet PocoCrypto PocoUtil PocoFoundation
|
||||
|
||||
include $(POCO_BASE)/build/rules/lib
|
||||
|
91
NetSSL_OpenSSL/include/Poco/Net/FTPSClientSession.h
Normal file
91
NetSSL_OpenSSL/include/Poco/Net/FTPSClientSession.h
Normal file
@ -0,0 +1,91 @@
|
||||
//
|
||||
// FTPSClientSession.h
|
||||
//
|
||||
// Library: Net
|
||||
// Package: FTP
|
||||
// Module: FTPSClientSession
|
||||
//
|
||||
// Definition of the FTPSClientSession class.
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#ifndef NetSSL_FTPSClientSession_INCLUDED
|
||||
#define NetSSL_FTPSClientSession_INCLUDED
|
||||
|
||||
|
||||
#include "Poco/Net/NetSSL.h"
|
||||
#include "Poco/Net/FTPClientSession.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Net {
|
||||
|
||||
|
||||
class NetSSL_API FTPSClientSession: public Poco::Net::FTPClientSession
|
||||
{
|
||||
public:
|
||||
FTPSClientSession();
|
||||
/// Creates an FTPSClientSession.
|
||||
///
|
||||
/// Passive mode will be used for data transfers.
|
||||
|
||||
explicit FTPSClientSession(const StreamSocket& socket, bool readWelcomeMessage = true, bool tryUseFTPS = true);
|
||||
/// Creates an FTPSClientSession using the given
|
||||
/// connected socket for the control connection.
|
||||
///
|
||||
/// Passive mode will be used for data transfers.
|
||||
|
||||
FTPSClientSession(const std::string& host, Poco::UInt16 port = FTP_PORT, const std::string& username = "", const std::string& password = "");
|
||||
/// Creates an FTPSClientSession 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 ~FTPSClientSession();
|
||||
|
||||
void tryFTPSmode(bool tryFTPS);
|
||||
/// avoid or require TLS mode
|
||||
|
||||
bool isSecure() const;
|
||||
/// Returns true if the session is FTPS.
|
||||
|
||||
protected:
|
||||
virtual StreamSocket establishDataConnection(const std::string& command, const std::string& arg);
|
||||
/// Create secure data connection
|
||||
|
||||
virtual void receiveServerReadyReply();
|
||||
/// Function that read server welcome message after connetion and set and make secure socket
|
||||
|
||||
private:
|
||||
void beforeCreateDataSocket();
|
||||
///Send commands to check if we can encrypt data socket
|
||||
|
||||
void afterCreateControlSocket();
|
||||
///Send commands to make SSL negotiating of control channel
|
||||
|
||||
bool _tryFTPS = true;
|
||||
bool _secureDataConnection = false;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// inlines
|
||||
//
|
||||
inline bool FTPSClientSession::isSecure() const
|
||||
{
|
||||
if (_pControlSocket != nullptr)
|
||||
return _pControlSocket->secure();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
||||
|
||||
|
||||
#endif // #define NetSSL_FTPSClientSession_INCLUDED
|
130
NetSSL_OpenSSL/src/FTPSClientSession.cpp
Normal file
130
NetSSL_OpenSSL/src/FTPSClientSession.cpp
Normal file
@ -0,0 +1,130 @@
|
||||
//
|
||||
// FTPSClientSession.cpp
|
||||
//
|
||||
// Library: Net
|
||||
// Package: FTP
|
||||
// Module: FTPSClientSession
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Net/FTPSClientSession.h"
|
||||
#include "Poco/Net/SecureStreamSocket.h"
|
||||
#include "Poco/Net/SecureStreamSocketImpl.h"
|
||||
#include "Poco/Net/SSLManager.h"
|
||||
#include "Poco/Net/NetException.h"
|
||||
|
||||
namespace Poco {
|
||||
namespace Net {
|
||||
|
||||
FTPSClientSession::FTPSClientSession() :
|
||||
FTPClientSession()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FTPSClientSession::~FTPSClientSession()
|
||||
{
|
||||
}
|
||||
|
||||
FTPSClientSession::FTPSClientSession(const StreamSocket& socket, bool readWelcomeMessage, bool tryUseFTPS) :
|
||||
FTPClientSession(socket, readWelcomeMessage), _tryFTPS(tryUseFTPS)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FTPSClientSession::FTPSClientSession(const std::string& host,
|
||||
Poco::UInt16 port,
|
||||
const std::string& username,
|
||||
const std::string& password) :
|
||||
FTPClientSession(host, port, username, password)
|
||||
{
|
||||
}
|
||||
|
||||
void FTPSClientSession::tryFTPSmode(bool bTryFTPS)
|
||||
{
|
||||
_tryFTPS = bTryFTPS;
|
||||
}
|
||||
|
||||
void FTPSClientSession::beforeCreateDataSocket()
|
||||
{
|
||||
if (_secureDataConnection)
|
||||
return;
|
||||
_secureDataConnection = false;
|
||||
if (!_pControlSocket->secure())
|
||||
return;
|
||||
std::string sResponse;
|
||||
int status = sendCommand("PBSZ 0", sResponse);
|
||||
if (isPositiveCompletion(status))
|
||||
{
|
||||
status = sendCommand("PROT P", sResponse);
|
||||
if (isPositiveCompletion(status))
|
||||
_secureDataConnection = true;
|
||||
}
|
||||
}
|
||||
|
||||
void FTPSClientSession::afterCreateControlSocket()
|
||||
{
|
||||
if (!_tryFTPS)
|
||||
return;
|
||||
_pControlSocket->setNoDelay(true);
|
||||
if (_pControlSocket->secure())
|
||||
return;
|
||||
|
||||
std::string sResponse;
|
||||
int status = sendCommand("AUTH TLS", sResponse);
|
||||
if (!isPositiveCompletion(status))
|
||||
status = sendCommand("AUTH SSL", sResponse);
|
||||
|
||||
if (isPositiveCompletion(status))
|
||||
{
|
||||
//Server support FTPS
|
||||
try
|
||||
{
|
||||
Poco::Net::SecureStreamSocket sss(Poco::Net::SecureStreamSocket::attach(*_pControlSocket, Poco::Net::SSLManager::instance().defaultClientContext()));
|
||||
*_pControlSocket = sss;
|
||||
}
|
||||
catch (Poco::Exception&)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_tryFTPS = false;
|
||||
}
|
||||
}
|
||||
|
||||
StreamSocket FTPSClientSession::establishDataConnection(const std::string& command, const std::string& arg)
|
||||
{
|
||||
beforeCreateDataSocket();
|
||||
|
||||
StreamSocket ss = FTPClientSession::establishDataConnection(command, arg);
|
||||
ss.setNoDelay(true);
|
||||
|
||||
//SSL nogotiating of data socket
|
||||
if ((_secureDataConnection) && (_pControlSocket->secure()))
|
||||
{
|
||||
//We need to reuse the control socket SSL session so the server can ensure that client that opened control socket is the same using data socket
|
||||
Poco::Net::SecureStreamSocketImpl* pSecure = dynamic_cast<Poco::Net::SecureStreamSocketImpl*>(_pControlSocket->impl());
|
||||
if (pSecure != nullptr)
|
||||
{
|
||||
Poco::Net::SecureStreamSocket sss(Poco::Net::SecureStreamSocket::attach(ss, pSecure->context(), pSecure->currentSession()));
|
||||
ss = sss;
|
||||
}
|
||||
}
|
||||
return ss;
|
||||
}
|
||||
|
||||
void FTPSClientSession::receiveServerReadyReply()
|
||||
{
|
||||
FTPClientSession::receiveServerReadyReply();
|
||||
afterCreateControlSocket();
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace Poco::Net
|
@ -20,7 +20,8 @@ endif
|
||||
objects = NetSSLTestSuite Driver \
|
||||
HTTPSClientSessionTest HTTPSClientTestSuite HTTPSServerTest HTTPSServerTestSuite \
|
||||
HTTPSStreamFactoryTest HTTPSTestServer TCPServerTest TCPServerTestSuite \
|
||||
WebSocketTest WebSocketTestSuite
|
||||
WebSocketTest WebSocketTestSuite FTPSClientSessionTest FTPSClientTestSuite \
|
||||
DialogServer
|
||||
|
||||
target = testrunner
|
||||
target_version = 1
|
||||
|
260
NetSSL_OpenSSL/testsuite/src/DialogServer.cpp
Normal file
260
NetSSL_OpenSSL/testsuite/src/DialogServer.cpp
Normal file
@ -0,0 +1,260 @@
|
||||
//
|
||||
// DialogServer.cpp
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "DialogServer.h"
|
||||
#include "Poco/Net/DialogSocket.h"
|
||||
#include "Poco/Net/SocketAddress.h"
|
||||
#include "Poco/Timespan.h"
|
||||
#include <iostream>
|
||||
#include "Poco/Net/SecureStreamSocket.h"
|
||||
#include "Poco/Net/SSLManager.h"
|
||||
#include "Poco/Net/Context.h"
|
||||
#include "Poco/Net/SecureStreamSocketImpl.h"
|
||||
|
||||
|
||||
using Poco::Net::Socket;
|
||||
using Poco::Net::DialogSocket;
|
||||
using Poco::Net::SocketAddress;
|
||||
using Poco::FastMutex;
|
||||
using Poco::Thread;
|
||||
using Poco::Net::SecureStreamSocket;
|
||||
using Poco::Net::SSLManager;
|
||||
using Poco::Exception;
|
||||
using Poco::Net::Context;
|
||||
using Poco::Net::Session;
|
||||
using Poco::Net::SecureStreamSocketImpl;
|
||||
|
||||
|
||||
DialogServer::DialogServer(bool acceptCommands, bool ssl):
|
||||
_socket(SocketAddress()),
|
||||
_thread("DialogServer"),
|
||||
_stop(false),
|
||||
_acceptCommands(acceptCommands),
|
||||
_log(false),
|
||||
_ssl(ssl)
|
||||
{
|
||||
_thread.start(*this);
|
||||
_ready.wait();
|
||||
}
|
||||
|
||||
|
||||
DialogServer::~DialogServer()
|
||||
{
|
||||
_stop = true;
|
||||
_thread.join();
|
||||
}
|
||||
|
||||
|
||||
Poco::UInt16 DialogServer::port() const
|
||||
{
|
||||
return _socket.address().port();
|
||||
}
|
||||
|
||||
|
||||
void handleDataSSLrequest(DialogSocket& ds, bool ssl, Session::Ptr& sslSession)
|
||||
{
|
||||
if (ssl)
|
||||
{
|
||||
try
|
||||
{
|
||||
Context::Ptr cDefaultServerContext = SSLManager::instance().defaultServerContext();
|
||||
SecureStreamSocket sss(SecureStreamSocket::attach(ds, cDefaultServerContext, sslSession));
|
||||
sss.setLazyHandshake(true);
|
||||
if (sss.completeHandshake() == 1)
|
||||
{
|
||||
ds = sss;
|
||||
}
|
||||
}
|
||||
catch (Exception&) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void handleSSLrequest(DialogSocket& ds, bool ssl, Session::Ptr& sslSession)
|
||||
{
|
||||
if (ssl)
|
||||
{
|
||||
try
|
||||
{
|
||||
Context::Ptr cDefaultServerContext = SSLManager::instance().defaultServerContext();
|
||||
ds.sendMessage("200 OK");
|
||||
SecureStreamSocket sss(SecureStreamSocket::attach(ds, cDefaultServerContext));
|
||||
sss.setLazyHandshake(true);
|
||||
if (sss.completeHandshake() == 1)
|
||||
{
|
||||
ds = sss;
|
||||
|
||||
SecureStreamSocketImpl* pSecure = dynamic_cast<SecureStreamSocketImpl*>(sss.impl());
|
||||
if (pSecure != nullptr)
|
||||
sslSession = pSecure->currentSession();
|
||||
}
|
||||
else
|
||||
{
|
||||
ds.sendMessage("501 Explicit TLS authentication not available");
|
||||
}
|
||||
}
|
||||
catch (Exception&) {
|
||||
ds.sendMessage("501 Explicit TLS authentication not available");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ds.sendMessage("501 Explicit TLS authentication not available");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DialogServer::run()
|
||||
{
|
||||
_ready.set();
|
||||
Poco::Timespan span(250000);
|
||||
while (!_stop)
|
||||
{
|
||||
if (_socket.poll(span, Socket::SELECT_READ))
|
||||
{
|
||||
DialogSocket ds = _socket.acceptConnection();
|
||||
if (!_SSLsession.isNull()) {
|
||||
handleDataSSLrequest(ds, _ssl, _SSLsession);
|
||||
}
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
if (!_nextResponses.empty())
|
||||
{
|
||||
ds.sendMessage(_nextResponses.front());
|
||||
_nextResponses.erase(_nextResponses.begin());
|
||||
}
|
||||
}
|
||||
if (_acceptCommands)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
std::string command;
|
||||
while (ds.receiveMessage(command))
|
||||
{
|
||||
if ((command == "AUTH TLS") || (command == "AUTH SSL"))
|
||||
{
|
||||
handleSSLrequest(ds, _ssl, _SSLsession);
|
||||
continue;
|
||||
}
|
||||
else if ((command == "PBSZ 0") || (command == "PROT P"))
|
||||
{
|
||||
ds.sendMessage("200 OK");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (_log) std::cout << ">> " << command << std::endl;
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
_lastCommands.push_back(command);
|
||||
if (!_nextResponses.empty())
|
||||
{
|
||||
if (_log) std::cout << "<< " << _nextResponses.front() << std::endl;
|
||||
ds.sendMessage(_nextResponses.front());
|
||||
_nextResponses.erase(_nextResponses.begin());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Poco::Exception& exc)
|
||||
{
|
||||
std::cerr << "DialogServer: " << exc.displayText() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const std::string& DialogServer::lastCommand() const
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
static const std::string EMPTY;
|
||||
if (_lastCommands.empty())
|
||||
return EMPTY;
|
||||
else
|
||||
return _lastCommands.back();
|
||||
}
|
||||
|
||||
|
||||
const std::vector<std::string>& DialogServer::lastCommands() const
|
||||
{
|
||||
return _lastCommands;
|
||||
}
|
||||
|
||||
|
||||
std::string DialogServer::popCommand()
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
std::string command;
|
||||
if (!_lastCommands.empty())
|
||||
{
|
||||
command = _lastCommands.front();
|
||||
_lastCommands.erase(_lastCommands.begin());
|
||||
}
|
||||
return command;
|
||||
}
|
||||
|
||||
|
||||
std::string DialogServer::popCommandWait()
|
||||
{
|
||||
std::string result(popCommand());
|
||||
while (result.empty())
|
||||
{
|
||||
Thread::sleep(100);
|
||||
result = popCommand();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void DialogServer::addResponse(const std::string& response)
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
_nextResponses.push_back(response);
|
||||
}
|
||||
|
||||
|
||||
void DialogServer::clearCommands()
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
_lastCommands.clear();
|
||||
}
|
||||
|
||||
|
||||
void DialogServer::clearResponses()
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
_nextResponses.clear();
|
||||
}
|
||||
|
||||
|
||||
void DialogServer::log(bool flag)
|
||||
{
|
||||
_log = flag;
|
||||
}
|
||||
|
||||
|
||||
void DialogServer::setSslSession(Session::Ptr cSession)
|
||||
{
|
||||
_SSLsession = cSession;
|
||||
}
|
||||
|
||||
|
||||
Session::Ptr DialogServer::getSslSession()
|
||||
{
|
||||
return _SSLsession;
|
||||
}
|
87
NetSSL_OpenSSL/testsuite/src/DialogServer.h
Normal file
87
NetSSL_OpenSSL/testsuite/src/DialogServer.h
Normal file
@ -0,0 +1,87 @@
|
||||
//
|
||||
// DialogServer.h
|
||||
//
|
||||
// Definition of the DialogServer class.
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#ifndef DialogServer_INCLUDED
|
||||
#define DialogServer_INCLUDED
|
||||
|
||||
|
||||
#include "Poco/Net/Net.h"
|
||||
#include "Poco/Net/ServerSocket.h"
|
||||
#include "Poco/Net/StreamSocket.h"
|
||||
#include "Poco/Thread.h"
|
||||
#include "Poco/Event.h"
|
||||
#include "Poco/Mutex.h"
|
||||
#include <vector>
|
||||
#include "Poco/Net/Session.h"
|
||||
|
||||
|
||||
class DialogServer: public Poco::Runnable
|
||||
/// A server for testing FTPClientSession and friends.
|
||||
{
|
||||
public:
|
||||
DialogServer(bool acceptCommands = true, bool ssl = false);
|
||||
/// Creates the DialogServer.
|
||||
|
||||
~DialogServer();
|
||||
/// Destroys the DialogServer.
|
||||
|
||||
Poco::UInt16 port() const;
|
||||
/// Returns the port the echo server is
|
||||
/// listening on.
|
||||
|
||||
void run();
|
||||
/// Does the work.
|
||||
|
||||
const std::string& lastCommand() const;
|
||||
/// Returns the last command received by the server.
|
||||
|
||||
std::string popCommand();
|
||||
/// Pops the next command from the list of received commands.
|
||||
|
||||
std::string popCommandWait();
|
||||
/// Pops the next command from the list of received commands.
|
||||
/// Waits until a command is available.
|
||||
|
||||
const std::vector<std::string>& lastCommands() const;
|
||||
/// Returns the last command received by the server.
|
||||
|
||||
void addResponse(const std::string& response);
|
||||
/// Sets the next response returned by the server.
|
||||
|
||||
void clearCommands();
|
||||
/// Clears all commands.
|
||||
|
||||
void clearResponses();
|
||||
/// Clears all responses.
|
||||
|
||||
void log(bool flag);
|
||||
/// Enables or disables logging to stdout.
|
||||
|
||||
Poco::Net::Session::Ptr getSslSession();
|
||||
void setSslSession(Poco::Net::Session::Ptr cSession);
|
||||
|
||||
private:
|
||||
Poco::Net::ServerSocket _socket;
|
||||
Poco::Thread _thread;
|
||||
Poco::Event _ready;
|
||||
mutable Poco::FastMutex _mutex;
|
||||
bool _stop;
|
||||
std::vector<std::string> _nextResponses;
|
||||
std::vector<std::string> _lastCommands;
|
||||
bool _acceptCommands;
|
||||
bool _log;
|
||||
bool _ssl;
|
||||
Poco::Net::Session::Ptr _SSLsession = nullptr;
|
||||
};
|
||||
|
||||
|
||||
#endif // DialogServer_INCLUDED
|
647
NetSSL_OpenSSL/testsuite/src/FTPSClientSessionTest.cpp
Normal file
647
NetSSL_OpenSSL/testsuite/src/FTPSClientSessionTest.cpp
Normal file
@ -0,0 +1,647 @@
|
||||
//
|
||||
// FTPSClientSessionTest.cpp
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "FTPSClientSessionTest.h"
|
||||
#include "Poco/CppUnit/TestCaller.h"
|
||||
#include "Poco/CppUnit/TestSuite.h"
|
||||
#include "Poco/Net/FTPSClientSession.h"
|
||||
#include "Poco/Net/DialogSocket.h"
|
||||
#include "Poco/Net/SocketAddress.h"
|
||||
#include "Poco/Net/NetException.h"
|
||||
#include "Poco/Thread.h"
|
||||
#include "Poco/ActiveMethod.h"
|
||||
#include "Poco/StreamCopier.h"
|
||||
#include "Poco/Net/Session.h"
|
||||
#include "DialogServer.h"
|
||||
#include <sstream>
|
||||
|
||||
|
||||
using Poco::Net::FTPSClientSession;
|
||||
using Poco::Net::DialogSocket;
|
||||
using Poco::Net::SocketAddress;
|
||||
using Poco::Net::FTPException;
|
||||
using Poco::ActiveMethod;
|
||||
using Poco::ActiveResult;
|
||||
using Poco::StreamCopier;
|
||||
using Poco::Thread;
|
||||
using Poco::Net::Session;
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
class ActiveDownloader
|
||||
{
|
||||
public:
|
||||
ActiveDownloader(FTPSClientSession& session):
|
||||
download(this, &ActiveDownloader::downloadImp),
|
||||
_session(session)
|
||||
{
|
||||
}
|
||||
|
||||
ActiveMethod<std::string, std::string, ActiveDownloader> download;
|
||||
|
||||
protected:
|
||||
std::string downloadImp(const std::string& path)
|
||||
{
|
||||
std::istream& istr = _session.beginDownload(path);
|
||||
std::ostringstream ostr;
|
||||
StreamCopier::copyStream(istr, ostr);
|
||||
_session.endDownload();
|
||||
return ostr.str();
|
||||
}
|
||||
|
||||
private:
|
||||
FTPSClientSession& _session;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
FTPSClientSessionTest::FTPSClientSessionTest(const std::string& name): CppUnit::TestCase(name)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FTPSClientSessionTest::~FTPSClientSessionTest()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void FTPSClientSessionTest::login(DialogServer& server, FTPSClientSession& session)
|
||||
{
|
||||
server.addResponse("331 Password required");
|
||||
server.addResponse("230 Welcome");
|
||||
server.addResponse("200 Type set to I");
|
||||
session.login("user", "password");
|
||||
std::string cmd = server.popCommand();
|
||||
assertTrue (cmd == "USER user");
|
||||
cmd = server.popCommand();
|
||||
assertTrue (cmd == "PASS password");
|
||||
cmd = server.popCommand();
|
||||
assertTrue (cmd == "TYPE I");
|
||||
|
||||
assertTrue (session.getFileType() == FTPSClientSession::TYPE_BINARY);
|
||||
}
|
||||
|
||||
|
||||
void FTPSClientSessionTest::testLogin1()
|
||||
{
|
||||
DialogServer server;
|
||||
server.addResponse("220 localhost FTP ready");
|
||||
FTPSClientSession session("127.0.0.1", server.port());
|
||||
assertTrue (session.isOpen());
|
||||
assertTrue (!session.isLoggedIn());
|
||||
login(server, session);
|
||||
assertTrue (session.isOpen());
|
||||
assertTrue (session.isLoggedIn());
|
||||
server.addResponse("221 Good Bye");
|
||||
session.logout();
|
||||
assertTrue (session.isOpen());
|
||||
assertTrue (!session.isLoggedIn());
|
||||
|
||||
server.clearCommands();
|
||||
server.clearResponses();
|
||||
|
||||
session.tryFTPSmode(true);
|
||||
login(server, session);
|
||||
assertTrue (session.isOpen());
|
||||
assertTrue (session.isLoggedIn());
|
||||
server.addResponse("221 Good Bye");
|
||||
session.close();
|
||||
assertTrue (!session.isOpen());
|
||||
assertTrue (!session.isLoggedIn());
|
||||
}
|
||||
|
||||
|
||||
void FTPSClientSessionTest::testLogin2()
|
||||
{
|
||||
DialogServer server;
|
||||
server.addResponse("220 localhost FTP ready");
|
||||
|
||||
server.addResponse("331 Password required");
|
||||
server.addResponse("230 Welcome");
|
||||
server.addResponse("200 Type set to I");
|
||||
Poco::UInt16 serverPort = server.port();
|
||||
FTPSClientSession session("127.0.0.1", serverPort, "user", "password");
|
||||
assertTrue (session.isOpen());
|
||||
assertTrue (session.isLoggedIn());
|
||||
server.addResponse("221 Good Bye");
|
||||
session.close();
|
||||
assertTrue (!session.isOpen());
|
||||
assertTrue (!session.isLoggedIn());
|
||||
|
||||
server.clearCommands();
|
||||
server.clearResponses();
|
||||
server.addResponse("220 localhost FTP ready");
|
||||
|
||||
server.addResponse("331 Password required");
|
||||
server.addResponse("230 Welcome");
|
||||
server.addResponse("200 Type set to I");
|
||||
session.tryFTPSmode(true);
|
||||
session.open("127.0.0.1", serverPort, "user", "password");
|
||||
assertTrue (session.isOpen());
|
||||
assertTrue (session.isLoggedIn());
|
||||
server.addResponse("221 Good Bye");
|
||||
session.close();
|
||||
assertTrue (!session.isOpen());
|
||||
assertTrue (!session.isLoggedIn());
|
||||
}
|
||||
|
||||
|
||||
void FTPSClientSessionTest::testLogin3()
|
||||
{
|
||||
DialogServer server;
|
||||
server.addResponse("220 localhost FTP ready");
|
||||
server.addResponse("331 Password required");
|
||||
server.addResponse("230 Welcome");
|
||||
server.addResponse("200 Type set to I");
|
||||
FTPSClientSession session;
|
||||
assertTrue (!session.isOpen());
|
||||
assertTrue (!session.isLoggedIn());
|
||||
session.open("127.0.0.1", server.port(), "user", "password");
|
||||
server.addResponse("221 Good Bye");
|
||||
session.close();
|
||||
assertTrue (!session.isOpen());
|
||||
assertTrue (!session.isLoggedIn());
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FTPSClientSessionTest::testLoginFailed1()
|
||||
{
|
||||
DialogServer server;
|
||||
server.addResponse("421 localhost FTP not ready");
|
||||
FTPSClientSession session("127.0.0.1", server.port());
|
||||
try
|
||||
{
|
||||
session.login("user", "password");
|
||||
fail("server not ready - must throw");
|
||||
}
|
||||
catch (FTPException&)
|
||||
{
|
||||
}
|
||||
server.addResponse("221 Good Bye");
|
||||
session.close();
|
||||
}
|
||||
|
||||
|
||||
void FTPSClientSessionTest::testLoginFailed2()
|
||||
{
|
||||
DialogServer server;
|
||||
server.addResponse("220 localhost FTP ready");
|
||||
server.addResponse("331 Password required");
|
||||
server.addResponse("530 Login incorrect");
|
||||
FTPSClientSession session("127.0.0.1", server.port());
|
||||
try
|
||||
{
|
||||
session.login("user", "password");
|
||||
fail("login incorrect - must throw");
|
||||
}
|
||||
catch (FTPException&)
|
||||
{
|
||||
}
|
||||
server.addResponse("221 Good Bye");
|
||||
session.close();
|
||||
}
|
||||
|
||||
|
||||
void FTPSClientSessionTest::testCommands()
|
||||
{
|
||||
DialogServer server;
|
||||
server.addResponse("220 localhost FTP ready");
|
||||
server.addResponse("331 Password required");
|
||||
server.addResponse("230 Welcome");
|
||||
server.addResponse("200 Type set to I");
|
||||
FTPSClientSession session("127.0.0.1", server.port());
|
||||
session.login("user", "password");
|
||||
std::string cmd = server.popCommand();
|
||||
assertTrue (cmd == "USER user");
|
||||
cmd = server.popCommand();
|
||||
assertTrue (cmd == "PASS password");
|
||||
cmd = server.popCommand();
|
||||
assertTrue (cmd == "TYPE I");
|
||||
|
||||
// systemType
|
||||
server.clearCommands();
|
||||
server.addResponse("215 UNIX Type: L8 Version: dummyFTP 1.0");
|
||||
std::string type = session.systemType();
|
||||
cmd = server.popCommand();
|
||||
assertTrue (cmd == "SYST");
|
||||
assertTrue (type == "UNIX Type: L8 Version: dummyFTP 1.0");
|
||||
|
||||
// getWorkingDirectory
|
||||
server.addResponse("257 \"/usr/test\" is current directory");
|
||||
std::string cwd = session.getWorkingDirectory();
|
||||
cmd = server.popCommand();
|
||||
assertTrue (cmd == "PWD");
|
||||
assertTrue (cwd == "/usr/test");
|
||||
|
||||
// getWorkingDirectory (quotes in filename)
|
||||
server.addResponse("257 \"\"\"quote\"\"\" is current directory");
|
||||
cwd = session.getWorkingDirectory();
|
||||
cmd = server.popCommand();
|
||||
assertTrue (cmd == "PWD");
|
||||
assertTrue (cwd == "\"quote\"");
|
||||
|
||||
// setWorkingDirectory
|
||||
server.addResponse("250 CWD OK");
|
||||
session.setWorkingDirectory("test");
|
||||
cmd = server.popCommand();
|
||||
assertTrue (cmd == "CWD test");
|
||||
|
||||
server.addResponse("250 CDUP OK");
|
||||
session.cdup();
|
||||
cmd = server.popCommand();
|
||||
assertTrue (cmd == "CDUP");
|
||||
|
||||
// rename
|
||||
server.addResponse("350 File exists, send destination name");
|
||||
server.addResponse("250 Rename OK");
|
||||
session.rename("old.txt", "new.txt");
|
||||
cmd = server.popCommand();
|
||||
assertTrue (cmd == "RNFR old.txt");
|
||||
cmd = server.popCommand();
|
||||
assertTrue (cmd == "RNTO new.txt");
|
||||
|
||||
// rename (failing)
|
||||
server.addResponse("550 not found");
|
||||
try
|
||||
{
|
||||
session.rename("old.txt", "new.txt");
|
||||
fail("not found - must throw");
|
||||
}
|
||||
catch (FTPException&)
|
||||
{
|
||||
}
|
||||
server.clearCommands();
|
||||
|
||||
// remove
|
||||
server.addResponse("250 delete ok");
|
||||
session.remove("test.txt");
|
||||
cmd = server.popCommand();
|
||||
assertTrue (cmd == "DELE test.txt");
|
||||
|
||||
// remove (failing)
|
||||
server.addResponse("550 not found");
|
||||
try
|
||||
{
|
||||
session.remove("test.txt");
|
||||
fail("not found - must throw");
|
||||
}
|
||||
catch (FTPException&)
|
||||
{
|
||||
}
|
||||
server.clearCommands();
|
||||
|
||||
// createDirectory
|
||||
server.addResponse("257 dir created");
|
||||
session.createDirectory("foo");
|
||||
cmd = server.popCommand();
|
||||
assertTrue (cmd == "MKD foo");
|
||||
|
||||
// createDirectory (failing)
|
||||
server.addResponse("550 exists");
|
||||
try
|
||||
{
|
||||
session.createDirectory("foo");
|
||||
fail("not found - must throw");
|
||||
}
|
||||
catch (FTPException&)
|
||||
{
|
||||
}
|
||||
server.clearCommands();
|
||||
|
||||
// removeDirectory
|
||||
server.addResponse("250 RMD OK");
|
||||
session.removeDirectory("foo");
|
||||
cmd = server.popCommand();
|
||||
assertTrue (cmd == "RMD foo");
|
||||
|
||||
// removeDirectory (failing)
|
||||
server.addResponse("550 not found");
|
||||
try
|
||||
{
|
||||
session.removeDirectory("foo");
|
||||
fail("not found - must throw");
|
||||
}
|
||||
catch (FTPException&)
|
||||
{
|
||||
}
|
||||
server.clearCommands();
|
||||
|
||||
server.addResponse("221 Good Bye");
|
||||
session.close();
|
||||
}
|
||||
|
||||
|
||||
void FTPSClientSessionTest::testDownloadPORT()
|
||||
{
|
||||
DialogServer server;
|
||||
server.addResponse("220 localhost FTP ready");
|
||||
server.addResponse("331 Password required");
|
||||
server.addResponse("230 Welcome");
|
||||
server.addResponse("200 Type set to I");
|
||||
FTPSClientSession session("127.0.0.1", server.port());
|
||||
session.setPassive(false);
|
||||
session.login("user", "password");
|
||||
server.clearCommands();
|
||||
|
||||
server.addResponse("500 EPRT not understood");
|
||||
server.addResponse("200 PORT OK");
|
||||
server.addResponse("150 Sending data\r\n226 Transfer complete");
|
||||
|
||||
ActiveDownloader dl(session);
|
||||
ActiveResult<std::string> result = dl.download("test.txt");
|
||||
|
||||
std::string cmd = server.popCommandWait();
|
||||
assertTrue (cmd.substr(0, 4) == "EPRT");
|
||||
|
||||
cmd = server.popCommandWait();
|
||||
assertTrue (cmd.substr(0, 4) == "PORT");
|
||||
|
||||
std::string dummy;
|
||||
int x, lo, hi;
|
||||
for (std::string::iterator it = cmd.begin(); it != cmd.end(); ++it)
|
||||
{
|
||||
if (*it == ',') *it = ' ';
|
||||
}
|
||||
std::istringstream istr(cmd);
|
||||
istr >> dummy >> x >> x >> x >> x >> hi >> lo;
|
||||
int port = hi*256 + lo;
|
||||
|
||||
cmd = server.popCommandWait();
|
||||
assertTrue (cmd == "RETR test.txt");
|
||||
|
||||
SocketAddress sa("127.0.0.1", (Poco::UInt16) port);
|
||||
DialogSocket dataSock;
|
||||
dataSock.connect(sa);
|
||||
|
||||
std::string data("This is some data");
|
||||
dataSock.sendString(data);
|
||||
dataSock.close();
|
||||
|
||||
result.wait();
|
||||
std::string received = result.data();
|
||||
assertTrue (received == data);
|
||||
|
||||
server.addResponse("221 Good Bye");
|
||||
session.close();
|
||||
}
|
||||
|
||||
|
||||
void FTPSClientSessionTest::testDownloadEPRT()
|
||||
{
|
||||
DialogServer server;
|
||||
server.addResponse("220 localhost FTP ready");
|
||||
server.addResponse("331 Password required");
|
||||
server.addResponse("230 Welcome");
|
||||
server.addResponse("200 Type set to I");
|
||||
FTPSClientSession session("127.0.0.1", server.port());
|
||||
session.setPassive(false);
|
||||
session.login("user", "password");
|
||||
server.clearCommands();
|
||||
|
||||
server.addResponse("200 EPRT OK");
|
||||
server.addResponse("150 Sending data\r\n226 Transfer complete");
|
||||
|
||||
ActiveDownloader dl(session);
|
||||
ActiveResult<std::string> result = dl.download("test.txt");
|
||||
|
||||
std::string cmd = server.popCommandWait();
|
||||
assertTrue (cmd.substr(0, 4) == "EPRT");
|
||||
|
||||
std::string dummy;
|
||||
char c;
|
||||
int d;
|
||||
int port;
|
||||
std::istringstream istr(cmd);
|
||||
istr >> dummy >> c >> d >> c >> d >> c >> d >> c >> d >> c >> d >> c >> port >> c;
|
||||
|
||||
cmd = server.popCommandWait();
|
||||
assertTrue (cmd == "RETR test.txt");
|
||||
|
||||
SocketAddress sa("127.0.0.1", (Poco::UInt16) port);
|
||||
DialogSocket dataSock;
|
||||
dataSock.connect(sa);
|
||||
|
||||
std::string data("This is some data");
|
||||
dataSock.sendString(data);
|
||||
dataSock.close();
|
||||
|
||||
result.wait();
|
||||
std::string received = result.data();
|
||||
assertTrue (received == data);
|
||||
|
||||
server.addResponse("221 Good Bye");
|
||||
session.close();
|
||||
}
|
||||
|
||||
|
||||
void FTPSClientSessionTest::testDownloadPASV()
|
||||
{
|
||||
DialogServer server;
|
||||
server.addResponse("220 localhost FTP ready");
|
||||
server.addResponse("331 Password required");
|
||||
server.addResponse("230 Welcome");
|
||||
server.addResponse("200 Type set to I");
|
||||
FTPSClientSession session("127.0.0.1", server.port());
|
||||
session.login("user", "password");
|
||||
server.clearCommands();
|
||||
|
||||
server.addResponse("500 EPSV not understood");
|
||||
|
||||
DialogServer dataServer(false);
|
||||
Poco::UInt16 dataServerPort = dataServer.port();
|
||||
dataServer.addResponse("This is some data");
|
||||
std::ostringstream pasv;
|
||||
pasv << "227 Entering Passive Mode (127,0,0,1," << (dataServerPort/256) << "," << (dataServerPort % 256) << ")";
|
||||
server.addResponse(pasv.str());
|
||||
server.addResponse("150 sending data\r\n226 Transfer complete");
|
||||
|
||||
std::istream& istr = session.beginDownload("test.txt");
|
||||
std::ostringstream dataStr;
|
||||
StreamCopier::copyStream(istr, dataStr);
|
||||
session.endDownload();
|
||||
std::string s(dataStr.str());
|
||||
assertTrue (s == "This is some data\r\n");
|
||||
|
||||
server.addResponse("221 Good Bye");
|
||||
session.close();
|
||||
}
|
||||
|
||||
|
||||
void FTPSClientSessionTest::testDownloadEPSV()
|
||||
{
|
||||
DialogServer server;
|
||||
server.addResponse("220 localhost FTP ready");
|
||||
server.addResponse("331 Password required");
|
||||
server.addResponse("230 Welcome");
|
||||
server.addResponse("200 Type set to I");
|
||||
FTPSClientSession session("127.0.0.1", server.port());
|
||||
session.login("user", "password");
|
||||
server.clearCommands();
|
||||
|
||||
DialogServer dataServer(false);
|
||||
dataServer.addResponse("This is some data");
|
||||
std::ostringstream epsv;
|
||||
epsv << "229 Entering Extended Passive Mode (|||" << dataServer.port() << "|)";
|
||||
server.addResponse(epsv.str());
|
||||
server.addResponse("150 sending data\r\n226 Transfer complete");
|
||||
|
||||
std::istream& istr = session.beginDownload("test.txt");
|
||||
std::ostringstream dataStr;
|
||||
StreamCopier::copyStream(istr, dataStr);
|
||||
session.endDownload();
|
||||
std::string s(dataStr.str());
|
||||
assertTrue (s == "This is some data\r\n");
|
||||
|
||||
std::string cmd = server.popCommand();
|
||||
assertTrue (cmd.substr(0, 4) == "EPSV");
|
||||
cmd = server.popCommand();
|
||||
assertTrue (cmd == "RETR test.txt");
|
||||
|
||||
server.addResponse("221 Good Bye");
|
||||
session.close();
|
||||
}
|
||||
|
||||
|
||||
void FTPSClientSessionTest::testUpload()
|
||||
{
|
||||
DialogServer server;
|
||||
server.addResponse("220 localhost FTP ready");
|
||||
server.addResponse("331 Password required");
|
||||
server.addResponse("230 Welcome");
|
||||
server.addResponse("200 Type set to I");
|
||||
FTPSClientSession session("127.0.0.1", server.port());
|
||||
session.login("user", "password");
|
||||
server.clearCommands();
|
||||
|
||||
DialogServer dataServer;
|
||||
std::ostringstream epsv;
|
||||
epsv << "229 Entering Extended Passive Mode (|||" << dataServer.port() << "|)";
|
||||
server.addResponse(epsv.str());
|
||||
server.addResponse("150 send data\r\n226 Transfer complete");
|
||||
|
||||
std::ostream& ostr = session.beginUpload("test.txt");
|
||||
ostr << "This is some data\r\n";
|
||||
session.endUpload();
|
||||
std::string s(dataServer.popCommandWait());
|
||||
assertTrue (s == "This is some data");
|
||||
|
||||
std::string cmd = server.popCommand();
|
||||
assertTrue (cmd.substr(0, 4) == "EPSV");
|
||||
cmd = server.popCommand();
|
||||
assertTrue (cmd == "STOR test.txt");
|
||||
|
||||
server.addResponse("221 Good Bye");
|
||||
session.close();
|
||||
}
|
||||
|
||||
|
||||
void FTPSClientSessionTest::testUploadSSL()
|
||||
{
|
||||
DialogServer server(true, true);
|
||||
server.addResponse("220 localhost FTP ready");
|
||||
server.addResponse("331 Password required");
|
||||
server.addResponse("230 Welcome");
|
||||
server.addResponse("200 Type set to I");
|
||||
FTPSClientSession session("127.0.0.1", server.port());
|
||||
session.login("user", "password");
|
||||
server.clearCommands();
|
||||
|
||||
DialogServer dataServer(true, true);
|
||||
Session::Ptr cSessionSSL = server.getSslSession();
|
||||
dataServer.setSslSession(cSessionSSL);
|
||||
|
||||
std::ostringstream epsv;
|
||||
epsv << "229 Entering Extended Passive Mode (|||" << dataServer.port() << "|)";
|
||||
server.addResponse(epsv.str());
|
||||
server.addResponse("150 send data\r\n226 Transfer complete");
|
||||
|
||||
std::ostream& ostr = session.beginUpload("test.txt");
|
||||
ostr << "This is some data\r\n";
|
||||
session.endUpload();
|
||||
std::string s(dataServer.popCommandWait());
|
||||
assertTrue (s == "This is some data");
|
||||
|
||||
std::string cmd = server.popCommand();
|
||||
assertTrue (cmd.substr(0, 4) == "EPSV");
|
||||
cmd = server.popCommand();
|
||||
assertTrue (cmd == "STOR test.txt");
|
||||
|
||||
server.addResponse("221 Good Bye");
|
||||
session.close();
|
||||
}
|
||||
|
||||
|
||||
void FTPSClientSessionTest::testList()
|
||||
{
|
||||
DialogServer server;
|
||||
server.addResponse("220 localhost FTP ready");
|
||||
server.addResponse("331 Password required");
|
||||
server.addResponse("230 Welcome");
|
||||
server.addResponse("200 Type set to I");
|
||||
FTPSClientSession session("127.0.0.1", server.port());
|
||||
session.login("user", "password");
|
||||
server.clearCommands();
|
||||
|
||||
DialogServer dataServer(false);
|
||||
dataServer.addResponse("file1\r\nfile2");
|
||||
std::ostringstream epsv;
|
||||
epsv << "229 Entering Extended Passive Mode (|||" << dataServer.port() << "|)";
|
||||
server.addResponse(epsv.str());
|
||||
server.addResponse("150 sending data\r\n226 Transfer complete");
|
||||
|
||||
std::istream& istr = session.beginList();
|
||||
std::ostringstream dataStr;
|
||||
StreamCopier::copyStream(istr, dataStr);
|
||||
session.endList();
|
||||
std::string s(dataStr.str());
|
||||
assertTrue (s == "file1\r\nfile2\r\n");
|
||||
|
||||
std::string cmd = server.popCommand();
|
||||
assertTrue (cmd.substr(0, 4) == "EPSV");
|
||||
cmd = server.popCommand();
|
||||
assertTrue (cmd == "NLST");
|
||||
|
||||
server.addResponse("221 Good Bye");
|
||||
session.close();
|
||||
}
|
||||
|
||||
|
||||
void FTPSClientSessionTest::setUp()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void FTPSClientSessionTest::tearDown()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
CppUnit::Test* FTPSClientSessionTest::suite()
|
||||
{
|
||||
CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("FTPSClientSessionTest");
|
||||
|
||||
CppUnit_addTest(pSuite, FTPSClientSessionTest, testLogin1);
|
||||
CppUnit_addTest(pSuite, FTPSClientSessionTest, testLogin2);
|
||||
CppUnit_addTest(pSuite, FTPSClientSessionTest, testLogin3);
|
||||
CppUnit_addTest(pSuite, FTPSClientSessionTest, testLoginFailed1);
|
||||
CppUnit_addTest(pSuite, FTPSClientSessionTest, testLoginFailed2);
|
||||
CppUnit_addTest(pSuite, FTPSClientSessionTest, testCommands);
|
||||
CppUnit_addTest(pSuite, FTPSClientSessionTest, testDownloadPORT);
|
||||
CppUnit_addTest(pSuite, FTPSClientSessionTest, testDownloadEPRT);
|
||||
CppUnit_addTest(pSuite, FTPSClientSessionTest, testDownloadPASV);
|
||||
CppUnit_addTest(pSuite, FTPSClientSessionTest, testDownloadEPSV);
|
||||
CppUnit_addTest(pSuite, FTPSClientSessionTest, testUpload);
|
||||
CppUnit_addTest(pSuite, FTPSClientSessionTest, testList);
|
||||
CppUnit_addTest(pSuite, FTPSClientSessionTest, testUploadSSL);
|
||||
|
||||
return pSuite;
|
||||
}
|
62
NetSSL_OpenSSL/testsuite/src/FTPSClientSessionTest.h
Normal file
62
NetSSL_OpenSSL/testsuite/src/FTPSClientSessionTest.h
Normal file
@ -0,0 +1,62 @@
|
||||
//
|
||||
// FTPClientSessionTest.h
|
||||
//
|
||||
// Definition of the FTPClientSessionTest class.
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#ifndef FTPClientSessionTest_INCLUDED
|
||||
#define FTPClientSessionTest_INCLUDED
|
||||
|
||||
|
||||
#include "Poco/Net/Net.h"
|
||||
#include "Poco/CppUnit/TestCase.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Net {
|
||||
|
||||
class FTPSClientSession;
|
||||
|
||||
} }
|
||||
|
||||
|
||||
class DialogServer;
|
||||
|
||||
|
||||
class FTPSClientSessionTest: public CppUnit::TestCase
|
||||
{
|
||||
public:
|
||||
FTPSClientSessionTest(const std::string& name);
|
||||
~FTPSClientSessionTest();
|
||||
|
||||
void testLogin1();
|
||||
void testLogin2();
|
||||
void testLogin3();
|
||||
void testLoginFailed1();
|
||||
void testLoginFailed2();
|
||||
void testCommands();
|
||||
void testDownloadPORT();
|
||||
void testDownloadEPRT();
|
||||
void testDownloadPASV();
|
||||
void testDownloadEPSV();
|
||||
void testUpload();
|
||||
void testList();
|
||||
void testUploadSSL();
|
||||
|
||||
void setUp();
|
||||
void tearDown();
|
||||
|
||||
static CppUnit::Test* suite();
|
||||
|
||||
private:
|
||||
void login(DialogServer& server, Poco::Net::FTPSClientSession& session);
|
||||
};
|
||||
|
||||
|
||||
#endif // FTPClientSessionTest_INCLUDED
|
22
NetSSL_OpenSSL/testsuite/src/FTPSClientTestSuite.cpp
Normal file
22
NetSSL_OpenSSL/testsuite/src/FTPSClientTestSuite.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
//
|
||||
// FTPClientTestSuite.cpp
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "FTPSClientTestSuite.h"
|
||||
#include "FTPSClientSessionTest.h"
|
||||
|
||||
|
||||
CppUnit::Test* FTPSClientTestSuite::suite()
|
||||
{
|
||||
CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("FTPSClientTestSuite");
|
||||
|
||||
pSuite->addTest(FTPSClientSessionTest::suite());
|
||||
|
||||
return pSuite;
|
||||
}
|
27
NetSSL_OpenSSL/testsuite/src/FTPSClientTestSuite.h
Normal file
27
NetSSL_OpenSSL/testsuite/src/FTPSClientTestSuite.h
Normal file
@ -0,0 +1,27 @@
|
||||
//
|
||||
// FTPClientTestSuite.h
|
||||
//
|
||||
// Definition of the FTPClientTestSuite class.
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#ifndef FTPClientTestSuite_INCLUDED
|
||||
#define FTPClientTestSuite_INCLUDED
|
||||
|
||||
|
||||
#include "Poco/CppUnit/TestSuite.h"
|
||||
|
||||
|
||||
class FTPSClientTestSuite
|
||||
{
|
||||
public:
|
||||
static CppUnit::Test* suite();
|
||||
};
|
||||
|
||||
|
||||
#endif // FTPClientTestSuite_INCLUDED
|
@ -14,6 +14,7 @@
|
||||
#include "TCPServerTestSuite.h"
|
||||
#include "HTTPSServerTestSuite.h"
|
||||
#include "WebSocketTestSuite.h"
|
||||
#include "FTPSClientTestSuite.h"
|
||||
|
||||
|
||||
CppUnit::Test* NetSSLTestSuite::suite()
|
||||
@ -24,6 +25,7 @@ CppUnit::Test* NetSSLTestSuite::suite()
|
||||
pSuite->addTest(TCPServerTestSuite::suite());
|
||||
pSuite->addTest(HTTPSServerTestSuite::suite());
|
||||
pSuite->addTest(WebSocketTestSuite::suite());
|
||||
pSuite->addTest(FTPSClientTestSuite::suite());
|
||||
|
||||
return pSuite;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user