Move SetDefaultTimeout to wxProtocol and set it to 60 seconds for both wxHTTP and wxFTP

Move SetPassword and SetUser implementations to wxProtocol to avoid code redundancy
Make const-correct various getters
Reorganize wxFTP docs
Move wxStringToStringHashMap to hashmap.h and document its existance



git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@58137 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Francesco Montorsi
2009-01-16 15:08:13 +00:00
parent dc813e6c7e
commit 730b772b41
13 changed files with 356 additions and 230 deletions

View File

@@ -745,5 +745,8 @@ public: \
WX_DECLARE_HASH_MAP_WITH_DECL( long, long, wxIntegerHash, wxIntegerEqual, WX_DECLARE_HASH_MAP_WITH_DECL( long, long, wxIntegerHash, wxIntegerEqual,
wxLongToLongHashMap, class WXDLLIMPEXP_BASE ); wxLongToLongHashMap, class WXDLLIMPEXP_BASE );
WX_DECLARE_STRING_HASH_MAP_WITH_DECL( wxString, wxStringToStringHashMap,
class WXDLLIMPEXP_BASE );
#endif // _WX_HASHMAP_H_ #endif // _WX_HASHMAP_H_

View File

@@ -18,18 +18,20 @@
#include "wx/protocol/protocol.h" #include "wx/protocol/protocol.h"
class WXDLLIMPEXP_NET wxFileProto: public wxProtocol { class WXDLLIMPEXP_NET wxFileProto: public wxProtocol
DECLARE_DYNAMIC_CLASS_NO_COPY(wxFileProto) {
DECLARE_PROTOCOL(wxFileProto)
protected:
wxProtocolError m_error;
public: public:
wxFileProto(); wxFileProto();
virtual ~wxFileProto(); virtual ~wxFileProto();
wxProtocolError GetError() { return m_error; } bool Abort() { return true; }
bool Abort() { return TRUE; } wxString GetContentType() const { return wxEmptyString; }
wxInputStream *GetInputStream(const wxString& path);
wxInputStream *GetInputStream(const wxString& path);
protected:
DECLARE_DYNAMIC_CLASS_NO_COPY(wxFileProto)
DECLARE_PROTOCOL(wxFileProto)
}; };
#endif // wxUSE_PROTOCOL_FILE #endif // wxUSE_PROTOCOL_FILE

View File

@@ -35,31 +35,27 @@ public:
virtual ~wxFTP(); virtual ~wxFTP();
// Connecting and disconnecting // Connecting and disconnecting
void SetUser(const wxString& user) { m_user = user; }
void SetPassword(const wxString& passwd) { m_passwd = passwd; }
bool Connect(const wxSockAddress& addr, bool wait = true); bool Connect(const wxSockAddress& addr, bool wait = true);
bool Connect(const wxString& host); bool Connect(const wxString& host);
// disconnect // disconnect
virtual bool Close(); // does NOT set m_lastError virtual bool Close();
// Parameters set up // Parameters set up
// set transfer mode now // set transfer mode now
void SetPassive(bool pasv) { m_bPassive = pasv; } void SetPassive(bool pasv) { m_bPassive = pasv; }
void SetDefaultTimeout(wxUint32 Value);
bool SetBinary() { return SetTransferMode(BINARY); } bool SetBinary() { return SetTransferMode(BINARY); }
bool SetAscii() { return SetTransferMode(ASCII); } bool SetAscii() { return SetTransferMode(ASCII); }
bool SetTransferMode(TransferMode mode); bool SetTransferMode(TransferMode mode);
// Generic FTP interface // Generic FTP interface
// the error code // FTP doesn't know the MIME type of the last downloaded/uploaded file
virtual wxProtocolError GetError() { return m_lastError; } virtual wxString GetContentType() const { return wxEmptyString; }
// the last FTP server reply // the last FTP server reply
const wxString& GetLastResult() { return m_lastResult; } const wxString& GetLastResult() const { return m_lastResult; }
// send any FTP command (should be full FTP command line but without // send any FTP command (should be full FTP command line but without
// trailing "\r\n") and return its return code // trailing "\r\n") and return its return code
@@ -68,6 +64,7 @@ public:
// check that the command returned the given code // check that the command returned the given code
bool CheckCommand(const wxString& command, char expectedReturn) bool CheckCommand(const wxString& command, char expectedReturn)
{ {
// SendCommand() does updates m_lastError
return SendCommand(command) == expectedReturn; return SendCommand(command) == expectedReturn;
} }
@@ -119,11 +116,6 @@ public:
bool details = false); bool details = false);
protected: protected:
// just change access from public to protected for this wxSocketBase function:
// use SetDefaultTimeout instead which also sets our m_uiDefaultTimeout var
virtual void SetTimeout(long seconds)
{ wxSocketBase::SetTimeout(seconds); }
// this executes a simple ftp command with the given argument and returns // this executes a simple ftp command with the given argument and returns
// true if it its return code starts with '2' // true if it its return code starts with '2'
bool DoSimpleCommand(const wxChar *command, bool DoSimpleCommand(const wxChar *command,
@@ -150,30 +142,27 @@ protected:
wxSocketBase *AcceptIfActive(wxSocketBase *sock); wxSocketBase *AcceptIfActive(wxSocketBase *sock);
wxString m_user, // internal variables:
m_passwd;
wxString m_lastResult; wxString m_lastResult;
wxProtocolError m_lastError;
// true if there is an FTP transfer going on // true if there is an FTP transfer going on
bool m_streaming; bool m_streaming;
// although this should be set to ASCII by default according to STD9, // although this should be set to ASCII by default according to STD9,
// we will use BINARY transfer mode by default for backwards compatibility // we will use BINARY transfer mode by default for backwards compatibility
TransferMode m_currentTransfermode; TransferMode m_currentTransfermode;
friend class wxInputFTPStream;
friend class wxOutputFTPStream;
bool m_bPassive; bool m_bPassive;
wxUint32 m_uiDefaultTimeout;
// following is true when a read or write times out, we then assume // following is true when a read or write times out, we then assume
// the connection is dead and abort. we avoid additional delays this way // the connection is dead and abort. we avoid additional delays this way
bool m_bEncounteredError; bool m_bEncounteredError;
friend class wxInputFTPStream;
friend class wxOutputFTPStream;
DECLARE_DYNAMIC_CLASS_NO_COPY(wxFTP) DECLARE_DYNAMIC_CLASS_NO_COPY(wxFTP)
DECLARE_PROTOCOL(wxFTP) DECLARE_PROTOCOL(wxFTP)
}; };

View File

@@ -18,71 +18,64 @@
#include "wx/hashmap.h" #include "wx/hashmap.h"
#include "wx/protocol/protocol.h" #include "wx/protocol/protocol.h"
WX_DECLARE_STRING_HASH_MAP_WITH_DECL( wxString, wxStringToStringHashMap,
class WXDLLIMPEXP_NET );
class WXDLLIMPEXP_NET wxHTTP : public wxProtocol class WXDLLIMPEXP_NET wxHTTP : public wxProtocol
{ {
public: public:
wxHTTP(); wxHTTP();
virtual ~wxHTTP(); virtual ~wxHTTP();
virtual bool Connect(const wxString& host, unsigned short port); virtual bool Connect(const wxString& host, unsigned short port);
virtual bool Connect(const wxString& host) { return Connect(host, 0); } virtual bool Connect(const wxString& host) { return Connect(host, 0); }
virtual bool Connect(const wxSockAddress& addr, bool wait); virtual bool Connect(const wxSockAddress& addr, bool wait);
bool Abort(); bool Abort();
wxInputStream *GetInputStream(const wxString& path);
inline wxProtocolError GetError() { return m_perr; }
wxString GetContentType();
void SetHeader(const wxString& header, const wxString& h_data); wxInputStream *GetInputStream(const wxString& path);
wxString GetHeader(const wxString& header) const;
void SetPostBuffer(const wxString& post_buf);
void SetProxyMode(bool on); wxString GetContentType() const;
wxString GetHeader(const wxString& header) const;
int GetResponse() const { return m_http_response; }
int GetResponse() { return m_http_response; } void SetHeader(const wxString& header, const wxString& h_data);
void SetPostBuffer(const wxString& post_buf);
virtual void SetUser(const wxString& user) { m_username = user; } void SetProxyMode(bool on);
virtual void SetPassword(const wxString& passwd ) { m_password = passwd; }
protected: protected:
enum wxHTTP_Req enum wxHTTP_Req
{ {
wxHTTP_GET, wxHTTP_GET,
wxHTTP_POST, wxHTTP_POST,
wxHTTP_HEAD wxHTTP_HEAD
}; };
typedef wxStringToStringHashMap::iterator wxHeaderIterator; typedef wxStringToStringHashMap::iterator wxHeaderIterator;
typedef wxStringToStringHashMap::const_iterator wxHeaderConstIterator; typedef wxStringToStringHashMap::const_iterator wxHeaderConstIterator;
bool BuildRequest(const wxString& path, wxHTTP_Req req); bool BuildRequest(const wxString& path, wxHTTP_Req req);
void SendHeaders(); void SendHeaders();
bool ParseHeaders(); bool ParseHeaders();
wxString GenerateAuthString(const wxString& user, const wxString& pass) const; wxString GenerateAuthString(const wxString& user, const wxString& pass) const;
// find the header in m_headers // find the header in m_headers
wxHeaderIterator FindHeader(const wxString& header); wxHeaderIterator FindHeader(const wxString& header);
wxHeaderConstIterator FindHeader(const wxString& header) const; wxHeaderConstIterator FindHeader(const wxString& header) const;
// deletes the header value strings // deletes the header value strings
void ClearHeaders(); void ClearHeaders();
wxProtocolError m_perr;
wxStringToStringHashMap m_headers;
bool m_read,
m_proxy_mode;
wxSockAddress *m_addr;
wxString m_post_buf;
int m_http_response;
wxString m_username;
wxString m_password;
DECLARE_DYNAMIC_CLASS(wxHTTP) // internal variables:
DECLARE_PROTOCOL(wxHTTP)
DECLARE_NO_COPY_CLASS(wxHTTP) wxStringToStringHashMap m_headers;
bool m_read,
m_proxy_mode;
wxSockAddress *m_addr;
wxString m_post_buf;
int m_http_response;
DECLARE_DYNAMIC_CLASS(wxHTTP)
DECLARE_PROTOCOL(wxHTTP)
DECLARE_NO_COPY_CLASS(wxHTTP)
}; };
#endif // wxUSE_PROTOCOL_HTTP #endif // wxUSE_PROTOCOL_HTTP

View File

@@ -58,8 +58,8 @@ public:
#if wxUSE_SOCKETS #if wxUSE_SOCKETS
bool Reconnect(); bool Reconnect();
virtual bool Connect( const wxString& WXUNUSED(host) ) { return FALSE; } virtual bool Connect( const wxString& WXUNUSED(host) ) { return false; }
virtual bool Connect( const wxSockAddress& addr, bool WXUNUSED(wait) = TRUE) virtual bool Connect( const wxSockAddress& addr, bool WXUNUSED(wait) = true)
{ return wxSocketClient::Connect(addr); } { return wxSocketClient::Connect(addr); }
// read a '\r\n' terminated line from the given socket and put it in // read a '\r\n' terminated line from the given socket and put it in
@@ -73,10 +73,31 @@ public:
virtual bool Abort() = 0; virtual bool Abort() = 0;
virtual wxInputStream *GetInputStream(const wxString& path) = 0; virtual wxInputStream *GetInputStream(const wxString& path) = 0;
virtual wxProtocolError GetError() = 0; virtual wxString GetContentType() const = 0;
virtual wxString GetContentType() { return wxEmptyString; }
virtual void SetUser(const wxString& WXUNUSED(user)) {} // the error code
virtual void SetPassword(const wxString& WXUNUSED(passwd) ) {} virtual wxProtocolError GetError() const { return m_lastError; }
void SetUser(const wxString& user) { m_username = user; }
void SetPassword(const wxString& passwd) { m_password = passwd; }
virtual void SetDefaultTimeout(wxUint32 Value);
// override wxSocketBase::SetTimeout function to avoid that the internal
// m_uiDefaultTimeout goes out-of-sync:
virtual void SetTimeout(long seconds)
{ SetDefaultTimeout(seconds); }
protected:
// the timeout associated with the protocol:
wxUint32 m_uiDefaultTimeout;
wxString m_username;
wxString m_password;
// this must be always updated by the derived classes!
wxProtocolError m_lastError;
private: private:
DECLARE_DYNAMIC_CLASS_NO_COPY(wxProtocol) DECLARE_DYNAMIC_CLASS_NO_COPY(wxProtocol)

View File

@@ -12,7 +12,7 @@
This is a simple, type-safe, and reasonably efficient hash map class, This is a simple, type-safe, and reasonably efficient hash map class,
whose interface is a subset of the interface of STL containers. whose interface is a subset of the interface of STL containers.
In particular, the interface is modeled after std::map, and the various, In particular, the interface is modeled after std::map, and the various,
non-standard, std::hash_map. non-standard, std::hash_map (http://www.cppreference.com/wiki/stl/map/start).
Example: Example:
@code @code
@@ -73,11 +73,11 @@
@endcode @endcode
The HASH_T and KEY_EQ_T are the types used for the hashing function and The HASH_T and KEY_EQ_T are the types used for the hashing function and
key comparison. wxWidgets provides three predefined hashing functions: key comparison. wxWidgets provides three predefined hashing functions:
wxIntegerHash for integer types ( int, long, short, and their unsigned counterparts ), @c wxIntegerHash for integer types ( int, long, short, and their unsigned counterparts ),
wxStringHash for strings ( wxString, wxChar*, char* ), and wxPointerHash for @c wxStringHash for strings ( wxString, wxChar*, char* ), and @c wxPointerHash for
any kind of pointer. any kind of pointer.
Similarly three equality predicates: wxIntegerEqual, wxStringEqual, Similarly three equality predicates: @c wxIntegerEqual, @c wxStringEqual,
wxPointerEqual are provided. @c wxPointerEqual are provided.
Using this you could declare a hash map mapping int values to wxString like this: Using this you could declare a hash map mapping int values to wxString like this:
@code @code
@@ -151,6 +151,13 @@
it + 3, it1 - it2. it + 3, it1 - it2.
@section hashmap_predef Predefined hashmap types
wxWidgets defines the following hashmap types:
- wxLongToLongHashMap (uses long both for keys and values)
- wxStringToStringHashMap (uses wxString both for keys and values)
@library{wxbase} @library{wxbase}
@category{containers} @category{containers}
*/ */

View File

@@ -20,8 +20,10 @@ enum TransferMode
@class wxFTP @class wxFTP
wxFTP can be used to establish a connection to an FTP server and perform all the wxFTP can be used to establish a connection to an FTP server and perform all the
usual operations. Please consult the RFC 959 for more details about the FTP usual operations. Please consult the RFC 959 (http://www.w3.org/Protocols/rfc959/)
protocol. for more details about the FTP protocol.
wxFTP can thus be used to create a (basic) FTP @b client.
To use a command which doesn't involve file transfer (i.e. directory oriented To use a command which doesn't involve file transfer (i.e. directory oriented
commands) you just need to call a corresponding member function or use the commands) you just need to call a corresponding member function or use the
@@ -38,14 +40,14 @@ enum TransferMode
ftp.SetUser("user"); ftp.SetUser("user");
ftp.SetPassword("password"); ftp.SetPassword("password");
if ( !ftp.Connect("ftp.wxwindows.org") ) if ( !ftp.Connect("ftp.wxwidgets.org") )
{ {
wxLogError("Couldn't connect"); wxLogError("Couldn't connect");
return; return;
} }
ftp.ChDir("/pub"); ftp.ChDir("/pub/2.8.9);
wxInputStream *in = ftp.GetInputStream("wxWidgets-4.2.0.tar.gz"); wxInputStream *i = ftp.GetInputStream("wxWidgets-2.8.9.tar.bz2");
if ( !in ) if ( !in )
{ {
wxLogError("Coudln't get file"); wxLogError("Coudln't get file");
@@ -67,6 +69,9 @@ enum TransferMode
delete [] data; delete [] data;
delete in; delete in;
} }
// gracefully close the connection to the server
ftp.Close();
@endcode @endcode
To upload a file you would do (assuming the connection to the server was opened To upload a file you would do (assuming the connection to the server was opened
@@ -99,6 +104,13 @@ public:
*/ */
virtual ~wxFTP(); virtual ~wxFTP();
/**
@name Functions for managing the FTP connection
*/
//@{
/** /**
Aborts the download currently in process, returns @true if ok, @false Aborts the download currently in process, returns @true if ok, @false
if an error occurred. if an error occurred.
@@ -106,10 +118,9 @@ public:
virtual bool Abort(); virtual bool Abort();
/** /**
Change the current FTP working directory. Gracefully closes the connection with the server.
Returns @true if successful.
*/ */
bool ChDir(const wxString& dir); virtual bool Close();
/** /**
Send the specified @a command to the FTP server. @a ret specifies Send the specified @a command to the FTP server. @a ret specifies
@@ -119,6 +130,96 @@ public:
*/ */
bool CheckCommand(const wxString& command, char ret); bool CheckCommand(const wxString& command, char ret);
/**
Returns the last command result, i.e. the full server reply for the last command.
*/
const wxString& GetLastResult();
/**
Send the specified @a command to the FTP server and return the first
character of the return code.
*/
char SendCommand(const wxString& command);
/**
Sets the transfer mode to ASCII. It will be used for the next transfer.
*/
bool SetAscii();
/**
Sets the transfer mode to binary. It will be used for the next transfer.
*/
bool SetBinary();
/**
If @a pasv is @true, passive connection to the FTP server is used.
This is the default as it works with practically all firewalls.
If the server doesn't support passive mode, you may call this function
with @false as argument to use an active connection.
*/
void SetPassive(bool pasv);
/**
Sets the password to be sent to the FTP server to be allowed to log in.
*/
virtual void SetPassword(const wxString& passwd);
/**
Sets the transfer mode to the specified one. It will be used for the next
transfer.
If this function is never called, binary transfer mode is used by default.
*/
bool SetTransferMode(TransferMode mode);
/**
Sets the user name to be sent to the FTP server to be allowed to log in.
*/
virtual void SetUser(const wxString& user);
//@}
/**
@name Filesystem commands
*/
//@{
/**
Change the current FTP working directory.
Returns @true if successful.
*/
bool ChDir(const wxString& dir);
/**
Create the specified directory in the current FTP working directory.
Returns @true if successful.
*/
bool MkDir(const wxString& dir);
/**
Returns the current FTP working directory.
*/
wxString Pwd();
/**
Rename the specified @a src element to @e dst. Returns @true if successful.
*/
bool Rename(const wxString& src, const wxString& dst);
/**
Remove the specified directory from the current FTP working directory.
Returns @true if successful.
*/
bool RmDir(const wxString& dir);
/**
Delete the file specified by @e path. Returns @true if successful.
*/
bool RmFile(const wxString& path);
/** /**
Returns @true if the given remote file exists, @false otherwise. Returns @true if the given remote file exists, @false otherwise.
*/ */
@@ -179,6 +280,14 @@ public:
bool GetFilesList(wxArrayString& files, bool GetFilesList(wxArrayString& files,
const wxString& wildcard = wxEmptyString); const wxString& wildcard = wxEmptyString);
//@}
/**
@name Download and upload functions
*/
//@{
/** /**
Creates a new input stream on the specified path. Creates a new input stream on the specified path.
@@ -190,95 +299,22 @@ public:
You will be notified when the EOF is reached by an error. You will be notified when the EOF is reached by an error.
@return Returns @NULL if an error occurred (it could be a network failure @return Returns @NULL if an error occurred (it could be a network failure
or the fact that the file doesn't exist). or the fact that the file doesn't exist).
*/ */
virtual wxInputStream* GetInputStream(const wxString& path); virtual wxInputStream* GetInputStream(const wxString& path);
/** /**
Returns the last command result, i.e. the full server reply for the last command. Initializes an output stream to the specified @a file.
*/
const wxString& GetLastResult();
/**
Initializes an output stream to the specified @e file.
The returned stream has all but the seek functionality of wxStreams. The returned stream has all but the seek functionality of wxStreams.
When the user finishes writing data, he has to delete the stream to close it. When the user finishes writing data, he has to delete the stream to close it.
@return An initialized write-only stream. @return An initialized write-only stream.
Returns @NULL if an error occurred (it could be a network failure
@see wxOutputStream or the fact that the file doesn't exist).
*/ */
virtual wxOutputStream* GetOutputStream(const wxString& file); virtual wxOutputStream* GetOutputStream(const wxString& file);
/** //@}
Create the specified directory in the current FTP working directory.
Returns @true if successful.
*/
bool MkDir(const wxString& dir);
/**
Returns the current FTP working directory.
*/
wxString Pwd();
/**
Rename the specified @a src element to @e dst. Returns @true if successful.
*/
bool Rename(const wxString& src, const wxString& dst);
/**
Remove the specified directory from the current FTP working directory.
Returns @true if successful.
*/
bool RmDir(const wxString& dir);
/**
Delete the file specified by @e path. Returns @true if successful.
*/
bool RmFile(const wxString& path);
/**
Send the specified @a command to the FTP server and return the first
character of the return code.
*/
char SendCommand(const wxString& command);
/**
Sets the transfer mode to ASCII. It will be used for the next transfer.
*/
bool SetAscii();
/**
Sets the transfer mode to binary (IMAGE). It will be used for the next transfer.
*/
bool SetBinary();
/**
If @a pasv is @true, passive connection to the FTP server is used.
This is the default as it works with practically all firewalls.
If the server doesn't support passive move, you may call this function with
@false argument to use active connection.
*/
void SetPassive(bool pasv);
/**
Sets the password to be sent to the FTP server to be allowed to log in.
*/
virtual void SetPassword(const wxString& passwd);
/**
Sets the transfer mode to the specified one. It will be used for the next
transfer.
If this function is never called, binary transfer mode is used by default.
*/
bool SetTransferMode(TransferMode mode);
/**
Sets the user name to be sent to the FTP server to be allowed to log in.
*/
virtual void SetUser(const wxString& user);
}; };

View File

@@ -11,6 +11,8 @@
wxHTTP can be used to establish a connection to an HTTP server. wxHTTP can be used to establish a connection to an HTTP server.
wxHTTP can thus be used to create a (basic) HTTP @b client.
@library{wxnet} @library{wxnet}
@category{net} @category{net}
@@ -19,6 +21,16 @@
class wxHTTP : public wxProtocol class wxHTTP : public wxProtocol
{ {
public: public:
/**
Default constructor.
*/
wxHTTP();
/**
Destructor will close the connection if connected.
*/
virtual ~wxHTTP();
//@{ //@{
/** /**
Connect to the HTTP server. Connect to the HTTP server.
@@ -32,7 +44,7 @@ public:
//@} //@}
/** /**
Returns the data attached with a field whose name is specified by @e header. Returns the data attached with a field whose name is specified by @a header.
If the field doesn't exist, it will return an empty string and not a @NULL string. If the field doesn't exist, it will return an empty string and not a @NULL string.
@note @note
@@ -71,12 +83,12 @@ public:
Please refer to RFC 2616 for the list of responses. Please refer to RFC 2616 for the list of responses.
*/ */
int GetResponse(); int GetResponse() const;
/** /**
It sets data of a field to be sent during the next request to the HTTP server. It sets data of a field to be sent during the next request to the HTTP server.
The field name is specified by @a header and the content by @e h_data. The field name is specified by @a header and the content by @a h_data.
This is a low level function and it assumes that you know what you are doing. This is a low level function and it assumes that you know what you are doing.
*/ */
void SetHeader(const wxString& header, const wxString& h_data); void SetHeader(const wxString& header, const wxString& h_data);

View File

@@ -28,6 +28,10 @@ enum wxProtocolError
Represents a protocol for use with wxURL. Represents a protocol for use with wxURL.
Note that you may want to change the default time-out for HTTP/FTP connections
and network operations (using SetDefaultTimeout()) since the default time-out
value is quite long (60 seconds).
@library{wxnet} @library{wxnet}
@category{net} @category{net}
@@ -49,15 +53,16 @@ public:
/** /**
Returns the type of the content of the last opened stream. It is a mime-type. Returns the type of the content of the last opened stream. It is a mime-type.
May be an empty string if the content-type is unknown.
*/ */
virtual wxString GetContentType(); virtual wxString GetContentType() const;
/** /**
Returns the last occurred error. Returns the last occurred error.
@see wxProtocolError @see wxProtocolError
*/ */
virtual wxProtocolError GetError() = 0; virtual wxProtocolError GetError() const;
/** /**
Creates a new input stream on the specified path. Creates a new input stream on the specified path.
@@ -85,13 +90,22 @@ public:
bool Reconnect(); bool Reconnect();
/** /**
Sets the authentication password. It is mainly useful when FTP is used. Sets the authentication password.
*/ */
virtual void SetPassword(const wxString& user); virtual void SetPassword(const wxString& user);
/** /**
Sets the authentication user. It is mainly useful when FTP is used. Sets the authentication user.
*/ */
virtual void SetUser(const wxString& user); virtual void SetUser(const wxString& user);
/**
Sets a new default timeout for the network operations.
The default timeout is 60 seconds.
@see wxSocketBase::SetTimeout
*/
void SetDefaultTimeout(wxUint32 Value);
}; };

View File

@@ -76,17 +76,15 @@ IMPLEMENT_PROTOCOL(wxFTP, wxT("ftp"), wxT("ftp"), true)
wxFTP::wxFTP() wxFTP::wxFTP()
{ {
m_lastError = wxPROTO_NOERR;
m_streaming = false; m_streaming = false;
m_currentTransfermode = NONE; m_currentTransfermode = NONE;
m_user = wxT("anonymous"); m_username = wxT("anonymous");
m_passwd << wxGetUserId() << wxT('@') << wxGetFullHostName(); m_password << wxGetUserId() << wxT('@') << wxGetFullHostName();
SetNotify(0); SetNotify(0);
SetFlags(wxSOCKET_NOWAIT); SetFlags(wxSOCKET_NOWAIT);
m_bPassive = true; m_bPassive = true;
SetDefaultTimeout(60); // Default is Sixty Seconds
m_bEncounteredError = false; m_bEncounteredError = false;
} }
@@ -115,7 +113,7 @@ bool wxFTP::Connect(const wxSockAddress& addr, bool WXUNUSED(wait))
return false; return false;
} }
if ( !m_user ) if ( !m_username )
{ {
m_lastError = wxPROTO_CONNERR; m_lastError = wxPROTO_CONNERR;
return false; return false;
@@ -129,27 +127,31 @@ bool wxFTP::Connect(const wxSockAddress& addr, bool WXUNUSED(wait))
} }
wxString command; wxString command;
command.Printf(wxT("USER %s"), m_user.c_str()); command.Printf(wxT("USER %s"), m_username.c_str());
char rc = SendCommand(command); char rc = SendCommand(command);
if ( rc == '2' ) if ( rc == '2' )
{ {
// 230 return: user accepted without password // 230 return: user accepted without password
m_lastError = wxPROTO_NOERR;
return true; return true;
} }
if ( rc != '3' ) if ( rc != '3' )
{ {
m_lastError = wxPROTO_CONNERR;
Close(); Close();
return false; return false;
} }
command.Printf(wxT("PASS %s"), m_passwd.c_str()); command.Printf(wxT("PASS %s"), m_password.c_str());
if ( !CheckCommand(command, '2') ) if ( !CheckCommand(command, '2') )
{ {
m_lastError = wxPROTO_CONNERR;
Close(); Close();
return false; return false;
} }
m_lastError = wxPROTO_NOERR;
return true; return true;
} }
@@ -174,6 +176,7 @@ bool wxFTP::Close()
{ {
if ( !CheckCommand(wxT("QUIT"), '2') ) if ( !CheckCommand(wxT("QUIT"), '2') )
{ {
m_lastError = wxPROTO_CONNERR;
wxLogDebug(_T("Failed to close connection gracefully.")); wxLogDebug(_T("Failed to close connection gracefully."));
} }
} }
@@ -201,6 +204,7 @@ wxSocketBase *wxFTP::AcceptIfActive(wxSocketBase *sock)
} }
else else
{ {
m_lastError = wxPROTO_NOERR;
sock = sockSrv->Accept(true); sock = sockSrv->Accept(true);
delete sockSrv; delete sockSrv;
} }
@@ -220,11 +224,6 @@ bool wxFTP::Abort()
return CheckResult('2'); return CheckResult('2');
} }
void wxFTP::SetDefaultTimeout(wxUint32 Value)
{
m_uiDefaultTimeout = Value;
SetTimeout(Value); // sets it for this socket
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Send command to FTP server // Send command to FTP server
@@ -261,6 +260,7 @@ char wxFTP::SendCommand(const wxString& command)
wxLogTrace(FTP_TRACE_MASK, _T("==> %s"), cmd.c_str()); wxLogTrace(FTP_TRACE_MASK, _T("==> %s"), cmd.c_str());
#endif // __WXDEBUG__ #endif // __WXDEBUG__
m_lastError = wxPROTO_NOERR;
return GetResult(); return GetResult();
} }
@@ -380,6 +380,8 @@ char wxFTP::GetResult()
return 0; return 0;
} }
else
m_lastError = wxPROTO_NOERR;
// if we got here we must have a non empty code string // if we got here we must have a non empty code string
return (char)code[0u]; return (char)code[0u];
@@ -439,10 +441,12 @@ bool wxFTP::DoSimpleCommand(const wxChar *command, const wxString& arg)
if ( !CheckCommand(fullcmd, '2') ) if ( !CheckCommand(fullcmd, '2') )
{ {
wxLogDebug(_T("FTP command '%s' failed."), fullcmd.c_str()); wxLogDebug(_T("FTP command '%s' failed."), fullcmd.c_str());
m_lastError = wxPROTO_NETERR;
return false; return false;
} }
m_lastError = wxPROTO_NOERR;
return true; return true;
} }
@@ -507,6 +511,7 @@ wxString wxFTP::Pwd()
} }
else else
{ {
m_lastError = wxPROTO_PROTERR;
wxLogDebug(_T("FTP PWD command failed.")); wxLogDebug(_T("FTP PWD command failed."));
} }
@@ -618,6 +623,7 @@ wxSocketBase *wxFTP::GetActivePort()
return NULL; return NULL;
} }
m_lastError = wxPROTO_NOERR;
sockSrv->Notify(false); // Don't send any events sockSrv->Notify(false); // Don't send any events
return sockSrv; return sockSrv;
} }
@@ -626,6 +632,7 @@ wxSocketBase *wxFTP::GetPassivePort()
{ {
if ( !DoSimpleCommand(_T("PASV")) ) if ( !DoSimpleCommand(_T("PASV")) )
{ {
m_lastError = wxPROTO_PROTERR;
wxLogError(_("The FTP server doesn't support passive mode.")); wxLogError(_("The FTP server doesn't support passive mode."));
return NULL; return NULL;
} }
@@ -660,12 +667,14 @@ wxSocketBase *wxFTP::GetPassivePort()
wxSocketClient *client = new wxSocketClient(); wxSocketClient *client = new wxSocketClient();
if ( !client->Connect(addr) ) if ( !client->Connect(addr) )
{ {
m_lastError = wxPROTO_CONNERR;
delete client; delete client;
return NULL; return NULL;
} }
client->Notify(false); client->Notify(false);
m_lastError = wxPROTO_NOERR;
return client; return client;
} }
@@ -761,7 +770,10 @@ public:
wxInputStream *wxFTP::GetInputStream(const wxString& path) wxInputStream *wxFTP::GetInputStream(const wxString& path)
{ {
if ( ( m_currentTransfermode == NONE ) && !SetTransferMode(BINARY) ) if ( ( m_currentTransfermode == NONE ) && !SetTransferMode(BINARY) )
{
m_lastError = wxPROTO_CONNERR;
return NULL; return NULL;
}
wxSocketBase *sock = GetPort(); wxSocketBase *sock = GetPort();
@@ -777,7 +789,10 @@ wxInputStream *wxFTP::GetInputStream(const wxString& path)
sock = AcceptIfActive(sock); sock = AcceptIfActive(sock);
if ( !sock ) if ( !sock )
{
m_lastError = wxPROTO_CONNERR;
return NULL; return NULL;
}
sock->SetFlags(wxSOCKET_WAITALL); sock->SetFlags(wxSOCKET_WAITALL);
@@ -785,13 +800,17 @@ wxInputStream *wxFTP::GetInputStream(const wxString& path)
wxInputFTPStream *in_stream = new wxInputFTPStream(this, sock); wxInputFTPStream *in_stream = new wxInputFTPStream(this, sock);
m_lastError = wxPROTO_NOERR;
return in_stream; return in_stream;
} }
wxOutputStream *wxFTP::GetOutputStream(const wxString& path) wxOutputStream *wxFTP::GetOutputStream(const wxString& path)
{ {
if ( ( m_currentTransfermode == NONE ) && !SetTransferMode(BINARY) ) if ( ( m_currentTransfermode == NONE ) && !SetTransferMode(BINARY) )
{
m_lastError = wxPROTO_CONNERR;
return NULL; return NULL;
}
wxSocketBase *sock = GetPort(); wxSocketBase *sock = GetPort();
@@ -803,6 +822,7 @@ wxOutputStream *wxFTP::GetOutputStream(const wxString& path)
m_streaming = true; m_streaming = true;
m_lastError = wxPROTO_NOERR;
return new wxOutputFTPStream(this, sock); return new wxOutputFTPStream(this, sock);
} }
@@ -815,8 +835,10 @@ bool wxFTP::GetList(wxArrayString& files,
bool details) bool details)
{ {
wxSocketBase *sock = GetPort(); wxSocketBase *sock = GetPort();
if (!sock) if (!sock) {
m_lastError = wxPROTO_NETERR;
return false; return false;
}
// NLST : List of Filenames (including Directory's !) // NLST : List of Filenames (including Directory's !)
// LIST : depending on BS of FTP-Server // LIST : depending on BS of FTP-Server
@@ -838,8 +860,10 @@ bool wxFTP::GetList(wxArrayString& files,
} }
sock = AcceptIfActive(sock); sock = AcceptIfActive(sock);
if ( !sock ) if ( !sock ) {
m_lastError = wxPROTO_CONNERR;
return false; return false;
}
files.Empty(); files.Empty();
while (ReadLine(sock, line) == wxPROTO_NOERR ) while (ReadLine(sock, line) == wxPROTO_NOERR )
@@ -850,6 +874,7 @@ bool wxFTP::GetList(wxArrayString& files,
delete sock; delete sock;
// the file list should be terminated by "226 Transfer complete"" // the file list should be terminated by "226 Transfer complete""
m_lastError = wxPROTO_NOERR;
return CheckResult('2'); return CheckResult('2');
} }

View File

@@ -34,6 +34,11 @@
#include "wx/sckstrm.h" #include "wx/sckstrm.h"
#include "wx/thread.h" #include "wx/thread.h"
// ----------------------------------------------------------------------------
// wxHTTP
// ----------------------------------------------------------------------------
IMPLEMENT_DYNAMIC_CLASS(wxHTTP, wxProtocol) IMPLEMENT_DYNAMIC_CLASS(wxHTTP, wxProtocol)
IMPLEMENT_PROTOCOL(wxHTTP, wxT("http"), wxT("80"), true) IMPLEMENT_PROTOCOL(wxHTTP, wxT("http"), wxT("80"), true)
@@ -58,10 +63,10 @@ wxHTTP::~wxHTTP()
void wxHTTP::ClearHeaders() void wxHTTP::ClearHeaders()
{ {
m_headers.clear(); m_headers.clear();
} }
wxString wxHTTP::GetContentType() wxString wxHTTP::GetContentType() const
{ {
return GetHeader(wxT("Content-Type")); return GetHeader(wxT("Content-Type"));
} }
@@ -177,8 +182,8 @@ bool wxHTTP::ParseHeaders()
for ( ;; ) for ( ;; )
{ {
m_perr = ReadLine(this, line); m_lastError = ReadLine(this, line);
if (m_perr != wxPROTO_NOERR) if (m_lastError != wxPROTO_NOERR)
return false; return false;
if (line.length() == 0) if (line.length() == 0)
@@ -205,7 +210,7 @@ bool wxHTTP::Connect(const wxString& host, unsigned short port)
if (!addr->Hostname(host)) { if (!addr->Hostname(host)) {
delete m_addr; delete m_addr;
m_addr = NULL; m_addr = NULL;
m_perr = wxPROTO_NETERR; m_lastError = wxPROTO_NETERR;
return false; return false;
} }
@@ -216,6 +221,7 @@ bool wxHTTP::Connect(const wxString& host, unsigned short port)
SetHeader(wxT("Host"), host); SetHeader(wxT("Host"), host);
m_lastError = wxPROTO_NOERR;
return true; return true;
} }
@@ -232,6 +238,7 @@ bool wxHTTP::Connect(const wxSockAddress& addr, bool WXUNUSED(wait))
if (ipv4addr) if (ipv4addr)
SetHeader(wxT("Host"), ipv4addr->OrigHostname()); SetHeader(wxT("Host"), ipv4addr->OrigHostname());
m_lastError = wxPROTO_NOERR;
return true; return true;
} }
@@ -286,8 +293,8 @@ bool wxHTTP::BuildRequest(const wxString& path, wxHTTP_Req req)
} }
wxString tmp_str; wxString tmp_str;
m_perr = ReadLine(this, tmp_str); m_lastError = ReadLine(this, tmp_str);
if (m_perr != wxPROTO_NOERR) { if (m_lastError != wxPROTO_NOERR) {
RestoreState(); RestoreState();
return false; return false;
} }
@@ -295,6 +302,7 @@ bool wxHTTP::BuildRequest(const wxString& path, wxHTTP_Req req)
if (!tmp_str.Contains(wxT("HTTP/"))) { if (!tmp_str.Contains(wxT("HTTP/"))) {
// TODO: support HTTP v0.9 which can have no header. // TODO: support HTTP v0.9 which can have no header.
// FIXME: tmp_str is not put back in the in-queue of the socket. // FIXME: tmp_str is not put back in the in-queue of the socket.
m_lastError = wxPROTO_NOERR;
SetHeader(wxT("Content-Length"), wxT("-1")); SetHeader(wxT("Content-Length"), wxT("-1"));
SetHeader(wxT("Content-Type"), wxT("none/none")); SetHeader(wxT("Content-Type"), wxT("none/none"));
RestoreState(); RestoreState();
@@ -325,16 +333,26 @@ bool wxHTTP::BuildRequest(const wxString& path, wxHTTP_Req req)
break; break;
default: default:
m_perr = wxPROTO_NOFILE; m_lastError = wxPROTO_NOFILE;
RestoreState(); RestoreState();
return false; return false;
} }
m_lastError = wxPROTO_NOERR;
ret_value = ParseHeaders(); ret_value = ParseHeaders();
RestoreState(); RestoreState();
return ret_value; return ret_value;
} }
bool wxHTTP::Abort(void)
{
return wxSocketClient::Close();
}
// ----------------------------------------------------------------------------
// wxHTTPStream and wxHTTP::GetInputStream
// ----------------------------------------------------------------------------
class wxHTTPStream : public wxSocketInputStream class wxHTTPStream : public wxSocketInputStream
{ {
public: public:
@@ -369,24 +387,19 @@ size_t wxHTTPStream::OnSysRead(void *buffer, size_t bufsize)
// which is equivalent to getting a READ_ERROR, for clients however this // which is equivalent to getting a READ_ERROR, for clients however this
// must be translated into EOF, as it is the expected way of signalling // must be translated into EOF, as it is the expected way of signalling
// end end of the content // end end of the content
m_lasterror = wxSTREAM_EOF ; m_lasterror = wxSTREAM_EOF;
} }
return ret; return ret;
} }
bool wxHTTP::Abort(void)
{
return wxSocketClient::Close();
}
wxInputStream *wxHTTP::GetInputStream(const wxString& path) wxInputStream *wxHTTP::GetInputStream(const wxString& path)
{ {
wxHTTPStream *inp_stream; wxHTTPStream *inp_stream;
wxString new_path; wxString new_path;
m_perr = wxPROTO_CONNERR; m_lastError = wxPROTO_CONNERR; // all following returns share this type of error
if (!m_addr) if (!m_addr)
return NULL; return NULL;
@@ -417,6 +430,8 @@ wxInputStream *wxHTTP::GetInputStream(const wxString& path)
Notify(false); Notify(false);
SetFlags(wxSOCKET_BLOCK | wxSOCKET_WAITALL); SetFlags(wxSOCKET_BLOCK | wxSOCKET_WAITALL);
// no error; reset m_lastError
m_lastError = wxPROTO_NOERR;
return inp_stream; return inp_stream;
} }

View File

@@ -28,15 +28,9 @@
#include <stdlib.h> #include <stdlib.h>
///////////////////////////////////////////////////////////////// // ----------------------------------------------------------------------------
// wxProtoInfo // wxProtoInfo
///////////////////////////////////////////////////////////////// // ----------------------------------------------------------------------------
/*
* --------------------------------------------------------------
* --------- wxProtoInfo CONSTRUCTOR ----------------------------
* --------------------------------------------------------------
*/
wxProtoInfo::wxProtoInfo(const wxChar *name, const wxChar *serv, wxProtoInfo::wxProtoInfo(const wxChar *name, const wxChar *serv,
const bool need_host1, wxClassInfo *info) const bool need_host1, wxClassInfo *info)
@@ -53,9 +47,10 @@ wxProtoInfo::wxProtoInfo(const wxChar *name, const wxChar *serv,
#endif #endif
} }
/////////////////////////////////////////////////////////////////
// wxProtocol /////////////////////////////////////////////////// // ----------------------------------------------------------------------------
///////////////////////////////////////////////////////////////// // wxProtocol
// ----------------------------------------------------------------------------
#if wxUSE_SOCKETS #if wxUSE_SOCKETS
IMPLEMENT_ABSTRACT_CLASS(wxProtocol, wxSocketClient) IMPLEMENT_ABSTRACT_CLASS(wxProtocol, wxSocketClient)
@@ -68,6 +63,8 @@ wxProtocol::wxProtocol()
: wxSocketClient() : wxSocketClient()
#endif #endif
{ {
m_lastError = wxPROTO_NOERR;
SetDefaultTimeout(60); // default timeout is 60 seconds
} }
#if wxUSE_SOCKETS #if wxUSE_SOCKETS
@@ -90,6 +87,15 @@ bool wxProtocol::Reconnect()
return true; return true;
} }
void wxProtocol::SetDefaultTimeout(wxUint32 Value)
{
m_uiDefaultTimeout = Value;
#if wxUSE_SOCKETS
wxSocketBase::SetTimeout(Value); // sets it for this socket
#endif
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Read a line from socket // Read a line from socket
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@@ -25,13 +25,17 @@
#include "wx/wfstream.h" #include "wx/wfstream.h"
#include "wx/protocol/file.h" #include "wx/protocol/file.h"
// ----------------------------------------------------------------------------
// wxFileProto
// ----------------------------------------------------------------------------
IMPLEMENT_DYNAMIC_CLASS(wxFileProto, wxProtocol) IMPLEMENT_DYNAMIC_CLASS(wxFileProto, wxProtocol)
IMPLEMENT_PROTOCOL(wxFileProto, wxT("file"), NULL, false) IMPLEMENT_PROTOCOL(wxFileProto, wxT("file"), NULL, false)
wxFileProto::wxFileProto() wxFileProto::wxFileProto()
: wxProtocol() : wxProtocol()
{ {
m_error = wxPROTO_NOERR;
} }
wxFileProto::~wxFileProto() wxFileProto::~wxFileProto()
@@ -43,12 +47,11 @@ wxInputStream *wxFileProto::GetInputStream(const wxString& path)
wxFileInputStream *retval = new wxFileInputStream(wxURI::Unescape(path)); wxFileInputStream *retval = new wxFileInputStream(wxURI::Unescape(path));
if ( retval->Ok() ) if ( retval->Ok() )
{ {
m_error = wxPROTO_NOERR; m_lastError = wxPROTO_NOERR;
return retval; return retval;
} }
m_error = wxPROTO_NOFILE; m_lastError = wxPROTO_NOFILE;
delete retval; delete retval;
return NULL; return NULL;