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