123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403 |
- //
- // FTPClientSession.h
- //
- // Library: Net
- // Package: FTP
- // Module: FTPClientSession
- //
- // Definition of the FTPClientSession class.
- //
- // Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
- // and Contributors.
- //
- // SPDX-License-Identifier: BSL-1.0
- //
- #ifndef Net_FTPClientSession_INCLUDED
- #define Net_FTPClientSession_INCLUDED
- #include "Poco/Net/Net.h"
- #include "Poco/Net/DialogSocket.h"
- #include "Poco/Timespan.h"
- #include <istream>
- #include <ostream>
- namespace Poco {
- namespace Net {
- class SocketStream;
- class Net_API FTPClientSession
- /// This class implements an File Transfer Protocol
- /// (FTP, RFC 959) client.
- ///
- /// Most of the features of the FTP protocol, as specified
- /// in RFC 959, are supported. Not supported are EBCDIC and
- /// LOCAL data types and format control and structured files.
- ///
- /// Also supported are the EPRT and EPSV commands from
- /// RFC 1738 (FTP Extensions for IPv6 and NAT).
- /// The client will first attempt to use the EPRT and EPSV
- /// commands. If the server does not supports these commands,
- /// the client will fall back to PORT and PASV.
- {
- public:
- enum
- {
- FTP_PORT = 21
- };
-
- enum FileType
- {
- TYPE_TEXT, // TYPE A (ASCII)
- 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.
-
- 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.
- 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.
- ///
- /// 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.
- void logout();
- 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.
-
- std::string systemType();
- /// Returns the system type of the FTP server.
- ///
- /// Sends a SYST command to the server and returns the result.
-
- void setFileType(FileType type);
- /// Sets the file type for transferring files.
- ///
- /// Sends a TYPE command with a corresponding argument to the
- /// server.
- ///
- /// Throws a FTPException in case of a FTP-specific error, or a
- /// NetException in case of a general network communication failure.
- FileType getFileType() const;
- /// Returns the file type for transferring files.
- void setWorkingDirectory(const std::string& path);
- /// Changes the current working directory on the server.
- ///
- /// Sends a CWD command with the given path as argument to the
- /// server.
- ///
- /// Throws a FTPException in case of a FTP-specific error, or a
- /// NetException in case of a general network communication failure.
- std::string getWorkingDirectory();
- /// Returns the current working directory on the server.
- ///
- /// Throws a FTPException in case of a FTP-specific error, or a
- /// NetException in case of a general network communication failure.
-
- void cdup();
- /// Moves one directory up from the current working directory
- /// on the server.
- ///
- /// Sends a CDUP command to the server.
- ///
- /// Throws a FTPException in case of a FTP-specific error, or a
- /// NetException in case of a general network communication failure.
-
- void rename(const std::string& oldName, const std::string& newName);
- /// Renames the file on the server given by oldName to newName.
- ///
- /// Sends a RNFR command, followed by a RNTO command to the server.
- ///
- /// Throws a FTPException in case of a FTP-specific error, or a
- /// NetException in case of a general network communication failure.
-
- void remove(const std::string& path);
- /// Deletes the file specified by path on the server.
- ///
- /// Sends a DELE command with path as argument to the server.
- ///
- /// Throws a FTPException in case of a FTP-specific error, or a
- /// NetException in case of a general network communication failure.
- void createDirectory(const std::string& path);
- /// Creates a new directory with the given path on the server.
- ///
- /// Sends a MKD command with path as argument to the server.
- ///
- /// Throws a FTPException in case of a FTP-specific error, or a
- /// NetException in case of a general network communication failure.
- void removeDirectory(const std::string& path);
- /// Removes the directory specified by path from the server.
- ///
- /// Sends a RMD command with path as argument to the server.
- ///
- /// Throws a FTPException in case of a FTP-specific error, or a
- /// NetException in case of a general network communication failure.
- std::istream& beginDownload(const std::string& path);
- /// Starts downloading the file with the given name.
- /// After all data has been read from the returned stream,
- /// endDownload() must be called to finish the download.
- ///
- /// A stream for reading the file's content is returned.
- /// The stream is valid until endDownload() is called.
- ///
- /// Creates a data connection between the client and the
- /// server. If passive mode is on, then the server waits for
- /// a connection request from the client. Otherwise, the
- /// client waits for a connection request from the server.
- /// After establishing the data connection, a SocketStream
- /// for transferring the data is created.
- ///
- /// If ASCII transfer mode is selected, the caller is
- /// responsible for converting the received data to
- /// the native text file format.
- /// The InputLineEndingConverter class from the Foundation
- /// library can be used for that purpose.
-
- void endDownload();
- /// Must be called to complete a download initiated with
- /// beginDownload().
-
- std::ostream& beginUpload(const std::string& path);
- /// Starts uploading the file with the given name.
- /// After all data has been written to the returned stream,
- /// endUpload() must be called to finish the upload.
- ///
- /// A stream for reading the file's content is returned.
- /// The stream is valid until endUpload() is called.
- ///
- /// Creates a data connection between the client and the
- /// server. If passive mode is on, then the server waits for
- /// a connection request from the client. Otherwise, the
- /// client waits for a connection request from the server.
- /// After establishing the data connection, a SocketStream
- /// for transferring the data is created.
- ///
- /// If ASCII transfer mode is selected, the caller is
- /// responsible for converting the data to be sent
- /// into network (CR-LF line endings) format.
- /// The OutputLineEndingConverter class from the Foundation
- /// library can be used for that purpose.
- void endUpload();
- /// Must be called to complete an upload initiated with
- /// beginUpload().
- std::istream& beginList(const std::string& path = "", bool extended = false);
- /// Starts downloading a directory listing.
- /// After all data has been read from the returned stream,
- /// endList() must be called to finish the download.
- ///
- /// A stream for reading the directory data is returned.
- /// The stream is valid until endList() is called.
- ///
- /// Optionally, a path to a directory or file can be specified.
- /// According to the FTP protocol, if a path to a filename is
- /// given, only information for the specific file is returned.
- /// If a path to a directory is given, a listing of that directory
- /// is returned. If no path is given, a listing of the current
- /// working directory is returned.
- ///
- /// If extended is false, only a filenames (one per line) are
- /// returned. Otherwise, a full directory listing including
- /// file attributes is returned. The format of this listing
- /// depends on the FTP server. No attempt is made to interpret
- /// this data.
- ///
- /// Creates a data connection between the client and the
- /// server. If passive mode is on, then the server waits for
- /// a connection request from the client. Otherwise, the
- /// client waits for a connection request from the server.
- /// After establishing the data connection, a SocketStream
- /// for transferring the data is created.
-
- void endList();
- /// Must be called to complete a directory listing download
- /// initiated with beginList().
- void abort();
- /// Aborts the download or upload currently in progress.
- ///
- /// Sends a TELNET IP/SYNCH sequence, followed by an ABOR
- /// command to the server.
- ///
- /// A separate call to endDownload() or endUpload() is
- /// not necessary.
-
- int sendCommand(const std::string& command, std::string& response);
- /// Sends the given command verbatim to the server
- /// 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.
- bool isOpen() const;
- /// Returns true if the connection with FTP server is opened.
- bool isLoggedIn() const;
- /// Returns true if the session is logged in.
- protected:
- enum StatusClass
- {
- FTP_POSITIVE_PRELIMINARY = 1,
- FTP_POSITIVE_COMPLETION = 2,
- FTP_POSITIVE_INTERMEDIATE = 3,
- FTP_TRANSIENT_NEGATIVE = 4,
- FTP_PERMANENT_NEGATIVE = 5
- };
- enum
- {
- DEFAULT_TIMEOUT = 30000000 // 30 seconds default timeout for socket operations
- };
- static bool isPositivePreliminary(int status);
- static bool isPositiveCompletion(int status);
- static bool isPositiveIntermediate(int status);
- static bool isTransientNegative(int status);
- static bool isPermanentNegative(int status);
- std::string extractPath(const std::string& response);
- StreamSocket establishDataConnection(const std::string& command, const std::string& arg);
- StreamSocket activeDataConnection(const std::string& command, const std::string& arg);
- StreamSocket passiveDataConnection(const std::string& command, const std::string& arg);
- void sendPortCommand(const SocketAddress& addr);
- SocketAddress sendPassiveCommand();
- bool sendEPRT(const SocketAddress& addr);
- void sendPORT(const SocketAddress& addr);
- bool sendEPSV(SocketAddress& addr);
- void sendPASV(SocketAddress& addr);
- void parseAddress(const std::string& str, SocketAddress& addr);
- void parseExtAddress(const std::string& str, SocketAddress& addr);
- 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;
- };
- //
- // inlines
- //
- inline bool FTPClientSession::isPositivePreliminary(int status)
- {
- return status/100 == FTP_POSITIVE_PRELIMINARY;
- }
- inline bool FTPClientSession::isPositiveCompletion(int status)
- {
- return status/100 == FTP_POSITIVE_COMPLETION;
- }
- inline bool FTPClientSession::isPositiveIntermediate(int status)
- {
- return status/100 == FTP_POSITIVE_INTERMEDIATE;
- }
- inline bool FTPClientSession::isTransientNegative(int status)
- {
- return status/100 == FTP_TRANSIENT_NEGATIVE;
- }
- inline bool FTPClientSession::isPermanentNegative(int status)
- {
- return status/100 == FTP_PERMANENT_NEGATIVE;
- }
- inline bool FTPClientSession::isOpen() const
- {
- return _pControlSocket != 0;
- }
- inline bool FTPClientSession::isLoggedIn() const
- {
- return _isLoggedIn;
- }
- } } // namespace Poco::Net
- #endif // Net_FTPClientSession_INCLUDED
|