2 * Copyright (C) 2003, 2006 Apple Computer, 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 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 "platform/network/ResourceRequest.h"
29 #include "platform/weborigin/SecurityOrigin.h"
30 #include "public/platform/WebURLRequest.h"
34 double ResourceRequest::s_defaultTimeoutInterval = INT_MAX;
36 PassOwnPtr<ResourceRequest> ResourceRequest::adopt(PassOwnPtr<CrossThreadResourceRequestData> data)
38 OwnPtr<ResourceRequest> request = adoptPtr(new ResourceRequest());
39 request->setURL(data->m_url);
40 request->setCachePolicy(data->m_cachePolicy);
41 request->setTimeoutInterval(data->m_timeoutInterval);
42 request->setFirstPartyForCookies(data->m_firstPartyForCookies);
43 request->setHTTPMethod(AtomicString(data->m_httpMethod));
44 request->setPriority(data->m_priority, data->m_intraPriorityValue);
46 request->m_httpHeaderFields.adopt(data->m_httpHeaders.release());
48 request->setHTTPBody(data->m_httpBody);
49 request->setAllowStoredCredentials(data->m_allowStoredCredentials);
50 request->setReportUploadProgress(data->m_reportUploadProgress);
51 request->setHasUserGesture(data->m_hasUserGesture);
52 request->setDownloadToFile(data->m_downloadToFile);
53 request->setSkipServiceWorker(data->m_skipServiceWorker);
54 request->setRequestorID(data->m_requestorID);
55 request->setRequestorProcessID(data->m_requestorProcessID);
56 request->setAppCacheHostID(data->m_appCacheHostID);
57 request->setRequestContext(data->m_requestContext);
58 request->setFrameType(data->m_frameType);
59 request->setFetchRequestMode(data->m_fetchRequestMode);
60 request->setFetchCredentialsMode(data->m_fetchCredentialsMode);
61 request->m_referrerPolicy = data->m_referrerPolicy;
62 return request.release();
65 PassOwnPtr<CrossThreadResourceRequestData> ResourceRequest::copyData() const
67 OwnPtr<CrossThreadResourceRequestData> data = adoptPtr(new CrossThreadResourceRequestData());
68 data->m_url = url().copy();
69 data->m_cachePolicy = cachePolicy();
70 data->m_timeoutInterval = timeoutInterval();
71 data->m_firstPartyForCookies = firstPartyForCookies().copy();
72 data->m_httpMethod = httpMethod().string().isolatedCopy();
73 data->m_httpHeaders = httpHeaderFields().copyData();
74 data->m_priority = priority();
75 data->m_intraPriorityValue = m_intraPriorityValue;
78 data->m_httpBody = m_httpBody->deepCopy();
79 data->m_allowStoredCredentials = m_allowStoredCredentials;
80 data->m_reportUploadProgress = m_reportUploadProgress;
81 data->m_hasUserGesture = m_hasUserGesture;
82 data->m_downloadToFile = m_downloadToFile;
83 data->m_skipServiceWorker = m_skipServiceWorker;
84 data->m_requestorID = m_requestorID;
85 data->m_requestorProcessID = m_requestorProcessID;
86 data->m_appCacheHostID = m_appCacheHostID;
87 data->m_requestContext = m_requestContext;
88 data->m_frameType = m_frameType;
89 data->m_fetchRequestMode = m_fetchRequestMode;
90 data->m_fetchCredentialsMode = m_fetchCredentialsMode;
91 data->m_referrerPolicy = m_referrerPolicy;
92 return data.release();
95 bool ResourceRequest::isEmpty() const
97 return m_url.isEmpty();
100 bool ResourceRequest::isNull() const
102 return m_url.isNull();
105 const KURL& ResourceRequest::url() const
110 void ResourceRequest::setURL(const KURL& url)
115 void ResourceRequest::removeCredentials()
117 if (m_url.user().isEmpty() && m_url.pass().isEmpty())
120 m_url.setUser(String());
121 m_url.setPass(String());
124 ResourceRequestCachePolicy ResourceRequest::cachePolicy() const
126 return m_cachePolicy;
129 void ResourceRequest::setCachePolicy(ResourceRequestCachePolicy cachePolicy)
131 m_cachePolicy = cachePolicy;
134 double ResourceRequest::timeoutInterval() const
136 return m_timeoutInterval;
139 void ResourceRequest::setTimeoutInterval(double timeoutInterval)
141 m_timeoutInterval = timeoutInterval;
144 const KURL& ResourceRequest::firstPartyForCookies() const
146 return m_firstPartyForCookies;
149 void ResourceRequest::setFirstPartyForCookies(const KURL& firstPartyForCookies)
151 m_firstPartyForCookies = firstPartyForCookies;
154 const AtomicString& ResourceRequest::httpMethod() const
159 void ResourceRequest::setHTTPMethod(const AtomicString& httpMethod)
161 m_httpMethod = httpMethod;
164 const HTTPHeaderMap& ResourceRequest::httpHeaderFields() const
166 return m_httpHeaderFields;
169 const AtomicString& ResourceRequest::httpHeaderField(const AtomicString& name) const
171 return m_httpHeaderFields.get(name);
174 const AtomicString& ResourceRequest::httpHeaderField(const char* name) const
176 return m_httpHeaderFields.get(name);
179 void ResourceRequest::setHTTPHeaderField(const AtomicString& name, const AtomicString& value)
181 m_httpHeaderFields.set(name, value);
184 void ResourceRequest::setHTTPHeaderField(const char* name, const AtomicString& value)
186 setHTTPHeaderField(AtomicString(name), value);
189 void ResourceRequest::setHTTPReferrer(const Referrer& referrer)
191 if (referrer.referrer.isEmpty())
192 m_httpHeaderFields.remove("Referer");
194 setHTTPHeaderField("Referer", referrer.referrer);
195 m_referrerPolicy = referrer.referrerPolicy;
198 void ResourceRequest::clearHTTPAuthorization()
200 m_httpHeaderFields.remove("Authorization");
203 void ResourceRequest::clearHTTPReferrer()
205 m_httpHeaderFields.remove("Referer");
206 m_referrerPolicy = ReferrerPolicyDefault;
209 void ResourceRequest::clearHTTPOrigin()
211 m_httpHeaderFields.remove("Origin");
214 void ResourceRequest::addHTTPOriginIfNeeded(const AtomicString& origin)
216 if (!httpOrigin().isEmpty())
217 return; // Request already has an Origin header.
219 // Don't send an Origin header for GET or HEAD to avoid privacy issues.
220 // For example, if an intranet page has a hyperlink to an external web
221 // site, we don't want to include the Origin of the request because it
222 // will leak the internal host name. Similar privacy concerns have lead
223 // to the widespread suppression of the Referer header at the network
225 if (httpMethod() == "GET" || httpMethod() == "HEAD")
228 // For non-GET and non-HEAD methods, always send an Origin header so the
229 // server knows we support this feature.
231 if (origin.isEmpty()) {
232 // If we don't know what origin header to attach, we attach the value
233 // for an empty origin.
234 setHTTPOrigin(SecurityOrigin::createUnique()->toAtomicString());
237 setHTTPOrigin(origin);
240 void ResourceRequest::clearHTTPUserAgent()
242 m_httpHeaderFields.remove("User-Agent");
245 FormData* ResourceRequest::httpBody() const
247 return m_httpBody.get();
250 void ResourceRequest::setHTTPBody(PassRefPtr<FormData> httpBody)
252 m_httpBody = httpBody;
255 bool ResourceRequest::allowStoredCredentials() const
257 return m_allowStoredCredentials;
260 void ResourceRequest::setAllowStoredCredentials(bool allowCredentials)
262 m_allowStoredCredentials = allowCredentials;
265 ResourceLoadPriority ResourceRequest::priority() const
270 void ResourceRequest::setPriority(ResourceLoadPriority priority, int intraPriorityValue)
272 m_priority = priority;
273 m_intraPriorityValue = intraPriorityValue;
276 void ResourceRequest::addHTTPHeaderField(const AtomicString& name, const AtomicString& value)
278 HTTPHeaderMap::AddResult result = m_httpHeaderFields.add(name, value);
279 if (!result.isNewEntry)
280 result.storedValue->value = result.storedValue->value + ',' + value;
283 void ResourceRequest::addHTTPHeaderFields(const HTTPHeaderMap& headerFields)
285 HTTPHeaderMap::const_iterator end = headerFields.end();
286 for (HTTPHeaderMap::const_iterator it = headerFields.begin(); it != end; ++it)
287 addHTTPHeaderField(it->key, it->value);
290 void ResourceRequest::clearHTTPHeaderField(const AtomicString& name)
292 m_httpHeaderFields.remove(name);
295 bool equalIgnoringHeaderFields(const ResourceRequest& a, const ResourceRequest& b)
297 if (a.url() != b.url())
300 if (a.cachePolicy() != b.cachePolicy())
303 if (a.timeoutInterval() != b.timeoutInterval())
306 if (a.firstPartyForCookies() != b.firstPartyForCookies())
309 if (a.httpMethod() != b.httpMethod())
312 if (a.allowStoredCredentials() != b.allowStoredCredentials())
315 if (a.priority() != b.priority())
318 if (a.referrerPolicy() != b.referrerPolicy())
321 FormData* formDataA = a.httpBody();
322 FormData* formDataB = b.httpBody();
329 if (*formDataA != *formDataB)
335 bool ResourceRequest::compare(const ResourceRequest& a, const ResourceRequest& b)
337 if (!equalIgnoringHeaderFields(a, b))
340 if (a.httpHeaderFields() != b.httpHeaderFields())
346 bool ResourceRequest::isConditional() const
348 return (m_httpHeaderFields.contains("If-Match")
349 || m_httpHeaderFields.contains("If-Modified-Since")
350 || m_httpHeaderFields.contains("If-None-Match")
351 || m_httpHeaderFields.contains("If-Range")
352 || m_httpHeaderFields.contains("If-Unmodified-Since"));
356 static const AtomicString& cacheControlHeaderString()
358 DEFINE_STATIC_LOCAL(const AtomicString, cacheControlHeader, ("cache-control", AtomicString::ConstructFromLiteral));
359 return cacheControlHeader;
362 static const AtomicString& pragmaHeaderString()
364 DEFINE_STATIC_LOCAL(const AtomicString, pragmaHeader, ("pragma", AtomicString::ConstructFromLiteral));
368 const CacheControlHeader& ResourceRequest::cacheControlHeader() const
370 if (!m_cacheControlHeaderCache.parsed)
371 m_cacheControlHeaderCache = parseCacheControlDirectives(m_httpHeaderFields.get(cacheControlHeaderString()), m_httpHeaderFields.get(pragmaHeaderString()));
372 return m_cacheControlHeaderCache;
375 bool ResourceRequest::cacheControlContainsNoCache() const
377 return cacheControlHeader().containsNoCache;
380 bool ResourceRequest::cacheControlContainsNoStore() const
382 return cacheControlHeader().containsNoStore;
385 bool ResourceRequest::hasCacheValidatorFields() const
387 DEFINE_STATIC_LOCAL(const AtomicString, lastModifiedHeader, ("last-modified", AtomicString::ConstructFromLiteral));
388 DEFINE_STATIC_LOCAL(const AtomicString, eTagHeader, ("etag", AtomicString::ConstructFromLiteral));
389 return !m_httpHeaderFields.get(lastModifiedHeader).isEmpty() || !m_httpHeaderFields.get(eTagHeader).isEmpty();
392 double ResourceRequest::defaultTimeoutInterval()
394 return s_defaultTimeoutInterval;
397 void ResourceRequest::setDefaultTimeoutInterval(double timeoutInterval)
399 s_defaultTimeoutInterval = timeoutInterval;
402 void ResourceRequest::initialize(const KURL& url)
405 m_cachePolicy = UseProtocolCachePolicy;
406 m_timeoutInterval = s_defaultTimeoutInterval;
407 m_httpMethod = "GET";
408 m_allowStoredCredentials = true;
409 m_reportUploadProgress = false;
410 m_reportRawHeaders = false;
411 m_hasUserGesture = false;
412 m_downloadToFile = false;
413 m_skipServiceWorker = false;
414 m_priority = ResourceLoadPriorityLowest;
415 m_intraPriorityValue = 0;
417 m_requestorProcessID = 0;
418 m_appCacheHostID = 0;
419 m_requestContext = WebURLRequest::RequestContextUnspecified;
420 m_frameType = WebURLRequest::FrameTypeNone;
421 m_fetchRequestMode = WebURLRequest::FetchRequestModeNoCORS;
422 // Contrary to the Fetch spec, we default to same-origin mode here, and deal
423 // with CORS modes in updateRequestForAccessControl if we're called in a
424 // context which requires it.
425 m_fetchCredentialsMode = WebURLRequest::FetchCredentialsModeSameOrigin;
426 m_referrerPolicy = ReferrerPolicyDefault;
429 // This is used by the loader to control the number of issued parallel load requests.
430 unsigned initializeMaximumHTTPConnectionCountPerHost()
432 // The chromium network stack already handles limiting the number of
433 // parallel requests per host, so there's no need to do it here. Therefore,
434 // this is set to a high value that should never be hit in practice.