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 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 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::URLToBSTR(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::URLToBSTR(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 WebMutableURLRequest::setHTTPBody(IStream* data) 290{ 291 if (!data) 292 return E_POINTER; 293 294 STATSTG stat; 295 if (FAILED(data->Stat(&stat, STATFLAG_NONAME))) 296 return E_FAIL; 297 298 if (stat.cbSize.HighPart || !stat.cbSize.LowPart) 299 return E_FAIL; 300 301 RefPtr<FormData> httpBody = FormData::create(); 302 char* formData = httpBody->expandDataStore(stat.cbSize.LowPart); 303 304 ULONG bytesRead = 0; 305 if (FAILED(data->Read(formData, stat.cbSize.LowPart, &bytesRead))) 306 return E_FAIL; 307 308 m_request.setHTTPBody(httpBody); 309 return S_OK; 310} 311 312HRESULT WebMutableURLRequest::setHTTPBodyStream(IStream* data) 313{ 314 return setHTTPBody(data); 315} 316 317HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setHTTPMethod( 318 /* [in] */ BSTR method) 319{ 320 m_request.setHTTPMethod(String(method)); 321 return S_OK; 322} 323 324HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setHTTPShouldHandleCookies( 325 /* [in] */ BOOL handleCookies) 326{ 327 m_request.setAllowCookies(handleCookies); 328 return S_OK; 329} 330 331HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setMainDocumentURL( 332 /* [in] */ BSTR theURL) 333{ 334 m_request.setFirstPartyForCookies(MarshallingHelpers::BSTRToKURL(theURL)); 335 return S_OK; 336} 337 338HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setTimeoutInterval( 339 /* [in] */ double timeoutInterval) 340{ 341 m_request.setTimeoutInterval(timeoutInterval); 342 return S_OK; 343} 344 345HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setURL( 346 /* [in] */ BSTR url) 347{ 348 m_request.setURL(MarshallingHelpers::BSTRToKURL(url)); 349 return S_OK; 350} 351 352HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setValue( 353 /* [in] */ BSTR value, 354 /* [in] */ BSTR field) 355{ 356 String valueString(value, SysStringLen(value)); 357 String fieldString(field, SysStringLen(field)); 358 m_request.setHTTPHeaderField(fieldString, valueString); 359 return S_OK; 360} 361 362HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setAllowsAnyHTTPSCertificate(void) 363{ 364 ResourceHandle::setHostAllowsAnyHTTPSCertificate(m_request.url().host()); 365 366 return S_OK; 367} 368 369HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setClientCertificate(/* [in] */ ULONG_PTR cert) 370{ 371 if (!cert) 372 return E_POINTER; 373 374 PCCERT_CONTEXT certContext = reinterpret_cast<PCCERT_CONTEXT>(cert); 375 RetainPtr<CFDataRef> certData = WebCore::copyCertificateToData(certContext); 376 ResourceHandle::setClientCertificate(m_request.url().host(), certData.get()); 377 return S_OK; 378} 379 380CFURLRequestRef STDMETHODCALLTYPE WebMutableURLRequest::cfRequest() 381{ 382 return m_request.cfURLRequest(UpdateHTTPBody); 383} 384 385HRESULT STDMETHODCALLTYPE WebMutableURLRequest::mutableCopy( 386 /* [out, retval] */ IWebMutableURLRequest** result) 387{ 388 if (!result) 389 return E_POINTER; 390 391#if USE(CFNETWORK) 392 RetainPtr<CFMutableURLRequestRef> mutableRequest = adoptCF(CFURLRequestCreateMutableCopy(kCFAllocatorDefault, m_request.cfURLRequest(UpdateHTTPBody))); 393 *result = createInstance(ResourceRequest(mutableRequest.get())); 394 return S_OK; 395#else 396 *result = createInstance(m_request); 397 return S_OK; 398#endif 399} 400 401// IWebMutableURLRequest ---------------------------------------------------- 402 403void WebMutableURLRequest::setFormData(const PassRefPtr<FormData> data) 404{ 405 m_request.setHTTPBody(data); 406} 407 408const PassRefPtr<FormData> WebMutableURLRequest::formData() const 409{ 410 return m_request.httpBody(); 411} 412 413const HTTPHeaderMap& WebMutableURLRequest::httpHeaderFields() const 414{ 415 return m_request.httpHeaderFields(); 416} 417 418const ResourceRequest& WebMutableURLRequest::resourceRequest() const 419{ 420 return m_request; 421} 422