2 * Copyright (C) 2003, 2006 Apple Computer, Inc. All rights reserved.
3 * Copyright (C) 2009 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 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.
28 #include "ResourceRequestBase.h"
29 #include "ResourceRequest.h"
35 #if !PLATFORM(MAC) || USE(CFNETWORK)
36 double ResourceRequestBase::s_defaultTimeoutInterval = INT_MAX;
38 // Will use NSURLRequest default timeout unless set to a non-zero value with setDefaultTimeoutInterval().
39 double ResourceRequestBase::s_defaultTimeoutInterval = 0;
42 inline const ResourceRequest& ResourceRequestBase::asResourceRequest() const
44 return *static_cast<const ResourceRequest*>(this);
47 PassOwnPtr<ResourceRequest> ResourceRequestBase::adopt(PassOwnPtr<CrossThreadResourceRequestData> data)
49 OwnPtr<ResourceRequest> request = adoptPtr(new ResourceRequest());
50 request->setURL(data->m_url);
51 request->setCachePolicy(data->m_cachePolicy);
52 request->setTimeoutInterval(data->m_timeoutInterval);
53 request->setFirstPartyForCookies(data->m_firstPartyForCookies);
54 request->setHTTPMethod(data->m_httpMethod);
55 request->setPriority(data->m_priority);
57 request->updateResourceRequest();
58 request->m_httpHeaderFields.adopt(data->m_httpHeaders.release());
60 #if PLATFORM(MAC) || PLATFORM(WIN)
61 size_t encodingCount = data->m_responseContentDispositionEncodingFallbackArray.size();
62 if (encodingCount > 0) {
63 String encoding1 = data->m_responseContentDispositionEncodingFallbackArray[0];
66 if (encodingCount > 1) {
67 encoding2 = data->m_responseContentDispositionEncodingFallbackArray[1];
68 if (encodingCount > 2)
69 encoding3 = data->m_responseContentDispositionEncodingFallbackArray[2];
71 ASSERT(encodingCount <= 3);
72 request->setResponseContentDispositionEncodingFallbackArray(encoding1, encoding2, encoding3);
75 request->setHTTPBody(data->m_httpBody);
76 request->setAllowCookies(data->m_allowCookies);
77 request->doPlatformAdopt(data);
78 return request.release();
81 PassOwnPtr<CrossThreadResourceRequestData> ResourceRequestBase::copyData() const
83 OwnPtr<CrossThreadResourceRequestData> data = adoptPtr(new CrossThreadResourceRequestData());
84 data->m_url = url().copy();
85 data->m_cachePolicy = cachePolicy();
86 data->m_timeoutInterval = timeoutInterval();
87 data->m_firstPartyForCookies = firstPartyForCookies().copy();
88 data->m_httpMethod = httpMethod().crossThreadString();
89 data->m_httpHeaders = httpHeaderFields().copyData();
90 data->m_priority = priority();
92 #if PLATFORM(MAC) || PLATFORM(WIN)
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].crossThreadString());
100 data->m_httpBody = m_httpBody->deepCopy();
101 data->m_allowCookies = m_allowCookies;
102 return asResourceRequest().doPlatformCopyData(data.release());
105 bool ResourceRequestBase::isEmpty() const
107 updateResourceRequest();
109 return m_url.isEmpty();
112 bool ResourceRequestBase::isNull() const
114 updateResourceRequest();
116 return m_url.isNull();
119 const KURL& ResourceRequestBase::url() const
121 updateResourceRequest();
126 void ResourceRequestBase::setURL(const KURL& url)
128 updateResourceRequest();
132 m_platformRequestUpdated = false;
135 void ResourceRequestBase::removeCredentials()
137 updateResourceRequest();
139 m_url.setUser(String());
140 m_url.setPass(String());
142 m_platformRequestUpdated = false;
145 ResourceRequestCachePolicy ResourceRequestBase::cachePolicy() const
147 updateResourceRequest();
149 return m_cachePolicy;
152 void ResourceRequestBase::setCachePolicy(ResourceRequestCachePolicy cachePolicy)
154 updateResourceRequest();
156 m_cachePolicy = cachePolicy;
158 if (url().protocolInHTTPFamily())
159 m_platformRequestUpdated = false;
162 double ResourceRequestBase::timeoutInterval() const
164 updateResourceRequest();
166 return m_timeoutInterval;
169 void ResourceRequestBase::setTimeoutInterval(double timeoutInterval)
171 updateResourceRequest();
173 m_timeoutInterval = timeoutInterval;
175 if (url().protocolInHTTPFamily())
176 m_platformRequestUpdated = false;
179 const KURL& ResourceRequestBase::firstPartyForCookies() const
181 updateResourceRequest();
183 return m_firstPartyForCookies;
186 void ResourceRequestBase::setFirstPartyForCookies(const KURL& firstPartyForCookies)
188 updateResourceRequest();
190 m_firstPartyForCookies = firstPartyForCookies;
192 m_platformRequestUpdated = false;
195 const String& ResourceRequestBase::httpMethod() const
197 updateResourceRequest();
202 void ResourceRequestBase::setHTTPMethod(const String& httpMethod)
204 updateResourceRequest();
206 m_httpMethod = httpMethod;
208 if (url().protocolInHTTPFamily())
209 m_platformRequestUpdated = false;
212 const HTTPHeaderMap& ResourceRequestBase::httpHeaderFields() const
214 updateResourceRequest();
216 return m_httpHeaderFields;
219 String ResourceRequestBase::httpHeaderField(const AtomicString& name) const
221 updateResourceRequest();
223 return m_httpHeaderFields.get(name);
226 String ResourceRequestBase::httpHeaderField(const char* name) const
228 updateResourceRequest();
230 return m_httpHeaderFields.get(name);
233 void ResourceRequestBase::setHTTPHeaderField(const AtomicString& name, const String& value)
235 updateResourceRequest();
237 m_httpHeaderFields.set(name, value);
239 if (url().protocolInHTTPFamily())
240 m_platformRequestUpdated = false;
243 void ResourceRequestBase::setHTTPHeaderField(const char* name, const String& value)
245 setHTTPHeaderField(AtomicString(name), value);
248 void ResourceRequestBase::clearHTTPAuthorization()
250 updateResourceRequest();
252 m_httpHeaderFields.remove("Authorization");
254 if (url().protocolInHTTPFamily())
255 m_platformRequestUpdated = false;
258 void ResourceRequestBase::clearHTTPReferrer()
260 updateResourceRequest();
262 m_httpHeaderFields.remove("Referer");
264 if (url().protocolInHTTPFamily())
265 m_platformRequestUpdated = false;
268 void ResourceRequestBase::clearHTTPOrigin()
270 updateResourceRequest();
272 m_httpHeaderFields.remove("Origin");
274 if (url().protocolInHTTPFamily())
275 m_platformRequestUpdated = false;
278 #if PLATFORM(MAC) || PLATFORM(WIN)
279 void ResourceRequestBase::setResponseContentDispositionEncodingFallbackArray(const String& encoding1, const String& encoding2, const String& encoding3)
281 updateResourceRequest();
283 m_responseContentDispositionEncodingFallbackArray.clear();
284 if (!encoding1.isNull())
285 m_responseContentDispositionEncodingFallbackArray.append(encoding1);
286 if (!encoding2.isNull())
287 m_responseContentDispositionEncodingFallbackArray.append(encoding2);
288 if (!encoding3.isNull())
289 m_responseContentDispositionEncodingFallbackArray.append(encoding3);
291 if (url().protocolInHTTPFamily())
292 m_platformRequestUpdated = false;
296 FormData* ResourceRequestBase::httpBody() const
298 updateResourceRequest();
300 return m_httpBody.get();
303 void ResourceRequestBase::setHTTPBody(PassRefPtr<FormData> httpBody)
305 updateResourceRequest();
307 m_httpBody = httpBody;
309 if (url().protocolInHTTPFamily())
310 m_platformRequestUpdated = false;
313 bool ResourceRequestBase::allowCookies() const
315 updateResourceRequest();
317 return m_allowCookies;
320 void ResourceRequestBase::setAllowCookies(bool allowCookies)
322 updateResourceRequest();
324 m_allowCookies = allowCookies;
326 if (url().protocolInHTTPFamily())
327 m_platformRequestUpdated = false;
330 ResourceLoadPriority ResourceRequestBase::priority() const
332 updateResourceRequest();
337 void ResourceRequestBase::setPriority(ResourceLoadPriority priority)
339 updateResourceRequest();
341 m_priority = priority;
343 if (url().protocolInHTTPFamily())
344 m_platformRequestUpdated = false;
347 void ResourceRequestBase::addHTTPHeaderField(const AtomicString& name, const String& value)
349 updateResourceRequest();
350 pair<HTTPHeaderMap::iterator, bool> result = m_httpHeaderFields.add(name, value);
352 result.first->second += "," + value;
354 if (url().protocolInHTTPFamily())
355 m_platformRequestUpdated = false;
358 void ResourceRequestBase::addHTTPHeaderFields(const HTTPHeaderMap& headerFields)
360 HTTPHeaderMap::const_iterator end = headerFields.end();
361 for (HTTPHeaderMap::const_iterator it = headerFields.begin(); it != end; ++it)
362 addHTTPHeaderField(it->first, it->second);
365 bool equalIgnoringHeaderFields(const ResourceRequestBase& a, const ResourceRequestBase& b)
367 if (a.url() != b.url())
370 if (a.cachePolicy() != b.cachePolicy())
373 if (a.timeoutInterval() != b.timeoutInterval())
376 if (a.firstPartyForCookies() != b.firstPartyForCookies())
379 if (a.httpMethod() != b.httpMethod())
382 if (a.allowCookies() != b.allowCookies())
385 if (a.priority() != b.priority())
388 FormData* formDataA = a.httpBody();
389 FormData* formDataB = b.httpBody();
396 if (*formDataA != *formDataB)
402 bool ResourceRequestBase::compare(const ResourceRequest& a, const ResourceRequest& b)
404 if (!equalIgnoringHeaderFields(a, b))
407 if (a.httpHeaderFields() != b.httpHeaderFields())
410 return ResourceRequest::platformCompare(a, b);
413 bool ResourceRequestBase::isConditional() const
415 return (m_httpHeaderFields.contains("If-Match") ||
416 m_httpHeaderFields.contains("If-Modified-Since") ||
417 m_httpHeaderFields.contains("If-None-Match") ||
418 m_httpHeaderFields.contains("If-Range") ||
419 m_httpHeaderFields.contains("If-Unmodified-Since"));
422 double ResourceRequestBase::defaultTimeoutInterval()
424 return s_defaultTimeoutInterval;
427 void ResourceRequestBase::setDefaultTimeoutInterval(double timeoutInterval)
429 s_defaultTimeoutInterval = timeoutInterval;
432 void ResourceRequestBase::updatePlatformRequest() const
434 if (m_platformRequestUpdated)
437 ASSERT(m_resourceRequestUpdated);
438 const_cast<ResourceRequest&>(asResourceRequest()).doUpdatePlatformRequest();
439 m_platformRequestUpdated = true;
442 void ResourceRequestBase::updateResourceRequest() const
444 if (m_resourceRequestUpdated)
447 ASSERT(m_platformRequestUpdated);
448 const_cast<ResourceRequest&>(asResourceRequest()).doUpdateResourceRequest();
449 m_resourceRequestUpdated = true;
452 #if !PLATFORM(MAC) && !USE(CFNETWORK) && !USE(SOUP) && !PLATFORM(CHROMIUM) && !PLATFORM(QT)
453 unsigned initializeMaximumHTTPConnectionCountPerHost()
455 // This is used by the loader to control the number of issued parallel load requests.
456 // Four seems to be a common default in HTTP frameworks.