diff --git a/include/wx/msw/private/webrequest_winhttp.h b/include/wx/msw/private/webrequest_winhttp.h index a722289822..3851e7f209 100644 --- a/include/wx/msw/private/webrequest_winhttp.h +++ b/include/wx/msw/private/webrequest_winhttp.h @@ -93,6 +93,11 @@ public: HINTERNET GetHandle() const { return m_request; } + wxWebRequestHandle GetNativeHandle() const wxOVERRIDE + { + return (wxWebRequestHandle)GetHandle(); + } + private: wxWebSessionWinHTTP& m_sessionImpl; wxString m_url; @@ -137,6 +142,11 @@ public: HINTERNET GetHandle() const { return m_handle; } + wxWebSessionHandle GetNativeHandle() const wxOVERRIDE + { + return (wxWebSessionHandle)GetHandle(); + } + private: HINTERNET m_handle; diff --git a/include/wx/osx/private/webrequest_urlsession.h b/include/wx/osx/private/webrequest_urlsession.h index 4ecf0a6abf..68a1210c9a 100644 --- a/include/wx/osx/private/webrequest_urlsession.h +++ b/include/wx/osx/private/webrequest_urlsession.h @@ -102,6 +102,11 @@ public: wxFileOffset GetBytesExpectedToReceive() const wxOVERRIDE; + wxWebRequestHandle GetNativeHandle() const wxOVERRIDE + { + return (wxWebRequestHandle)m_task; + } + void HandleCompletion(); void HandleChallenge(wxWebAuthChallengeURLSession* challenge); @@ -139,6 +144,11 @@ public: wxVersionInfo GetLibraryVersionInfo() wxOVERRIDE; + wxWebSessionHandle GetNativeHandle() const wxOVERRIDE + { + return (wxWebSessionHandle)m_session; + } + WX_NSURLSession GetSession() { return m_session; } WX_wxWebSessionDelegate GetDelegate() { return m_delegate; } diff --git a/include/wx/private/webrequest.h b/include/wx/private/webrequest.h index ab58725167..95588feba3 100644 --- a/include/wx/private/webrequest.h +++ b/include/wx/private/webrequest.h @@ -92,6 +92,8 @@ public: virtual wxFileOffset GetBytesExpectedToReceive() const; + virtual wxWebRequestHandle GetNativeHandle() const = 0; + void SetState(wxWebRequest::State state, const wxString& failMsg = wxString()); void ReportDataReceived(size_t sizeReceived); @@ -222,6 +224,8 @@ public: const wxWebRequestHeaderMap& GetHeaders() const { return m_headers; } + virtual wxWebSessionHandle GetNativeHandle() const = 0; + protected: wxWebSessionImpl(); diff --git a/include/wx/private/webrequest_curl.h b/include/wx/private/webrequest_curl.h index ac3e53634b..5229db7bc2 100644 --- a/include/wx/private/webrequest_curl.h +++ b/include/wx/private/webrequest_curl.h @@ -64,6 +64,11 @@ public: CURL* GetHandle() const { return m_handle; } + wxWebRequestHandle GetNativeHandle() const wxOVERRIDE + { + return (wxWebRequestHandle)GetHandle(); + } + bool StartRequest(); void HandleCompletion(); @@ -133,6 +138,11 @@ public: wxVersionInfo GetLibraryVersionInfo() wxOVERRIDE; + wxWebSessionHandle GetNativeHandle() const wxOVERRIDE + { + return (wxWebSessionHandle)m_handle; + } + bool StartRequest(wxWebRequestCURL& request); void CancelRequest(wxWebRequestCURL* request); diff --git a/include/wx/webrequest.h b/include/wx/webrequest.h index ac69374a21..be4cec2a15 100644 --- a/include/wx/webrequest.h +++ b/include/wx/webrequest.h @@ -45,6 +45,9 @@ class wxWebResponse; class wxWebSession; class wxWebSessionFactory; +typedef struct wxWebRequestHandleOpaque* wxWebRequestHandle; +typedef struct wxWebSessionHandleOpaque* wxWebSessionHandle; + class wxWebAuthChallengeImpl; class wxWebRequestImpl; class wxWebResponseImpl; @@ -183,6 +186,8 @@ public: wxFileOffset GetBytesExpectedToReceive() const; + wxWebRequestHandle GetNativeHandle() const; + private: // Ctor is only used by wxWebSession. friend class wxWebSession; @@ -230,6 +235,8 @@ public: void Close(); + wxWebSessionHandle GetNativeHandle() const; + private: static void RegisterFactory(const wxString& backend, wxWebSessionFactory* factory); diff --git a/interface/wx/webrequest.h b/interface/wx/webrequest.h index 11e592eebc..10c4ef2e16 100644 --- a/interface/wx/webrequest.h +++ b/interface/wx/webrequest.h @@ -207,10 +207,25 @@ public: /** Check if the object is valid. - No other methods can be used if this function returns @false. + If the object is invalid, it must be assigned a valid request before + any other methods can be used (with the exception of GetNativeHandle()). */ bool IsOk() const; + /** + Return the native handle corresponding to this request object. + + @c wxWebRequestHandle is an opaque type containing a value of the + following type according to the backend being used: + + - For WinHTTP backend, this is @c HINTERNET request handle. + - For CURL backend, this is a @c CURL struct pointer. + - For macOS backend, this is @c NSURLSessionTask object pointer. + + @see wxWebSession::GetNativeHandle() + */ + wxWebRequestHandle GetNativeHandle() const; + /** Send the request to the server asynchronously. @@ -692,6 +707,20 @@ public: */ static bool IsBackendAvailable(const wxString& backend); + /** + Return the native handle corresponding to this session object. + + @c wxWebSessionHandle is an opaque type containing a value of the + following type according to the backend being used: + + - For WinHTTP backend, this is @c HINTERNET session handle. + - For CURL backend, this is a @c CURLM struct pointer. + - For macOS backend, this is @c NSURLSession object pointer. + + @see wxWebRequest::GetNativeHandle() + */ + wxWebSessionHandle GetNativeHandle() const; + /** Return true if the session was successfully opened and can be used. */ diff --git a/src/common/webrequest.cpp b/src/common/webrequest.cpp index dcfaeabb55..7d77112a82 100644 --- a/src/common/webrequest.cpp +++ b/src/common/webrequest.cpp @@ -463,6 +463,11 @@ wxFileOffset wxWebRequest::GetBytesExpectedToReceive() const return m_impl->GetBytesExpectedToReceive(); } +wxWebRequestHandle wxWebRequest::GetNativeHandle() const +{ + return m_impl ? m_impl->GetNativeHandle() : NULL; +} + // // wxWebAuthChallenge @@ -931,6 +936,11 @@ void wxWebSession::Close() m_impl.reset(NULL); } +wxWebSessionHandle wxWebSession::GetNativeHandle() const +{ + return m_impl ? m_impl->GetNativeHandle() : NULL; +} + // ---------------------------------------------------------------------------- // Module ensuring all global/singleton objects are destroyed on shutdown. // ---------------------------------------------------------------------------- diff --git a/tests/net/webrequest.cpp b/tests/net/webrequest.cpp index 6e12f57036..8e9db16321 100644 --- a/tests/net/webrequest.cpp +++ b/tests/net/webrequest.cpp @@ -144,6 +144,33 @@ TEST_CASE_METHOD(RequestFixture, CHECK( request.GetBytesReceived() == 65536 ); } +TEST_CASE_METHOD(RequestFixture, + "WebRequest::Get::Simple", "[net][webrequest][get]") +{ + if ( !InitBaseURL() ) + return; + + // Note that the session may be initialized on demand, so don't check the + // native handle before actually using it. + wxWebSession& session = wxWebSession::GetDefault(); + REQUIRE( session.IsOpened() ); + + // Request is not initialized yet. + CHECK( !request.IsOk() ); + CHECK( !request.GetNativeHandle() ); + + Create("/status/200"); + CHECK( request.IsOk() ); + CHECK( session.GetNativeHandle() ); + + // Note that the request must be started to have a valid native handle. + request.Start(); + CHECK( request.GetNativeHandle() ); + RunLoopWithTimeout(); + CHECK( request.GetState() == wxWebRequest::State_Completed ); + CHECK( request.GetResponse().GetStatus() == 200 ); +} + TEST_CASE_METHOD(RequestFixture, "WebRequest::Get::String", "[net][webrequest][get]") {