Use a Variant for FormDataElement
[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(CF)
40 #include <WebCore/CertificateCFWin.h>
41 #endif
42
43 #if USE(CFURLCONNECTION)
44 #include <CFNetwork/CFURLRequestPriv.h>
45 #endif
46
47 using namespace WebCore;
48
49 // IWebURLRequest ----------------------------------------------------------------
50
51 WebMutableURLRequest::WebMutableURLRequest(bool isMutable)
52     : m_isMutable(isMutable)
53 {
54     gClassCount++;
55     gClassNameCount().add("WebMutableURLRequest");
56 }
57
58 WebMutableURLRequest* WebMutableURLRequest::createInstance()
59 {
60     WebMutableURLRequest* instance = new WebMutableURLRequest(true);
61     instance->AddRef();
62     return instance;
63 }
64
65 WebMutableURLRequest* WebMutableURLRequest::createInstance(IWebMutableURLRequest* req)
66 {
67     WebMutableURLRequest* instance = new WebMutableURLRequest(true);
68     instance->AddRef();
69     instance->m_request = static_cast<WebMutableURLRequest*>(req)->m_request;
70     return instance;
71 }
72
73 WebMutableURLRequest* WebMutableURLRequest::createInstance(const ResourceRequest& request)
74 {
75     WebMutableURLRequest* instance = new WebMutableURLRequest(true);
76     instance->AddRef();
77     instance->m_request = request;
78     return instance;
79 }
80
81 WebMutableURLRequest* WebMutableURLRequest::createImmutableInstance()
82 {
83     WebMutableURLRequest* instance = new WebMutableURLRequest(false);
84     instance->AddRef();
85     return instance;
86 }
87
88 WebMutableURLRequest* WebMutableURLRequest::createImmutableInstance(const ResourceRequest& request)
89 {
90     WebMutableURLRequest* instance = new WebMutableURLRequest(false);
91     instance->AddRef();
92     instance->m_request = request;
93     return instance;
94 }
95
96 WebMutableURLRequest::~WebMutableURLRequest()
97 {
98     gClassCount--;
99     gClassNameCount().remove("WebMutableURLRequest");
100 }
101
102 // IUnknown -------------------------------------------------------------------
103
104 HRESULT WebMutableURLRequest::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject)
105 {
106     if (!ppvObject)
107         return E_POINTER;
108     *ppvObject = nullptr;
109     if (IsEqualGUID(riid, CLSID_WebMutableURLRequest))
110         *ppvObject = this;
111     else if (IsEqualGUID(riid, IID_IUnknown))
112         *ppvObject = static_cast<IWebURLRequest*>(this);
113     else if (IsEqualGUID(riid, IID_IWebMutableURLRequest) && m_isMutable)
114         *ppvObject = static_cast<IWebMutableURLRequest*>(this);
115     else if (IsEqualGUID(riid, __uuidof(IWebMutableURLRequestPrivate)) && m_isMutable)
116         *ppvObject = static_cast<IWebMutableURLRequestPrivate*>(this);
117     else if (IsEqualGUID(riid, IID_IWebURLRequest))
118         *ppvObject = static_cast<IWebURLRequest*>(this);
119     else
120         return E_NOINTERFACE;
121
122     AddRef();
123     return S_OK;
124 }
125
126 ULONG WebMutableURLRequest::AddRef()
127 {
128     return ++m_refCount;
129 }
130
131 ULONG WebMutableURLRequest::Release()
132 {
133     ULONG newRef = --m_refCount;
134     if (!newRef)
135         delete(this);
136
137     return newRef;
138 }
139
140 // IWebURLRequest --------------------------------------------------------------------
141
142 HRESULT WebMutableURLRequest::requestWithURL(_In_ BSTR /*theURL*/, WebURLRequestCachePolicy /*cachePolicy*/, double /*timeoutInterval*/)
143 {
144     ASSERT_NOT_REACHED();
145     return E_NOTIMPL;
146 }
147
148 HRESULT WebMutableURLRequest::allHTTPHeaderFields(_COM_Outptr_opt_ IPropertyBag** result)
149 {
150     ASSERT_NOT_REACHED();
151     if (!result)
152         return E_POINTER;
153     *result = nullptr;
154     return E_NOTIMPL;
155 }
156
157 HRESULT WebMutableURLRequest::cachePolicy(_Out_ WebURLRequestCachePolicy* result)
158 {
159     if (!result)
160         return E_POINTER;
161     *result = kit(m_request.cachePolicy());
162     return S_OK;
163 }
164
165 HRESULT WebMutableURLRequest::HTTPBody(_COM_Outptr_opt_ IStream** result)
166 {
167     ASSERT_NOT_REACHED();
168     if (!result)
169         return E_POINTER;
170     *result = nullptr;
171     return E_NOTIMPL;
172 }
173
174 HRESULT WebMutableURLRequest::HTTPBodyStream(_COM_Outptr_opt_ IStream** result)
175 {
176     ASSERT_NOT_REACHED();
177     if (!result)
178         return E_POINTER;
179     *result = nullptr;
180     return E_NOTIMPL;
181 }
182
183 HRESULT WebMutableURLRequest::HTTPMethod(__deref_opt_out BSTR* result)
184 {
185     if (!result)
186         return E_POINTER;
187     BString httpMethod = BString(m_request.httpMethod());
188     *result = httpMethod.release();
189     return S_OK;
190 }
191
192 HRESULT WebMutableURLRequest::HTTPShouldHandleCookies(_Out_ BOOL* result)
193 {
194     if (!result)
195         return E_POINTER;
196     bool shouldHandleCookies = m_request.allowCookies();
197
198     *result = shouldHandleCookies ? TRUE : FALSE;
199     return S_OK;
200 }
201
202 HRESULT WebMutableURLRequest::initWithURL(_In_ BSTR url, WebURLRequestCachePolicy cachePolicy, double timeoutInterval)
203 {
204     m_request.setURL(MarshallingHelpers::BSTRToKURL(url));
205     m_request.setCachePolicy(core(cachePolicy));
206     m_request.setTimeoutInterval(timeoutInterval);
207
208     return S_OK;
209 }
210
211 HRESULT WebMutableURLRequest::mainDocumentURL(__deref_opt_out BSTR* result)
212 {
213     if (!result)
214         return E_POINTER;
215     *result = MarshallingHelpers::URLToBSTR(m_request.firstPartyForCookies());
216     return S_OK;
217 }
218
219 HRESULT WebMutableURLRequest::timeoutInterval(_Out_ double* result)
220 {
221     if (!result)
222         return E_POINTER;
223     *result = m_request.timeoutInterval();
224     return S_OK;
225 }
226
227 HRESULT WebMutableURLRequest::URL(__deref_opt_out BSTR* result)
228 {
229     if (!result)
230         return E_POINTER;
231     *result = MarshallingHelpers::URLToBSTR(m_request.url());
232     return S_OK;
233 }
234
235 HRESULT WebMutableURLRequest::valueForHTTPHeaderField(_In_ BSTR field, __deref_opt_out BSTR* result)
236 {
237     if (!result) {
238         ASSERT_NOT_REACHED();
239         return E_POINTER;
240     }
241
242     *result = BString(m_request.httpHeaderField(String(field, SysStringLen(field)))).release();
243     return S_OK;
244 }
245
246 HRESULT WebMutableURLRequest::isEmpty(_Out_ BOOL* result)
247 {
248     if (!result)
249         return E_POINTER;
250     *result = m_request.isEmpty();
251     return S_OK;
252 }
253
254 HRESULT WebMutableURLRequest::isEqual(_In_opt_ IWebURLRequest* other, _Out_ BOOL* result)
255 {
256     if (!result)
257         return E_POINTER;
258
259     COMPtr<WebMutableURLRequest> requestImpl(Query, other);
260
261     if (!requestImpl) {
262         *result = FALSE;
263         return S_OK;
264     }
265
266     *result = m_request == requestImpl->resourceRequest();
267     return S_OK;
268 }
269
270
271 // IWebMutableURLRequest --------------------------------------------------------
272
273 HRESULT WebMutableURLRequest::addValue(_In_ BSTR value, _In_ BSTR field)
274 {
275     m_request.addHTTPHeaderField(WTF::AtomicString(value, SysStringLen(value)), String(field, SysStringLen(field)));
276     return S_OK;
277 }
278
279 HRESULT WebMutableURLRequest::setAllHTTPHeaderFields(_In_opt_ IPropertyBag* /*headerFields*/)
280 {
281     ASSERT_NOT_REACHED();
282     return E_NOTIMPL;
283 }
284
285 HRESULT WebMutableURLRequest::setCachePolicy(WebURLRequestCachePolicy policy)
286 {
287     m_request.setCachePolicy(core(policy));
288     return S_OK;
289 }
290
291 HRESULT WebMutableURLRequest::setHTTPBody(_In_opt_ IStream* data)
292 {
293     if (!data)
294         return E_POINTER;
295
296     STATSTG stat;
297     if (FAILED(data->Stat(&stat, STATFLAG_NONAME)))
298         return E_FAIL;
299
300     if (stat.cbSize.HighPart || !stat.cbSize.LowPart)
301         return E_FAIL;
302
303     size_t length = stat.cbSize.LowPart;
304     Vector<char> vector(length);
305     ULONG bytesRead = 0;
306     if (FAILED(data->Read(vector.data(), stat.cbSize.LowPart, &bytesRead)))
307         return E_FAIL;
308     m_request.setHTTPBody(FormData::create(WTFMove(vector)));
309     return S_OK;
310 }
311
312 HRESULT WebMutableURLRequest::setHTTPBodyStream(_In_opt_ IStream* data)
313 {
314     return setHTTPBody(data);
315 }
316
317 HRESULT WebMutableURLRequest::setHTTPMethod(_In_ BSTR method)
318 {
319     m_request.setHTTPMethod(String(method));
320     return S_OK;
321 }
322
323 HRESULT WebMutableURLRequest::setHTTPShouldHandleCookies(BOOL handleCookies)
324 {
325     m_request.setAllowCookies(handleCookies);
326     return S_OK;
327 }
328
329 HRESULT WebMutableURLRequest::setMainDocumentURL(_In_ BSTR theURL)
330 {
331     m_request.setFirstPartyForCookies(MarshallingHelpers::BSTRToKURL(theURL));
332     return S_OK;
333 }
334
335 HRESULT WebMutableURLRequest::setTimeoutInterval(double timeoutInterval)
336 {
337     m_request.setTimeoutInterval(timeoutInterval);
338     return S_OK;
339 }
340
341 HRESULT WebMutableURLRequest::setURL(_In_ BSTR url)
342 {
343     m_request.setURL(MarshallingHelpers::BSTRToKURL(url));
344     return S_OK;
345 }
346
347 HRESULT WebMutableURLRequest::setValue(_In_ BSTR value, _In_ BSTR field)
348 {
349     String valueString(value, SysStringLen(value));
350     String fieldString(field, SysStringLen(field));
351     m_request.setHTTPHeaderField(fieldString, valueString);
352     return S_OK;
353 }
354
355 HRESULT WebMutableURLRequest::setAllowsAnyHTTPSCertificate()
356 {
357     ResourceHandle::setHostAllowsAnyHTTPSCertificate(m_request.url().host().toString());
358
359     return S_OK;
360 }
361
362 HRESULT WebMutableURLRequest::setClientCertificate(ULONG_PTR cert)
363 {
364     if (!cert)
365         return E_POINTER;
366
367     PCCERT_CONTEXT certContext = reinterpret_cast<PCCERT_CONTEXT>(cert);
368     RetainPtr<CFDataRef> certData = WebCore::copyCertificateToData(certContext);
369     ResourceHandle::setClientCertificate(m_request.url().host().toString(), certData.get());
370     return S_OK;
371 }
372
373 CFURLRequestRef WebMutableURLRequest::cfRequest()
374 {
375     return m_request.cfURLRequest(UpdateHTTPBody);
376 }
377
378 HRESULT WebMutableURLRequest::mutableCopy(_COM_Outptr_opt_ IWebMutableURLRequest** result)
379 {
380     if (!result)
381         return E_POINTER;
382
383 #if USE(CFURLCONNECTION)
384     RetainPtr<CFMutableURLRequestRef> mutableRequest = adoptCF(CFURLRequestCreateMutableCopy(kCFAllocatorDefault, m_request.cfURLRequest(UpdateHTTPBody)));
385     *result = createInstance(ResourceRequest(mutableRequest.get()));
386     return S_OK;
387 #else
388     *result = createInstance(m_request);
389     return S_OK;
390 #endif
391 }
392
393 // IWebMutableURLRequest ----------------------------------------------------
394
395 void WebMutableURLRequest::setFormData(RefPtr<FormData>&& data)
396 {
397     m_request.setHTTPBody(WTFMove(data));
398 }
399
400 const RefPtr<FormData> WebMutableURLRequest::formData() const
401 {
402     return m_request.httpBody();
403 }
404
405 const HTTPHeaderMap& WebMutableURLRequest::httpHeaderFields() const
406 {
407     return m_request.httpHeaderFields();
408 }
409
410 const ResourceRequest& WebMutableURLRequest::resourceRequest() const
411 {
412     return m_request;
413 }