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 49using namespace WebCore; 50 51// IWebURLRequest ---------------------------------------------------------------- 52 53WebMutableURLRequest::WebMutableURLRequest(bool isMutable) 54 : m_refCount(0) 55 , m_isMutable(isMutable) 56{ 57 gClassCount++; 58 gClassNameCount.add("WebMutableURLRequest"); 59} 60 61WebMutableURLRequest* WebMutableURLRequest::createInstance() 62{ 63 WebMutableURLRequest* instance = new WebMutableURLRequest(true); 64 instance->AddRef(); 65 return instance; 66} 67 68WebMutableURLRequest* 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 76WebMutableURLRequest* 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 84WebMutableURLRequest* WebMutableURLRequest::createImmutableInstance() 85{ 86 WebMutableURLRequest* instance = new WebMutableURLRequest(false); 87 instance->AddRef(); 88 return instance; 89} 90 91WebMutableURLRequest* 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 99WebMutableURLRequest::~WebMutableURLRequest() 100{ 101 gClassCount--; 102 gClassNameCount.remove("WebMutableURLRequest"); 103} 104 105// IUnknown ------------------------------------------------------------------- 106 107HRESULT 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 127ULONG STDMETHODCALLTYPE WebMutableURLRequest::AddRef(void) 128{ 129 return ++m_refCount; 130} 131 132ULONG 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 143HRESULT 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 152HRESULT STDMETHODCALLTYPE WebMutableURLRequest::allHTTPHeaderFields( 153 /* [retval][out] */ IPropertyBag** /*result*/) 154{ 155 ASSERT_NOT_REACHED(); 156 return E_NOTIMPL; 157} 158 159HRESULT STDMETHODCALLTYPE WebMutableURLRequest::cachePolicy( 160 /* [retval][out] */ WebURLRequestCachePolicy* result) 161{ 162 *result = kit(m_request.cachePolicy()); 163 return S_OK; 164} 165 166HRESULT STDMETHODCALLTYPE WebMutableURLRequest::HTTPBody( 167 /* [retval][out] */ IStream** /*result*/) 168{ 169 ASSERT_NOT_REACHED(); 170 return E_NOTIMPL; 171} 172 173HRESULT STDMETHODCALLTYPE WebMutableURLRequest::HTTPBodyStream( 174 /* [retval][out] */ IStream** /*result*/) 175{ 176 ASSERT_NOT_REACHED(); 177 return E_NOTIMPL; 178} 179 180HRESULT 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 188HRESULT STDMETHODCALLTYPE WebMutableURLRequest::HTTPShouldHandleCookies( 189 /* [retval][out] */ BOOL* /*result*/) 190{ 191 ASSERT_NOT_REACHED(); 192 return E_NOTIMPL; 193} 194 195HRESULT 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 207HRESULT STDMETHODCALLTYPE WebMutableURLRequest::mainDocumentURL( 208 /* [retval][out] */ BSTR* result) 209{ 210 *result = MarshallingHelpers::KURLToBSTR(m_request.firstPartyForCookies()); 211 return S_OK; 212} 213 214HRESULT STDMETHODCALLTYPE WebMutableURLRequest::timeoutInterval( 215 /* [retval][out] */ double* result) 216{ 217 *result = m_request.timeoutInterval(); 218 return S_OK; 219} 220 221HRESULT STDMETHODCALLTYPE WebMutableURLRequest::URL( 222 /* [retval][out] */ BSTR* result) 223{ 224 *result = MarshallingHelpers::KURLToBSTR(m_request.url()); 225 return S_OK; 226} 227 228HRESULT 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 241HRESULT STDMETHODCALLTYPE WebMutableURLRequest::isEmpty( 242 /* [retval][out] */ BOOL* result) 243{ 244 *result = m_request.isEmpty(); 245 return S_OK; 246} 247 248HRESULT 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 266HRESULT STDMETHODCALLTYPE WebMutableURLRequest::addValue( 267 /* [in] */ BSTR /*value*/, 268 /* [in] */ BSTR /*field*/) 269{ 270 ASSERT_NOT_REACHED(); 271 return E_NOTIMPL; 272} 273 274HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setAllHTTPHeaderFields( 275 /* [in] */ IPropertyBag* /*headerFields*/) 276{ 277 ASSERT_NOT_REACHED(); 278 return E_NOTIMPL; 279} 280 281HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setCachePolicy( 282 /* [in] */ WebURLRequestCachePolicy policy) 283{ 284 m_request.setCachePolicy(core(policy)); 285 return S_OK; 286} 287 288HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setHTTPBody( 289 /* [in] */ IStream* /*data*/) 290{ 291 ASSERT_NOT_REACHED(); 292 return E_NOTIMPL; 293} 294 295HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setHTTPBodyStream( 296 /* [in] */ IStream* /*data*/) 297{ 298 ASSERT_NOT_REACHED(); 299 return E_NOTIMPL; 300} 301 302HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setHTTPMethod( 303 /* [in] */ BSTR method) 304{ 305 m_request.setHTTPMethod(String(method)); 306 return S_OK; 307} 308 309HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setHTTPShouldHandleCookies( 310 /* [in] */ BOOL handleCookies) 311{ 312 m_request.setAllowCookies(handleCookies); 313 return S_OK; 314} 315 316HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setMainDocumentURL( 317 /* [in] */ BSTR /*theURL*/) 318{ 319 ASSERT_NOT_REACHED(); 320 return E_NOTIMPL; 321} 322 323HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setTimeoutInterval( 324 /* [in] */ double timeoutInterval) 325{ 326 m_request.setTimeoutInterval(timeoutInterval); 327 return S_OK; 328} 329 330HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setURL( 331 /* [in] */ BSTR url) 332{ 333 m_request.setURL(MarshallingHelpers::BSTRToKURL(url)); 334 return S_OK; 335} 336 337HRESULT 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 347HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setAllowsAnyHTTPSCertificate(void) 348{ 349 ResourceHandle::setHostAllowsAnyHTTPSCertificate(m_request.url().host()); 350 351 return S_OK; 352} 353 354HRESULT 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 366CFURLRequestRef STDMETHODCALLTYPE WebMutableURLRequest::cfRequest() 367{ 368 return m_request.cfURLRequest(); 369} 370 371HRESULT 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 389void WebMutableURLRequest::setFormData(const PassRefPtr<FormData> data) 390{ 391 m_request.setHTTPBody(data); 392} 393 394const PassRefPtr<FormData> WebMutableURLRequest::formData() const 395{ 396 return m_request.httpBody(); 397} 398 399void WebMutableURLRequest::addHTTPHeaderFields(const HTTPHeaderMap& headerFields) 400{ 401 m_request.addHTTPHeaderFields(headerFields); 402} 403 404const HTTPHeaderMap& WebMutableURLRequest::httpHeaderFields() const 405{ 406 return m_request.httpHeaderFields(); 407} 408 409const ResourceRequest& WebMutableURLRequest::resourceRequest() const 410{ 411 return m_request; 412} 413