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 52 WebMutableURLRequest::WebMutableURLRequest(bool isMutable) 53 : m_refCount(0) 54 , m_isMutable(isMutable) 55 { 56 gClassCount++; 57 gClassNameCount.add("WebMutableURLRequest"); 58 } 59 60 WebMutableURLRequest* WebMutableURLRequest::createInstance() 61 { 62 WebMutableURLRequest* instance = new WebMutableURLRequest(true); 63 instance->AddRef(); 64 return instance; 65 } 66 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 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 83 WebMutableURLRequest* WebMutableURLRequest::createImmutableInstance() 84 { 85 WebMutableURLRequest* instance = new WebMutableURLRequest(false); 86 instance->AddRef(); 87 return instance; 88 } 89 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 98 WebMutableURLRequest::~WebMutableURLRequest() 99 { 100 gClassCount--; 101 gClassNameCount.remove("WebMutableURLRequest"); 102 } 103 104 // IUnknown ------------------------------------------------------------------- 105 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 126 ULONG STDMETHODCALLTYPE WebMutableURLRequest::AddRef(void) 127 { 128 return ++m_refCount; 129 } 130 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 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 151 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::allHTTPHeaderFields( 152 /* [retval][out] */ IPropertyBag** /*result*/) 153 { 154 ASSERT_NOT_REACHED(); 155 return E_NOTIMPL; 156 } 157 158 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::cachePolicy( 159 /* [retval][out] */ WebURLRequestCachePolicy* result) 160 { 161 *result = kit(m_request.cachePolicy()); 162 return S_OK; 163 } 164 165 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::HTTPBody( 166 /* [retval][out] */ IStream** /*result*/) 167 { 168 ASSERT_NOT_REACHED(); 169 return E_NOTIMPL; 170 } 171 172 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::HTTPBodyStream( 173 /* [retval][out] */ IStream** /*result*/) 174 { 175 ASSERT_NOT_REACHED(); 176 return E_NOTIMPL; 177 } 178 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 187 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::HTTPShouldHandleCookies( 188 /* [retval][out] */ BOOL* /*result*/) 189 { 190 ASSERT_NOT_REACHED(); 191 return E_NOTIMPL; 192 } 193 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 206 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::mainDocumentURL( 207 /* [retval][out] */ BSTR* result) 208 { 209 *result = MarshallingHelpers::KURLToBSTR(m_request.firstPartyForCookies()); 210 return S_OK; 211 } 212 213 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::timeoutInterval( 214 /* [retval][out] */ double* result) 215 { 216 *result = m_request.timeoutInterval(); 217 return S_OK; 218 } 219 220 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::URL( 221 /* [retval][out] */ BSTR* result) 222 { 223 *result = MarshallingHelpers::KURLToBSTR(m_request.url()); 224 return S_OK; 225 } 226 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 240 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::isEmpty( 241 /* [retval][out] */ BOOL* result) 242 { 243 *result = m_request.isEmpty(); 244 return S_OK; 245 } 246 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 265 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::addValue( 266 /* [in] */ BSTR /*value*/, 267 /* [in] */ BSTR /*field*/) 268 { 269 ASSERT_NOT_REACHED(); 270 return E_NOTIMPL; 271 } 272 273 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setAllHTTPHeaderFields( 274 /* [in] */ IPropertyBag* /*headerFields*/) 275 { 276 ASSERT_NOT_REACHED(); 277 return E_NOTIMPL; 278 } 279 280 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setCachePolicy( 281 /* [in] */ WebURLRequestCachePolicy policy) 282 { 283 m_request.setCachePolicy(core(policy)); 284 return S_OK; 285 } 286 287 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setHTTPBody( 288 /* [in] */ IStream* /*data*/) 289 { 290 ASSERT_NOT_REACHED(); 291 return E_NOTIMPL; 292 } 293 294 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setHTTPBodyStream( 295 /* [in] */ IStream* /*data*/) 296 { 297 ASSERT_NOT_REACHED(); 298 return E_NOTIMPL; 299 } 300 301 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setHTTPMethod( 302 /* [in] */ BSTR method) 303 { 304 m_request.setHTTPMethod(String(method)); 305 return S_OK; 306 } 307 308 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setHTTPShouldHandleCookies( 309 /* [in] */ BOOL handleCookies) 310 { 311 m_request.setAllowCookies(handleCookies); 312 return S_OK; 313 } 314 315 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setMainDocumentURL( 316 /* [in] */ BSTR /*theURL*/) 317 { 318 ASSERT_NOT_REACHED(); 319 return E_NOTIMPL; 320 } 321 322 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setTimeoutInterval( 323 /* [in] */ double /*timeoutInterval*/) 324 { 325 ASSERT_NOT_REACHED(); 326 return E_NOTIMPL; 327 } 328 329 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setURL( 330 /* [in] */ BSTR url) 331 { 332 m_request.setURL(MarshallingHelpers::BSTRToKURL(url)); 333 return S_OK; 334 } 335 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 346 HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setAllowsAnyHTTPSCertificate(void) 347 { 348 ResourceHandle::setHostAllowsAnyHTTPSCertificate(m_request.url().host()); 349 350 return S_OK; 351 } 352 353 static void deallocCertContext(void* ptr, void* info) 354 { 355 if (ptr) 356 CertFreeCertificateContext(reinterpret_cast<PCCERT_CONTEXT>(ptr)); 357 } 358 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 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 385 CFURLRequestRef STDMETHODCALLTYPE WebMutableURLRequest::cfRequest() 386 { 387 return m_request.cfURLRequest(); 388 } 389 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 408 void WebMutableURLRequest::setFormData(const PassRefPtr<FormData> data) 409 { 410 m_request.setHTTPBody(data); 411 } 412 413 const PassRefPtr<FormData> WebMutableURLRequest::formData() const 414 { 415 return m_request.httpBody(); 416 } 417 418 void WebMutableURLRequest::addHTTPHeaderFields(const HTTPHeaderMap& headerFields) 419 { 420 m_request.addHTTPHeaderFields(headerFields); 421 } 422 423 const HTTPHeaderMap& WebMutableURLRequest::httpHeaderFields() const 424 { 425 return m_request.httpHeaderFields(); 426 } 427 428 const ResourceRequest& WebMutableURLRequest::resourceRequest() const 429 { 430 return m_request; 431 } 432