Change wxWebRequest and related objects to hide ref counting

Don't force the application code to deal with wxObjectDataPtr<> or,
worse, calling {Inc,Dec}Ref() manually by hiding it inside the wx
objects themselves and giving the value-like semantics to them.

There should be no real changes in the behaviour, but the API does
change significantly. Notably, wxWebRequest is not a wxEvtHandler itself
any longer, as this would be incompatible with the value semantics, and
an event handler needs to be specified when creating it, so that it
could be notified about the request state changes.
This commit is contained in:
Vadim Zeitlin
2020-12-30 01:10:02 +01:00
parent 04bbb844ae
commit 50424cba2c
12 changed files with 1100 additions and 385 deletions

View File

@@ -19,7 +19,7 @@
class wxWebSessionWinHTTP; class wxWebSessionWinHTTP;
class wxWebRequestWinHTTP; class wxWebRequestWinHTTP;
class WXDLLIMPEXP_NET wxWebResponseWinHTTP : public wxWebResponse class wxWebResponseWinHTTP : public wxWebResponseImpl
{ {
public: public:
wxWebResponseWinHTTP(wxWebRequestWinHTTP& request); wxWebResponseWinHTTP(wxWebRequestWinHTTP& request);
@@ -45,10 +45,11 @@ private:
wxDECLARE_NO_COPY_CLASS(wxWebResponseWinHTTP); wxDECLARE_NO_COPY_CLASS(wxWebResponseWinHTTP);
}; };
class WXDLLIMPEXP_NET wxWebAuthChallengeWinHTTP : public wxWebAuthChallenge class wxWebAuthChallengeWinHTTP : public wxWebAuthChallengeImpl
{ {
public: public:
wxWebAuthChallengeWinHTTP(Source source, wxWebRequestWinHTTP& request); wxWebAuthChallengeWinHTTP(wxWebAuthChallenge::Source source,
wxWebRequestWinHTTP& request);
bool Init(); bool Init();
@@ -62,10 +63,14 @@ private:
wxDECLARE_NO_COPY_CLASS(wxWebAuthChallengeWinHTTP); wxDECLARE_NO_COPY_CLASS(wxWebAuthChallengeWinHTTP);
}; };
class WXDLLIMPEXP_NET wxWebRequestWinHTTP : public wxWebRequest class wxWebRequestWinHTTP : public wxWebRequestImpl
{ {
public: public:
wxWebRequestWinHTTP(int id, wxWebSessionWinHTTP& session, const wxString& url); wxWebRequestWinHTTP(wxWebSession& session,
wxWebSessionWinHTTP& sessionWinHTTP,
wxEvtHandler* handler,
const wxString& url,
int id);
~wxWebRequestWinHTTP(); ~wxWebRequestWinHTTP();
@@ -73,9 +78,11 @@ public:
void Cancel() wxOVERRIDE; 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; } wxFileOffset GetBytesSent() const wxOVERRIDE { return m_dataWritten; }
@@ -87,11 +94,12 @@ public:
HINTERNET GetHandle() const { return m_request; } HINTERNET GetHandle() const { return m_request; }
private: private:
wxWebSessionWinHTTP& m_sessionWinHTTP;
wxString m_url; wxString m_url;
HINTERNET m_connect; HINTERNET m_connect;
HINTERNET m_request; HINTERNET m_request;
wxScopedPtr<wxWebResponseWinHTTP> m_response; wxObjectDataPtr<wxWebResponseWinHTTP> m_response;
wxScopedPtr<wxWebAuthChallengeWinHTTP> m_authChallenge; wxObjectDataPtr<wxWebAuthChallengeWinHTTP> m_authChallenge;
wxMemoryBuffer m_dataWriteBuffer; wxMemoryBuffer m_dataWriteBuffer;
wxFileOffset m_dataWritten; wxFileOffset m_dataWritten;
@@ -108,14 +116,18 @@ private:
wxDECLARE_NO_COPY_CLASS(wxWebRequestWinHTTP); wxDECLARE_NO_COPY_CLASS(wxWebRequestWinHTTP);
}; };
class WXDLLIMPEXP_NET wxWebSessionWinHTTP : public wxWebSession class wxWebSessionWinHTTP : public wxWebSessionImpl
{ {
public: public:
wxWebSessionWinHTTP(); wxWebSessionWinHTTP();
~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; wxVersionInfo GetLibraryVersionInfo() wxOVERRIDE;
@@ -130,10 +142,10 @@ private:
wxDECLARE_NO_COPY_CLASS(wxWebSessionWinHTTP); wxDECLARE_NO_COPY_CLASS(wxWebSessionWinHTTP);
}; };
class WXDLLIMPEXP_NET wxWebSessionFactoryWinHTTP : public wxWebSessionFactory class wxWebSessionFactoryWinHTTP : public wxWebSessionFactory
{ {
public: public:
wxWebSession* Create() wxOVERRIDE wxWebSessionImpl* Create() wxOVERRIDE
{ return new wxWebSessionWinHTTP(); } { return new wxWebSessionWinHTTP(); }
}; };

View File

@@ -19,12 +19,13 @@ DECLARE_WXCOCOA_OBJC_CLASS(NSURLSessionTask);
DECLARE_WXCOCOA_OBJC_CLASS(wxWebSessionDelegate); DECLARE_WXCOCOA_OBJC_CLASS(wxWebSessionDelegate);
class wxWebSessionURLSession; class wxWebSessionURLSession;
class wxWebRequestURLSession;
class wxWebResponseURLSession; class wxWebResponseURLSession;
class WXDLLIMPEXP_NET wxWebResponseURLSession : public wxWebResponse class wxWebResponseURLSession : public wxWebResponseImpl
{ {
public: public:
wxWebResponseURLSession(wxWebRequest& request, WX_NSURLSessionTask task); wxWebResponseURLSession(wxWebRequestURLSession& request, WX_NSURLSessionTask task);
~wxWebResponseURLSession(); ~wxWebResponseURLSession();
@@ -44,12 +45,18 @@ public:
private: private:
WX_NSURLSessionTask m_task; WX_NSURLSessionTask m_task;
wxDECLARE_NO_COPY_CLASS(wxWebResponseURLSession);
}; };
class WXDLLIMPEXP_NET wxWebRequestURLSession : public wxWebRequest class wxWebRequestURLSession : public wxWebRequestImpl
{ {
public: public:
wxWebRequestURLSession(wxWebSessionURLSession& session, const wxString& url, int id); wxWebRequestURLSession(wxWebSession& session,
wxWebSessionURLSession& sessionImpl,
wxEvtHandler* handler,
const wxString& url,
int winid);
~wxWebRequestURLSession(); ~wxWebRequestURLSession();
@@ -57,10 +64,10 @@ public:
void Cancel() wxOVERRIDE; void Cancel() wxOVERRIDE;
wxWebResponse* GetResponse() const wxOVERRIDE wxWebResponseImplPtr GetResponse() const wxOVERRIDE
{ return m_response.get(); } { return m_response; }
wxWebAuthChallenge* GetAuthChallenge() const wxOVERRIDE; wxWebAuthChallengeImplPtr GetAuthChallenge() const wxOVERRIDE;
wxFileOffset GetBytesSent() const wxOVERRIDE; wxFileOffset GetBytesSent() const wxOVERRIDE;
@@ -72,22 +79,30 @@ public:
void HandleCompletion(); void HandleCompletion();
wxWebResponseURLSession* GetResponseImplPtr() const
{ return m_response.get(); }
private: private:
wxWebSessionURLSession& m_sessionImpl;
wxString m_url; wxString m_url;
WX_NSURLSessionTask m_task; WX_NSURLSessionTask m_task;
wxScopedPtr<wxWebResponseURLSession> m_response; wxObjectDataPtr<wxWebResponseURLSession> m_response;
wxDECLARE_NO_COPY_CLASS(wxWebRequestURLSession); wxDECLARE_NO_COPY_CLASS(wxWebRequestURLSession);
}; };
class WXDLLIMPEXP_NET wxWebSessionURLSession : public wxWebSession class wxWebSessionURLSession : public wxWebSessionImpl
{ {
public: public:
wxWebSessionURLSession(); wxWebSessionURLSession();
~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; wxVersionInfo GetLibraryVersionInfo() wxOVERRIDE;
@@ -102,10 +117,10 @@ private:
wxDECLARE_NO_COPY_CLASS(wxWebSessionURLSession); wxDECLARE_NO_COPY_CLASS(wxWebSessionURLSession);
}; };
class WXDLLIMPEXP_NET wxWebSessionFactoryURLSession : public wxWebSessionFactory class wxWebSessionFactoryURLSession : public wxWebSessionFactory
{ {
public: public:
wxWebSession* Create() wxOVERRIDE wxWebSessionImpl* Create() wxOVERRIDE
{ return new wxWebSessionURLSession(); } { return new wxWebSessionURLSession(); }
}; };

View File

@@ -10,6 +10,170 @@
#ifndef _WX_PRIVATE_WEBREQUEST_H_ #ifndef _WX_PRIVATE_WEBREQUEST_H_
#define _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<wxInputStream>& 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<wxInputStream> 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<wxInputStream> m_stream;
wxDECLARE_NO_COPY_CLASS(wxWebResponseImpl);
};
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxWebSessionFactory // wxWebSessionFactory
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -17,9 +181,48 @@
class wxWebSessionFactory class wxWebSessionFactory
{ {
public: public:
virtual wxWebSession* Create() = 0; virtual wxWebSessionImpl* Create() = 0;
virtual ~wxWebSessionFactory() { } 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_ #endif // _WX_PRIVATE_WEBREQUEST_H_

View File

@@ -19,13 +19,15 @@
#include "curl/curl.h" #include "curl/curl.h"
class wxWebResponseCURL;
class wxWebRequestCURL; class wxWebRequestCURL;
class wxWebResponseCURL;
class wxWebSessionCURL;
class WXDLLIMPEXP_NET wxWebAuthChallengeCURL : public wxWebAuthChallenge class wxWebAuthChallengeCURL : public wxWebAuthChallengeImpl
{ {
public: public:
wxWebAuthChallengeCURL(Source source, wxWebRequestCURL& request); wxWebAuthChallengeCURL(wxWebAuthChallenge::Source source,
wxWebRequestCURL& request);
bool Init(); bool Init();
@@ -37,10 +39,14 @@ private:
wxDECLARE_NO_COPY_CLASS(wxWebAuthChallengeCURL); wxDECLARE_NO_COPY_CLASS(wxWebAuthChallengeCURL);
}; };
class WXDLLIMPEXP_NET wxWebRequestCURL : public wxWebRequest class wxWebRequestCURL : public wxWebRequestImpl
{ {
public: public:
wxWebRequestCURL(wxWebSession& session, int id, const wxString& url); wxWebRequestCURL(wxWebSession& session,
wxWebSessionCURL& sessionImpl,
wxEvtHandler* handler,
const wxString& url,
int id);
~wxWebRequestCURL(); ~wxWebRequestCURL();
@@ -48,10 +54,11 @@ public:
void Cancel() wxOVERRIDE; void Cancel() wxOVERRIDE;
wxWebResponse* GetResponse() const wxOVERRIDE; wxWebResponseImplPtr GetResponse() const wxOVERRIDE
{ return m_response; }
wxWebAuthChallenge* GetAuthChallenge() const wxOVERRIDE wxWebAuthChallengeImplPtr GetAuthChallenge() const wxOVERRIDE
{ return m_authChallenge.get(); } { return m_authChallenge; }
wxFileOffset GetBytesSent() const wxOVERRIDE; wxFileOffset GetBytesSent() const wxOVERRIDE;
@@ -68,11 +75,13 @@ public:
size_t ReadData(char* buffer, size_t size); size_t ReadData(char* buffer, size_t size);
private: private:
wxWebSessionCURL& m_sessionImpl;
CURL* m_handle; CURL* m_handle;
char m_errorBuffer[CURL_ERROR_SIZE]; char m_errorBuffer[CURL_ERROR_SIZE];
struct curl_slist *m_headerList; struct curl_slist *m_headerList;
wxScopedPtr<wxWebResponseCURL> m_response; wxObjectDataPtr<wxWebResponseCURL> m_response;
wxScopedPtr<wxWebAuthChallengeCURL> m_authChallenge; wxObjectDataPtr<wxWebAuthChallengeCURL> m_authChallenge;
wxFileOffset m_bytesSent; wxFileOffset m_bytesSent;
void DestroyHeaderList(); void DestroyHeaderList();
@@ -80,10 +89,10 @@ private:
wxDECLARE_NO_COPY_CLASS(wxWebRequestCURL); wxDECLARE_NO_COPY_CLASS(wxWebRequestCURL);
}; };
class WXDLLIMPEXP_NET wxWebResponseCURL : public wxWebResponse class wxWebResponseCURL : public wxWebResponseImpl
{ {
public: public:
wxWebResponseCURL(wxWebRequest& request); explicit wxWebResponseCURL(wxWebRequestCURL& request);
wxInt64 GetContentLength() const wxOVERRIDE; wxInt64 GetContentLength() const wxOVERRIDE;
@@ -109,14 +118,18 @@ private:
wxDECLARE_NO_COPY_CLASS(wxWebResponseCURL); wxDECLARE_NO_COPY_CLASS(wxWebResponseCURL);
}; };
class WXDLLIMPEXP_NET wxWebSessionCURL : public wxWebSession, private wxThreadHelper class wxWebSessionCURL : public wxWebSessionImpl, private wxThreadHelper
{ {
public: public:
wxWebSessionCURL(); wxWebSessionCURL();
~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; wxVersionInfo GetLibraryVersionInfo() wxOVERRIDE;
@@ -140,10 +153,10 @@ private:
wxDECLARE_NO_COPY_CLASS(wxWebSessionCURL); wxDECLARE_NO_COPY_CLASS(wxWebSessionCURL);
}; };
class WXDLLIMPEXP_NET wxWebSessionFactoryCURL : public wxWebSessionFactory class wxWebSessionFactoryCURL : public wxWebSessionFactory
{ {
public: public:
wxWebSession* Create() wxOVERRIDE wxWebSessionImpl* Create() wxOVERRIDE
{ return new wxWebSessionCURL(); } { return new wxWebSessionCURL(); }
}; };

View File

@@ -15,23 +15,93 @@
#if wxUSE_WEBREQUEST #if wxUSE_WEBREQUEST
#include "wx/event.h" #include "wx/event.h"
#include "wx/ffile.h"
#include "wx/hashmap.h"
#include "wx/object.h" #include "wx/object.h"
#include "wx/scopedptr.h"
#include "wx/sharedptr.h" #include "wx/sharedptr.h"
#include "wx/stream.h" #include "wx/stream.h"
#include "wx/vector.h"
#include "wx/versioninfo.h" #include "wx/versioninfo.h"
class wxWebResponse; class wxWebResponse;
class wxWebSession; class wxWebSession;
class wxWebSessionFactory; 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<wxWebAuthChallengeImpl> wxWebAuthChallengeImplPtr;
typedef wxObjectDataPtr<wxWebRequestImpl> wxWebRequestImplPtr;
typedef wxObjectDataPtr<wxWebResponseImpl> wxWebResponseImplPtr;
typedef wxObjectDataPtr<wxWebSessionImpl> 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: public:
enum State enum State
@@ -51,149 +121,55 @@ public:
Storage_None Storage_None
}; };
virtual ~wxWebRequest() { } wxWebRequest();
wxWebRequest(const wxWebRequest& other);
wxWebRequest& operator=(const wxWebRequest& other);
~wxWebRequest();
virtual void SetHeader(const wxString& name, const wxString& value) bool IsOk() const { return m_impl.get() != NULL; }
{ m_headers[name] = value; }
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); void SetData(const wxString& text, const wxString& contentType, const wxMBConv& conv = wxConvUTF8);
bool SetData(const wxSharedPtr<wxInputStream>& dataStream, const wxString& contentType, wxFileOffset dataSize = wxInvalidOffset); bool SetData(const wxSharedPtr<wxInputStream>& 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; 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<wxInputStream> m_dataStream;
wxWebRequest(wxWebSession& session, int id);
bool CheckServerStatus();
static bool IsActiveState(State state);
private: private:
wxWebSession& m_session; // Ctor is only used by wxWebSession.
int m_id; friend class wxWebSession;
State m_state; explicit wxWebRequest(const wxWebRequestImplPtr& impl);
bool m_ignoreServerErrorStatus;
wxFileOffset m_bytesReceived;
wxCharBuffer m_dataText;
void ProcessStateEvent(State state, const wxString& failMsg); wxWebRequestImplPtr m_impl;
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<wxInputStream> 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);
}; };
extern WXDLLIMPEXP_DATA_NET(const char) wxWebSessionBackendDefault[]; extern WXDLLIMPEXP_DATA_NET(const char) wxWebSessionBackendDefault[];
@@ -204,45 +180,49 @@ extern WXDLLIMPEXP_DATA_NET(const char) wxWebSessionBackendCURL[];
class WXDLLIMPEXP_NET wxWebSession class WXDLLIMPEXP_NET wxWebSession
{ {
public: 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 // Objects of this class can't be created directly, use the following
// factory functions to get access to them. // factory functions to get access to them.
static wxWebSession& GetDefault(); 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 // Can be used to check if the given backend is available without actually
// creating a session using it. // creating a session using it.
static bool IsBackendAvailable(const wxString& backend); 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; void SetHeader(const wxString& name, const wxString& value);
virtual void SetHeader(const wxString& name, const wxString& value)
{ m_headers[name] = value; }
void SetTempDir(const wxString& dir) { m_tempDir = dir; }
void SetTempDir(const wxString& dir);
wxString GetTempDir() const; wxString GetTempDir() const;
protected: bool IsOpened() const;
wxWebSession();
const wxWebRequestHeaderMap& GetHeaders() const { return m_headers; } void Close();
wxWebSessionImpl* GetImpl() const { return m_impl.get(); }
private: private:
static void RegisterFactory(const wxString& backend, static void RegisterFactory(const wxString& backend,
const wxSharedPtr<wxWebSessionFactory>& factory); const wxSharedPtr<wxWebSessionFactory>& factory);
// Make it a friend to allow accessing our m_headers.
friend class wxWebRequest;
wxWebRequestHeaderMap m_headers;
wxString m_tempDir;
static void InitFactoryMap(); static void InitFactoryMap();
explicit wxWebSession(const wxWebSessionImplPtr& impl);
wxWebSessionImplPtr m_impl;
}; };
class WXDLLIMPEXP_NET wxWebRequestEvent : public wxEvent class WXDLLIMPEXP_NET wxWebRequestEvent : public wxEvent
@@ -251,7 +231,7 @@ public:
wxWebRequestEvent(wxEventType type = wxEVT_NULL, wxWebRequestEvent(wxEventType type = wxEVT_NULL,
int id = wxID_ANY, int id = wxID_ANY,
wxWebRequest::State state = wxWebRequest::State_Idle, wxWebRequest::State state = wxWebRequest::State_Idle,
wxWebResponse* response = NULL, const wxWebResponse& response = wxWebResponse(),
const wxString& errorDesc = wxString()) const wxString& errorDesc = wxString())
: wxEvent(id, type), : wxEvent(id, type),
m_state(state), m_response(response), m_data(NULL), m_dataSize(0), m_state(state), m_response(response), m_data(NULL), m_dataSize(0),
@@ -260,7 +240,7 @@ public:
wxWebRequest::State GetState() const { return m_state; } 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; } const wxString& GetErrorDescription() const { return m_errorDescription; }
@@ -279,7 +259,7 @@ public:
private: private:
wxWebRequest::State m_state; wxWebRequest::State m_state;
wxWebResponse* const m_response; // non-owning, may be NULL const wxWebResponse m_response; // may be invalid
wxString m_responseFileName; wxString m_responseFileName;
const void* m_data; const void* m_data;
size_t m_dataSize; size_t m_dataSize;

View File

@@ -23,21 +23,28 @@
communicate the request status. The response data may be stored in communicate the request status. The response data may be stored in
memory, to a file or processed directly, see SetStorage() for details. 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 @code
// Create the request object // Create the request object
wxObjectDataPtr<wxWebRequest> request( wxWebRequest request = wxWebSession::GetDefault().CreateRequest(
wxWebSession::GetDefault().CreateRequest("https://www.wxwidgets.org/downloads/logos/blocks.png")); this,
"https://www.wxwidgets.org/downloads/logos/blocks.png"
);
if ( !request.IsOk() ) {
// This is not expected, but handle the error somehow.
}
// Bind state event // Bind state event
request->Bind(wxEVT_WEBREQUEST_STATE, [](wxWebRequestEvent& evt) { Bind(wxEVT_WEBREQUEST_STATE, [](wxWebRequestEvent& evt) {
switch (evt.GetState()) switch (evt.GetState())
{ {
// Request completed // Request completed
case wxWebRequest::State_Completed: case wxWebRequest::State_Completed:
{ {
wxImage logoImage(*evt->GetResponse()->GetStream()); wxImage logoImage(*evt.GetResponse().GetStream());
if (logoImage.IsOK()) if (logoImage.IsOK())
wxLogInfo("Image loaded"); wxLogInfo("Image loaded");
break; break;
@@ -51,7 +58,7 @@
}); });
// Start the request // Start the request
request->Start(); request.Start();
@endcode @endcode
@section descriptions Implementation Descriptions @section descriptions Implementation Descriptions
@@ -110,7 +117,7 @@
@see wxWebResponse, wxWebSession @see wxWebResponse, wxWebSession
*/ */
class wxWebRequest: public wxEvtHandler, public wxRefCounter class wxWebRequest
{ {
public: public:
/** /**
@@ -158,6 +165,23 @@ public:
Storage_None 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. Send the request to the server asynchronously.
@@ -176,18 +200,16 @@ public:
Returns a response object after a successful request. Returns a response object after a successful request.
Before sending a request or after a failed request this will return Before sending a request or after a failed request this will return
@c NULL. an invalid response object, i.e. such that wxWebResponse::IsOk()
returns @NULL.
Note that this pointer remains owned by wxWebRequest object and must
not be freed.
*/ */
wxWebResponse* GetResponse() const; wxWebResponse GetResponse() const;
/** /**
Returns the current authentication challenge object while the request Returns the current authentication challenge object while the request
is in @c State_Unauthorized. is in @c State_Unauthorized.
*/ */
wxWebAuthChallenge* GetAuthChallenge() const; wxWebAuthChallenge GetAuthChallenge() const;
/** /**
Returns the id specified while creating this request. Returns the id specified while creating this request.
@@ -377,6 +399,23 @@ public:
class wxWebResponse class wxWebResponse
{ {
public: 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. Returns the final URL.
This URL might be different than the request URL when a redirection This URL might be different than the request URL when a redirection
@@ -428,7 +467,10 @@ public:
/** /**
@class wxWebSession @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. instances.
Usually the default session available via wxWebSession::GetDefault() Usually the default session available via wxWebSession::GetDefault()
@@ -451,14 +493,27 @@ class wxWebSession
{ {
public: 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 @param url
The URL of the HTTP resource for this request The URL of the HTTP resource for this request
@param id @param id
Optional id sent with events 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 Retrieve the version information about the implementation library used
@@ -499,13 +554,15 @@ public:
/** /**
Creates a new wxWebSession object. Creates a new wxWebSession object.
Use IsOpened() to check if the session creation succeeded.
@param backend @param backend
The backend web session implementation to use. The backend web session implementation to use.
@return @return
The created wxWebSession 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. 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. before 10.9 does not have the @c NSURLSession implementation available.
*/ */
static bool IsBackendAvailable(const wxString& backend); 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 class wxWebRequestEvent : public wxEvent
{ {
public: public:
wxWebRequestEvent();
wxWebRequestEvent(wxEventType type, int id, wxWebRequest::State state,
wxWebResponse* response = NULL, const wxString& errorDesc = "");
/** /**
Return the current state of the request Return the current state of the request
*/ */
wxWebRequest::State GetState() const; wxWebRequest::State GetState() const;
/** /**
The response with the state set to @c State_Complete or @c NULL for other The response with the state set to @c State_Complete or empty response
events. object for other events.
*/ */
wxWebResponse* GetResponse() const; const wxWebResponse& GetResponse() const;
/** /**
A textual error description for a client side error A textual error description for a client side error
@@ -562,8 +629,6 @@ public:
*/ */
const wxString& GetResponseFileName() const; const wxString& GetResponseFileName() const;
void SetResponseFileName(const wxString& filename);
/** /**
Only for @c wxEVT_WEBREQUEST_DATA events. The buffer is only valid Only for @c wxEVT_WEBREQUEST_DATA events. The buffer is only valid
inside the event handler. inside the event handler.
@@ -573,9 +638,6 @@ public:
size_t GetDataSize() const; size_t GetDataSize() const;
///@} ///@}
void SetDataBuffer(const void* buffer, size_t size);
}; };
wxEventType wxEVT_WEBREQUEST_STATE; wxEventType wxEVT_WEBREQUEST_STATE;

View File

@@ -169,8 +169,6 @@ public:
m_downloadProgressTimer.Bind(wxEVT_TIMER, m_downloadProgressTimer.Bind(wxEVT_TIMER,
&WebRequestFrame::OnProgressTimer, this); &WebRequestFrame::OnProgressTimer, this);
m_currentRequest = NULL;
} }
void OnStartButton(wxCommandEvent& WXUNUSED(evt)) void OnStartButton(wxCommandEvent& WXUNUSED(evt))
@@ -178,12 +176,11 @@ public:
GetStatusBar()->SetStatusText("Started request..."); GetStatusBar()->SetStatusText("Started request...");
// Create request for the specified URL from the default session // Create request for the specified URL from the default session
wxObjectDataPtr<wxWebRequest> request(wxWebSession::GetDefault().CreateRequest( m_currentRequest = wxWebSession::GetDefault().CreateRequest(this,
m_urlTextCtrl->GetValue())); m_urlTextCtrl->GetValue());
m_currentRequest = request.get();
// Bind event for state change // 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 // Prepare request based on selected action
switch (m_notebook->GetSelection()) switch (m_notebook->GetSelection())
@@ -199,12 +196,12 @@ public:
// Set postdata if checked // Set postdata if checked
if ( m_postCheckBox->IsChecked() ) if ( m_postCheckBox->IsChecked() )
{ {
request->SetData(m_postRequestTextCtrl->GetValue(), m_currentRequest.SetData(m_postRequestTextCtrl->GetValue(),
m_postContentTypeTextCtrl->GetValue()); m_postContentTypeTextCtrl->GetValue());
} }
break; break;
case Page_Download: case Page_Download:
request->SetStorage(wxWebRequest::Storage_File); m_currentRequest.SetStorage(wxWebRequest::Storage_File);
m_downloadGauge->SetValue(0); m_downloadGauge->SetValue(0);
m_downloadGauge->Pulse(); m_downloadGauge->Pulse();
m_downloadStaticText->SetLabel(""); m_downloadStaticText->SetLabel("");
@@ -212,8 +209,8 @@ public:
GetStatusBar()->SetStatusText(""); GetStatusBar()->SetStatusText("");
break; break;
case Page_Advanced: case Page_Advanced:
request->SetStorage(wxWebRequest::Storage_None); m_currentRequest.SetStorage(wxWebRequest::Storage_None);
request->Bind(wxEVT_WEBREQUEST_DATA, &WebRequestFrame::OnRequestData, this); Bind(wxEVT_WEBREQUEST_DATA, &WebRequestFrame::OnRequestData, this);
GetStatusBar()->SetStatusText("Counting..."); GetStatusBar()->SetStatusText("Counting...");
m_advCount = 0; m_advCount = 0;
@@ -224,13 +221,13 @@ public:
m_startButton->Disable(); m_startButton->Disable();
// Start the request (events will be sent on success or failure) // Start the request (events will be sent on success or failure)
request->Start(); m_currentRequest.Start();
} }
void OnCancelButton(wxCommandEvent& WXUNUSED(evt)) void OnCancelButton(wxCommandEvent& WXUNUSED(evt))
{ {
if ( m_currentRequest ) if ( m_currentRequest.IsOk() )
m_currentRequest->Cancel(); m_currentRequest.Cancel();
} }
void OnWebRequestState(wxWebRequestEvent& evt) void OnWebRequestState(wxWebRequestEvent& evt)
@@ -240,7 +237,7 @@ public:
if ( evt.GetState() != wxWebRequest::State_Active ) if ( evt.GetState() != wxWebRequest::State_Active )
{ {
m_currentRequest = NULL; m_currentRequest = wxWebRequest();
m_downloadProgressTimer.Stop(); m_downloadProgressTimer.Stop();
} }
@@ -251,18 +248,18 @@ public:
{ {
case Page_Image: case Page_Image:
{ {
wxImage img(*evt.GetResponse()->GetStream()); wxImage img(*evt.GetResponse().GetStream());
m_imageStaticBitmap->SetBitmap(img); m_imageStaticBitmap->SetBitmap(img);
m_notebook->GetPage(Page_Image)->Layout(); 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; break;
} }
case Page_Text: 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)", GetStatusBar()->SetStatusText(wxString::Format("Loaded %lld bytes text data (Status: %d %s)",
evt.GetResponse()->GetContentLength(), evt.GetResponse().GetContentLength(),
evt.GetResponse()->GetStatus(), evt.GetResponse().GetStatus(),
evt.GetResponse()->GetStatusText())); evt.GetResponse().GetStatusText()));
break; break;
case Page_Download: case Page_Download:
{ {
@@ -273,7 +270,7 @@ public:
// Ask the user where to save the file // Ask the user where to save the file
wxFileDialog fileDlg(this, "Save download", "", wxFileDialog fileDlg(this, "Save download", "",
evt.GetResponse()->GetSuggestedFileName(), "*.*", evt.GetResponse().GetSuggestedFileName(), "*.*",
wxFD_SAVE | wxFD_OVERWRITE_PROMPT); wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
if ( fileDlg.ShowModal() == wxID_OK ) if ( fileDlg.ShowModal() == wxID_OK )
{ {
@@ -334,14 +331,14 @@ public:
void OnProgressTimer(wxTimerEvent& WXUNUSED(evt)) void OnProgressTimer(wxTimerEvent& WXUNUSED(evt))
{ {
if ( !m_currentRequest || m_currentRequest->GetBytesExpectedToReceive() <= 0 ) if ( !m_currentRequest.IsOk() || m_currentRequest.GetBytesExpectedToReceive() <= 0 )
return; return;
m_downloadGauge->SetValue((m_currentRequest->GetBytesReceived() * 100) / m_downloadGauge->SetValue((m_currentRequest.GetBytesReceived() * 100) /
m_currentRequest->GetBytesExpectedToReceive()); m_currentRequest.GetBytesExpectedToReceive());
m_downloadStaticText->SetLabelText(wxString::Format("%lld/%lld", m_downloadStaticText->SetLabelText(wxString::Format("%lld/%lld",
m_currentRequest->GetBytesReceived(), m_currentRequest->GetBytesExpectedToReceive())); m_currentRequest.GetBytesReceived(), m_currentRequest.GetBytesExpectedToReceive()));
} }
void OnPostCheckBox(wxCommandEvent& WXUNUSED(evt)) void OnPostCheckBox(wxCommandEvent& WXUNUSED(evt))
@@ -382,7 +379,7 @@ private:
wxButton* m_startButton; wxButton* m_startButton;
wxButton* m_cancelButton; wxButton* m_cancelButton;
wxStaticBitmap* m_imageStaticBitmap; wxStaticBitmap* m_imageStaticBitmap;
wxWebRequest* m_currentRequest; wxWebRequest m_currentRequest;
wxCheckBox* m_postCheckBox; wxCheckBox* m_postCheckBox;
wxTextCtrl* m_postContentTypeTextCtrl; wxTextCtrl* m_postContentTypeTextCtrl;

View File

@@ -54,27 +54,34 @@ extern WXDLLIMPEXP_DATA_NET(const char) wxWebSessionBackendDefault[] = "wxWebSes
wxDEFINE_EVENT(wxEVT_WEBREQUEST_STATE, wxWebRequestEvent); wxDEFINE_EVENT(wxEVT_WEBREQUEST_STATE, wxWebRequestEvent);
wxDEFINE_EVENT(wxEVT_WEBREQUEST_DATA, 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) wxWebRequestImpl::wxWebRequestImpl(wxWebSession& session, wxEvtHandler* handler, int id)
: m_storage(Storage_Memory), : m_storage(wxWebRequest::Storage_Memory),
m_headers(session.m_headers), m_headers(session.GetImpl()->GetHeaders()),
m_dataSize(0), m_dataSize(0),
m_session(session), m_session(session),
m_handler(handler),
m_id(id), m_id(id),
m_state(State_Idle), m_state(wxWebRequest::State_Idle),
m_ignoreServerErrorStatus(false), m_ignoreServerErrorStatus(false),
m_bytesReceived(0) m_bytesReceived(0)
{ {
} }
bool wxWebRequest::CheckServerStatus() bool wxWebRequestImpl::CheckServerStatus()
{ {
const wxWebResponse* resp = GetResponse(); const wxWebResponseImplPtr& resp = GetResponse();
if ( resp && resp->GetStatus() >= 400 && !m_ignoreServerErrorStatus ) 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())); resp->GetStatusText(), resp->GetStatus()));
return false; return false;
} }
@@ -82,18 +89,18 @@ bool wxWebRequest::CheckServerStatus()
return true; 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); m_dataText = text.mb_str(conv);
SetData(wxSharedPtr<wxInputStream>(new wxMemoryInputStream(m_dataText, m_dataText.length())), contentType); SetData(wxSharedPtr<wxInputStream>(new wxMemoryInputStream(m_dataText, m_dataText.length())), contentType);
} }
bool wxWebRequest::SetData(const wxSharedPtr<wxInputStream>& dataStream, const wxString& contentType, wxFileOffset dataSize) bool wxWebRequestImpl::SetData(const wxSharedPtr<wxInputStream>& dataStream, const wxString& contentType, wxFileOffset dataSize)
{ {
if ( !dataStream->IsOk() ) if ( !dataStream->IsOk() )
return false; return false;
@@ -121,12 +128,12 @@ bool wxWebRequest::SetData(const wxSharedPtr<wxInputStream>& dataStream, const w
return true; return true;
} }
wxFileOffset wxWebRequest::GetBytesReceived() const wxFileOffset wxWebRequestImpl::GetBytesReceived() const
{ {
return m_bytesReceived; return m_bytesReceived;
} }
wxFileOffset wxWebRequest::GetBytesExpectedToReceive() const wxFileOffset wxWebRequestImpl::GetBytesExpectedToReceive() const
{ {
if ( GetResponse() ) if ( GetResponse() )
return GetResponse()->GetContentLength(); return GetResponse()->GetContentLength();
@@ -134,7 +141,34 @@ wxFileOffset wxWebRequest::GetBytesExpectedToReceive() const
return -1; 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 // Add a reference while the request is active
if ( IsActiveState(state) && !IsActiveState(m_state) ) if ( IsActiveState(state) && !IsActiveState(m_state) )
@@ -143,10 +177,10 @@ void wxWebRequest::SetState(State state, const wxString & failMsg)
m_state = state; m_state = state;
// Trigger the event in the main thread // 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; m_bytesReceived += sizeReceived;
} }
@@ -231,7 +265,7 @@ SplitParameters(const wxString& s, wxWebRequestHeaderMap& parameters)
} // namespace wxPrivate } // namespace wxPrivate
void wxWebRequest::ProcessStateEvent(State state, const wxString& failMsg) void wxWebRequestImpl::ProcessStateEvent(wxWebRequest::State state, const wxString& failMsg)
{ {
if ( !IsActiveState(state) && GetResponse() ) if ( !IsActiveState(state) && GetResponse() )
GetResponse()->Finalize(); GetResponse()->Finalize();
@@ -239,17 +273,17 @@ void wxWebRequest::ProcessStateEvent(State state, const wxString& failMsg)
wxString responseFileName; wxString responseFileName;
wxWebRequestEvent evt(wxEVT_WEBREQUEST_STATE, GetId(), state, wxWebRequestEvent evt(wxEVT_WEBREQUEST_STATE, GetId(), state,
GetResponse(), failMsg); wxWebResponse(GetResponse()), failMsg);
if ( state == State_Completed && m_storage == Storage_File ) if ( state == wxWebRequest::State_Completed && m_storage == wxWebRequest::Storage_File )
{ {
responseFileName = GetResponse()->GetFileName(); responseFileName = GetResponse()->GetFileName();
evt.SetResponseFileName(responseFileName); evt.SetResponseFileName(responseFileName);
} }
ProcessEvent(evt); m_handler->ProcessEvent(evt);
// Remove temporary file if it still exists // 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) ) wxFileExists(responseFileName) )
wxRemoveFile(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<wxInputStream>& 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_request(request),
m_readSize(8 * 1024) m_readSize(8 * 1024)
{ {
} }
wxWebResponse::~wxWebResponse() wxWebResponseImpl::~wxWebResponseImpl()
{ {
if ( wxFileExists(m_file.GetName()) ) if ( wxFileExists(m_file.GetName()) )
wxRemoveFile(m_file.GetName()); wxRemoveFile(m_file.GetName());
} }
void wxWebResponse::Init() void wxWebResponseImpl::Init()
{ {
if ( m_request.GetStorage() == wxWebRequest::Storage_File ) 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"); return GetHeader("Mime-Type");
} }
wxInputStream * wxWebResponse::GetStream() const wxInputStream * wxWebResponseImpl::GetStream() const
{ {
if ( !m_stream.get() ) if ( !m_stream.get() )
{ {
@@ -325,7 +562,7 @@ wxInputStream * wxWebResponse::GetStream() const
return m_stream.get(); return m_stream.get();
} }
wxString wxWebResponse::GetSuggestedFileName() const wxString wxWebResponseImpl::GetSuggestedFileName() const
{ {
wxString suggestedFilename; wxString suggestedFilename;
@@ -355,7 +592,7 @@ wxString wxWebResponse::GetSuggestedFileName() const
return suggestedFilename; return suggestedFilename;
} }
wxString wxWebResponse::AsString() const wxString wxWebResponseImpl::AsString() const
{ {
if ( m_request.GetStorage() == wxWebRequest::Storage_Memory ) if ( m_request.GetStorage() == wxWebRequest::Storage_Memory )
{ {
@@ -367,12 +604,12 @@ wxString wxWebResponse::AsString() const
return wxString(); return wxString();
} }
void* wxWebResponse::GetDataBuffer(size_t sizeNeeded) void* wxWebResponseImpl::GetDataBuffer(size_t sizeNeeded)
{ {
return m_readBuffer.GetAppendBuf(sizeNeeded); return m_readBuffer.GetAppendBuf(sizeNeeded);
} }
void wxWebResponse::ReportDataReceived(size_t sizeReceived) void wxWebResponseImpl::ReportDataReceived(size_t sizeReceived)
{ {
m_readBuffer.UngetAppendBuf(sizeReceived); m_readBuffer.UngetAppendBuf(sizeReceived);
m_request.ReportDataReceived(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); wxWebRequestEvent evt(wxEVT_WEBREQUEST_DATA, m_request.GetId(), wxWebRequest::State_Active);
evt.SetDataBuffer(m_readBuffer.GetData(), m_readBuffer.GetDataLen()); evt.SetDataBuffer(m_readBuffer.GetData(), m_readBuffer.GetDataLen());
m_request.ProcessEvent(evt); m_request.GetHandler()->ProcessEvent(evt);
} }
if ( m_request.GetStorage() != wxWebRequest::Storage_Memory ) if ( m_request.GetStorage() != wxWebRequest::Storage_Memory )
m_readBuffer.Clear(); m_readBuffer.Clear();
} }
wxString wxWebResponse::GetFileName() const wxString wxWebResponseImpl::GetFileName() const
{ {
return m_file.GetName(); return m_file.GetName();
} }
void wxWebResponse::Finalize() void wxWebResponseImpl::Finalize()
{ {
if ( m_request.GetStorage() == wxWebRequest::Storage_File ) if ( m_request.GetStorage() == wxWebRequest::Storage_File )
m_file.Close(); 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<wxWebSessionFactory>, wxStringWebSessionFactoryMap); WX_DECLARE_STRING_HASH_MAP(wxSharedPtr<wxWebSessionFactory>, wxStringWebSessionFactoryMap);
@@ -412,12 +748,12 @@ WX_DECLARE_STRING_HASH_MAP(wxSharedPtr<wxWebSessionFactory>, wxStringWebSessionF
namespace namespace
{ {
wxScopedPtr<wxWebSession> gs_defaultSession; wxWebSession gs_defaultSession;
wxStringWebSessionFactoryMap gs_factoryMap; wxStringWebSessionFactoryMap gs_factoryMap;
} // anonymous namespace } // anonymous namespace
wxWebSession::wxWebSession() wxWebSessionImpl::wxWebSessionImpl()
{ {
// Initialize the user-Agent header with a reasonable default // Initialize the user-Agent header with a reasonable default
SetHeader("User-Agent", wxString::Format("%s/1 wxWidgets/%d.%d.%d", SetHeader("User-Agent", wxString::Format("%s/1 wxWidgets/%d.%d.%d",
@@ -425,7 +761,7 @@ wxWebSession::wxWebSession()
wxMAJOR_VERSION, wxMINOR_VERSION, wxRELEASE_NUMBER)); wxMAJOR_VERSION, wxMINOR_VERSION, wxRELEASE_NUMBER));
} }
wxString wxWebSession::GetTempDir() const wxString wxWebSessionImpl::GetTempDir() const
{ {
if ( m_tempDir.empty() ) if ( m_tempDir.empty() )
return wxStandardPaths::Get().GetTempDir(); return wxStandardPaths::Get().GetTempDir();
@@ -433,26 +769,56 @@ wxString wxWebSession::GetTempDir() const
return m_tempDir; return m_tempDir;
} }
// static //
wxWebSession& wxWebSession::GetDefault() // wxWebSession
{ //
if ( gs_defaultSession == NULL )
gs_defaultSession.reset(wxWebSession::New());
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 // 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() ) if ( gs_factoryMap.empty() )
InitFactoryMap(); InitFactoryMap();
wxStringWebSessionFactoryMap::iterator factory = gs_factoryMap.find(backend); wxStringWebSessionFactoryMap::iterator factory = gs_factoryMap.find(backend);
wxWebSessionImplPtr impl;
if ( factory != gs_factoryMap.end() ) if ( factory != gs_factoryMap.end() )
return factory->second->Create(); impl = factory->second->Create();
else
return NULL; return wxWebSession(impl);
} }
// static // static
@@ -490,6 +856,52 @@ bool wxWebSession::IsBackendAvailable(const wxString& backend)
return factory != gs_factoryMap.end(); 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. // Module ensuring all global/singleton objects are destroyed on shutdown.
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -509,7 +921,7 @@ public:
virtual void OnExit() wxOVERRIDE virtual void OnExit() wxOVERRIDE
{ {
gs_factoryMap.clear(); gs_factoryMap.clear();
gs_defaultSession.reset(); gs_defaultSession.Close();
} }
private: private:

View File

@@ -55,8 +55,8 @@ static size_t wxCURLHeader(char *buffer, size_t size, size_t nitems, void *userd
return 0; return 0;
} }
wxWebResponseCURL::wxWebResponseCURL(wxWebRequest& request) : wxWebResponseCURL::wxWebResponseCURL(wxWebRequestCURL& request) :
wxWebResponse(request) wxWebResponseImpl(request)
{ {
curl_easy_setopt(GetHandle(), CURLOPT_WRITEDATA, static_cast<void*>(this)); curl_easy_setopt(GetHandle(), CURLOPT_WRITEDATA, static_cast<void*>(this));
curl_easy_setopt(GetHandle(), CURLOPT_HEADERDATA, static_cast<void*>(this)); curl_easy_setopt(GetHandle(), CURLOPT_HEADERDATA, static_cast<void*>(this));
@@ -143,8 +143,13 @@ static size_t wxCURLRead(char *buffer, size_t size, size_t nitems, void *userdat
return 0; return 0;
} }
wxWebRequestCURL::wxWebRequestCURL(wxWebSession & session, int id, const wxString & url): wxWebRequestCURL::wxWebRequestCURL(wxWebSession & session,
wxWebRequest(session, id) wxWebSessionCURL& sessionImpl,
wxEvtHandler* handler,
const wxString & url,
int id):
wxWebRequestImpl(session, handler, id),
m_sessionImpl(sessionImpl)
{ {
m_headerList = NULL; m_headerList = NULL;
@@ -182,7 +187,7 @@ wxWebRequestCURL::~wxWebRequestCURL()
void wxWebRequestCURL::Start() void wxWebRequestCURL::Start()
{ {
if ( GetState() != State_Idle ) if ( GetState() != wxWebRequest::State_Idle )
return; return;
m_response.reset(new wxWebResponseCURL(*this)); m_response.reset(new wxWebResponseCURL(*this));
@@ -228,21 +233,21 @@ bool wxWebRequestCURL::StartRequest()
{ {
m_bytesSent = 0; m_bytesSent = 0;
if ( static_cast<wxWebSessionCURL&>(GetSession()).StartRequest(*this) ) if ( m_sessionImpl.StartRequest(*this) )
{ {
SetState(State_Active); SetState(wxWebRequest::State_Active);
return true; return true;
} }
else else
{ {
SetState(State_Failed); SetState(wxWebRequest::State_Failed);
return false; return false;
} }
} }
void wxWebRequestCURL::Cancel() void wxWebRequestCURL::Cancel()
{ {
static_cast<wxWebSessionCURL&>(GetSession()).CancelRequest(this); m_sessionImpl.CancelRequest(this);
} }
void wxWebRequestCURL::HandleCompletion() void wxWebRequestCURL::HandleCompletion()
@@ -250,15 +255,15 @@ void wxWebRequestCURL::HandleCompletion()
int status = m_response ? m_response->GetStatus() : 0; int status = m_response ? m_response->GetStatus() : 0;
if ( status == 0) if ( status == 0)
SetState(State_Failed, GetError()); SetState(wxWebRequest::State_Failed, GetError());
else if ( status == 401 || status == 407 ) else if ( status == 401 || status == 407 )
{ {
m_authChallenge.reset(new wxWebAuthChallengeCURL( m_authChallenge.reset(new wxWebAuthChallengeCURL(
(status == 407) ? wxWebAuthChallenge::Source_Proxy : wxWebAuthChallenge::Source_Server, *this)); (status == 407) ? wxWebAuthChallenge::Source_Proxy : wxWebAuthChallenge::Source_Server, *this));
if ( m_authChallenge->Init() ) if ( m_authChallenge->Init() )
SetState(State_Unauthorized, m_response->GetStatusText()); SetState(wxWebRequest::State_Unauthorized, m_response->GetStatusText());
else else
SetState(State_Failed); SetState(wxWebRequest::State_Failed);
} }
else if ( CheckServerStatus() ) else if ( CheckServerStatus() )
SetState(wxWebRequest::State_Completed); SetState(wxWebRequest::State_Completed);
@@ -291,11 +296,6 @@ void wxWebRequestCURL::DestroyHeaderList()
} }
} }
wxWebResponse* wxWebRequestCURL::GetResponse() const
{
return m_response.get();
}
wxFileOffset wxWebRequestCURL::GetBytesSent() const wxFileOffset wxWebRequestCURL::GetBytesSent() const
{ {
return m_bytesSent; return m_bytesSent;
@@ -310,8 +310,9 @@ wxFileOffset wxWebRequestCURL::GetBytesExpectedToSend() const
// wxWebAuthChallengeCURL // wxWebAuthChallengeCURL
// //
wxWebAuthChallengeCURL::wxWebAuthChallengeCURL(Source source, wxWebRequestCURL& request) : wxWebAuthChallengeCURL::wxWebAuthChallengeCURL(wxWebAuthChallenge::Source source,
wxWebAuthChallenge(source), wxWebRequestCURL& request) :
wxWebAuthChallengeImpl(source),
m_request(request) m_request(request)
{ {
} }
@@ -325,7 +326,7 @@ void wxWebAuthChallengeCURL::SetCredentials(const wxString& user, const wxString
{ {
wxString authStr = wxString::Format("%s:%s", user, password); wxString authStr = wxString::Format("%s:%s", user, password);
curl_easy_setopt(m_request.GetHandle(), curl_easy_setopt(m_request.GetHandle(),
(GetSource() == Source_Proxy) ? CURLOPT_PROXYUSERPWD : CURLOPT_USERPWD, (GetSource() == wxWebAuthChallenge::Source_Proxy) ? CURLOPT_PROXYUSERPWD : CURLOPT_USERPWD,
static_cast<const char*>(authStr.mb_str())); static_cast<const char*>(authStr.mb_str()));
m_request.StartRequest(); m_request.StartRequest();
} }
@@ -373,7 +374,11 @@ wxWebSessionCURL::~wxWebSessionCURL()
curl_global_cleanup(); 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. // Allocate our handle on demand.
if ( !m_handle ) if ( !m_handle )
@@ -382,11 +387,11 @@ wxWebRequest* wxWebSessionCURL::CreateRequest(const wxString& url, int id)
if ( !m_handle ) if ( !m_handle )
{ {
wxLogDebug("curl_multi_init() failed"); 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, static CURLMcode wx_curl_multi_wait(CURLM *multi_handle, int timeout_ms,

View File

@@ -141,8 +141,13 @@ static void CALLBACK wxRequestStatusCallback(
// wxWebRequestWinHTTP // wxWebRequestWinHTTP
// //
wxWebRequestWinHTTP::wxWebRequestWinHTTP(int id, wxWebSessionWinHTTP& session, const wxString& url): wxWebRequestWinHTTP::wxWebRequestWinHTTP(wxWebSession& session,
wxWebRequest(session, id), wxWebSessionWinHTTP& sessionWinHTTP,
wxEvtHandler* handler,
const wxString& url,
int id):
wxWebRequestImpl(session, handler, id),
m_sessionWinHTTP(sessionWinHTTP),
m_url(url), m_url(url),
m_connect(NULL), m_connect(NULL),
m_request(NULL), m_request(NULL),
@@ -173,11 +178,11 @@ void wxWebRequestWinHTTP::HandleCallback(DWORD dwInternetStatus,
if ( dwStatusInformationLength > 0 ) if ( dwStatusInformationLength > 0 )
{ {
if ( !m_response->ReportAvailableData(dwStatusInformationLength) && if ( !m_response->ReportAvailableData(dwStatusInformationLength) &&
GetState() != State_Cancelled ) GetState() != wxWebRequest::State_Cancelled )
SetFailedWithLastError(); SetFailedWithLastError();
} }
else else
SetState(State_Completed); SetState(wxWebRequest::State_Completed);
break; break;
case WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE: case WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE:
WriteData(); WriteData();
@@ -185,7 +190,7 @@ void wxWebRequestWinHTTP::HandleCallback(DWORD dwInternetStatus,
case WINHTTP_CALLBACK_STATUS_REQUEST_ERROR: case WINHTTP_CALLBACK_STATUS_REQUEST_ERROR:
{ {
LPWINHTTP_ASYNC_RESULT asyncResult = reinterpret_cast<LPWINHTTP_ASYNC_RESULT>(lpvStatusInformation); LPWINHTTP_ASYNC_RESULT asyncResult = reinterpret_cast<LPWINHTTP_ASYNC_RESULT>(lpvStatusInformation);
SetState(State_Failed, wxWinHTTPErrorToString(asyncResult->dwError)); SetState(wxWebRequest::State_Failed, wxWinHTTPErrorToString(asyncResult->dwError));
break; break;
} }
} }
@@ -217,7 +222,7 @@ void wxWebRequestWinHTTP::CreateResponse()
m_response.reset(new wxWebResponseWinHTTP(*this)); m_response.reset(new wxWebResponseWinHTTP(*this));
// wxWebResponseWinHTTP ctor could have changed the state if its // wxWebResponseWinHTTP ctor could have changed the state if its
// initialization failed, so check for this. // initialization failed, so check for this.
if ( GetState() == State_Failed ) if ( GetState() == wxWebRequest::State_Failed )
return; return;
int status = m_response->GetStatus(); int status = m_response->GetStatus();
@@ -226,7 +231,7 @@ void wxWebRequestWinHTTP::CreateResponse()
m_authChallenge.reset(new wxWebAuthChallengeWinHTTP( m_authChallenge.reset(new wxWebAuthChallengeWinHTTP(
(status == 407) ? wxWebAuthChallenge::Source_Proxy : wxWebAuthChallenge::Source_Server, *this)); (status == 407) ? wxWebAuthChallenge::Source_Proxy : wxWebAuthChallenge::Source_Server, *this));
if ( m_authChallenge->Init() ) if ( m_authChallenge->Init() )
SetState(State_Unauthorized, m_response->GetStatusText()); SetState(wxWebRequest::State_Unauthorized, m_response->GetStatusText());
else else
SetFailedWithLastError(); SetFailedWithLastError();
} }
@@ -244,12 +249,12 @@ void wxWebRequestWinHTTP::CreateResponse()
void wxWebRequestWinHTTP::SetFailedWithLastError() void wxWebRequestWinHTTP::SetFailedWithLastError()
{ {
wxString failMessage = wxWinHTTPErrorToString(::GetLastError()); wxString failMessage = wxWinHTTPErrorToString(::GetLastError());
SetState(State_Failed, failMessage); SetState(wxWebRequest::State_Failed, failMessage);
} }
void wxWebRequestWinHTTP::Start() 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; return;
// Parse the URL // Parse the URL
@@ -264,7 +269,7 @@ void wxWebRequestWinHTTP::Start()
// Open a connection // Open a connection
m_connect = ::WinHttpConnect( m_connect = ::WinHttpConnect(
static_cast<wxWebSessionWinHTTP&>(GetSession()).GetHandle(), m_sessionWinHTTP.GetHandle(),
uri.GetServer().wc_str(), port, 0); uri.GetServer().wc_str(), port, 0);
if ( m_connect == NULL ) if ( m_connect == NULL )
{ {
@@ -328,7 +333,7 @@ void wxWebRequestWinHTTP::SendRequest()
NULL, 0, m_dataSize, NULL, 0, m_dataSize,
(DWORD_PTR)this) ) (DWORD_PTR)this) )
{ {
SetState(State_Active); SetState(wxWebRequest::State_Active);
} }
else else
SetFailedWithLastError(); SetFailedWithLastError();
@@ -336,7 +341,7 @@ void wxWebRequestWinHTTP::SendRequest()
void wxWebRequestWinHTTP::Cancel() void wxWebRequestWinHTTP::Cancel()
{ {
SetState(State_Cancelled); SetState(wxWebRequest::State_Cancelled);
if ( m_request != NULL ) if ( m_request != NULL )
{ {
::WinHttpCloseHandle(m_request); ::WinHttpCloseHandle(m_request);
@@ -344,17 +349,12 @@ void wxWebRequestWinHTTP::Cancel()
} }
} }
wxWebResponse* wxWebRequestWinHTTP::GetResponse() const
{
return m_response.get();
}
// //
// wxWebResponseWinHTTP // wxWebResponseWinHTTP
// //
wxWebResponseWinHTTP::wxWebResponseWinHTTP(wxWebRequestWinHTTP& request): wxWebResponseWinHTTP::wxWebResponseWinHTTP(wxWebRequestWinHTTP& request):
wxWebResponse(request), wxWebResponseImpl(request),
m_requestHandle(request.GetHandle()) m_requestHandle(request.GetHandle())
{ {
wxString contentLengthStr = wxWinHTTPQueryHeaderString(m_requestHandle, wxString contentLengthStr = wxWinHTTPQueryHeaderString(m_requestHandle,
@@ -415,8 +415,9 @@ bool wxWebResponseWinHTTP::ReportAvailableData(DWORD dataLen)
// //
// wxWebAuthChallengeWinHTTP // wxWebAuthChallengeWinHTTP
// //
wxWebAuthChallengeWinHTTP::wxWebAuthChallengeWinHTTP(Source source, wxWebRequestWinHTTP & request): wxWebAuthChallengeWinHTTP::wxWebAuthChallengeWinHTTP(wxWebAuthChallenge::Source source,
wxWebAuthChallenge(source), wxWebRequestWinHTTP & request):
wxWebAuthChallengeImpl(source),
m_request(request), m_request(request),
m_target(0), m_target(0),
m_selectedScheme(0) m_selectedScheme(0)
@@ -519,12 +520,17 @@ void wxWebSessionWinHTTP::Init()
m_initialized = true; 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 ) if ( !m_initialized )
Init(); Init();
return new wxWebRequestWinHTTP(id, *this, url); return wxWebRequestImplPtr(
new wxWebRequestWinHTTP(session, *this, handler, url, id));
} }
wxVersionInfo wxWebSessionWinHTTP::GetLibraryVersionInfo() wxVersionInfo wxWebSessionWinHTTP::GetLibraryVersionInfo()

View File

@@ -68,7 +68,7 @@
wxWebRequestURLSession* request = [self requestForTask:dataTask]; wxWebRequestURLSession* request = [self requestForTask:dataTask];
if (request) if (request)
static_cast<wxWebResponseURLSession*>(request->GetResponse())->HandleData(data); request->GetResponseImplPtr()->HandleData(data);
} }
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
@@ -90,8 +90,13 @@
// //
// wxWebRequestURLSession // wxWebRequestURLSession
// //
wxWebRequestURLSession::wxWebRequestURLSession(wxWebSessionURLSession& session, const wxString& url, int id): wxWebRequestURLSession::wxWebRequestURLSession(wxWebSession& session,
wxWebRequest(session, id), wxWebSessionURLSession& sessionImpl,
wxEvtHandler* handler,
const wxString& url,
int winid):
wxWebRequestImpl(session, handler, winid),
m_sessionImpl(sessionImpl),
m_url(url) m_url(url)
{ {
} }
@@ -103,8 +108,6 @@ wxWebRequestURLSession::~wxWebRequestURLSession()
void wxWebRequestURLSession::Start() void wxWebRequestURLSession::Start()
{ {
wxWebSessionURLSession& session = static_cast<wxWebSessionURLSession&>(GetSession());
NSMutableURLRequest* req = [NSMutableURLRequest requestWithURL: NSMutableURLRequest* req = [NSMutableURLRequest requestWithURL:
[NSURL URLWithString:wxCFStringRef(m_url).AsNSString()]]; [NSURL URLWithString:wxCFStringRef(m_url).AsNSString()]];
if (m_method.empty()) if (m_method.empty())
@@ -127,20 +130,20 @@ void wxWebRequestURLSession::Start()
// Create NSData from memory buffer // Create NSData from memory buffer
NSData* data = [NSData dataWithBytes:memBuf.GetData() length:m_dataSize]; 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 else
{ {
// Create data task // 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 // 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)); m_response.reset(new wxWebResponseURLSession(*this, m_task));
SetState(State_Active); SetState(wxWebRequest::State_Active);
[m_task resume]; [m_task resume];
} }
@@ -152,13 +155,13 @@ void wxWebRequestURLSession::Cancel()
void wxWebRequestURLSession::HandleCompletion() void wxWebRequestURLSession::HandleCompletion()
{ {
if ( CheckServerStatus() ) if ( CheckServerStatus() )
SetState(State_Completed); SetState(wxWebRequest::State_Completed);
} }
wxWebAuthChallenge* wxWebRequestURLSession::GetAuthChallenge() const wxWebAuthChallengeImplPtr wxWebRequestURLSession::GetAuthChallenge() const
{ {
wxFAIL_MSG("not implemented"); wxFAIL_MSG("not implemented");
return NULL; return wxWebAuthChallengeImplPtr();
} }
wxFileOffset wxWebRequestURLSession::GetBytesSent() const wxFileOffset wxWebRequestURLSession::GetBytesSent() const
@@ -185,8 +188,9 @@ wxFileOffset wxWebRequestURLSession::GetBytesExpectedToReceive() const
// wxWebResponseURLSession // wxWebResponseURLSession
// //
wxWebResponseURLSession::wxWebResponseURLSession(wxWebRequest& request, WX_NSURLSessionTask task): wxWebResponseURLSession::wxWebResponseURLSession(wxWebRequestURLSession& request,
wxWebResponse(request) WX_NSURLSessionTask task):
wxWebResponseImpl(request)
{ {
m_task = [task retain]; m_task = [task retain];
@@ -260,9 +264,13 @@ wxWebSessionURLSession::~wxWebSessionURLSession()
[m_delegate release]; [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() wxVersionInfo wxWebSessionURLSession::GetLibraryVersionInfo()

View File

@@ -33,7 +33,7 @@
// disable running the test entirely. // disable running the test entirely.
static const char* WX_TEST_WEBREQUEST_URL_DEFAULT = "https://httpbin.org"; static const char* WX_TEST_WEBREQUEST_URL_DEFAULT = "https://httpbin.org";
class RequestFixture class RequestFixture : public wxEvtHandler
{ {
public: public:
RequestFixture() RequestFixture()
@@ -57,9 +57,9 @@ public:
void CreateAbs(const wxString& url) void CreateAbs(const wxString& url)
{ {
request.reset(wxWebSession::GetDefault().CreateRequest(url)); request = wxWebSession::GetDefault().CreateRequest(this, url);
request->Bind(wxEVT_WEBREQUEST_STATE, &RequestFixture::OnRequestState, this); Bind(wxEVT_WEBREQUEST_STATE, &RequestFixture::OnRequestState, this);
request->Bind(wxEVT_WEBREQUEST_DATA, &RequestFixture::OnData, this); Bind(wxEVT_WEBREQUEST_DATA, &RequestFixture::OnData, this);
} }
void OnRequestState(wxWebRequestEvent& evt) void OnRequestState(wxWebRequestEvent& evt)
@@ -68,7 +68,7 @@ public:
{ {
case wxWebRequest::State_Unauthorized: case wxWebRequest::State_Unauthorized:
case wxWebRequest::State_Completed: case wxWebRequest::State_Completed:
if ( request->GetStorage() == wxWebRequest::Storage_File ) if ( request.GetStorage() == wxWebRequest::Storage_File )
{ {
wxFileName fn(evt.GetResponseFileName()); wxFileName fn(evt.GetResponseFileName());
REQUIRE( fn.GetSize() == expectedFileSize ); REQUIRE( fn.GetSize() == expectedFileSize );
@@ -94,17 +94,17 @@ public:
void Run(wxWebRequest::State requiredState = wxWebRequest::State_Completed, void Run(wxWebRequest::State requiredState = wxWebRequest::State_Completed,
int requiredStatus = 200) int requiredStatus = 200)
{ {
REQUIRE( request->GetState() == wxWebRequest::State_Idle ); REQUIRE( request.GetState() == wxWebRequest::State_Idle );
request->Start(); request.Start();
loop.Run(); loop.Run();
REQUIRE( request->GetState() == requiredState ); REQUIRE( request.GetState() == requiredState );
if (requiredStatus) if (requiredStatus)
REQUIRE( request->GetResponse()->GetStatus() == requiredStatus ); REQUIRE( request.GetResponse().GetStatus() == requiredStatus );
} }
wxString baseURL; wxString baseURL;
wxEventLoop loop; wxEventLoop loop;
wxObjectDataPtr<wxWebRequest> request; wxWebRequest request;
wxInt64 expectedFileSize; wxInt64 expectedFileSize;
wxInt64 dataSize; wxInt64 dataSize;
}; };
@@ -119,9 +119,9 @@ TEST_CASE_METHOD(RequestFixture, "WebRequest", "[net][webrequest]")
{ {
Create("/bytes/65536"); Create("/bytes/65536");
Run(); Run();
REQUIRE( request->GetResponse()->GetContentLength() == 65536 ); REQUIRE( request.GetResponse().GetContentLength() == 65536 );
REQUIRE( request->GetBytesExpectedToReceive() == 65536 ); REQUIRE( request.GetBytesExpectedToReceive() == 65536 );
REQUIRE( request->GetBytesReceived() == 65536 ); REQUIRE( request.GetBytesReceived() == 65536 );
} }
SECTION("GET 404 error") SECTION("GET 404 error")
@@ -139,7 +139,7 @@ TEST_CASE_METHOD(RequestFixture, "WebRequest", "[net][webrequest]")
SECTION("POST form data") SECTION("POST form data")
{ {
Create("/post"); 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(); Run();
} }
@@ -147,25 +147,25 @@ TEST_CASE_METHOD(RequestFixture, "WebRequest", "[net][webrequest]")
{ {
Create("/base64/VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZw=="); Create("/base64/VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZw==");
Run(); 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") SECTION("GET 99KB to file")
{ {
expectedFileSize = 99 * 1024; expectedFileSize = 99 * 1024;
Create(wxString::Format("/bytes/%lld", expectedFileSize)); Create(wxString::Format("/bytes/%lld", expectedFileSize));
request->SetStorage(wxWebRequest::Storage_File); request.SetStorage(wxWebRequest::Storage_File);
Run(); Run();
REQUIRE( request->GetBytesReceived() == expectedFileSize ); REQUIRE( request.GetBytesReceived() == expectedFileSize );
} }
SECTION("Process 99KB data") SECTION("Process 99KB data")
{ {
int processingSize = 99 * 1024; int processingSize = 99 * 1024;
Create(wxString::Format("/bytes/%d", processingSize)); Create(wxString::Format("/bytes/%d", processingSize));
request->SetStorage(wxWebRequest::Storage_None); request.SetStorage(wxWebRequest::Storage_None);
Run(); Run();
REQUIRE( request->GetBytesReceived() == processingSize ); REQUIRE( request.GetBytesReceived() == processingSize );
REQUIRE( dataSize == processingSize ); REQUIRE( dataSize == processingSize );
} }
@@ -175,8 +175,8 @@ TEST_CASE_METHOD(RequestFixture, "WebRequest", "[net][webrequest]")
wxSharedPtr<wxInputStream> is(new wxFileInputStream("horse.png")); wxSharedPtr<wxInputStream> is(new wxFileInputStream("horse.png"));
REQUIRE( is->IsOk() ); REQUIRE( is->IsOk() );
request->SetData(is, "image/png"); request.SetData(is, "image/png");
request->SetMethod("PUT"); request.SetMethod("PUT");
Run(); Run();
} }
@@ -184,25 +184,27 @@ TEST_CASE_METHOD(RequestFixture, "WebRequest", "[net][webrequest]")
{ {
Create("/digest-auth/auth/wxtest/wxwidgets"); Create("/digest-auth/auth/wxtest/wxwidgets");
Run(wxWebRequest::State_Unauthorized, 401); Run(wxWebRequest::State_Unauthorized, 401);
REQUIRE( request->GetAuthChallenge() != NULL ); REQUIRE( request.GetAuthChallenge().IsOk() );
request->GetAuthChallenge()->SetCredentials("wxtest", "wxwidgets"); request.GetAuthChallenge().SetCredentials("wxtest", "wxwidgets");
loop.Run(); loop.Run();
REQUIRE( request->GetResponse()->GetStatus() == 200 ); REQUIRE( request.GetResponse().GetStatus() == 200 );
REQUIRE( request->GetState() == wxWebRequest::State_Completed ); REQUIRE( request.GetState() == wxWebRequest::State_Completed );
} }
SECTION("Server auth DIGEST") SECTION("Server auth DIGEST")
{ {
Create("/digest-auth/auth/wxtest/wxwidgets"); Create("/digest-auth/auth/wxtest/wxwidgets");
Run(wxWebRequest::State_Unauthorized, 401); Run(wxWebRequest::State_Unauthorized, 401);
REQUIRE( request->GetAuthChallenge() != NULL ); REQUIRE( request.GetAuthChallenge().IsOk() );
request->GetAuthChallenge()->SetCredentials("wxtest", "wxwidgets"); request.GetAuthChallenge().SetCredentials("wxtest", "wxwidgets");
loop.Run(); loop.Run();
REQUIRE( request->GetResponse()->GetStatus() == 200 ); REQUIRE( request.GetResponse().GetStatus() == 200 );
REQUIRE( request->GetState() == wxWebRequest::State_Completed ); REQUIRE( request.GetState() == wxWebRequest::State_Completed );
} }
} }
WX_DECLARE_STRING_HASH_MAP(wxString, wxWebRequestHeaderMap);
namespace wxPrivate namespace wxPrivate
{ {
WXDLLIMPEXP_NET wxString WXDLLIMPEXP_NET wxString