Wasm error message should be cross-thread-copied
[WebKit-https.git] / Source / WebKitLegacy / win / WebMutableURLRequest.cpp
1 /*
2  * Copyright (C) 2006-2007, 2015 Apple Inc.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "WebKitDLL.h"
27 #include "WebMutableURLRequest.h"
28
29 #include "WebKit.h"
30 #include "MarshallingHelpers.h"
31 #include "WebKit.h"
32 #include <WebCore/BString.h>
33 #include <WebCore/COMPtr.h>
34 #include <WebCore/FormData.h>
35 #include <WebCore/ResourceHandle.h>
36 #include <wtf/text/CString.h>
37 #include <wtf/RetainPtr.h>
38
39 #if USE(CFURLCONNECTION)
40 #include <CFNetwork/CFURLRequestPriv.h>
41 #include <WebCore/CertificateCFWin.h>
42 #endif
43
44 using namespace WebCore;
45
46 // IWebURLRequest ----------------------------------------------------------------
47
48 WebMutableURLRequest::WebMutableURLRequest(bool isMutable)
49     : m_isMutable(isMutable)
50 {
51     gClassCount++;
52     gClassNameCount().add("WebMutableURLRequest");
53 }
54
55 WebMutableURLRequest* WebMutableURLRequest::createInstance()
56 {
57     WebMutableURLRequest* instance = new WebMutableURLRequest(true);
58     instance->AddRef();
59     return instance;
60 }
61
62 WebMutableURLRequest* WebMutableURLRequest::createInstance(IWebMutableURLRequest* req)
63 {
64     WebMutableURLRequest* instance = new WebMutableURLRequest(true);
65     instance->AddRef();
66     instance->m_request = static_cast<WebMutableURLRequest*>(req)->m_request;
67     return instance;
68 }
69
70 WebMutableURLRequest* WebMutableURLRequest::createInstance(const ResourceRequest& request)
71 {
72     WebMutableURLRequest* instance = new WebMutableURLRequest(true);
73     instance->AddRef();
74     instance->m_request = request;
75     return instance;
76 }
77
78 WebMutableURLRequest* WebMutableURLRequest::createImmutableInstance()
79 {
80     WebMutableURLRequest* instance = new WebMutableURLRequest(false);
81     instance->AddRef();
82     return instance;
83 }
84
85 WebMutableURLRequest* WebMutableURLRequest::createImmutableInstance(const ResourceRequest& request)
86 {
87     WebMutableURLRequest* instance = new WebMutableURLRequest(false);
88     instance->AddRef();
89     instance->m_request = request;
90     return instance;
91 }
92
93 WebMutableURLRequest::~WebMutableURLRequest()
94 {
95     gClassCount--;
96     gClassNameCount().remove("WebMutableURLRequest");
97 }
98
99 // IUnknown -------------------------------------------------------------------
100
101 HRESULT WebMutableURLRequest::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject)
102 {
103     if (!ppvObject)
104         return E_POINTER;
105     *ppvObject = nullptr;
106     if (IsEqualGUID(riid, CLSID_WebMutableURLRequest))
107         *ppvObject = this;
108     else if (IsEqualGUID(riid, IID_IUnknown))
109         *ppvObject = static_cast<IWebURLRequest*>(this);
110     else if (IsEqualGUID(riid, IID_IWebMutableURLRequest) && m_isMutable)
111         *ppvObject = static_cast<IWebMutableURLRequest*>(this);
112     else if (IsEqualGUID(riid, __uuidof(IWebMutableURLRequestPrivate)) && m_isMutable)
113         *ppvObject = static_cast<IWebMutableURLRequestPrivate*>(this);
114     else if (IsEqualGUID(riid, IID_IWebURLRequest))
115         *ppvObject = static_cast<IWebURLRequest*>(this);
116     else
117         return E_NOINTERFACE;
118
119     AddRef();
120     return S_OK;
121 }
122
123 ULONG WebMutableURLRequest::AddRef()
124 {
125     return ++m_refCount;
126 }
127
128 ULONG WebMutableURLRequest::Release()
129 {
130     ULONG newRef = --m_refCount;
131     if (!newRef)
132         delete(this);
133
134     return newRef;
135 }
136
137 // IWebURLRequest --------------------------------------------------------------------
138
139 HRESULT WebMutableURLRequest::requestWithURL(_In_ BSTR /*theURL*/, WebURLRequestCachePolicy /*cachePolicy*/, double /*timeoutInterval*/)
140 {
141     ASSERT_NOT_REACHED();
142     return E_NOTIMPL;
143 }
144
145 HRESULT WebMutableURLRequest::allHTTPHeaderFields(_COM_Outptr_opt_ IPropertyBag** result)
146 {
147     ASSERT_NOT_REACHED();
148     if (!result)
149         return E_POINTER;
150     *result = nullptr;
151     return E_NOTIMPL;
152 }
153
154 HRESULT WebMutableURLRequest::cachePolicy(_Out_ WebURLRequestCachePolicy* result)
155 {
156     if (!result)
157         return E_POINTER;
158     *result = kit(m_request.cachePolicy());
159     return S_OK;
160 }
161
162 HRESULT WebMutableURLRequest::HTTPBody(_COM_Outptr_opt_ IStream** result)
163 {
164     ASSERT_NOT_REACHED();
165     if (!result)
166         return E_POINTER;
167     *result = nullptr;
168     return E_NOTIMPL;
169 }
170
171 HRESULT WebMutableURLRequest::HTTPBodyStream(_COM_Outptr_opt_ IStream** result)
172 {
173     ASSERT_NOT_REACHED();
174     if (!result)
175         return E_POINTER;
176     *result = nullptr;
177     return E_NOTIMPL;
178 }
179
180 HRESULT WebMutableURLRequest::HTTPMethod(__deref_opt_out BSTR* result)
181 {
182     if (!result)
183         return E_POINTER;
184     BString httpMethod = BString(m_request.httpMethod());
185     *result = httpMethod.release();
186     return S_OK;
187 }
188
189 HRESULT WebMutableURLRequest::HTTPShouldHandleCookies(_Out_ BOOL* result)
190 {
191     if (!result)
192         return E_POINTER;
193     bool shouldHandleCookies = m_request.allowCookies();
194
195     *result = shouldHandleCookies ? TRUE : FALSE;
196     return S_OK;
197 }
198
199 HRESULT WebMutableURLRequest::initWithURL(_In_ BSTR url, WebURLRequestCachePolicy cachePolicy, double timeoutInterval)
200 {
201     m_request.setURL(MarshallingHelpers::BSTRToKURL(url));
202     m_request.setCachePolicy(core(cachePolicy));
203     m_request.setTimeoutInterval(timeoutInterval);
204
205     return S_OK;
206 }
207
208 HRESULT WebMutableURLRequest::mainDocumentURL(__deref_opt_out BSTR* result)
209 {
210     if (!result)
211         return E_POINTER;
212     *result = MarshallingHelpers::URLToBSTR(m_request.firstPartyForCookies());
213     return S_OK;
214 }
215
216 HRESULT WebMutableURLRequest::timeoutInterval(_Out_ double* result)
217 {
218     if (!result)
219         return E_POINTER;
220     *result = m_request.timeoutInterval();
221     return S_OK;
222 }
223
224 HRESULT WebMutableURLRequest::URL(__deref_opt_out BSTR* result)
225 {
226     if (!result)
227         return E_POINTER;
228     *result = MarshallingHelpers::URLToBSTR(m_request.url());
229     return S_OK;
230 }
231
232 HRESULT WebMutableURLRequest::valueForHTTPHeaderField(_In_ BSTR field, __deref_opt_out BSTR* result)
233 {
234     if (!result) {
235         ASSERT_NOT_REACHED();
236         return E_POINTER;
237     }
238
239     *result = BString(m_request.httpHeaderField(String(field, SysStringLen(field)))).release();
240     return S_OK;
241 }
242
243 HRESULT WebMutableURLRequest::isEmpty(_Out_ BOOL* result)
244 {
245     if (!result)
246         return E_POINTER;
247     *result = m_request.isEmpty();
248     return S_OK;
249 }
250
251 HRESULT WebMutableURLRequest::isEqual(_In_opt_ IWebURLRequest* other, _Out_ BOOL* result)
252 {
253     if (!result)
254         return E_POINTER;
255
256     COMPtr<WebMutableURLRequest> requestImpl(Query, other);
257
258     if (!requestImpl) {
259         *result = FALSE;
260         return S_OK;
261     }
262
263     *result = m_request == requestImpl->resourceRequest();
264     return S_OK;
265 }
266
267
268 // IWebMutableURLRequest --------------------------------------------------------
269
270 HRESULT WebMutableURLRequest::addValue(_In_ BSTR value, _In_ BSTR field)
271 {
272     m_request.addHTTPHeaderField(WTF::AtomString(value, SysStringLen(value)), String(field, SysStringLen(field)));
273     return S_OK;
274 }
275
276 HRESULT WebMutableURLRequest::setAllHTTPHeaderFields(_In_opt_ IPropertyBag* /*headerFields*/)
277 {
278     ASSERT_NOT_REACHED();
279     return E_NOTIMPL;
280 }
281
282 HRESULT WebMutableURLRequest::setCachePolicy(WebURLRequestCachePolicy policy)
283 {
284     m_request.setCachePolicy(core(policy));
285     return S_OK;
286 }
287
288 HRESULT WebMutableURLRequest::setHTTPBody(_In_opt_ IStream* data)
289 {
290     if (!data)
291         return E_POINTER;
292
293     STATSTG stat;
294     if (FAILED(data->Stat(&stat, STATFLAG_NONAME)))
295         return E_FAIL;
296
297     if (stat.cbSize.HighPart || !stat.cbSize.LowPart)
298         return E_FAIL;
299
300     size_t length = stat.cbSize.LowPart;
301     Vector<char> vector(length);
302     ULONG bytesRead = 0;
303     if (FAILED(data->Read(vector.data(), stat.cbSize.LowPart, &bytesRead)))
304         return E_FAIL;
305     m_request.setHTTPBody(FormData::create(WTFMove(vector)));
306     return S_OK;
307 }
308
309 HRESULT WebMutableURLRequest::setHTTPBodyStream(_In_opt_ IStream* data)
310 {
311     return setHTTPBody(data);
312 }
313
314 HRESULT WebMutableURLRequest::setHTTPMethod(_In_ BSTR method)
315 {
316     m_request.setHTTPMethod(String(method));
317     return S_OK;
318 }
319
320 HRESULT WebMutableURLRequest::setHTTPShouldHandleCookies(BOOL handleCookies)
321 {
322     m_request.setAllowCookies(handleCookies);
323     return S_OK;
324 }
325
326 HRESULT WebMutableURLRequest::setMainDocumentURL(_In_ BSTR theURL)
327 {
328     m_request.setFirstPartyForCookies(MarshallingHelpers::BSTRToKURL(theURL));
329     return S_OK;
330 }
331
332 HRESULT WebMutableURLRequest::setTimeoutInterval(double timeoutInterval)
333 {
334     m_request.setTimeoutInterval(timeoutInterval);
335     return S_OK;
336 }
337
338 HRESULT WebMutableURLRequest::setURL(_In_ BSTR url)
339 {
340     m_request.setURL(MarshallingHelpers::BSTRToKURL(url));
341     return S_OK;
342 }
343
344 HRESULT WebMutableURLRequest::setValue(_In_ BSTR value, _In_ BSTR field)
345 {
346     String valueString(value, SysStringLen(value));
347     String fieldString(field, SysStringLen(field));
348     m_request.setHTTPHeaderField(fieldString, valueString);
349     return S_OK;
350 }
351
352 HRESULT WebMutableURLRequest::setAllowsAnyHTTPSCertificate()
353 {
354     ResourceHandle::setHostAllowsAnyHTTPSCertificate(m_request.url().host().toString());
355
356     return S_OK;
357 }
358
359 HRESULT WebMutableURLRequest::setClientCertificate(ULONG_PTR cert)
360 {
361     if (!cert)
362         return E_POINTER;
363
364 #if USE(CFURLCONNECTION)
365     PCCERT_CONTEXT certContext = reinterpret_cast<PCCERT_CONTEXT>(cert);
366     RetainPtr<CFDataRef> certData = WebCore::copyCertificateToData(certContext);
367     ResourceHandle::setClientCertificate(m_request.url().host().toString(), certData.get());
368     return S_OK;
369 #else
370     return E_NOTIMPL;
371 #endif
372 }
373
374 CFURLRequestRef WebMutableURLRequest::cfRequest()
375 {
376     return m_request.cfURLRequest(UpdateHTTPBody);
377 }
378
379 HRESULT WebMutableURLRequest::mutableCopy(_COM_Outptr_opt_ IWebMutableURLRequest** result)
380 {
381     if (!result)
382         return E_POINTER;
383
384 #if USE(CFURLCONNECTION)
385     RetainPtr<CFMutableURLRequestRef> mutableRequest = adoptCF(CFURLRequestCreateMutableCopy(kCFAllocatorDefault, m_request.cfURLRequest(UpdateHTTPBody)));
386     *result = createInstance(ResourceRequest(mutableRequest.get()));
387     return S_OK;
388 #else
389     *result = createInstance(m_request);
390     return S_OK;
391 #endif
392 }
393
394 // IWebMutableURLRequest ----------------------------------------------------
395
396 void WebMutableURLRequest::setFormData(RefPtr<FormData>&& data)
397 {
398     m_request.setHTTPBody(WTFMove(data));
399 }
400
401 const RefPtr<FormData> WebMutableURLRequest::formData() const
402 {
403     return m_request.httpBody();
404 }
405
406 const HTTPHeaderMap& WebMutableURLRequest::httpHeaderFields() const
407 {
408     return m_request.httpHeaderFields();
409 }
410
411 const ResourceRequest& WebMutableURLRequest::resourceRequest() const
412 {
413     return m_request;
414 }