diff --git a/include/wx/msw/private/webrequest_winhttp.h b/include/wx/msw/private/webrequest_winhttp.h index 58bfcc52bd..ad21393ec1 100644 --- a/include/wx/msw/private/webrequest_winhttp.h +++ b/include/wx/msw/private/webrequest_winhttp.h @@ -19,7 +19,7 @@ class wxWebSessionWinHTTP; class wxWebRequestWinHTTP; -class WXDLLIMPEXP_NET wxWebResponseWinHTTP : public wxWebResponse +class wxWebResponseWinHTTP : public wxWebResponseImpl { public: wxWebResponseWinHTTP(wxWebRequestWinHTTP& request); @@ -45,10 +45,11 @@ private: wxDECLARE_NO_COPY_CLASS(wxWebResponseWinHTTP); }; -class WXDLLIMPEXP_NET wxWebAuthChallengeWinHTTP : public wxWebAuthChallenge +class wxWebAuthChallengeWinHTTP : public wxWebAuthChallengeImpl { public: - wxWebAuthChallengeWinHTTP(Source source, wxWebRequestWinHTTP& request); + wxWebAuthChallengeWinHTTP(wxWebAuthChallenge::Source source, + wxWebRequestWinHTTP& request); bool Init(); @@ -62,10 +63,14 @@ private: wxDECLARE_NO_COPY_CLASS(wxWebAuthChallengeWinHTTP); }; -class WXDLLIMPEXP_NET wxWebRequestWinHTTP : public wxWebRequest +class wxWebRequestWinHTTP : public wxWebRequestImpl { public: - wxWebRequestWinHTTP(int id, wxWebSessionWinHTTP& session, const wxString& url); + wxWebRequestWinHTTP(wxWebSession& session, + wxWebSessionWinHTTP& sessionWinHTTP, + wxEvtHandler* handler, + const wxString& url, + int id); ~wxWebRequestWinHTTP(); @@ -73,9 +78,11 @@ public: void Cancel() wxOVERRIDE; - wxWebResponse* GetResponse() const wxOVERRIDE; + wxWebResponseImplPtr GetResponse() const wxOVERRIDE + { return m_response; } - wxWebAuthChallenge* GetAuthChallenge() const wxOVERRIDE { return m_authChallenge.get(); } + wxWebAuthChallengeImplPtr GetAuthChallenge() const wxOVERRIDE + { return m_authChallenge; } wxFileOffset GetBytesSent() const wxOVERRIDE { return m_dataWritten; } @@ -87,11 +94,12 @@ public: HINTERNET GetHandle() const { return m_request; } private: + wxWebSessionWinHTTP& m_sessionWinHTTP; wxString m_url; HINTERNET m_connect; HINTERNET m_request; - wxScopedPtr m_response; - wxScopedPtr m_authChallenge; + wxObjectDataPtr m_response; + wxObjectDataPtr m_authChallenge; wxMemoryBuffer m_dataWriteBuffer; wxFileOffset m_dataWritten; @@ -108,14 +116,18 @@ private: wxDECLARE_NO_COPY_CLASS(wxWebRequestWinHTTP); }; -class WXDLLIMPEXP_NET wxWebSessionWinHTTP : public wxWebSession +class wxWebSessionWinHTTP : public wxWebSessionImpl { public: wxWebSessionWinHTTP(); ~wxWebSessionWinHTTP(); - wxWebRequest* CreateRequest(const wxString& url, int id = wxID_ANY) wxOVERRIDE; + wxWebRequestImplPtr + CreateRequest(wxWebSession& session, + wxEvtHandler* handler, + const wxString& url, + int id) wxOVERRIDE; wxVersionInfo GetLibraryVersionInfo() wxOVERRIDE; @@ -130,10 +142,10 @@ private: wxDECLARE_NO_COPY_CLASS(wxWebSessionWinHTTP); }; -class WXDLLIMPEXP_NET wxWebSessionFactoryWinHTTP : public wxWebSessionFactory +class wxWebSessionFactoryWinHTTP : public wxWebSessionFactory { public: - wxWebSession* Create() wxOVERRIDE + wxWebSessionImpl* Create() wxOVERRIDE { return new wxWebSessionWinHTTP(); } }; diff --git a/include/wx/osx/private/webrequest_urlsession.h b/include/wx/osx/private/webrequest_urlsession.h index 4d6f3721fa..770b42d305 100644 --- a/include/wx/osx/private/webrequest_urlsession.h +++ b/include/wx/osx/private/webrequest_urlsession.h @@ -19,12 +19,13 @@ DECLARE_WXCOCOA_OBJC_CLASS(NSURLSessionTask); DECLARE_WXCOCOA_OBJC_CLASS(wxWebSessionDelegate); class wxWebSessionURLSession; +class wxWebRequestURLSession; class wxWebResponseURLSession; -class WXDLLIMPEXP_NET wxWebResponseURLSession : public wxWebResponse +class wxWebResponseURLSession : public wxWebResponseImpl { public: - wxWebResponseURLSession(wxWebRequest& request, WX_NSURLSessionTask task); + wxWebResponseURLSession(wxWebRequestURLSession& request, WX_NSURLSessionTask task); ~wxWebResponseURLSession(); @@ -44,12 +45,18 @@ public: private: WX_NSURLSessionTask m_task; + + wxDECLARE_NO_COPY_CLASS(wxWebResponseURLSession); }; -class WXDLLIMPEXP_NET wxWebRequestURLSession : public wxWebRequest +class wxWebRequestURLSession : public wxWebRequestImpl { public: - wxWebRequestURLSession(wxWebSessionURLSession& session, const wxString& url, int id); + wxWebRequestURLSession(wxWebSession& session, + wxWebSessionURLSession& sessionImpl, + wxEvtHandler* handler, + const wxString& url, + int winid); ~wxWebRequestURLSession(); @@ -57,10 +64,10 @@ public: void Cancel() wxOVERRIDE; - wxWebResponse* GetResponse() const wxOVERRIDE - { return m_response.get(); } + wxWebResponseImplPtr GetResponse() const wxOVERRIDE + { return m_response; } - wxWebAuthChallenge* GetAuthChallenge() const wxOVERRIDE; + wxWebAuthChallengeImplPtr GetAuthChallenge() const wxOVERRIDE; wxFileOffset GetBytesSent() const wxOVERRIDE; @@ -72,22 +79,30 @@ public: void HandleCompletion(); + wxWebResponseURLSession* GetResponseImplPtr() const + { return m_response.get(); } + private: + wxWebSessionURLSession& m_sessionImpl; wxString m_url; WX_NSURLSessionTask m_task; - wxScopedPtr m_response; + wxObjectDataPtr m_response; wxDECLARE_NO_COPY_CLASS(wxWebRequestURLSession); }; -class WXDLLIMPEXP_NET wxWebSessionURLSession : public wxWebSession +class wxWebSessionURLSession : public wxWebSessionImpl { public: wxWebSessionURLSession(); ~wxWebSessionURLSession(); - wxWebRequest* CreateRequest(const wxString& url, int id = wxID_ANY) wxOVERRIDE; + wxWebRequestImplPtr + CreateRequest(wxWebSession& session, + wxEvtHandler* handler, + const wxString& url, + int winid = wxID_ANY) wxOVERRIDE; wxVersionInfo GetLibraryVersionInfo() wxOVERRIDE; @@ -102,10 +117,10 @@ private: wxDECLARE_NO_COPY_CLASS(wxWebSessionURLSession); }; -class WXDLLIMPEXP_NET wxWebSessionFactoryURLSession : public wxWebSessionFactory +class wxWebSessionFactoryURLSession : public wxWebSessionFactory { public: - wxWebSession* Create() wxOVERRIDE + wxWebSessionImpl* Create() wxOVERRIDE { return new wxWebSessionURLSession(); } }; diff --git a/include/wx/private/webrequest.h b/include/wx/private/webrequest.h index c4746f7fe9..e77858ef57 100644 --- a/include/wx/private/webrequest.h +++ b/include/wx/private/webrequest.h @@ -10,6 +10,170 @@ #ifndef _WX_PRIVATE_WEBREQUEST_H_ #define _WX_PRIVATE_WEBREQUEST_H_ +#include "wx/ffile.h" +#include "wx/hashmap.h" +#include "wx/scopedptr.h" + +WX_DECLARE_STRING_HASH_MAP(wxString, wxWebRequestHeaderMap); + +// ---------------------------------------------------------------------------- +// wxWebAuthChallengeImpl +// ---------------------------------------------------------------------------- + +class wxWebAuthChallengeImpl : public wxRefCounter +{ +public: + virtual ~wxWebAuthChallengeImpl() { } + + wxWebAuthChallenge::Source GetSource() const { return m_source; } + + virtual void + SetCredentials(const wxString& user, const wxString& password) = 0; + +protected: + explicit wxWebAuthChallengeImpl(wxWebAuthChallenge::Source source) + : m_source(source) { } + +private: + const wxWebAuthChallenge::Source m_source; + + wxDECLARE_NO_COPY_CLASS(wxWebAuthChallengeImpl); +}; + +// ---------------------------------------------------------------------------- +// wxWebRequestImpl +// ---------------------------------------------------------------------------- + +class wxWebRequestImpl : public wxRefCounter +{ +public: + virtual ~wxWebRequestImpl() { } + + void SetHeader(const wxString& name, const wxString& value) + { m_headers[name] = value; } + + void SetMethod(const wxString& method) { m_method = method; } + + void SetData(const wxString& text, const wxString& contentType, const wxMBConv& conv = wxConvUTF8); + + bool SetData(const wxSharedPtr& dataStream, const wxString& contentType, wxFileOffset dataSize = wxInvalidOffset); + + void SetIgnoreServerErrorStatus(bool ignore) { m_ignoreServerErrorStatus = ignore; } + + void SetStorage(wxWebRequest::Storage storage) { m_storage = storage; } + + wxWebRequest::Storage GetStorage() const { return m_storage; } + + virtual void Start() = 0; + + virtual void Cancel() = 0; + + virtual wxWebResponseImplPtr GetResponse() const = 0; + + virtual wxWebAuthChallengeImplPtr GetAuthChallenge() const = 0; + + int GetId() const { return m_id; } + + wxWebSession& GetSession() const { return m_session; } + + wxWebRequest::State GetState() const { return m_state; } + + virtual wxFileOffset GetBytesSent() const = 0; + + virtual wxFileOffset GetBytesExpectedToSend() const = 0; + + virtual wxFileOffset GetBytesReceived() const; + + virtual wxFileOffset GetBytesExpectedToReceive() const; + + void SetState(wxWebRequest::State state, const wxString& failMsg = wxString()); + + void ReportDataReceived(size_t sizeReceived); + + wxEvtHandler* GetHandler() const { return m_handler; } + + void ProcessStateEvent(wxWebRequest::State state, const wxString& failMsg); + +protected: + wxString m_method; + wxWebRequest::Storage m_storage; + wxWebRequestHeaderMap m_headers; + wxFileOffset m_dataSize; + wxSharedPtr m_dataStream; + + wxWebRequestImpl(wxWebSession& session, wxEvtHandler* handler, int id); + + bool CheckServerStatus(); + + static bool IsActiveState(wxWebRequest::State state); + +private: + wxWebSession& m_session; + wxEvtHandler* const m_handler; + const int m_id; + wxWebRequest::State m_state; + bool m_ignoreServerErrorStatus; + wxFileOffset m_bytesReceived; + wxCharBuffer m_dataText; + + wxDECLARE_NO_COPY_CLASS(wxWebRequestImpl); +}; + +// ---------------------------------------------------------------------------- +// wxWebResponseImpl +// ---------------------------------------------------------------------------- + +class wxWebResponseImpl : public wxRefCounter +{ +public: + virtual ~wxWebResponseImpl(); + + virtual wxInt64 GetContentLength() const = 0; + + virtual wxString GetURL() const = 0; + + virtual wxString GetHeader(const wxString& name) const = 0; + + virtual wxString GetMimeType() const; + + virtual int GetStatus() const = 0; + + virtual wxString GetStatusText() const = 0; + + virtual wxInputStream* GetStream() const; + + virtual wxString GetSuggestedFileName() const; + + wxString AsString() const; + + virtual wxString GetFileName() const; + +protected: + wxWebRequestImpl& m_request; + size_t m_readSize; + + explicit wxWebResponseImpl(wxWebRequestImpl& request); + + // Called from derived class ctor to finish initialization which can't be + // performed in ctor itself as it needs to use pure virtual method. + void Init(); + + void* GetDataBuffer(size_t sizeNeeded); + + void ReportDataReceived(size_t sizeReceived); + +private: + // Called by wxWebRequestImpl only. + friend class wxWebRequestImpl; + void Finalize(); + + wxMemoryBuffer m_readBuffer; + mutable wxFFile m_file; + mutable wxScopedPtr m_stream; + + wxDECLARE_NO_COPY_CLASS(wxWebResponseImpl); +}; + // ---------------------------------------------------------------------------- // wxWebSessionFactory // ---------------------------------------------------------------------------- @@ -17,9 +181,48 @@ class wxWebSessionFactory { public: - virtual wxWebSession* Create() = 0; + virtual wxWebSessionImpl* Create() = 0; virtual ~wxWebSessionFactory() { } }; +// ---------------------------------------------------------------------------- +// wxWebSessionImpl +// ---------------------------------------------------------------------------- + +class wxWebSessionImpl : public wxRefCounter +{ +public: + virtual ~wxWebSessionImpl() { } + + virtual wxWebRequestImplPtr + CreateRequest(wxWebSession& session, + wxEvtHandler* handler, + const wxString& url, + int id) = 0; + + virtual wxVersionInfo GetLibraryVersionInfo() = 0; + + void SetHeader(const wxString& name, const wxString& value) + { m_headers[name] = value; } + + void SetTempDir(const wxString& dir) { m_tempDir = dir; } + + wxString GetTempDir() const; + + const wxWebRequestHeaderMap& GetHeaders() const { return m_headers; } + +protected: + wxWebSessionImpl(); + +private: + // Make it a friend to allow accessing our m_headers. + friend class wxWebRequest; + + wxWebRequestHeaderMap m_headers; + wxString m_tempDir; + + wxDECLARE_NO_COPY_CLASS(wxWebSessionImpl); +}; + #endif // _WX_PRIVATE_WEBREQUEST_H_ diff --git a/include/wx/private/webrequest_curl.h b/include/wx/private/webrequest_curl.h index c88e1d16db..42669a5530 100644 --- a/include/wx/private/webrequest_curl.h +++ b/include/wx/private/webrequest_curl.h @@ -19,13 +19,15 @@ #include "curl/curl.h" -class wxWebResponseCURL; class wxWebRequestCURL; +class wxWebResponseCURL; +class wxWebSessionCURL; -class WXDLLIMPEXP_NET wxWebAuthChallengeCURL : public wxWebAuthChallenge +class wxWebAuthChallengeCURL : public wxWebAuthChallengeImpl { public: - wxWebAuthChallengeCURL(Source source, wxWebRequestCURL& request); + wxWebAuthChallengeCURL(wxWebAuthChallenge::Source source, + wxWebRequestCURL& request); bool Init(); @@ -37,10 +39,14 @@ private: wxDECLARE_NO_COPY_CLASS(wxWebAuthChallengeCURL); }; -class WXDLLIMPEXP_NET wxWebRequestCURL : public wxWebRequest +class wxWebRequestCURL : public wxWebRequestImpl { public: - wxWebRequestCURL(wxWebSession& session, int id, const wxString& url); + wxWebRequestCURL(wxWebSession& session, + wxWebSessionCURL& sessionImpl, + wxEvtHandler* handler, + const wxString& url, + int id); ~wxWebRequestCURL(); @@ -48,10 +54,11 @@ public: void Cancel() wxOVERRIDE; - wxWebResponse* GetResponse() const wxOVERRIDE; + wxWebResponseImplPtr GetResponse() const wxOVERRIDE + { return m_response; } - wxWebAuthChallenge* GetAuthChallenge() const wxOVERRIDE - { return m_authChallenge.get(); } + wxWebAuthChallengeImplPtr GetAuthChallenge() const wxOVERRIDE + { return m_authChallenge; } wxFileOffset GetBytesSent() const wxOVERRIDE; @@ -68,11 +75,13 @@ public: size_t ReadData(char* buffer, size_t size); private: + wxWebSessionCURL& m_sessionImpl; + CURL* m_handle; char m_errorBuffer[CURL_ERROR_SIZE]; struct curl_slist *m_headerList; - wxScopedPtr m_response; - wxScopedPtr m_authChallenge; + wxObjectDataPtr m_response; + wxObjectDataPtr m_authChallenge; wxFileOffset m_bytesSent; void DestroyHeaderList(); @@ -80,10 +89,10 @@ private: wxDECLARE_NO_COPY_CLASS(wxWebRequestCURL); }; -class WXDLLIMPEXP_NET wxWebResponseCURL : public wxWebResponse +class wxWebResponseCURL : public wxWebResponseImpl { public: - wxWebResponseCURL(wxWebRequest& request); + explicit wxWebResponseCURL(wxWebRequestCURL& request); wxInt64 GetContentLength() const wxOVERRIDE; @@ -109,14 +118,18 @@ private: wxDECLARE_NO_COPY_CLASS(wxWebResponseCURL); }; -class WXDLLIMPEXP_NET wxWebSessionCURL : public wxWebSession, private wxThreadHelper +class wxWebSessionCURL : public wxWebSessionImpl, private wxThreadHelper { public: wxWebSessionCURL(); ~wxWebSessionCURL(); - wxWebRequest* CreateRequest(const wxString& url, int id = wxID_ANY) wxOVERRIDE; + wxWebRequestImplPtr + CreateRequest(wxWebSession& session, + wxEvtHandler* handler, + const wxString& url, + int id = wxID_ANY) wxOVERRIDE; wxVersionInfo GetLibraryVersionInfo() wxOVERRIDE; @@ -140,10 +153,10 @@ private: wxDECLARE_NO_COPY_CLASS(wxWebSessionCURL); }; -class WXDLLIMPEXP_NET wxWebSessionFactoryCURL : public wxWebSessionFactory +class wxWebSessionFactoryCURL : public wxWebSessionFactory { public: - wxWebSession* Create() wxOVERRIDE + wxWebSessionImpl* Create() wxOVERRIDE { return new wxWebSessionCURL(); } }; diff --git a/include/wx/webrequest.h b/include/wx/webrequest.h index b6b9cae8f9..0f9da9aa3f 100644 --- a/include/wx/webrequest.h +++ b/include/wx/webrequest.h @@ -15,23 +15,93 @@ #if wxUSE_WEBREQUEST #include "wx/event.h" -#include "wx/ffile.h" -#include "wx/hashmap.h" #include "wx/object.h" -#include "wx/scopedptr.h" #include "wx/sharedptr.h" #include "wx/stream.h" -#include "wx/vector.h" #include "wx/versioninfo.h" class wxWebResponse; class wxWebSession; class wxWebSessionFactory; -class wxWebAuthChallenge; -WX_DECLARE_STRING_HASH_MAP(wxString, wxWebRequestHeaderMap); +class wxWebAuthChallengeImpl; +class wxWebRequestImpl; +class wxWebResponseImpl; +class wxWebSessionImpl; -class WXDLLIMPEXP_NET wxWebRequest : public wxEvtHandler, public wxRefCounter +typedef wxObjectDataPtr wxWebAuthChallengeImplPtr; +typedef wxObjectDataPtr wxWebRequestImplPtr; +typedef wxObjectDataPtr wxWebResponseImplPtr; +typedef wxObjectDataPtr wxWebSessionImplPtr; + +class WXDLLIMPEXP_NET wxWebAuthChallenge +{ +public: + enum Source + { + Source_Server, + Source_Proxy + }; + + wxWebAuthChallenge(); + wxWebAuthChallenge(const wxWebAuthChallenge& other); + wxWebAuthChallenge& operator=(const wxWebAuthChallenge& other); + ~wxWebAuthChallenge(); + + bool IsOk() const { return m_impl.get() != NULL; } + + Source GetSource() const; + + void SetCredentials(const wxString& user, const wxString& password); + +private: + // Ctor is used by wxWebRequest only. + friend class wxWebRequest; + explicit wxWebAuthChallenge(const wxWebAuthChallengeImplPtr& impl); + + wxWebAuthChallengeImplPtr m_impl; +}; + +class WXDLLIMPEXP_NET wxWebResponse +{ +public: + wxWebResponse(); + wxWebResponse(const wxWebResponse& other); + wxWebResponse& operator=(const wxWebResponse& other); + ~wxWebResponse(); + + bool IsOk() const { return m_impl.get() != NULL; } + + wxInt64 GetContentLength() const; + + wxString GetURL() const; + + wxString GetHeader(const wxString& name) const; + + wxString GetMimeType() const; + + int GetStatus() const; + + wxString GetStatusText() const; + + wxInputStream* GetStream() const; + + wxString GetSuggestedFileName() const; + + wxString AsString() const; + + wxString GetFileName() const; + +protected: + // Ctor is used by wxWebRequest and wxWebRequestImpl. + friend class wxWebRequest; + friend class wxWebRequestImpl; + explicit wxWebResponse(const wxWebResponseImplPtr& impl); + + wxWebResponseImplPtr m_impl; +}; + +class WXDLLIMPEXP_NET wxWebRequest { public: enum State @@ -51,149 +121,55 @@ public: Storage_None }; - virtual ~wxWebRequest() { } + wxWebRequest(); + wxWebRequest(const wxWebRequest& other); + wxWebRequest& operator=(const wxWebRequest& other); + ~wxWebRequest(); - virtual void SetHeader(const wxString& name, const wxString& value) - { m_headers[name] = value; } + bool IsOk() const { return m_impl.get() != NULL; } - virtual void SetMethod(const wxString& method) { m_method = method; } + void SetHeader(const wxString& name, const wxString& value); + + void SetMethod(const wxString& method); void SetData(const wxString& text, const wxString& contentType, const wxMBConv& conv = wxConvUTF8); bool SetData(const wxSharedPtr& dataStream, const wxString& contentType, wxFileOffset dataSize = wxInvalidOffset); - void SetIgnoreServerErrorStatus(bool ignore) { m_ignoreServerErrorStatus = ignore; } + void SetIgnoreServerErrorStatus(bool ignore); - virtual void SetStorage(Storage storage) { m_storage = storage; } + void SetStorage(Storage storage); - Storage GetStorage() const { return m_storage; } + Storage GetStorage() const; - virtual void Start() = 0; + void Start(); - virtual void Cancel() = 0; + void Cancel(); - virtual wxWebResponse* GetResponse() const = 0; + wxWebResponse GetResponse() const; - virtual wxWebAuthChallenge* GetAuthChallenge() const = 0; + wxWebAuthChallenge GetAuthChallenge() const; - int GetId() const { return m_id; } + int GetId() const; - wxWebSession& GetSession() const { return m_session; } + wxWebSession& GetSession() const; - State GetState() const { return m_state; } + State GetState() const; - virtual wxFileOffset GetBytesSent() const = 0; + wxFileOffset GetBytesSent() const; - virtual wxFileOffset GetBytesExpectedToSend() const = 0; + wxFileOffset GetBytesExpectedToSend() const; - virtual wxFileOffset GetBytesReceived() const; + wxFileOffset GetBytesReceived() const; - virtual wxFileOffset GetBytesExpectedToReceive() const; - - void SetState(State state, const wxString& failMsg = ""); - - void ReportDataReceived(size_t sizeReceived); - -protected: - wxString m_method; - Storage m_storage; - wxWebRequestHeaderMap m_headers; - wxFileOffset m_dataSize; - wxSharedPtr m_dataStream; - - wxWebRequest(wxWebSession& session, int id); - - bool CheckServerStatus(); - - static bool IsActiveState(State state); + wxFileOffset GetBytesExpectedToReceive() const; private: - wxWebSession& m_session; - int m_id; - State m_state; - bool m_ignoreServerErrorStatus; - wxFileOffset m_bytesReceived; - wxCharBuffer m_dataText; + // Ctor is only used by wxWebSession. + friend class wxWebSession; + explicit wxWebRequest(const wxWebRequestImplPtr& impl); - void ProcessStateEvent(State state, const wxString& failMsg); - - wxDECLARE_NO_COPY_CLASS(wxWebRequest); -}; - -class WXDLLIMPEXP_NET wxWebResponse -{ -public: - virtual ~wxWebResponse(); - - virtual wxInt64 GetContentLength() const = 0; - - virtual wxString GetURL() const = 0; - - virtual wxString GetHeader(const wxString& name) const = 0; - - virtual wxString GetMimeType() const; - - virtual int GetStatus() const = 0; - - virtual wxString GetStatusText() const = 0; - - virtual wxInputStream* GetStream() const; - - virtual wxString GetSuggestedFileName() const; - - wxString AsString() const; - - virtual wxString GetFileName() const; - -protected: - wxWebRequest& m_request; - size_t m_readSize; - - wxWebResponse(wxWebRequest& request); - - // Called from derived class ctor to finish initialization which can't be - // performed in ctor itself as it needs to use pure virtual method. - void Init(); - - void* GetDataBuffer(size_t sizeNeeded); - - void ReportDataReceived(size_t sizeReceived); - -private: - // Called by wxWebRequest only. - void Finalize(); - - wxMemoryBuffer m_readBuffer; - mutable wxFFile m_file; - mutable wxScopedPtr m_stream; - - friend class wxWebRequest; - - wxDECLARE_NO_COPY_CLASS(wxWebResponse); -}; - -class WXDLLIMPEXP_NET wxWebAuthChallenge -{ -public: - enum Source - { - Source_Server, - Source_Proxy - }; - - virtual ~wxWebAuthChallenge() { } - - Source GetSource() const { return m_source; } - - virtual void SetCredentials(const wxString& user, const wxString& password) = 0; - -protected: - wxWebAuthChallenge(Source source): m_source(source) { } - -private: - Source m_source; - - wxDECLARE_NO_COPY_CLASS(wxWebAuthChallenge); + wxWebRequestImplPtr m_impl; }; extern WXDLLIMPEXP_DATA_NET(const char) wxWebSessionBackendDefault[]; @@ -204,45 +180,49 @@ extern WXDLLIMPEXP_DATA_NET(const char) wxWebSessionBackendCURL[]; class WXDLLIMPEXP_NET wxWebSession { public: + // Default ctor creates an invalid session object, only IsOpened() can be + // called on it. + wxWebSession(); + + wxWebSession(const wxWebSession& other); + wxWebSession& operator=(const wxWebSession& other); + ~wxWebSession(); + // Objects of this class can't be created directly, use the following // factory functions to get access to them. static wxWebSession& GetDefault(); - static wxWebSession* New(const wxString& backend = wxWebSessionBackendDefault); + static wxWebSession New(const wxString& backend = wxWebSessionBackendDefault); // Can be used to check if the given backend is available without actually // creating a session using it. static bool IsBackendAvailable(const wxString& backend); - virtual ~wxWebSession() { } + wxWebRequest + CreateRequest(wxEvtHandler* handler, const wxString& url, int id = wxID_ANY); - virtual wxWebRequest* CreateRequest(const wxString& url, int id = wxID_ANY) = 0; + wxVersionInfo GetLibraryVersionInfo(); - virtual wxVersionInfo GetLibraryVersionInfo() = 0; - - virtual void SetHeader(const wxString& name, const wxString& value) - { m_headers[name] = value; } - - void SetTempDir(const wxString& dir) { m_tempDir = dir; } + void SetHeader(const wxString& name, const wxString& value); + void SetTempDir(const wxString& dir); wxString GetTempDir() const; -protected: - wxWebSession(); + bool IsOpened() const; - const wxWebRequestHeaderMap& GetHeaders() const { return m_headers; } + void Close(); + + wxWebSessionImpl* GetImpl() const { return m_impl.get(); } private: static void RegisterFactory(const wxString& backend, const wxSharedPtr& factory); - // Make it a friend to allow accessing our m_headers. - friend class wxWebRequest; - - wxWebRequestHeaderMap m_headers; - wxString m_tempDir; - static void InitFactoryMap(); + + explicit wxWebSession(const wxWebSessionImplPtr& impl); + + wxWebSessionImplPtr m_impl; }; class WXDLLIMPEXP_NET wxWebRequestEvent : public wxEvent @@ -251,7 +231,7 @@ public: wxWebRequestEvent(wxEventType type = wxEVT_NULL, int id = wxID_ANY, wxWebRequest::State state = wxWebRequest::State_Idle, - wxWebResponse* response = NULL, + const wxWebResponse& response = wxWebResponse(), const wxString& errorDesc = wxString()) : wxEvent(id, type), m_state(state), m_response(response), m_data(NULL), m_dataSize(0), @@ -260,7 +240,7 @@ public: wxWebRequest::State GetState() const { return m_state; } - wxWebResponse* GetResponse() const { return m_response; } + const wxWebResponse& GetResponse() const { return m_response; } const wxString& GetErrorDescription() const { return m_errorDescription; } @@ -279,7 +259,7 @@ public: private: wxWebRequest::State m_state; - wxWebResponse* const m_response; // non-owning, may be NULL + const wxWebResponse m_response; // may be invalid wxString m_responseFileName; const void* m_data; size_t m_dataSize; diff --git a/interface/wx/webrequest.h b/interface/wx/webrequest.h index 76ea78de21..1eea20b305 100644 --- a/interface/wx/webrequest.h +++ b/interface/wx/webrequest.h @@ -23,21 +23,28 @@ communicate the request status. The response data may be stored in memory, to a file or processed directly, see SetStorage() for details. - Example usage: + Example usage in an event handler function of some window (i.e. @c this in + the example below is a wxWindow pointer): @code // Create the request object - wxObjectDataPtr request( - wxWebSession::GetDefault().CreateRequest("https://www.wxwidgets.org/downloads/logos/blocks.png")); + wxWebRequest request = wxWebSession::GetDefault().CreateRequest( + this, + "https://www.wxwidgets.org/downloads/logos/blocks.png" + ); + + if ( !request.IsOk() ) { + // This is not expected, but handle the error somehow. + } // Bind state event - request->Bind(wxEVT_WEBREQUEST_STATE, [](wxWebRequestEvent& evt) { + Bind(wxEVT_WEBREQUEST_STATE, [](wxWebRequestEvent& evt) { switch (evt.GetState()) { // Request completed case wxWebRequest::State_Completed: { - wxImage logoImage(*evt->GetResponse()->GetStream()); + wxImage logoImage(*evt.GetResponse().GetStream()); if (logoImage.IsOK()) wxLogInfo("Image loaded"); break; @@ -51,7 +58,7 @@ }); // Start the request - request->Start(); + request.Start(); @endcode @section descriptions Implementation Descriptions @@ -110,7 +117,7 @@ @see wxWebResponse, wxWebSession */ -class wxWebRequest: public wxEvtHandler, public wxRefCounter +class wxWebRequest { public: /** @@ -158,6 +165,23 @@ public: Storage_None }; + /** + Default constructor creates an invalid object. + + Initialize it by assigning wxWebSession::CreateRequest() to it before + using it. + + @see IsOk() + */ + wxWebRequest(); + + /** + Check if the object is valid. + + No other methods can be used if this function returns @false. + */ + bool IsOk() const; + /** Send the request to the server asynchronously. @@ -176,18 +200,16 @@ public: Returns a response object after a successful request. Before sending a request or after a failed request this will return - @c NULL. - - Note that this pointer remains owned by wxWebRequest object and must - not be freed. + an invalid response object, i.e. such that wxWebResponse::IsOk() + returns @NULL. */ - wxWebResponse* GetResponse() const; + wxWebResponse GetResponse() const; /** Returns the current authentication challenge object while the request is in @c State_Unauthorized. */ - wxWebAuthChallenge* GetAuthChallenge() const; + wxWebAuthChallenge GetAuthChallenge() const; /** Returns the id specified while creating this request. @@ -377,6 +399,23 @@ public: class wxWebResponse { public: + /** + Default constructor creates an invalid object. + + Initialize it by assigning wxWebRequest::GetResponse() to it before + using it. + + @see IsOk() + */ + wxWebResponse(); + + /** + Check if the object is valid. + + No other methods can be used if this function returns @false. + */ + bool IsOk() const; + /** Returns the final URL. This URL might be different than the request URL when a redirection @@ -428,7 +467,10 @@ public: /** @class wxWebSession - This class handles session-wide parameters and data used by wxWebRequest + Session allows creating wxWebRequest objects used for the actual HTTP + requests. + + It also handles session-wide parameters and data used by wxWebRequest instances. Usually the default session available via wxWebSession::GetDefault() @@ -451,14 +493,27 @@ class wxWebSession { public: /** - Create a new request for the specified URL + Create a new request for the specified URL. + The specified objects will be notified via wxWebRequestEvent objects + when the request state changes, e.g. when it is completed. It must be + specified and its lifetime must be long enough to last until the + request is completed. In particular, if the handler is a top-level + window, the request must be cancelled before the window can be closed + and destroyed. + + @param handler + The handler object to notify, must be non-@NULL. @param url The URL of the HTTP resource for this request @param id Optional id sent with events + @return + The new request object, use wxWebRequest::IsOk() to check if its + creation has succeeded. */ - wxWebRequest* CreateRequest(const wxString& url, int id = wxID_ANY); + wxWebRequest + CreateRequest(wxEvtHandler* handler, const wxString& url, int id = wxID_ANY); /** Retrieve the version information about the implementation library used @@ -499,13 +554,15 @@ public: /** Creates a new wxWebSession object. + Use IsOpened() to check if the session creation succeeded. + @param backend The backend web session implementation to use. @return The created wxWebSession */ - static wxWebSession* New(const wxString& backend = wxWebSessionBackendDefault); + static wxWebSession New(const wxString& backend = wxWebSessionBackendDefault); /** Allows to check if the specified backend is available at runtime. @@ -514,6 +571,20 @@ public: before 10.9 does not have the @c NSURLSession implementation available. */ static bool IsBackendAvailable(const wxString& backend); + + /** + Return true if the session was successfully opened and can be used. + */ + bool IsOpened() const; + + /** + Close the session. + + This frees any resources associated with the session and puts it in an + invalid state. Another session object can be assigned to it later to + allow using this object again. + */ + void Close(); }; /** @@ -531,20 +602,16 @@ public: class wxWebRequestEvent : public wxEvent { public: - wxWebRequestEvent(); - wxWebRequestEvent(wxEventType type, int id, wxWebRequest::State state, - wxWebResponse* response = NULL, const wxString& errorDesc = ""); - /** Return the current state of the request */ wxWebRequest::State GetState() const; /** - The response with the state set to @c State_Complete or @c NULL for other - events. + The response with the state set to @c State_Complete or empty response + object for other events. */ - wxWebResponse* GetResponse() const; + const wxWebResponse& GetResponse() const; /** A textual error description for a client side error @@ -562,8 +629,6 @@ public: */ const wxString& GetResponseFileName() const; - void SetResponseFileName(const wxString& filename); - /** Only for @c wxEVT_WEBREQUEST_DATA events. The buffer is only valid inside the event handler. @@ -573,9 +638,6 @@ public: size_t GetDataSize() const; ///@} - - void SetDataBuffer(const void* buffer, size_t size); - }; wxEventType wxEVT_WEBREQUEST_STATE; diff --git a/samples/webrequest/webrequest.cpp b/samples/webrequest/webrequest.cpp index 4baf5abc62..d2eaabf852 100644 --- a/samples/webrequest/webrequest.cpp +++ b/samples/webrequest/webrequest.cpp @@ -169,8 +169,6 @@ public: m_downloadProgressTimer.Bind(wxEVT_TIMER, &WebRequestFrame::OnProgressTimer, this); - - m_currentRequest = NULL; } void OnStartButton(wxCommandEvent& WXUNUSED(evt)) @@ -178,12 +176,11 @@ public: GetStatusBar()->SetStatusText("Started request..."); // Create request for the specified URL from the default session - wxObjectDataPtr request(wxWebSession::GetDefault().CreateRequest( - m_urlTextCtrl->GetValue())); - m_currentRequest = request.get(); + m_currentRequest = wxWebSession::GetDefault().CreateRequest(this, + m_urlTextCtrl->GetValue()); // Bind event for state change - request->Bind(wxEVT_WEBREQUEST_STATE, &WebRequestFrame::OnWebRequestState, this); + Bind(wxEVT_WEBREQUEST_STATE, &WebRequestFrame::OnWebRequestState, this); // Prepare request based on selected action switch (m_notebook->GetSelection()) @@ -199,12 +196,12 @@ public: // Set postdata if checked if ( m_postCheckBox->IsChecked() ) { - request->SetData(m_postRequestTextCtrl->GetValue(), + m_currentRequest.SetData(m_postRequestTextCtrl->GetValue(), m_postContentTypeTextCtrl->GetValue()); } break; case Page_Download: - request->SetStorage(wxWebRequest::Storage_File); + m_currentRequest.SetStorage(wxWebRequest::Storage_File); m_downloadGauge->SetValue(0); m_downloadGauge->Pulse(); m_downloadStaticText->SetLabel(""); @@ -212,8 +209,8 @@ public: GetStatusBar()->SetStatusText(""); break; case Page_Advanced: - request->SetStorage(wxWebRequest::Storage_None); - request->Bind(wxEVT_WEBREQUEST_DATA, &WebRequestFrame::OnRequestData, this); + m_currentRequest.SetStorage(wxWebRequest::Storage_None); + Bind(wxEVT_WEBREQUEST_DATA, &WebRequestFrame::OnRequestData, this); GetStatusBar()->SetStatusText("Counting..."); m_advCount = 0; @@ -224,13 +221,13 @@ public: m_startButton->Disable(); // Start the request (events will be sent on success or failure) - request->Start(); + m_currentRequest.Start(); } void OnCancelButton(wxCommandEvent& WXUNUSED(evt)) { - if ( m_currentRequest ) - m_currentRequest->Cancel(); + if ( m_currentRequest.IsOk() ) + m_currentRequest.Cancel(); } void OnWebRequestState(wxWebRequestEvent& evt) @@ -240,7 +237,7 @@ public: if ( evt.GetState() != wxWebRequest::State_Active ) { - m_currentRequest = NULL; + m_currentRequest = wxWebRequest(); m_downloadProgressTimer.Stop(); } @@ -251,18 +248,18 @@ public: { case Page_Image: { - wxImage img(*evt.GetResponse()->GetStream()); + wxImage img(*evt.GetResponse().GetStream()); m_imageStaticBitmap->SetBitmap(img); m_notebook->GetPage(Page_Image)->Layout(); - GetStatusBar()->SetStatusText(wxString::Format("Loaded %lld bytes image data", evt.GetResponse()->GetContentLength())); + GetStatusBar()->SetStatusText(wxString::Format("Loaded %lld bytes image data", evt.GetResponse().GetContentLength())); break; } case Page_Text: - m_textResponseTextCtrl->SetValue(evt.GetResponse()->AsString()); + m_textResponseTextCtrl->SetValue(evt.GetResponse().AsString()); GetStatusBar()->SetStatusText(wxString::Format("Loaded %lld bytes text data (Status: %d %s)", - evt.GetResponse()->GetContentLength(), - evt.GetResponse()->GetStatus(), - evt.GetResponse()->GetStatusText())); + evt.GetResponse().GetContentLength(), + evt.GetResponse().GetStatus(), + evt.GetResponse().GetStatusText())); break; case Page_Download: { @@ -273,7 +270,7 @@ public: // Ask the user where to save the file wxFileDialog fileDlg(this, "Save download", "", - evt.GetResponse()->GetSuggestedFileName(), "*.*", + evt.GetResponse().GetSuggestedFileName(), "*.*", wxFD_SAVE | wxFD_OVERWRITE_PROMPT); if ( fileDlg.ShowModal() == wxID_OK ) { @@ -334,14 +331,14 @@ public: void OnProgressTimer(wxTimerEvent& WXUNUSED(evt)) { - if ( !m_currentRequest || m_currentRequest->GetBytesExpectedToReceive() <= 0 ) + if ( !m_currentRequest.IsOk() || m_currentRequest.GetBytesExpectedToReceive() <= 0 ) return; - m_downloadGauge->SetValue((m_currentRequest->GetBytesReceived() * 100) / - m_currentRequest->GetBytesExpectedToReceive()); + m_downloadGauge->SetValue((m_currentRequest.GetBytesReceived() * 100) / + m_currentRequest.GetBytesExpectedToReceive()); m_downloadStaticText->SetLabelText(wxString::Format("%lld/%lld", - m_currentRequest->GetBytesReceived(), m_currentRequest->GetBytesExpectedToReceive())); + m_currentRequest.GetBytesReceived(), m_currentRequest.GetBytesExpectedToReceive())); } void OnPostCheckBox(wxCommandEvent& WXUNUSED(evt)) @@ -382,7 +379,7 @@ private: wxButton* m_startButton; wxButton* m_cancelButton; wxStaticBitmap* m_imageStaticBitmap; - wxWebRequest* m_currentRequest; + wxWebRequest m_currentRequest; wxCheckBox* m_postCheckBox; wxTextCtrl* m_postContentTypeTextCtrl; diff --git a/src/common/webrequest.cpp b/src/common/webrequest.cpp index 3f6b02cdb1..2f82d9d5fa 100644 --- a/src/common/webrequest.cpp +++ b/src/common/webrequest.cpp @@ -54,27 +54,34 @@ extern WXDLLIMPEXP_DATA_NET(const char) wxWebSessionBackendDefault[] = "wxWebSes wxDEFINE_EVENT(wxEVT_WEBREQUEST_STATE, wxWebRequestEvent); wxDEFINE_EVENT(wxEVT_WEBREQUEST_DATA, wxWebRequestEvent); +static const wxStringCharType* wxNO_IMPL_MSG + = wxS("can't be used with an invalid/uninitialized object"); + +#define wxCHECK_IMPL(rc) wxCHECK_MSG( m_impl, (rc), wxNO_IMPL_MSG ) +#define wxCHECK_IMPL_VOID() wxCHECK_RET( m_impl, wxNO_IMPL_MSG ) + // -// wxWebRequest +// wxWebRequestImpl // -wxWebRequest::wxWebRequest(wxWebSession& session, int id) - : m_storage(Storage_Memory), - m_headers(session.m_headers), +wxWebRequestImpl::wxWebRequestImpl(wxWebSession& session, wxEvtHandler* handler, int id) + : m_storage(wxWebRequest::Storage_Memory), + m_headers(session.GetImpl()->GetHeaders()), m_dataSize(0), m_session(session), + m_handler(handler), m_id(id), - m_state(State_Idle), + m_state(wxWebRequest::State_Idle), m_ignoreServerErrorStatus(false), m_bytesReceived(0) { } -bool wxWebRequest::CheckServerStatus() +bool wxWebRequestImpl::CheckServerStatus() { - const wxWebResponse* resp = GetResponse(); + const wxWebResponseImplPtr& resp = GetResponse(); if ( resp && resp->GetStatus() >= 400 && !m_ignoreServerErrorStatus ) { - SetState(State_Failed, wxString::Format(_("Error: %s (%d)"), + SetState(wxWebRequest::State_Failed, wxString::Format(_("Error: %s (%d)"), resp->GetStatusText(), resp->GetStatus())); return false; } @@ -82,18 +89,18 @@ bool wxWebRequest::CheckServerStatus() return true; } -bool wxWebRequest::IsActiveState(State state) +bool wxWebRequestImpl::IsActiveState(wxWebRequest::State state) { - return (state == State_Active || state == State_Unauthorized); + return (state == wxWebRequest::State_Active || state == wxWebRequest::State_Unauthorized); } -void wxWebRequest::SetData(const wxString& text, const wxString& contentType, const wxMBConv& conv) +void wxWebRequestImpl::SetData(const wxString& text, const wxString& contentType, const wxMBConv& conv) { m_dataText = text.mb_str(conv); SetData(wxSharedPtr(new wxMemoryInputStream(m_dataText, m_dataText.length())), contentType); } -bool wxWebRequest::SetData(const wxSharedPtr& dataStream, const wxString& contentType, wxFileOffset dataSize) +bool wxWebRequestImpl::SetData(const wxSharedPtr& dataStream, const wxString& contentType, wxFileOffset dataSize) { if ( !dataStream->IsOk() ) return false; @@ -121,12 +128,12 @@ bool wxWebRequest::SetData(const wxSharedPtr& dataStream, const w return true; } -wxFileOffset wxWebRequest::GetBytesReceived() const +wxFileOffset wxWebRequestImpl::GetBytesReceived() const { return m_bytesReceived; } -wxFileOffset wxWebRequest::GetBytesExpectedToReceive() const +wxFileOffset wxWebRequestImpl::GetBytesExpectedToReceive() const { if ( GetResponse() ) return GetResponse()->GetContentLength(); @@ -134,7 +141,34 @@ wxFileOffset wxWebRequest::GetBytesExpectedToReceive() const return -1; } -void wxWebRequest::SetState(State state, const wxString & failMsg) +namespace +{ + +// Functor used with CallAfter() below. +// +// TODO-C++11: Replace with a lambda. +struct StateEventProcessor +{ + StateEventProcessor(wxWebRequestImpl& request, + wxWebRequest::State state, + const wxString& failMsg) + : m_request(request), m_state(state), m_failMsg(failMsg) + { + } + + void operator()() + { + m_request.ProcessStateEvent(m_state, m_failMsg); + } + + wxWebRequestImpl& m_request; + const wxWebRequest::State m_state; + const wxString m_failMsg; +}; + +} // anonymous namespace + +void wxWebRequestImpl::SetState(wxWebRequest::State state, const wxString & failMsg) { // Add a reference while the request is active if ( IsActiveState(state) && !IsActiveState(m_state) ) @@ -143,10 +177,10 @@ void wxWebRequest::SetState(State state, const wxString & failMsg) m_state = state; // Trigger the event in the main thread - CallAfter(&wxWebRequest::ProcessStateEvent, state, failMsg); + m_handler->CallAfter(StateEventProcessor(*this, state, failMsg)); } -void wxWebRequest::ReportDataReceived(size_t sizeReceived) +void wxWebRequestImpl::ReportDataReceived(size_t sizeReceived) { m_bytesReceived += sizeReceived; } @@ -231,7 +265,7 @@ SplitParameters(const wxString& s, wxWebRequestHeaderMap& parameters) } // namespace wxPrivate -void wxWebRequest::ProcessStateEvent(State state, const wxString& failMsg) +void wxWebRequestImpl::ProcessStateEvent(wxWebRequest::State state, const wxString& failMsg) { if ( !IsActiveState(state) && GetResponse() ) GetResponse()->Finalize(); @@ -239,17 +273,17 @@ void wxWebRequest::ProcessStateEvent(State state, const wxString& failMsg) wxString responseFileName; wxWebRequestEvent evt(wxEVT_WEBREQUEST_STATE, GetId(), state, - GetResponse(), failMsg); - if ( state == State_Completed && m_storage == Storage_File ) + wxWebResponse(GetResponse()), failMsg); + if ( state == wxWebRequest::State_Completed && m_storage == wxWebRequest::Storage_File ) { responseFileName = GetResponse()->GetFileName(); evt.SetResponseFileName(responseFileName); } - ProcessEvent(evt); + m_handler->ProcessEvent(evt); // Remove temporary file if it still exists - if ( state == State_Completed && m_storage == Storage_File && + if ( state == wxWebRequest::State_Completed && m_storage == wxWebRequest::Storage_File && wxFileExists(responseFileName) ) wxRemoveFile(responseFileName); @@ -259,21 +293,224 @@ void wxWebRequest::ProcessStateEvent(State state, const wxString& failMsg) } // -// wxWebResponse +// wxWebRequest // -wxWebResponse::wxWebResponse(wxWebRequest& request) : + +wxWebRequest::wxWebRequest() +{ +} + +wxWebRequest::wxWebRequest(const wxWebRequestImplPtr& impl) + : m_impl(impl) +{ +} + +wxWebRequest::wxWebRequest(const wxWebRequest& other) + : m_impl(other.m_impl) +{ +} + +wxWebRequest& wxWebRequest::operator=(const wxWebRequest& other) +{ + m_impl = other.m_impl; + return *this; +} + +wxWebRequest::~wxWebRequest() +{ +} + +void wxWebRequest::SetHeader(const wxString& name, const wxString& value) +{ + wxCHECK_IMPL_VOID(); + + m_impl->SetHeader(name, value); +} + +void wxWebRequest::SetMethod(const wxString& method) +{ + wxCHECK_IMPL_VOID(); + + m_impl->SetMethod(method); +} + +void wxWebRequest::SetData(const wxString& text, const wxString& contentType, const wxMBConv& conv) +{ + wxCHECK_IMPL_VOID(); + + m_impl->SetData(text, contentType, conv); +} + +bool +wxWebRequest::SetData(const wxSharedPtr& dataStream, + const wxString& contentType, + wxFileOffset dataSize) +{ + wxCHECK_IMPL( false ); + + return m_impl->SetData(dataStream, contentType, dataSize); +} + +void wxWebRequest::SetIgnoreServerErrorStatus(bool ignore) +{ + wxCHECK_IMPL_VOID(); + + m_impl->SetIgnoreServerErrorStatus(ignore); +} + +void wxWebRequest::SetStorage(Storage storage) +{ + wxCHECK_IMPL_VOID(); + + m_impl->SetStorage(storage); +} + +wxWebRequest::Storage wxWebRequest::GetStorage() const +{ + wxCHECK_IMPL( Storage_None ); + + return m_impl->GetStorage(); +} + +void wxWebRequest::Start() +{ + wxCHECK_IMPL_VOID(); + + m_impl->Start(); +} + +void wxWebRequest::Cancel() +{ + wxCHECK_IMPL_VOID(); + + m_impl->Cancel(); +} + +wxWebResponse wxWebRequest::GetResponse() const +{ + wxCHECK_IMPL( wxWebResponse() ); + + return wxWebResponse(m_impl->GetResponse()); +} + +wxWebAuthChallenge wxWebRequest::GetAuthChallenge() const +{ + wxCHECK_IMPL( wxWebAuthChallenge() ); + + return wxWebAuthChallenge(m_impl->GetAuthChallenge()); +} + +int wxWebRequest::GetId() const +{ + wxCHECK_IMPL( wxID_ANY ); + + return m_impl->GetId(); +} + +wxWebSession& wxWebRequest::GetSession() const +{ + wxCHECK_IMPL( wxWebSession::GetDefault() ); + + return m_impl->GetSession(); +} + +wxWebRequest::State wxWebRequest::GetState() const +{ + wxCHECK_IMPL( State_Failed ); + + return m_impl->GetState(); +} + +wxFileOffset wxWebRequest::GetBytesSent() const +{ + wxCHECK_IMPL( wxInvalidOffset ); + + return m_impl->GetBytesSent(); +} + +wxFileOffset wxWebRequest::GetBytesExpectedToSend() const +{ + wxCHECK_IMPL( wxInvalidOffset ); + + return m_impl->GetBytesExpectedToSend(); +} + +wxFileOffset wxWebRequest::GetBytesReceived() const +{ + wxCHECK_IMPL( wxInvalidOffset ); + + return m_impl->GetBytesReceived(); +} + +wxFileOffset wxWebRequest::GetBytesExpectedToReceive() const +{ + wxCHECK_IMPL( wxInvalidOffset ); + + return m_impl->GetBytesExpectedToReceive(); +} + + +// +// wxWebAuthChallenge +// + +wxWebAuthChallenge::wxWebAuthChallenge() +{ +} + +wxWebAuthChallenge::wxWebAuthChallenge(const wxWebAuthChallengeImplPtr& impl) + : m_impl(impl) +{ +} + +wxWebAuthChallenge::wxWebAuthChallenge(const wxWebAuthChallenge& other) + : m_impl(other.m_impl) +{ +} + +wxWebAuthChallenge& wxWebAuthChallenge::operator=(const wxWebAuthChallenge& other) +{ + m_impl = other.m_impl; + return *this; +} + +wxWebAuthChallenge::~wxWebAuthChallenge() +{ +} + +wxWebAuthChallenge::Source wxWebAuthChallenge::GetSource() const +{ + wxCHECK_IMPL( Source_Server ); + + return m_impl->GetSource(); +} + +void +wxWebAuthChallenge::SetCredentials(const wxString& user, + const wxString& password) +{ + wxCHECK_IMPL_VOID(); + + m_impl->SetCredentials(user, password); +} + +// +// wxWebResponseImpl +// + +wxWebResponseImpl::wxWebResponseImpl(wxWebRequestImpl& request) : m_request(request), m_readSize(8 * 1024) { } -wxWebResponse::~wxWebResponse() +wxWebResponseImpl::~wxWebResponseImpl() { if ( wxFileExists(m_file.GetName()) ) wxRemoveFile(m_file.GetName()); } -void wxWebResponse::Init() +void wxWebResponseImpl::Init() { if ( m_request.GetStorage() == wxWebRequest::Storage_File ) { @@ -296,12 +533,12 @@ void wxWebResponse::Init() } } -wxString wxWebResponse::GetMimeType() const +wxString wxWebResponseImpl::GetMimeType() const { return GetHeader("Mime-Type"); } -wxInputStream * wxWebResponse::GetStream() const +wxInputStream * wxWebResponseImpl::GetStream() const { if ( !m_stream.get() ) { @@ -325,7 +562,7 @@ wxInputStream * wxWebResponse::GetStream() const return m_stream.get(); } -wxString wxWebResponse::GetSuggestedFileName() const +wxString wxWebResponseImpl::GetSuggestedFileName() const { wxString suggestedFilename; @@ -355,7 +592,7 @@ wxString wxWebResponse::GetSuggestedFileName() const return suggestedFilename; } -wxString wxWebResponse::AsString() const +wxString wxWebResponseImpl::AsString() const { if ( m_request.GetStorage() == wxWebRequest::Storage_Memory ) { @@ -367,12 +604,12 @@ wxString wxWebResponse::AsString() const return wxString(); } -void* wxWebResponse::GetDataBuffer(size_t sizeNeeded) +void* wxWebResponseImpl::GetDataBuffer(size_t sizeNeeded) { return m_readBuffer.GetAppendBuf(sizeNeeded); } -void wxWebResponse::ReportDataReceived(size_t sizeReceived) +void wxWebResponseImpl::ReportDataReceived(size_t sizeReceived) { m_readBuffer.UngetAppendBuf(sizeReceived); m_request.ReportDataReceived(sizeReceived); @@ -385,26 +622,125 @@ void wxWebResponse::ReportDataReceived(size_t sizeReceived) { wxWebRequestEvent evt(wxEVT_WEBREQUEST_DATA, m_request.GetId(), wxWebRequest::State_Active); evt.SetDataBuffer(m_readBuffer.GetData(), m_readBuffer.GetDataLen()); - m_request.ProcessEvent(evt); + m_request.GetHandler()->ProcessEvent(evt); } if ( m_request.GetStorage() != wxWebRequest::Storage_Memory ) m_readBuffer.Clear(); } -wxString wxWebResponse::GetFileName() const +wxString wxWebResponseImpl::GetFileName() const { return m_file.GetName(); } -void wxWebResponse::Finalize() +void wxWebResponseImpl::Finalize() { if ( m_request.GetStorage() == wxWebRequest::Storage_File ) m_file.Close(); } // -// wxWebSession +// wxWebResponse +// + +wxWebResponse::wxWebResponse() +{ +} + +wxWebResponse::wxWebResponse(const wxWebResponseImplPtr& impl) + : m_impl(impl) +{ +} + +wxWebResponse::wxWebResponse(const wxWebResponse& other) + : m_impl(other.m_impl) +{ +} + +wxWebResponse& wxWebResponse::operator=(const wxWebResponse& other) +{ + m_impl = other.m_impl; + return *this; +} + +wxWebResponse::~wxWebResponse() +{ +} + +wxInt64 wxWebResponse::GetContentLength() const +{ + wxCHECK_IMPL( -1 ); + + return m_impl->GetContentLength(); +} + +wxString wxWebResponse::GetURL() const +{ + wxCHECK_IMPL( wxString() ); + + return m_impl->GetURL(); +} + +wxString wxWebResponse::GetHeader(const wxString& name) const +{ + wxCHECK_IMPL( wxString() ); + + return m_impl->GetHeader(name); +} + +wxString wxWebResponse::GetMimeType() const +{ + wxCHECK_IMPL( wxString() ); + + return m_impl->GetMimeType(); +} + +int wxWebResponse::GetStatus() const +{ + wxCHECK_IMPL( -1 ); + + return m_impl->GetStatus(); +} + +wxString wxWebResponse::GetStatusText() const +{ + wxCHECK_IMPL( wxString() ); + + return m_impl->GetStatusText(); +} + +wxInputStream* wxWebResponse::GetStream() const +{ + wxCHECK_IMPL( NULL ); + + return m_impl->GetStream(); +} + +wxString wxWebResponse::GetSuggestedFileName() const +{ + wxCHECK_IMPL( wxString() ); + + return m_impl->GetSuggestedFileName(); +} + +wxString wxWebResponse::AsString() const +{ + wxCHECK_IMPL( wxString() ); + + return m_impl->AsString(); +} + +wxString wxWebResponse::GetFileName() const +{ + wxCHECK_IMPL( wxString() ); + + return m_impl->GetFileName(); +} + + +// +// wxWebSessionImpl // WX_DECLARE_STRING_HASH_MAP(wxSharedPtr, wxStringWebSessionFactoryMap); @@ -412,12 +748,12 @@ WX_DECLARE_STRING_HASH_MAP(wxSharedPtr, wxStringWebSessionF namespace { -wxScopedPtr gs_defaultSession; +wxWebSession gs_defaultSession; wxStringWebSessionFactoryMap gs_factoryMap; } // anonymous namespace -wxWebSession::wxWebSession() +wxWebSessionImpl::wxWebSessionImpl() { // Initialize the user-Agent header with a reasonable default SetHeader("User-Agent", wxString::Format("%s/1 wxWidgets/%d.%d.%d", @@ -425,7 +761,7 @@ wxWebSession::wxWebSession() wxMAJOR_VERSION, wxMINOR_VERSION, wxRELEASE_NUMBER)); } -wxString wxWebSession::GetTempDir() const +wxString wxWebSessionImpl::GetTempDir() const { if ( m_tempDir.empty() ) return wxStandardPaths::Get().GetTempDir(); @@ -433,26 +769,56 @@ wxString wxWebSession::GetTempDir() const return m_tempDir; } -// static -wxWebSession& wxWebSession::GetDefault() -{ - if ( gs_defaultSession == NULL ) - gs_defaultSession.reset(wxWebSession::New()); +// +// wxWebSession +// - return *gs_defaultSession; +wxWebSession::wxWebSession() +{ +} + +wxWebSession::wxWebSession(const wxWebSessionImplPtr& impl) + : m_impl(impl) +{ +} + +wxWebSession::wxWebSession(const wxWebSession& other) + : m_impl(other.m_impl) +{ +} + +wxWebSession& wxWebSession::operator=(const wxWebSession& other) +{ + m_impl = other.m_impl; + return *this; +} + +wxWebSession::~wxWebSession() +{ } // static -wxWebSession* wxWebSession::New(const wxString& backend) +wxWebSession& wxWebSession::GetDefault() +{ + if ( !gs_defaultSession.IsOpened() ) + gs_defaultSession = wxWebSession::New(); + + return gs_defaultSession; +} + +// static +wxWebSession wxWebSession::New(const wxString& backend) { if ( gs_factoryMap.empty() ) InitFactoryMap(); wxStringWebSessionFactoryMap::iterator factory = gs_factoryMap.find(backend); + + wxWebSessionImplPtr impl; if ( factory != gs_factoryMap.end() ) - return factory->second->Create(); - else - return NULL; + impl = factory->second->Create(); + + return wxWebSession(impl); } // static @@ -490,6 +856,52 @@ bool wxWebSession::IsBackendAvailable(const wxString& backend) return factory != gs_factoryMap.end(); } +wxWebRequest +wxWebSession::CreateRequest(wxEvtHandler* handler, const wxString& url, int id) +{ + wxCHECK_IMPL( wxWebRequest() ); + + return wxWebRequest(m_impl->CreateRequest(*this, handler, url, id)); +} + +wxVersionInfo wxWebSession::GetLibraryVersionInfo() +{ + wxCHECK_IMPL( wxVersionInfo() ); + + return m_impl->GetLibraryVersionInfo(); +} + +void wxWebSession::SetHeader(const wxString& name, const wxString& value) +{ + wxCHECK_IMPL_VOID(); + + m_impl->SetHeader(name, value); +} + +void wxWebSession::SetTempDir(const wxString& dir) +{ + wxCHECK_IMPL_VOID(); + + m_impl->SetTempDir(dir); +} + +wxString wxWebSession::GetTempDir() const +{ + wxCHECK_IMPL( wxString() ); + + return m_impl->GetTempDir(); +} + +bool wxWebSession::IsOpened() const +{ + return m_impl.get() != NULL; +} + +void wxWebSession::Close() +{ + m_impl.reset(NULL); +} + // ---------------------------------------------------------------------------- // Module ensuring all global/singleton objects are destroyed on shutdown. // ---------------------------------------------------------------------------- @@ -509,7 +921,7 @@ public: virtual void OnExit() wxOVERRIDE { gs_factoryMap.clear(); - gs_defaultSession.reset(); + gs_defaultSession.Close(); } private: diff --git a/src/common/webrequest_curl.cpp b/src/common/webrequest_curl.cpp index 68c2cff8b1..98b43c51aa 100644 --- a/src/common/webrequest_curl.cpp +++ b/src/common/webrequest_curl.cpp @@ -55,8 +55,8 @@ static size_t wxCURLHeader(char *buffer, size_t size, size_t nitems, void *userd return 0; } -wxWebResponseCURL::wxWebResponseCURL(wxWebRequest& request) : - wxWebResponse(request) +wxWebResponseCURL::wxWebResponseCURL(wxWebRequestCURL& request) : + wxWebResponseImpl(request) { curl_easy_setopt(GetHandle(), CURLOPT_WRITEDATA, static_cast(this)); curl_easy_setopt(GetHandle(), CURLOPT_HEADERDATA, static_cast(this)); @@ -143,8 +143,13 @@ static size_t wxCURLRead(char *buffer, size_t size, size_t nitems, void *userdat return 0; } -wxWebRequestCURL::wxWebRequestCURL(wxWebSession & session, int id, const wxString & url): - wxWebRequest(session, id) +wxWebRequestCURL::wxWebRequestCURL(wxWebSession & session, + wxWebSessionCURL& sessionImpl, + wxEvtHandler* handler, + const wxString & url, + int id): + wxWebRequestImpl(session, handler, id), + m_sessionImpl(sessionImpl) { m_headerList = NULL; @@ -182,7 +187,7 @@ wxWebRequestCURL::~wxWebRequestCURL() void wxWebRequestCURL::Start() { - if ( GetState() != State_Idle ) + if ( GetState() != wxWebRequest::State_Idle ) return; m_response.reset(new wxWebResponseCURL(*this)); @@ -228,21 +233,21 @@ bool wxWebRequestCURL::StartRequest() { m_bytesSent = 0; - if ( static_cast(GetSession()).StartRequest(*this) ) + if ( m_sessionImpl.StartRequest(*this) ) { - SetState(State_Active); + SetState(wxWebRequest::State_Active); return true; } else { - SetState(State_Failed); + SetState(wxWebRequest::State_Failed); return false; } } void wxWebRequestCURL::Cancel() { - static_cast(GetSession()).CancelRequest(this); + m_sessionImpl.CancelRequest(this); } void wxWebRequestCURL::HandleCompletion() @@ -250,15 +255,15 @@ void wxWebRequestCURL::HandleCompletion() int status = m_response ? m_response->GetStatus() : 0; if ( status == 0) - SetState(State_Failed, GetError()); + SetState(wxWebRequest::State_Failed, GetError()); else if ( status == 401 || status == 407 ) { m_authChallenge.reset(new wxWebAuthChallengeCURL( (status == 407) ? wxWebAuthChallenge::Source_Proxy : wxWebAuthChallenge::Source_Server, *this)); if ( m_authChallenge->Init() ) - SetState(State_Unauthorized, m_response->GetStatusText()); + SetState(wxWebRequest::State_Unauthorized, m_response->GetStatusText()); else - SetState(State_Failed); + SetState(wxWebRequest::State_Failed); } else if ( CheckServerStatus() ) SetState(wxWebRequest::State_Completed); @@ -291,11 +296,6 @@ void wxWebRequestCURL::DestroyHeaderList() } } -wxWebResponse* wxWebRequestCURL::GetResponse() const -{ - return m_response.get(); -} - wxFileOffset wxWebRequestCURL::GetBytesSent() const { return m_bytesSent; @@ -310,8 +310,9 @@ wxFileOffset wxWebRequestCURL::GetBytesExpectedToSend() const // wxWebAuthChallengeCURL // -wxWebAuthChallengeCURL::wxWebAuthChallengeCURL(Source source, wxWebRequestCURL& request) : - wxWebAuthChallenge(source), +wxWebAuthChallengeCURL::wxWebAuthChallengeCURL(wxWebAuthChallenge::Source source, + wxWebRequestCURL& request) : + wxWebAuthChallengeImpl(source), m_request(request) { } @@ -325,7 +326,7 @@ void wxWebAuthChallengeCURL::SetCredentials(const wxString& user, const wxString { wxString authStr = wxString::Format("%s:%s", user, password); curl_easy_setopt(m_request.GetHandle(), - (GetSource() == Source_Proxy) ? CURLOPT_PROXYUSERPWD : CURLOPT_USERPWD, + (GetSource() == wxWebAuthChallenge::Source_Proxy) ? CURLOPT_PROXYUSERPWD : CURLOPT_USERPWD, static_cast(authStr.mb_str())); m_request.StartRequest(); } @@ -373,7 +374,11 @@ wxWebSessionCURL::~wxWebSessionCURL() curl_global_cleanup(); } -wxWebRequest* wxWebSessionCURL::CreateRequest(const wxString& url, int id) +wxWebRequestImplPtr +wxWebSessionCURL::CreateRequest(wxWebSession& session, + wxEvtHandler* handler, + const wxString& url, + int id) { // Allocate our handle on demand. if ( !m_handle ) @@ -382,11 +387,11 @@ wxWebRequest* wxWebSessionCURL::CreateRequest(const wxString& url, int id) if ( !m_handle ) { wxLogDebug("curl_multi_init() failed"); - return NULL; + return wxWebRequestImplPtr(); } } - return new wxWebRequestCURL(*this, id, url); + return wxWebRequestImplPtr(new wxWebRequestCURL(session, *this, handler, url, id)); } static CURLMcode wx_curl_multi_wait(CURLM *multi_handle, int timeout_ms, diff --git a/src/msw/webrequest_winhttp.cpp b/src/msw/webrequest_winhttp.cpp index 86ef8fc003..49504568aa 100644 --- a/src/msw/webrequest_winhttp.cpp +++ b/src/msw/webrequest_winhttp.cpp @@ -141,8 +141,13 @@ static void CALLBACK wxRequestStatusCallback( // wxWebRequestWinHTTP // -wxWebRequestWinHTTP::wxWebRequestWinHTTP(int id, wxWebSessionWinHTTP& session, const wxString& url): - wxWebRequest(session, id), +wxWebRequestWinHTTP::wxWebRequestWinHTTP(wxWebSession& session, + wxWebSessionWinHTTP& sessionWinHTTP, + wxEvtHandler* handler, + const wxString& url, + int id): + wxWebRequestImpl(session, handler, id), + m_sessionWinHTTP(sessionWinHTTP), m_url(url), m_connect(NULL), m_request(NULL), @@ -173,11 +178,11 @@ void wxWebRequestWinHTTP::HandleCallback(DWORD dwInternetStatus, if ( dwStatusInformationLength > 0 ) { if ( !m_response->ReportAvailableData(dwStatusInformationLength) && - GetState() != State_Cancelled ) + GetState() != wxWebRequest::State_Cancelled ) SetFailedWithLastError(); } else - SetState(State_Completed); + SetState(wxWebRequest::State_Completed); break; case WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE: WriteData(); @@ -185,7 +190,7 @@ void wxWebRequestWinHTTP::HandleCallback(DWORD dwInternetStatus, case WINHTTP_CALLBACK_STATUS_REQUEST_ERROR: { LPWINHTTP_ASYNC_RESULT asyncResult = reinterpret_cast(lpvStatusInformation); - SetState(State_Failed, wxWinHTTPErrorToString(asyncResult->dwError)); + SetState(wxWebRequest::State_Failed, wxWinHTTPErrorToString(asyncResult->dwError)); break; } } @@ -217,7 +222,7 @@ void wxWebRequestWinHTTP::CreateResponse() m_response.reset(new wxWebResponseWinHTTP(*this)); // wxWebResponseWinHTTP ctor could have changed the state if its // initialization failed, so check for this. - if ( GetState() == State_Failed ) + if ( GetState() == wxWebRequest::State_Failed ) return; int status = m_response->GetStatus(); @@ -226,7 +231,7 @@ void wxWebRequestWinHTTP::CreateResponse() m_authChallenge.reset(new wxWebAuthChallengeWinHTTP( (status == 407) ? wxWebAuthChallenge::Source_Proxy : wxWebAuthChallenge::Source_Server, *this)); if ( m_authChallenge->Init() ) - SetState(State_Unauthorized, m_response->GetStatusText()); + SetState(wxWebRequest::State_Unauthorized, m_response->GetStatusText()); else SetFailedWithLastError(); } @@ -244,12 +249,12 @@ void wxWebRequestWinHTTP::CreateResponse() void wxWebRequestWinHTTP::SetFailedWithLastError() { wxString failMessage = wxWinHTTPErrorToString(::GetLastError()); - SetState(State_Failed, failMessage); + SetState(wxWebRequest::State_Failed, failMessage); } void wxWebRequestWinHTTP::Start() { - if ( GetState() != State_Idle ) // Completed requests can not be restarted + if ( GetState() != wxWebRequest::State_Idle ) // Completed requests can not be restarted return; // Parse the URL @@ -264,7 +269,7 @@ void wxWebRequestWinHTTP::Start() // Open a connection m_connect = ::WinHttpConnect( - static_cast(GetSession()).GetHandle(), + m_sessionWinHTTP.GetHandle(), uri.GetServer().wc_str(), port, 0); if ( m_connect == NULL ) { @@ -328,7 +333,7 @@ void wxWebRequestWinHTTP::SendRequest() NULL, 0, m_dataSize, (DWORD_PTR)this) ) { - SetState(State_Active); + SetState(wxWebRequest::State_Active); } else SetFailedWithLastError(); @@ -336,7 +341,7 @@ void wxWebRequestWinHTTP::SendRequest() void wxWebRequestWinHTTP::Cancel() { - SetState(State_Cancelled); + SetState(wxWebRequest::State_Cancelled); if ( m_request != NULL ) { ::WinHttpCloseHandle(m_request); @@ -344,17 +349,12 @@ void wxWebRequestWinHTTP::Cancel() } } -wxWebResponse* wxWebRequestWinHTTP::GetResponse() const -{ - return m_response.get(); -} - // // wxWebResponseWinHTTP // wxWebResponseWinHTTP::wxWebResponseWinHTTP(wxWebRequestWinHTTP& request): - wxWebResponse(request), + wxWebResponseImpl(request), m_requestHandle(request.GetHandle()) { wxString contentLengthStr = wxWinHTTPQueryHeaderString(m_requestHandle, @@ -415,8 +415,9 @@ bool wxWebResponseWinHTTP::ReportAvailableData(DWORD dataLen) // // wxWebAuthChallengeWinHTTP // -wxWebAuthChallengeWinHTTP::wxWebAuthChallengeWinHTTP(Source source, wxWebRequestWinHTTP & request): - wxWebAuthChallenge(source), +wxWebAuthChallengeWinHTTP::wxWebAuthChallengeWinHTTP(wxWebAuthChallenge::Source source, + wxWebRequestWinHTTP & request): + wxWebAuthChallengeImpl(source), m_request(request), m_target(0), m_selectedScheme(0) @@ -519,12 +520,17 @@ void wxWebSessionWinHTTP::Init() m_initialized = true; } -wxWebRequest* wxWebSessionWinHTTP::CreateRequest(const wxString& url, int id) +wxWebRequestImplPtr +wxWebSessionWinHTTP::CreateRequest(wxWebSession& session, + wxEvtHandler* handler, + const wxString& url, + int id) { if ( !m_initialized ) Init(); - return new wxWebRequestWinHTTP(id, *this, url); + return wxWebRequestImplPtr( + new wxWebRequestWinHTTP(session, *this, handler, url, id)); } wxVersionInfo wxWebSessionWinHTTP::GetLibraryVersionInfo() diff --git a/src/osx/webrequest_urlsession.mm b/src/osx/webrequest_urlsession.mm index b42b7f858f..9283c67820 100644 --- a/src/osx/webrequest_urlsession.mm +++ b/src/osx/webrequest_urlsession.mm @@ -68,7 +68,7 @@ wxWebRequestURLSession* request = [self requestForTask:dataTask]; if (request) - static_cast(request->GetResponse())->HandleData(data); + request->GetResponseImplPtr()->HandleData(data); } - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error @@ -90,8 +90,13 @@ // // wxWebRequestURLSession // -wxWebRequestURLSession::wxWebRequestURLSession(wxWebSessionURLSession& session, const wxString& url, int id): - wxWebRequest(session, id), +wxWebRequestURLSession::wxWebRequestURLSession(wxWebSession& session, + wxWebSessionURLSession& sessionImpl, + wxEvtHandler* handler, + const wxString& url, + int winid): + wxWebRequestImpl(session, handler, winid), + m_sessionImpl(sessionImpl), m_url(url) { } @@ -103,8 +108,6 @@ wxWebRequestURLSession::~wxWebRequestURLSession() void wxWebRequestURLSession::Start() { - wxWebSessionURLSession& session = static_cast(GetSession()); - NSMutableURLRequest* req = [NSMutableURLRequest requestWithURL: [NSURL URLWithString:wxCFStringRef(m_url).AsNSString()]]; if (m_method.empty()) @@ -127,20 +130,20 @@ void wxWebRequestURLSession::Start() // Create NSData from memory buffer NSData* data = [NSData dataWithBytes:memBuf.GetData() length:m_dataSize]; - m_task = [[session.GetSession() uploadTaskWithRequest:req fromData:data] retain]; + m_task = [[m_sessionImpl.GetSession() uploadTaskWithRequest:req fromData:data] retain]; } else { // Create data task - m_task = [[session.GetSession() dataTaskWithRequest:req] retain]; + m_task = [[m_sessionImpl.GetSession() dataTaskWithRequest:req] retain]; } // The session delegate needs to know which task is wrapped in which request - [session.GetDelegate() registerRequest:this task:m_task]; + [m_sessionImpl.GetDelegate() registerRequest:this task:m_task]; m_response.reset(new wxWebResponseURLSession(*this, m_task)); - SetState(State_Active); + SetState(wxWebRequest::State_Active); [m_task resume]; } @@ -152,13 +155,13 @@ void wxWebRequestURLSession::Cancel() void wxWebRequestURLSession::HandleCompletion() { if ( CheckServerStatus() ) - SetState(State_Completed); + SetState(wxWebRequest::State_Completed); } -wxWebAuthChallenge* wxWebRequestURLSession::GetAuthChallenge() const +wxWebAuthChallengeImplPtr wxWebRequestURLSession::GetAuthChallenge() const { wxFAIL_MSG("not implemented"); - return NULL; + return wxWebAuthChallengeImplPtr(); } wxFileOffset wxWebRequestURLSession::GetBytesSent() const @@ -185,8 +188,9 @@ wxFileOffset wxWebRequestURLSession::GetBytesExpectedToReceive() const // wxWebResponseURLSession // -wxWebResponseURLSession::wxWebResponseURLSession(wxWebRequest& request, WX_NSURLSessionTask task): - wxWebResponse(request) +wxWebResponseURLSession::wxWebResponseURLSession(wxWebRequestURLSession& request, + WX_NSURLSessionTask task): + wxWebResponseImpl(request) { m_task = [task retain]; @@ -260,9 +264,13 @@ wxWebSessionURLSession::~wxWebSessionURLSession() [m_delegate release]; } -wxWebRequest* wxWebSessionURLSession::CreateRequest(const wxString& url, int id) +wxWebRequestImplPtr +wxWebSessionURLSession::CreateRequest(wxWebSession& session, + wxEvtHandler* handler, + const wxString& url, + int winid) { - return new wxWebRequestURLSession(*this, url, id); + return wxWebRequestImplPtr(new wxWebRequestURLSession(session, *this, handler, url, winid)); } wxVersionInfo wxWebSessionURLSession::GetLibraryVersionInfo() diff --git a/tests/net/webrequest.cpp b/tests/net/webrequest.cpp index 6d8d51a178..4bf92ec8b2 100644 --- a/tests/net/webrequest.cpp +++ b/tests/net/webrequest.cpp @@ -33,7 +33,7 @@ // disable running the test entirely. static const char* WX_TEST_WEBREQUEST_URL_DEFAULT = "https://httpbin.org"; -class RequestFixture +class RequestFixture : public wxEvtHandler { public: RequestFixture() @@ -57,9 +57,9 @@ public: void CreateAbs(const wxString& url) { - request.reset(wxWebSession::GetDefault().CreateRequest(url)); - request->Bind(wxEVT_WEBREQUEST_STATE, &RequestFixture::OnRequestState, this); - request->Bind(wxEVT_WEBREQUEST_DATA, &RequestFixture::OnData, this); + request = wxWebSession::GetDefault().CreateRequest(this, url); + Bind(wxEVT_WEBREQUEST_STATE, &RequestFixture::OnRequestState, this); + Bind(wxEVT_WEBREQUEST_DATA, &RequestFixture::OnData, this); } void OnRequestState(wxWebRequestEvent& evt) @@ -68,7 +68,7 @@ public: { case wxWebRequest::State_Unauthorized: case wxWebRequest::State_Completed: - if ( request->GetStorage() == wxWebRequest::Storage_File ) + if ( request.GetStorage() == wxWebRequest::Storage_File ) { wxFileName fn(evt.GetResponseFileName()); REQUIRE( fn.GetSize() == expectedFileSize ); @@ -94,17 +94,17 @@ public: void Run(wxWebRequest::State requiredState = wxWebRequest::State_Completed, int requiredStatus = 200) { - REQUIRE( request->GetState() == wxWebRequest::State_Idle ); - request->Start(); + REQUIRE( request.GetState() == wxWebRequest::State_Idle ); + request.Start(); loop.Run(); - REQUIRE( request->GetState() == requiredState ); + REQUIRE( request.GetState() == requiredState ); if (requiredStatus) - REQUIRE( request->GetResponse()->GetStatus() == requiredStatus ); + REQUIRE( request.GetResponse().GetStatus() == requiredStatus ); } wxString baseURL; wxEventLoop loop; - wxObjectDataPtr request; + wxWebRequest request; wxInt64 expectedFileSize; wxInt64 dataSize; }; @@ -119,9 +119,9 @@ TEST_CASE_METHOD(RequestFixture, "WebRequest", "[net][webrequest]") { Create("/bytes/65536"); Run(); - REQUIRE( request->GetResponse()->GetContentLength() == 65536 ); - REQUIRE( request->GetBytesExpectedToReceive() == 65536 ); - REQUIRE( request->GetBytesReceived() == 65536 ); + REQUIRE( request.GetResponse().GetContentLength() == 65536 ); + REQUIRE( request.GetBytesExpectedToReceive() == 65536 ); + REQUIRE( request.GetBytesReceived() == 65536 ); } SECTION("GET 404 error") @@ -139,7 +139,7 @@ TEST_CASE_METHOD(RequestFixture, "WebRequest", "[net][webrequest]") SECTION("POST form data") { Create("/post"); - request->SetData("app=WebRequestSample&version=1", "application/x-www-form-urlencoded"); + request.SetData("app=WebRequestSample&version=1", "application/x-www-form-urlencoded"); Run(); } @@ -147,25 +147,25 @@ TEST_CASE_METHOD(RequestFixture, "WebRequest", "[net][webrequest]") { Create("/base64/VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZw=="); Run(); - REQUIRE( request->GetResponse()->AsString() == "The quick brown fox jumps over the lazy dog" ); + REQUIRE( request.GetResponse().AsString() == "The quick brown fox jumps over the lazy dog" ); } SECTION("GET 99KB to file") { expectedFileSize = 99 * 1024; Create(wxString::Format("/bytes/%lld", expectedFileSize)); - request->SetStorage(wxWebRequest::Storage_File); + request.SetStorage(wxWebRequest::Storage_File); Run(); - REQUIRE( request->GetBytesReceived() == expectedFileSize ); + REQUIRE( request.GetBytesReceived() == expectedFileSize ); } SECTION("Process 99KB data") { int processingSize = 99 * 1024; Create(wxString::Format("/bytes/%d", processingSize)); - request->SetStorage(wxWebRequest::Storage_None); + request.SetStorage(wxWebRequest::Storage_None); Run(); - REQUIRE( request->GetBytesReceived() == processingSize ); + REQUIRE( request.GetBytesReceived() == processingSize ); REQUIRE( dataSize == processingSize ); } @@ -175,8 +175,8 @@ TEST_CASE_METHOD(RequestFixture, "WebRequest", "[net][webrequest]") wxSharedPtr is(new wxFileInputStream("horse.png")); REQUIRE( is->IsOk() ); - request->SetData(is, "image/png"); - request->SetMethod("PUT"); + request.SetData(is, "image/png"); + request.SetMethod("PUT"); Run(); } @@ -184,25 +184,27 @@ TEST_CASE_METHOD(RequestFixture, "WebRequest", "[net][webrequest]") { Create("/digest-auth/auth/wxtest/wxwidgets"); Run(wxWebRequest::State_Unauthorized, 401); - REQUIRE( request->GetAuthChallenge() != NULL ); - request->GetAuthChallenge()->SetCredentials("wxtest", "wxwidgets"); + REQUIRE( request.GetAuthChallenge().IsOk() ); + request.GetAuthChallenge().SetCredentials("wxtest", "wxwidgets"); loop.Run(); - REQUIRE( request->GetResponse()->GetStatus() == 200 ); - REQUIRE( request->GetState() == wxWebRequest::State_Completed ); + REQUIRE( request.GetResponse().GetStatus() == 200 ); + REQUIRE( request.GetState() == wxWebRequest::State_Completed ); } SECTION("Server auth DIGEST") { Create("/digest-auth/auth/wxtest/wxwidgets"); Run(wxWebRequest::State_Unauthorized, 401); - REQUIRE( request->GetAuthChallenge() != NULL ); - request->GetAuthChallenge()->SetCredentials("wxtest", "wxwidgets"); + REQUIRE( request.GetAuthChallenge().IsOk() ); + request.GetAuthChallenge().SetCredentials("wxtest", "wxwidgets"); loop.Run(); - REQUIRE( request->GetResponse()->GetStatus() == 200 ); - REQUIRE( request->GetState() == wxWebRequest::State_Completed ); + REQUIRE( request.GetResponse().GetStatus() == 200 ); + REQUIRE( request.GetState() == wxWebRequest::State_Completed ); } } +WX_DECLARE_STRING_HASH_MAP(wxString, wxWebRequestHeaderMap); + namespace wxPrivate { WXDLLIMPEXP_NET wxString