1 /*
2 * Copyright (C) 2006, 2007 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 COMPUTER, 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 COMPUTER, 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 "config.h"
27 #include "WebKitDLL.h"
28 #include "WebMutableURLRequest.h"
29
30 #include "WebKit.h"
31 #include "MarshallingHelpers.h"
32 #include "WebKit.h"
33 #pragma warning(push, 0)
34 #include <WebCore/BString.h>
35 #include <WebCore/COMPtr.h>
36 #include <WebCore/CString.h>
37 #include <WebCore/FormData.h>
38 #include <WebCore/NotImplemented.h>
39 #include <WebCore/ResourceHandle.h>
40 #pragma warning(pop)
41
42 #include <wtf/RetainPtr.h>
43
44 #if USE(CFNETWORK)
45 #include <CFNetwork/CFURLRequestPriv.h>
46 #endif
47
48 using namespace WebCore;
49
50 // IWebURLRequest ----------------------------------------------------------------
51
WebMutableURLRequest(bool isMutable)52 WebMutableURLRequest::WebMutableURLRequest(bool isMutable)
53 : m_refCount(0)
54 , m_isMutable(isMutable)
55 {
56 gClassCount++;
57 gClassNameCount.add("WebMutableURLRequest");
58 }
59
createInstance()60 WebMutableURLRequest* WebMutableURLRequest::createInstance()
61 {
62 WebMutableURLRequest* instance = new WebMutableURLRequest(true);
63 instance->AddRef();
64 return instance;
65 }
66
createInstance(IWebMutableURLRequest * req)67 WebMutableURLRequest* WebMutableURLRequest::createInstance(IWebMutableURLRequest* req)
68 {
69 WebMutableURLRequest* instance = new WebMutableURLRequest(true);
70 instance->AddRef();
71 instance->m_request = static_cast<WebMutableURLRequest*>(req)->m_request;
72 return instance;
73 }
74
createInstance(const ResourceRequest & request)75 WebMutableURLRequest* WebMutableURLRequest::createInstance(const ResourceRequest& request)
76 {
77 WebMutableURLRequest* instance = new WebMutableURLRequest(true);
78 instance->AddRef();
79 instance->m_request = request;
80 return instance;
81 }
82
createImmutableInstance()83 WebMutableURLRequest* WebMutableURLRequest::createImmutableInstance()
84 {
85 WebMutableURLRequest* instance = new WebMutableURLRequest(false);
86 instance->AddRef();
87 return instance;
88 }
89
createImmutableInstance(const ResourceRequest & request)90 WebMutableURLRequest* WebMutableURLRequest::createImmutableInstance(const ResourceRequest& request)
91 {
92 WebMutableURLRequest* instance = new WebMutableURLRequest(false);
93 instance->AddRef();
94 instance->m_request = request;
95 return instance;
96 }
97
~WebMutableURLRequest()98 WebMutableURLRequest::~WebMutableURLRequest()
99 {
100 gClassCount--;
101 gClassNameCount.remove("WebMutableURLRequest");
102 }
103
104 // IUnknown -------------------------------------------------------------------
105
QueryInterface(REFIID riid,void ** ppvObject)106 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::QueryInterface(REFIID riid, void** ppvObject)
107 {
108 *ppvObject = 0;
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
AddRef(void)126 ULONG STDMETHODCALLTYPE WebMutableURLRequest::AddRef(void)
127 {
128 return ++m_refCount;
129 }
130
Release(void)131 ULONG STDMETHODCALLTYPE WebMutableURLRequest::Release(void)
132 {
133 ULONG newRef = --m_refCount;
134 if (!newRef)
135 delete(this);
136
137 return newRef;
138 }
139
140 // IWebURLRequest --------------------------------------------------------------------
141
requestWithURL(BSTR,WebURLRequestCachePolicy,double)142 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::requestWithURL(
143 /* [in] */ BSTR /*theURL*/,
144 /* [optional][in] */ WebURLRequestCachePolicy /*cachePolicy*/,
145 /* [optional][in] */ double /*timeoutInterval*/)
146 {
147 ASSERT_NOT_REACHED();
148 return E_NOTIMPL;
149 }
150
allHTTPHeaderFields(IPropertyBag **)151 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::allHTTPHeaderFields(
152 /* [retval][out] */ IPropertyBag** /*result*/)
153 {
154 ASSERT_NOT_REACHED();
155 return E_NOTIMPL;
156 }
157
cachePolicy(WebURLRequestCachePolicy * result)158 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::cachePolicy(
159 /* [retval][out] */ WebURLRequestCachePolicy* result)
160 {
161 *result = kit(m_request.cachePolicy());
162 return S_OK;
163 }
164
HTTPBody(IStream **)165 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::HTTPBody(
166 /* [retval][out] */ IStream** /*result*/)
167 {
168 ASSERT_NOT_REACHED();
169 return E_NOTIMPL;
170 }
171
HTTPBodyStream(IStream **)172 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::HTTPBodyStream(
173 /* [retval][out] */ IStream** /*result*/)
174 {
175 ASSERT_NOT_REACHED();
176 return E_NOTIMPL;
177 }
178
HTTPMethod(BSTR * result)179 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::HTTPMethod(
180 /* [retval][out] */ BSTR* result)
181 {
182 BString httpMethod = BString(m_request.httpMethod());
183 *result = httpMethod.release();
184 return S_OK;
185 }
186
HTTPShouldHandleCookies(BOOL *)187 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::HTTPShouldHandleCookies(
188 /* [retval][out] */ BOOL* /*result*/)
189 {
190 ASSERT_NOT_REACHED();
191 return E_NOTIMPL;
192 }
193
initWithURL(BSTR url,WebURLRequestCachePolicy cachePolicy,double timeoutInterval)194 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::initWithURL(
195 /* [in] */ BSTR url,
196 /* [optional][in] */ WebURLRequestCachePolicy cachePolicy,
197 /* [optional][in] */ double timeoutInterval)
198 {
199 m_request.setURL(MarshallingHelpers::BSTRToKURL(url));
200 m_request.setCachePolicy(core(cachePolicy));
201 m_request.setTimeoutInterval(timeoutInterval);
202
203 return S_OK;
204 }
205
mainDocumentURL(BSTR * result)206 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::mainDocumentURL(
207 /* [retval][out] */ BSTR* result)
208 {
209 *result = MarshallingHelpers::KURLToBSTR(m_request.firstPartyForCookies());
210 return S_OK;
211 }
212
timeoutInterval(double * result)213 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::timeoutInterval(
214 /* [retval][out] */ double* result)
215 {
216 *result = m_request.timeoutInterval();
217 return S_OK;
218 }
219
URL(BSTR * result)220 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::URL(
221 /* [retval][out] */ BSTR* result)
222 {
223 *result = MarshallingHelpers::KURLToBSTR(m_request.url());
224 return S_OK;
225 }
226
valueForHTTPHeaderField(BSTR field,BSTR * result)227 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::valueForHTTPHeaderField(
228 /* [in] */ BSTR field,
229 /* [retval][out] */ BSTR* result)
230 {
231 if (!result) {
232 ASSERT_NOT_REACHED();
233 return E_POINTER;
234 }
235
236 *result = BString(m_request.httpHeaderField(String(field, SysStringLen(field)))).release();
237 return S_OK;
238 }
239
isEmpty(BOOL * result)240 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::isEmpty(
241 /* [retval][out] */ BOOL* result)
242 {
243 *result = m_request.isEmpty();
244 return S_OK;
245 }
246
isEqual(IWebURLRequest * other,BOOL * result)247 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::isEqual(
248 /* [in] */ IWebURLRequest* other,
249 /* [out, retval] */ BOOL* result)
250 {
251 COMPtr<WebMutableURLRequest> requestImpl(Query, other);
252
253 if (!requestImpl) {
254 *result = FALSE;
255 return S_OK;
256 }
257
258 *result = m_request == requestImpl->resourceRequest();
259 return S_OK;
260 }
261
262
263 // IWebMutableURLRequest --------------------------------------------------------
264
addValue(BSTR,BSTR)265 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::addValue(
266 /* [in] */ BSTR /*value*/,
267 /* [in] */ BSTR /*field*/)
268 {
269 ASSERT_NOT_REACHED();
270 return E_NOTIMPL;
271 }
272
setAllHTTPHeaderFields(IPropertyBag *)273 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setAllHTTPHeaderFields(
274 /* [in] */ IPropertyBag* /*headerFields*/)
275 {
276 ASSERT_NOT_REACHED();
277 return E_NOTIMPL;
278 }
279
setCachePolicy(WebURLRequestCachePolicy policy)280 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setCachePolicy(
281 /* [in] */ WebURLRequestCachePolicy policy)
282 {
283 m_request.setCachePolicy(core(policy));
284 return S_OK;
285 }
286
setHTTPBody(IStream *)287 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setHTTPBody(
288 /* [in] */ IStream* /*data*/)
289 {
290 ASSERT_NOT_REACHED();
291 return E_NOTIMPL;
292 }
293
setHTTPBodyStream(IStream *)294 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setHTTPBodyStream(
295 /* [in] */ IStream* /*data*/)
296 {
297 ASSERT_NOT_REACHED();
298 return E_NOTIMPL;
299 }
300
setHTTPMethod(BSTR method)301 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setHTTPMethod(
302 /* [in] */ BSTR method)
303 {
304 m_request.setHTTPMethod(String(method));
305 return S_OK;
306 }
307
setHTTPShouldHandleCookies(BOOL handleCookies)308 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setHTTPShouldHandleCookies(
309 /* [in] */ BOOL handleCookies)
310 {
311 m_request.setAllowHTTPCookies(handleCookies);
312 return S_OK;
313 }
314
setMainDocumentURL(BSTR)315 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setMainDocumentURL(
316 /* [in] */ BSTR /*theURL*/)
317 {
318 ASSERT_NOT_REACHED();
319 return E_NOTIMPL;
320 }
321
setTimeoutInterval(double)322 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setTimeoutInterval(
323 /* [in] */ double /*timeoutInterval*/)
324 {
325 ASSERT_NOT_REACHED();
326 return E_NOTIMPL;
327 }
328
setURL(BSTR url)329 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setURL(
330 /* [in] */ BSTR url)
331 {
332 m_request.setURL(MarshallingHelpers::BSTRToKURL(url));
333 return S_OK;
334 }
335
setValue(BSTR value,BSTR field)336 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setValue(
337 /* [in] */ BSTR value,
338 /* [in] */ BSTR field)
339 {
340 String valueString(value, SysStringLen(value));
341 String fieldString(field, SysStringLen(field));
342 m_request.setHTTPHeaderField(fieldString, valueString);
343 return S_OK;
344 }
345
setAllowsAnyHTTPSCertificate(void)346 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setAllowsAnyHTTPSCertificate(void)
347 {
348 ResourceHandle::setHostAllowsAnyHTTPSCertificate(m_request.url().host());
349
350 return S_OK;
351 }
352
deallocCertContext(void * ptr,void * info)353 static void deallocCertContext(void* ptr, void* info)
354 {
355 if (ptr)
356 CertFreeCertificateContext(reinterpret_cast<PCCERT_CONTEXT>(ptr));
357 }
358
copyCert(PCCERT_CONTEXT cert)359 static CFDataRef copyCert(PCCERT_CONTEXT cert)
360 {
361 static CFAllocatorRef certDealloc;
362 PCCERT_CONTEXT certCopy = 0;
363 if (!certDealloc) {
364 CFAllocatorContext allocContext = {
365 0, 0, 0, 0, 0, 0, 0, deallocCertContext, 0
366 };
367 certDealloc = CFAllocatorCreate(kCFAllocatorDefault, &allocContext);
368 }
369 certCopy = CertDuplicateCertificateContext(cert);
370 return CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, reinterpret_cast<const UInt8*>(certCopy), sizeof(*certCopy), certDealloc);
371 }
372
setClientCertificate(OLE_HANDLE cert)373 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setClientCertificate(
374 /* [in] */ OLE_HANDLE cert)
375 {
376 if (!cert)
377 return E_POINTER;
378
379 PCCERT_CONTEXT certContext = reinterpret_cast<PCCERT_CONTEXT>((ULONG64)cert);
380 RetainPtr<CFDataRef> certData(AdoptCF, copyCert(certContext));
381 ResourceHandle::setClientCertificate(m_request.url().host(), certData.get());
382 return S_OK;
383 }
384
cfRequest()385 CFURLRequestRef STDMETHODCALLTYPE WebMutableURLRequest::cfRequest()
386 {
387 return m_request.cfURLRequest();
388 }
389
mutableCopy(IWebMutableURLRequest ** result)390 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::mutableCopy(
391 /* [out, retval] */ IWebMutableURLRequest** result)
392 {
393 if (!result)
394 return E_POINTER;
395
396 #if USE(CFNETWORK)
397 RetainPtr<CFMutableURLRequestRef> mutableRequest(AdoptCF, CFURLRequestCreateMutableCopy(kCFAllocatorDefault, m_request.cfURLRequest()));
398 *result = createInstance(ResourceRequest(mutableRequest.get()));
399 return S_OK;
400 #else
401 notImplemented();
402 return E_NOTIMPL;
403 #endif
404 }
405
406 // IWebMutableURLRequest ----------------------------------------------------
407
setFormData(const PassRefPtr<FormData> data)408 void WebMutableURLRequest::setFormData(const PassRefPtr<FormData> data)
409 {
410 m_request.setHTTPBody(data);
411 }
412
formData() const413 const PassRefPtr<FormData> WebMutableURLRequest::formData() const
414 {
415 return m_request.httpBody();
416 }
417
addHTTPHeaderFields(const HTTPHeaderMap & headerFields)418 void WebMutableURLRequest::addHTTPHeaderFields(const HTTPHeaderMap& headerFields)
419 {
420 m_request.addHTTPHeaderFields(headerFields);
421 }
422
httpHeaderFields() const423 const HTTPHeaderMap& WebMutableURLRequest::httpHeaderFields() const
424 {
425 return m_request.httpHeaderFields();
426 }
427
resourceRequest() const428 const ResourceRequest& WebMutableURLRequest::resourceRequest() const
429 {
430 return m_request;
431 }
432