1 /* 2 * Copyright (C) 2003, 2006 Apple Computer, Inc. All rights reserved. 3 * Copyright (C) 2009, 2012 Google Inc. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 #include "config.h" 28 #include "platform/network/ResourceRequest.h" 29 30 namespace WebCore { 31 32 double ResourceRequest::s_defaultTimeoutInterval = INT_MAX; 33 34 PassOwnPtr<ResourceRequest> ResourceRequest::adopt(PassOwnPtr<CrossThreadResourceRequestData> data) 35 { 36 OwnPtr<ResourceRequest> request = adoptPtr(new ResourceRequest()); 37 request->setURL(data->m_url); 38 request->setCachePolicy(data->m_cachePolicy); 39 request->setTimeoutInterval(data->m_timeoutInterval); 40 request->setFirstPartyForCookies(data->m_firstPartyForCookies); 41 request->setHTTPMethod(AtomicString(data->m_httpMethod)); 42 request->setPriority(data->m_priority); 43 44 request->m_httpHeaderFields.adopt(data->m_httpHeaders.release()); 45 46 request->setHTTPBody(data->m_httpBody); 47 request->setAllowCookies(data->m_allowCookies); 48 request->setReportUploadProgress(data->m_reportUploadProgress); 49 request->setHasUserGesture(data->m_hasUserGesture); 50 request->setDownloadToFile(data->m_downloadToFile); 51 request->setRequestorID(data->m_requestorID); 52 request->setRequestorProcessID(data->m_requestorProcessID); 53 request->setAppCacheHostID(data->m_appCacheHostID); 54 request->setTargetType(data->m_targetType); 55 return request.release(); 56 } 57 58 PassOwnPtr<CrossThreadResourceRequestData> ResourceRequest::copyData() const 59 { 60 OwnPtr<CrossThreadResourceRequestData> data = adoptPtr(new CrossThreadResourceRequestData()); 61 data->m_url = url().copy(); 62 data->m_cachePolicy = cachePolicy(); 63 data->m_timeoutInterval = timeoutInterval(); 64 data->m_firstPartyForCookies = firstPartyForCookies().copy(); 65 data->m_httpMethod = httpMethod().string().isolatedCopy(); 66 data->m_httpHeaders = httpHeaderFields().copyData(); 67 data->m_priority = priority(); 68 69 if (m_httpBody) 70 data->m_httpBody = m_httpBody->deepCopy(); 71 data->m_allowCookies = m_allowCookies; 72 data->m_reportUploadProgress = m_reportUploadProgress; 73 data->m_hasUserGesture = m_hasUserGesture; 74 data->m_downloadToFile = m_downloadToFile; 75 data->m_requestorID = m_requestorID; 76 data->m_requestorProcessID = m_requestorProcessID; 77 data->m_appCacheHostID = m_appCacheHostID; 78 data->m_targetType = m_targetType; 79 return data.release(); 80 } 81 82 bool ResourceRequest::isEmpty() const 83 { 84 return m_url.isEmpty(); 85 } 86 87 bool ResourceRequest::isNull() const 88 { 89 return m_url.isNull(); 90 } 91 92 const KURL& ResourceRequest::url() const 93 { 94 return m_url; 95 } 96 97 void ResourceRequest::setURL(const KURL& url) 98 { 99 m_url = url; 100 } 101 102 void ResourceRequest::removeCredentials() 103 { 104 if (m_url.user().isEmpty() && m_url.pass().isEmpty()) 105 return; 106 107 m_url.setUser(String()); 108 m_url.setPass(String()); 109 } 110 111 ResourceRequestCachePolicy ResourceRequest::cachePolicy() const 112 { 113 return m_cachePolicy; 114 } 115 116 void ResourceRequest::setCachePolicy(ResourceRequestCachePolicy cachePolicy) 117 { 118 m_cachePolicy = cachePolicy; 119 } 120 121 double ResourceRequest::timeoutInterval() const 122 { 123 return m_timeoutInterval; 124 } 125 126 void ResourceRequest::setTimeoutInterval(double timeoutInterval) 127 { 128 m_timeoutInterval = timeoutInterval; 129 } 130 131 const KURL& ResourceRequest::firstPartyForCookies() const 132 { 133 return m_firstPartyForCookies; 134 } 135 136 void ResourceRequest::setFirstPartyForCookies(const KURL& firstPartyForCookies) 137 { 138 m_firstPartyForCookies = firstPartyForCookies; 139 } 140 141 const AtomicString& ResourceRequest::httpMethod() const 142 { 143 return m_httpMethod; 144 } 145 146 void ResourceRequest::setHTTPMethod(const AtomicString& httpMethod) 147 { 148 m_httpMethod = httpMethod; 149 } 150 151 const HTTPHeaderMap& ResourceRequest::httpHeaderFields() const 152 { 153 return m_httpHeaderFields; 154 } 155 156 const AtomicString& ResourceRequest::httpHeaderField(const AtomicString& name) const 157 { 158 return m_httpHeaderFields.get(name); 159 } 160 161 const AtomicString& ResourceRequest::httpHeaderField(const char* name) const 162 { 163 return m_httpHeaderFields.get(name); 164 } 165 166 void ResourceRequest::setHTTPHeaderField(const AtomicString& name, const AtomicString& value) 167 { 168 m_httpHeaderFields.set(name, value); 169 } 170 171 void ResourceRequest::setHTTPHeaderField(const char* name, const AtomicString& value) 172 { 173 setHTTPHeaderField(AtomicString(name), value); 174 } 175 176 void ResourceRequest::clearHTTPAuthorization() 177 { 178 m_httpHeaderFields.remove("Authorization"); 179 } 180 181 void ResourceRequest::clearHTTPContentType() 182 { 183 m_httpHeaderFields.remove("Content-Type"); 184 } 185 186 void ResourceRequest::clearHTTPReferrer() 187 { 188 m_httpHeaderFields.remove("Referer"); 189 } 190 191 void ResourceRequest::clearHTTPOrigin() 192 { 193 m_httpHeaderFields.remove("Origin"); 194 } 195 196 void ResourceRequest::clearHTTPUserAgent() 197 { 198 m_httpHeaderFields.remove("User-Agent"); 199 } 200 201 void ResourceRequest::clearHTTPAccept() 202 { 203 m_httpHeaderFields.remove("Accept"); 204 } 205 206 FormData* ResourceRequest::httpBody() const 207 { 208 return m_httpBody.get(); 209 } 210 211 void ResourceRequest::setHTTPBody(PassRefPtr<FormData> httpBody) 212 { 213 m_httpBody = httpBody; 214 } 215 216 bool ResourceRequest::allowCookies() const 217 { 218 return m_allowCookies; 219 } 220 221 void ResourceRequest::setAllowCookies(bool allowCookies) 222 { 223 m_allowCookies = allowCookies; 224 } 225 226 ResourceLoadPriority ResourceRequest::priority() const 227 { 228 return m_priority; 229 } 230 231 void ResourceRequest::setPriority(ResourceLoadPriority priority) 232 { 233 m_priority = priority; 234 } 235 236 void ResourceRequest::addHTTPHeaderField(const AtomicString& name, const AtomicString& value) 237 { 238 HTTPHeaderMap::AddResult result = m_httpHeaderFields.add(name, value); 239 if (!result.isNewEntry) 240 result.iterator->value = result.iterator->value + ',' + value; 241 } 242 243 void ResourceRequest::addHTTPHeaderFields(const HTTPHeaderMap& headerFields) 244 { 245 HTTPHeaderMap::const_iterator end = headerFields.end(); 246 for (HTTPHeaderMap::const_iterator it = headerFields.begin(); it != end; ++it) 247 addHTTPHeaderField(it->key, it->value); 248 } 249 250 void ResourceRequest::clearHTTPHeaderField(const AtomicString& name) 251 { 252 m_httpHeaderFields.remove(name); 253 } 254 255 bool equalIgnoringHeaderFields(const ResourceRequest& a, const ResourceRequest& b) 256 { 257 if (a.url() != b.url()) 258 return false; 259 260 if (a.cachePolicy() != b.cachePolicy()) 261 return false; 262 263 if (a.timeoutInterval() != b.timeoutInterval()) 264 return false; 265 266 if (a.firstPartyForCookies() != b.firstPartyForCookies()) 267 return false; 268 269 if (a.httpMethod() != b.httpMethod()) 270 return false; 271 272 if (a.allowCookies() != b.allowCookies()) 273 return false; 274 275 if (a.priority() != b.priority()) 276 return false; 277 278 FormData* formDataA = a.httpBody(); 279 FormData* formDataB = b.httpBody(); 280 281 if (!formDataA) 282 return !formDataB; 283 if (!formDataB) 284 return !formDataA; 285 286 if (*formDataA != *formDataB) 287 return false; 288 289 return true; 290 } 291 292 bool ResourceRequest::compare(const ResourceRequest& a, const ResourceRequest& b) 293 { 294 if (!equalIgnoringHeaderFields(a, b)) 295 return false; 296 297 if (a.httpHeaderFields() != b.httpHeaderFields()) 298 return false; 299 300 return true; 301 } 302 303 bool ResourceRequest::isConditional() const 304 { 305 return (m_httpHeaderFields.contains("If-Match") || 306 m_httpHeaderFields.contains("If-Modified-Since") || 307 m_httpHeaderFields.contains("If-None-Match") || 308 m_httpHeaderFields.contains("If-Range") || 309 m_httpHeaderFields.contains("If-Unmodified-Since")); 310 } 311 312 double ResourceRequest::defaultTimeoutInterval() 313 { 314 return s_defaultTimeoutInterval; 315 } 316 317 void ResourceRequest::setDefaultTimeoutInterval(double timeoutInterval) 318 { 319 s_defaultTimeoutInterval = timeoutInterval; 320 } 321 322 void ResourceRequest::initialize(const KURL& url, ResourceRequestCachePolicy cachePolicy) 323 { 324 m_url = url; 325 m_cachePolicy = cachePolicy; 326 m_timeoutInterval = s_defaultTimeoutInterval; 327 m_httpMethod = "GET"; 328 m_allowCookies = true; 329 m_reportUploadProgress = false; 330 m_reportLoadTiming = false; 331 m_reportRawHeaders = false; 332 m_hasUserGesture = false; 333 m_downloadToFile = false; 334 m_priority = ResourceLoadPriorityLow; 335 m_requestorID = 0; 336 m_requestorProcessID = 0; 337 m_appCacheHostID = 0; 338 m_targetType = TargetIsUnspecified; 339 } 340 341 // This is used by the loader to control the number of issued parallel load requests. 342 unsigned initializeMaximumHTTPConnectionCountPerHost() 343 { 344 // The chromium network stack already handles limiting the number of 345 // parallel requests per host, so there's no need to do it here. Therefore, 346 // this is set to a high value that should never be hit in practice. 347 return 10000; 348 } 349 350 } 351