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