2 * Copyright (C) 2003, 2006 Apple Inc. All rights reserved.
3 * Copyright (C) 2009, 2012 Google Inc. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
14 * THIS SOFTWARE IS PROVIDED BY APPLE 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 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.
27 #include "ResourceRequestBase.h"
29 #include "ResourceRequest.h"
33 #if !USE(SOUP) && (!PLATFORM(COCOA) || USE(CFNETWORK))
34 double ResourceRequestBase::s_defaultTimeoutInterval = INT_MAX;
36 // Will use NSURLRequest default timeout unless set to a non-zero value with setDefaultTimeoutInterval().
37 // For libsoup the timeout enabled with integer milliseconds. We set 0 as the default value to avoid integer overflow.
38 double ResourceRequestBase::s_defaultTimeoutInterval = 0;
42 bool ResourceRequestBase::s_defaultAllowCookies = true;
45 inline const ResourceRequest& ResourceRequestBase::asResourceRequest() const
47 return *static_cast<const ResourceRequest*>(this);
50 PassOwnPtr<ResourceRequest> ResourceRequestBase::adopt(PassOwnPtr<CrossThreadResourceRequestData> data)
52 OwnPtr<ResourceRequest> request = adoptPtr(new ResourceRequest());
53 request->setURL(data->m_url);
54 request->setCachePolicy(data->m_cachePolicy);
55 request->setTimeoutInterval(data->m_timeoutInterval);
56 request->setFirstPartyForCookies(data->m_firstPartyForCookies);
57 request->setHTTPMethod(data->m_httpMethod);
58 request->setPriority(data->m_priority);
60 request->updateResourceRequest();
61 request->m_httpHeaderFields.adopt(data->m_httpHeaders.release());
63 size_t encodingCount = data->m_responseContentDispositionEncodingFallbackArray.size();
64 if (encodingCount > 0) {
65 String encoding1 = data->m_responseContentDispositionEncodingFallbackArray[0];
68 if (encodingCount > 1) {
69 encoding2 = data->m_responseContentDispositionEncodingFallbackArray[1];
70 if (encodingCount > 2)
71 encoding3 = data->m_responseContentDispositionEncodingFallbackArray[2];
73 ASSERT(encodingCount <= 3);
74 request->setResponseContentDispositionEncodingFallbackArray(encoding1, encoding2, encoding3);
76 request->setHTTPBody(data->m_httpBody);
77 request->setAllowCookies(data->m_allowCookies);
78 request->doPlatformAdopt(data);
79 return request.release();
82 PassOwnPtr<CrossThreadResourceRequestData> ResourceRequestBase::copyData() const
84 OwnPtr<CrossThreadResourceRequestData> data = adoptPtr(new CrossThreadResourceRequestData());
85 data->m_url = url().copy();
86 data->m_cachePolicy = cachePolicy();
87 data->m_timeoutInterval = timeoutInterval();
88 data->m_firstPartyForCookies = firstPartyForCookies().copy();
89 data->m_httpMethod = httpMethod().isolatedCopy();
90 data->m_httpHeaders = httpHeaderFields().copyData();
91 data->m_priority = priority();
93 data->m_responseContentDispositionEncodingFallbackArray.reserveInitialCapacity(m_responseContentDispositionEncodingFallbackArray.size());
94 size_t encodingArraySize = m_responseContentDispositionEncodingFallbackArray.size();
95 for (size_t index = 0; index < encodingArraySize; ++index) {
96 data->m_responseContentDispositionEncodingFallbackArray.append(m_responseContentDispositionEncodingFallbackArray[index].isolatedCopy());
99 data->m_httpBody = m_httpBody->deepCopy();
100 data->m_allowCookies = m_allowCookies;
101 return asResourceRequest().doPlatformCopyData(data.release());
104 bool ResourceRequestBase::isEmpty() const
106 updateResourceRequest();
108 return m_url.isEmpty();
111 bool ResourceRequestBase::isNull() const
113 updateResourceRequest();
115 return m_url.isNull();
118 const URL& ResourceRequestBase::url() const
120 updateResourceRequest();
125 void ResourceRequestBase::setURL(const URL& url)
127 updateResourceRequest();
131 m_platformRequestUpdated = false;
134 void ResourceRequestBase::removeCredentials()
136 updateResourceRequest();
138 if (m_url.user().isEmpty() && m_url.pass().isEmpty())
141 m_url.setUser(String());
142 m_url.setPass(String());
144 m_platformRequestUpdated = false;
147 ResourceRequestCachePolicy ResourceRequestBase::cachePolicy() const
149 updateResourceRequest();
151 return m_cachePolicy;
154 void ResourceRequestBase::setCachePolicy(ResourceRequestCachePolicy cachePolicy)
156 updateResourceRequest();
158 if (m_cachePolicy == cachePolicy)
161 m_cachePolicy = cachePolicy;
163 if (url().protocolIsInHTTPFamily())
164 m_platformRequestUpdated = false;
167 double ResourceRequestBase::timeoutInterval() const
169 updateResourceRequest();
171 return m_timeoutInterval;
174 void ResourceRequestBase::setTimeoutInterval(double timeoutInterval)
176 updateResourceRequest();
178 if (m_timeoutInterval == timeoutInterval)
181 m_timeoutInterval = timeoutInterval;
183 if (url().protocolIsInHTTPFamily())
184 m_platformRequestUpdated = false;
187 const URL& ResourceRequestBase::firstPartyForCookies() const
189 updateResourceRequest();
191 return m_firstPartyForCookies;
194 void ResourceRequestBase::setFirstPartyForCookies(const URL& firstPartyForCookies)
196 updateResourceRequest();
198 if (m_firstPartyForCookies == firstPartyForCookies)
201 m_firstPartyForCookies = firstPartyForCookies;
203 m_platformRequestUpdated = false;
206 const String& ResourceRequestBase::httpMethod() const
208 updateResourceRequest();
213 void ResourceRequestBase::setHTTPMethod(const String& httpMethod)
215 updateResourceRequest();
217 if (m_httpMethod == httpMethod)
220 m_httpMethod = httpMethod;
222 if (url().protocolIsInHTTPFamily())
223 m_platformRequestUpdated = false;
226 const HTTPHeaderMap& ResourceRequestBase::httpHeaderFields() const
228 updateResourceRequest();
230 return m_httpHeaderFields;
233 String ResourceRequestBase::httpHeaderField(const AtomicString& name) const
235 updateResourceRequest();
237 return m_httpHeaderFields.get(name);
240 String ResourceRequestBase::httpHeaderField(const char* name) const
242 updateResourceRequest();
244 return m_httpHeaderFields.get(name);
247 void ResourceRequestBase::setHTTPHeaderField(const AtomicString& name, const String& value)
249 updateResourceRequest();
251 m_httpHeaderFields.set(name, value);
253 if (url().protocolIsInHTTPFamily())
254 m_platformRequestUpdated = false;
257 void ResourceRequestBase::setHTTPHeaderField(const char* name, const String& value)
259 setHTTPHeaderField(AtomicString(name), value);
262 void ResourceRequestBase::clearHTTPAuthorization()
264 updateResourceRequest();
266 HTTPHeaderMap::iterator iter = m_httpHeaderFields.find("Authorization");
267 if (iter == m_httpHeaderFields.end())
270 m_httpHeaderFields.remove(iter);
272 if (url().protocolIsInHTTPFamily())
273 m_platformRequestUpdated = false;
276 void ResourceRequestBase::clearHTTPContentType()
278 updateResourceRequest();
280 m_httpHeaderFields.remove("Content-Type");
282 if (url().protocolIsInHTTPFamily())
283 m_platformRequestUpdated = false;
286 void ResourceRequestBase::clearHTTPReferrer()
288 updateResourceRequest();
290 m_httpHeaderFields.remove("Referer");
292 if (url().protocolIsInHTTPFamily())
293 m_platformRequestUpdated = false;
296 void ResourceRequestBase::clearHTTPOrigin()
298 updateResourceRequest();
300 m_httpHeaderFields.remove("Origin");
302 if (url().protocolIsInHTTPFamily())
303 m_platformRequestUpdated = false;
306 void ResourceRequestBase::clearHTTPUserAgent()
308 updateResourceRequest();
310 m_httpHeaderFields.remove("User-Agent");
312 if (url().protocolIsInHTTPFamily())
313 m_platformRequestUpdated = false;
316 void ResourceRequestBase::clearHTTPAccept()
318 updateResourceRequest();
320 m_httpHeaderFields.remove("Accept");
322 if (url().protocolIsInHTTPFamily())
323 m_platformRequestUpdated = false;
326 void ResourceRequestBase::setResponseContentDispositionEncodingFallbackArray(const String& encoding1, const String& encoding2, const String& encoding3)
328 updateResourceRequest();
330 m_responseContentDispositionEncodingFallbackArray.clear();
331 m_responseContentDispositionEncodingFallbackArray.reserveInitialCapacity(!encoding1.isNull() + !encoding2.isNull() + !encoding3.isNull());
332 if (!encoding1.isNull())
333 m_responseContentDispositionEncodingFallbackArray.uncheckedAppend(encoding1);
334 if (!encoding2.isNull())
335 m_responseContentDispositionEncodingFallbackArray.uncheckedAppend(encoding2);
336 if (!encoding3.isNull())
337 m_responseContentDispositionEncodingFallbackArray.uncheckedAppend(encoding3);
339 if (url().protocolIsInHTTPFamily())
340 m_platformRequestUpdated = false;
343 FormData* ResourceRequestBase::httpBody() const
345 updateResourceRequest(UpdateHTTPBody);
347 return m_httpBody.get();
350 void ResourceRequestBase::setHTTPBody(PassRefPtr<FormData> httpBody)
352 updateResourceRequest();
354 m_httpBody = httpBody;
356 m_resourceRequestBodyUpdated = true;
358 if (url().protocolIsInHTTPFamily())
359 m_platformRequestBodyUpdated = false;
362 bool ResourceRequestBase::allowCookies() const
364 updateResourceRequest();
366 return m_allowCookies;
369 void ResourceRequestBase::setAllowCookies(bool allowCookies)
371 updateResourceRequest();
373 if (m_allowCookies == allowCookies)
376 m_allowCookies = allowCookies;
378 if (url().protocolIsInHTTPFamily())
379 m_platformRequestUpdated = false;
382 ResourceLoadPriority ResourceRequestBase::priority() const
384 updateResourceRequest();
389 void ResourceRequestBase::setPriority(ResourceLoadPriority priority)
391 updateResourceRequest();
393 if (m_priority == priority)
396 m_priority = priority;
398 if (url().protocolIsInHTTPFamily())
399 m_platformRequestUpdated = false;
402 void ResourceRequestBase::addHTTPHeaderField(const AtomicString& name, const String& value)
404 updateResourceRequest();
405 HTTPHeaderMap::AddResult result = m_httpHeaderFields.add(name, value);
406 if (!result.isNewEntry)
407 result.iterator->value = result.iterator->value + ',' + value;
409 if (url().protocolIsInHTTPFamily())
410 m_platformRequestUpdated = false;
413 void ResourceRequestBase::addHTTPHeaderFields(const HTTPHeaderMap& headerFields)
415 for (const auto& header : headerFields)
416 addHTTPHeaderField(header.key, header.value);
419 bool equalIgnoringHeaderFields(const ResourceRequestBase& a, const ResourceRequestBase& b)
421 if (a.url() != b.url())
424 if (a.cachePolicy() != b.cachePolicy())
427 if (a.timeoutInterval() != b.timeoutInterval())
430 if (a.firstPartyForCookies() != b.firstPartyForCookies())
433 if (a.httpMethod() != b.httpMethod())
436 if (a.allowCookies() != b.allowCookies())
439 if (a.priority() != b.priority())
442 FormData* formDataA = a.httpBody();
443 FormData* formDataB = b.httpBody();
450 if (*formDataA != *formDataB)
456 bool ResourceRequestBase::compare(const ResourceRequest& a, const ResourceRequest& b)
458 if (!equalIgnoringHeaderFields(a, b))
461 if (a.httpHeaderFields() != b.httpHeaderFields())
464 return ResourceRequest::platformCompare(a, b);
467 bool ResourceRequestBase::isConditional() const
469 return (m_httpHeaderFields.contains("If-Match") ||
470 m_httpHeaderFields.contains("If-Modified-Since") ||
471 m_httpHeaderFields.contains("If-None-Match") ||
472 m_httpHeaderFields.contains("If-Range") ||
473 m_httpHeaderFields.contains("If-Unmodified-Since"));
476 void ResourceRequestBase::makeUnconditional()
478 m_httpHeaderFields.remove("If-Match");
479 m_httpHeaderFields.remove("If-Modified-Since");
480 m_httpHeaderFields.remove("If-None-Match");
481 m_httpHeaderFields.remove("If-Range");
482 m_httpHeaderFields.remove("If-Unmodified-Since");
485 double ResourceRequestBase::defaultTimeoutInterval()
487 return s_defaultTimeoutInterval;
490 void ResourceRequestBase::setDefaultTimeoutInterval(double timeoutInterval)
492 s_defaultTimeoutInterval = timeoutInterval;
495 void ResourceRequestBase::updatePlatformRequest(HTTPBodyUpdatePolicy bodyPolicy) const
497 if (!m_platformRequestUpdated) {
498 ASSERT(m_resourceRequestUpdated);
499 const_cast<ResourceRequest&>(asResourceRequest()).doUpdatePlatformRequest();
500 m_platformRequestUpdated = true;
503 if (!m_platformRequestBodyUpdated && bodyPolicy == UpdateHTTPBody) {
504 ASSERT(m_resourceRequestBodyUpdated);
505 const_cast<ResourceRequest&>(asResourceRequest()).doUpdatePlatformHTTPBody();
506 m_platformRequestBodyUpdated = true;
510 void ResourceRequestBase::updateResourceRequest(HTTPBodyUpdatePolicy bodyPolicy) const
512 if (!m_resourceRequestUpdated) {
513 ASSERT(m_platformRequestUpdated);
514 const_cast<ResourceRequest&>(asResourceRequest()).doUpdateResourceRequest();
515 m_resourceRequestUpdated = true;
518 if (!m_resourceRequestBodyUpdated && bodyPolicy == UpdateHTTPBody) {
519 ASSERT(m_platformRequestBodyUpdated);
520 const_cast<ResourceRequest&>(asResourceRequest()).doUpdateResourceHTTPBody();
521 m_resourceRequestBodyUpdated = true;
525 #if !PLATFORM(COCOA) && !USE(CFNETWORK) && !USE(SOUP)
526 unsigned initializeMaximumHTTPConnectionCountPerHost()
528 // This is used by the loader to control the number of issued parallel load requests.
529 // Four seems to be a common default in HTTP frameworks.
535 void ResourceRequestBase::setDefaultAllowCookies(bool allowCookies)
537 s_defaultAllowCookies = allowCookies;
540 bool ResourceRequestBase::defaultAllowCookies()
542 return s_defaultAllowCookies;