1 /////////////////////////////////////////////////////////////////////////////// 2 // Name: wx/webrequest_curl.h 3 // Purpose: wxWebRequest implementation using libcurl 4 // Author: Tobias Taschner 5 // Created: 2018-10-25 6 // Copyright: (c) 2018 wxWidgets development team 7 // Licence: wxWindows licence 8 /////////////////////////////////////////////////////////////////////////////// 9 10 #ifndef _WX_WEBREQUEST_CURL_H 11 #define _WX_WEBREQUEST_CURL_H 12 13 #if wxUSE_WEBREQUEST_CURL 14 15 #include "wx/private/webrequest.h" 16 17 #include "wx/thread.h" 18 #include "wx/vector.h" 19 #include "wx/timer.h" 20 #include "wx/hashmap.h" 21 22 #include "curl/curl.h" 23 24 class wxWebRequestCURL; 25 class wxWebResponseCURL; 26 class wxWebSessionCURL; 27 class SocketPoller; 28 29 class wxWebAuthChallengeCURL : public wxWebAuthChallengeImpl 30 { 31 public: 32 wxWebAuthChallengeCURL(wxWebAuthChallenge::Source source, 33 wxWebRequestCURL& request); 34 35 void SetCredentials(const wxWebCredentials& cred) wxOVERRIDE; 36 37 private: 38 wxWebRequestCURL& m_request; 39 40 wxDECLARE_NO_COPY_CLASS(wxWebAuthChallengeCURL); 41 }; 42 43 class wxWebRequestCURL : public wxWebRequestImpl 44 { 45 public: 46 wxWebRequestCURL(wxWebSession& session, 47 wxWebSessionCURL& sessionImpl, 48 wxEvtHandler* handler, 49 const wxString& url, 50 int id); 51 52 ~wxWebRequestCURL(); 53 54 void Start() wxOVERRIDE; 55 GetResponse()56 wxWebResponseImplPtr GetResponse() const wxOVERRIDE 57 { return m_response; } 58 GetAuthChallenge()59 wxWebAuthChallengeImplPtr GetAuthChallenge() const wxOVERRIDE 60 { return m_authChallenge; } 61 62 wxFileOffset GetBytesSent() const wxOVERRIDE; 63 64 wxFileOffset GetBytesExpectedToSend() const wxOVERRIDE; 65 GetHandle()66 CURL* GetHandle() const { return m_handle; } 67 GetNativeHandle()68 wxWebRequestHandle GetNativeHandle() const wxOVERRIDE 69 { 70 return (wxWebRequestHandle)GetHandle(); 71 } 72 73 bool StartRequest(); 74 75 void HandleCompletion(); 76 77 wxString GetError() const; 78 79 // Method called from libcurl callback 80 size_t CURLOnRead(char* buffer, size_t size); 81 82 private: 83 void DoCancel() wxOVERRIDE; 84 85 wxWebSessionCURL& m_sessionImpl; 86 87 CURL* m_handle; 88 char m_errorBuffer[CURL_ERROR_SIZE]; 89 struct curl_slist *m_headerList; 90 wxObjectDataPtr<wxWebResponseCURL> m_response; 91 wxObjectDataPtr<wxWebAuthChallengeCURL> m_authChallenge; 92 wxFileOffset m_bytesSent; 93 94 void DestroyHeaderList(); 95 96 wxDECLARE_NO_COPY_CLASS(wxWebRequestCURL); 97 }; 98 99 class wxWebResponseCURL : public wxWebResponseImpl 100 { 101 public: 102 explicit wxWebResponseCURL(wxWebRequestCURL& request); 103 104 wxFileOffset GetContentLength() const wxOVERRIDE; 105 106 wxString GetURL() const wxOVERRIDE; 107 108 wxString GetHeader(const wxString& name) const wxOVERRIDE; 109 110 int GetStatus() const wxOVERRIDE; 111 GetStatusText()112 wxString GetStatusText() const wxOVERRIDE { return m_statusText; } 113 114 115 // Methods called from libcurl callbacks 116 size_t CURLOnWrite(void *buffer, size_t size); 117 size_t CURLOnHeader(const char* buffer, size_t size); 118 int CURLOnProgress(curl_off_t); 119 120 private: 121 wxWebRequestHeaderMap m_headers; 122 wxString m_statusText; 123 wxFileOffset m_knownDownloadSize; 124 GetHandle()125 CURL* GetHandle() const 126 { return static_cast<wxWebRequestCURL&>(m_request).GetHandle(); } 127 128 wxDECLARE_NO_COPY_CLASS(wxWebResponseCURL); 129 }; 130 131 class wxWebSessionCURL : public wxWebSessionImpl, public wxEvtHandler 132 { 133 public: 134 wxWebSessionCURL(); 135 136 ~wxWebSessionCURL(); 137 138 wxWebRequestImplPtr 139 CreateRequest(wxWebSession& session, 140 wxEvtHandler* handler, 141 const wxString& url, 142 int id = wxID_ANY) wxOVERRIDE; 143 144 wxVersionInfo GetLibraryVersionInfo() wxOVERRIDE; 145 GetNativeHandle()146 wxWebSessionHandle GetNativeHandle() const wxOVERRIDE 147 { 148 return (wxWebSessionHandle)m_handle; 149 } 150 151 bool StartRequest(wxWebRequestCURL& request); 152 153 void CancelRequest(wxWebRequestCURL* request); 154 155 void RequestHasTerminated(wxWebRequestCURL* request); 156 157 static bool CurlRuntimeAtLeastVersion(unsigned int, unsigned int, 158 unsigned int); 159 160 private: 161 static int TimerCallback(CURLM*, long, void*); 162 static int SocketCallback(CURL*, curl_socket_t, int, void*, void*); 163 164 void ProcessTimerCallback(long); 165 void TimeoutNotification(wxTimerEvent&); 166 void ProcessTimeoutNotification(); 167 void ProcessSocketCallback(CURL*, curl_socket_t, int); 168 void ProcessSocketPollerResult(wxThreadEvent&); 169 void CheckForCompletedTransfers(); 170 void FailRequest(CURL*, const wxString&); 171 void StopActiveTransfer(CURL*); 172 void RemoveActiveSocket(CURL*); 173 174 WX_DECLARE_HASH_MAP(CURL*, wxWebRequestCURL*, wxPointerHash, \ 175 wxPointerEqual, TransferSet); 176 177 WX_DECLARE_HASH_MAP(CURL*, curl_socket_t, wxPointerHash, \ 178 wxPointerEqual, CurlSocketMap); 179 180 TransferSet m_activeTransfers; 181 CurlSocketMap m_activeSockets; 182 183 SocketPoller* m_socketPoller; 184 wxTimer m_timeoutTimer; 185 CURLM* m_handle; 186 187 static int ms_activeSessions; 188 static unsigned int ms_runtimeVersion; 189 190 wxDECLARE_NO_COPY_CLASS(wxWebSessionCURL); 191 }; 192 193 class wxWebSessionFactoryCURL : public wxWebSessionFactory 194 { 195 public: Create()196 wxWebSessionImpl* Create() wxOVERRIDE 197 { return new wxWebSessionCURL(); } 198 }; 199 200 #endif // wxUSE_WEBREQUEST_CURL 201 202 #endif 203