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