1 ///////////////////////////////////////////////////////////////////////////////
2 // Name:        wx/msw/webrequest_winhttp.h
3 // Purpose:     wxWebRequest WinHTTP implementation
4 // Author:      Tobias Taschner
5 // Created:     2018-10-17
6 // Copyright:   (c) 2018 wxWidgets development team
7 // Licence:     wxWindows licence
8 ///////////////////////////////////////////////////////////////////////////////
9 
10 #ifndef _WX_MSW_WEBREQUEST_WINHTTP_H
11 #define _WX_MSW_WEBREQUEST_WINHTTP_H
12 
13 #include "wx/private/webrequest.h"
14 
15 #include "wx/msw/wrapwin.h"
16 #include <winhttp.h>
17 #include "wx/buffer.h"
18 
19 class wxWebSessionWinHTTP;
20 class wxWebRequestWinHTTP;
21 
22 class wxWebResponseWinHTTP : public wxWebResponseImpl
23 {
24 public:
25     wxWebResponseWinHTTP(wxWebRequestWinHTTP& request);
26 
GetContentLength()27     wxFileOffset GetContentLength() const wxOVERRIDE { return m_contentLength; }
28 
29     wxString GetURL() const wxOVERRIDE;
30 
31     wxString GetHeader(const wxString& name) const wxOVERRIDE;
32 
33     int GetStatus() const wxOVERRIDE;
34 
35     wxString GetStatusText() const wxOVERRIDE;
36 
37     bool ReadData();
38 
39     bool ReportAvailableData(DWORD dataLen);
40 
41 private:
42     HINTERNET m_requestHandle;
43     wxFileOffset m_contentLength;
44 
45     wxDECLARE_NO_COPY_CLASS(wxWebResponseWinHTTP);
46 };
47 
48 class wxWebAuthChallengeWinHTTP : public wxWebAuthChallengeImpl
49 {
50 public:
51     wxWebAuthChallengeWinHTTP(wxWebAuthChallenge::Source source,
52                               wxWebRequestWinHTTP& request);
53 
54     bool Init();
55 
56     void SetCredentials(const wxWebCredentials& cred) wxOVERRIDE;
57 
58 private:
59     wxWebRequestWinHTTP& m_request;
60     DWORD m_target;
61     DWORD m_selectedScheme;
62 
63     wxDECLARE_NO_COPY_CLASS(wxWebAuthChallengeWinHTTP);
64 };
65 
66 class wxWebRequestWinHTTP : public wxWebRequestImpl
67 {
68 public:
69     wxWebRequestWinHTTP(wxWebSession& session,
70                         wxWebSessionWinHTTP& sessionImpl,
71                         wxEvtHandler* handler,
72                         const wxString& url,
73                         int id);
74 
75     ~wxWebRequestWinHTTP();
76 
77     void Start() wxOVERRIDE;
78 
GetResponse()79     wxWebResponseImplPtr GetResponse() const wxOVERRIDE
80         { return m_response; }
81 
GetAuthChallenge()82     wxWebAuthChallengeImplPtr GetAuthChallenge() const wxOVERRIDE
83         { return m_authChallenge; }
84 
GetBytesSent()85     wxFileOffset GetBytesSent() const wxOVERRIDE { return m_dataWritten; }
86 
GetBytesExpectedToSend()87     wxFileOffset GetBytesExpectedToSend() const wxOVERRIDE { return m_dataSize; }
88 
89     void HandleCallback(DWORD dwInternetStatus, LPVOID lpvStatusInformation,
90         DWORD dwStatusInformationLength);
91 
GetHandle()92     HINTERNET GetHandle() const { return m_request; }
93 
GetNativeHandle()94     wxWebRequestHandle GetNativeHandle() const wxOVERRIDE
95     {
96         return (wxWebRequestHandle)GetHandle();
97     }
98 
99 private:
100     void DoCancel() wxOVERRIDE;
101 
102     wxWebSessionWinHTTP& m_sessionImpl;
103     wxString m_url;
104     HINTERNET m_connect;
105     HINTERNET m_request;
106     wxObjectDataPtr<wxWebResponseWinHTTP> m_response;
107     wxObjectDataPtr<wxWebAuthChallengeWinHTTP> m_authChallenge;
108     wxMemoryBuffer m_dataWriteBuffer;
109     wxFileOffset m_dataWritten;
110 
111     void SendRequest();
112 
113     void WriteData();
114 
115     void CreateResponse();
116 
117     // Set the state to State_Failed with the error string including the
118     // provided description of the operation and the error message for this
119     // error code.
120     void SetFailed(const wxString& operation, DWORD errorCode);
121 
SetFailedWithLastError(const wxString & operation)122     void SetFailedWithLastError(const wxString& operation)
123     {
124         SetFailed(operation, ::GetLastError());
125     }
126 
127     friend class wxWebAuthChallengeWinHTTP;
128 
129     wxDECLARE_NO_COPY_CLASS(wxWebRequestWinHTTP);
130 };
131 
132 class wxWebSessionWinHTTP : public wxWebSessionImpl
133 {
134 public:
135     wxWebSessionWinHTTP();
136 
137     ~wxWebSessionWinHTTP();
138 
139     static bool Initialize();
140 
141     wxWebRequestImplPtr
142     CreateRequest(wxWebSession& session,
143                   wxEvtHandler* handler,
144                   const wxString& url,
145                   int id) wxOVERRIDE;
146 
147     wxVersionInfo GetLibraryVersionInfo() wxOVERRIDE;
148 
GetHandle()149     HINTERNET GetHandle() const { return m_handle; }
150 
GetNativeHandle()151     wxWebSessionHandle GetNativeHandle() const wxOVERRIDE
152     {
153         return (wxWebSessionHandle)GetHandle();
154     }
155 
156 private:
157     HINTERNET m_handle;
158 
159     bool Open();
160 
161     wxDECLARE_NO_COPY_CLASS(wxWebSessionWinHTTP);
162 };
163 
164 class wxWebSessionFactoryWinHTTP : public wxWebSessionFactory
165 {
166 public:
Create()167     wxWebSessionImpl* Create() wxOVERRIDE
168     {
169         return new wxWebSessionWinHTTP();
170     }
171 
Initialize()172     bool Initialize() wxOVERRIDE
173     {
174         return wxWebSessionWinHTTP::Initialize();
175     }
176 };
177 
178 #endif // _WX_MSW_WEBREQUEST_WINHTTP_H
179