Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / platform / network / ResourceRequest.cpp
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 #include "platform/weborigin/SecurityOrigin.h"
30 #include "public/platform/WebURLRequest.h"
31
32 namespace blink {
33
34 double ResourceRequest::s_defaultTimeoutInterval = INT_MAX;
35
36 PassOwnPtr<ResourceRequest> ResourceRequest::adopt(PassOwnPtr<CrossThreadResourceRequestData> data)
37 {
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);
45
46     request->m_httpHeaderFields.adopt(data->m_httpHeaders.release());
47
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();
63 }
64
65 PassOwnPtr<CrossThreadResourceRequestData> ResourceRequest::copyData() const
66 {
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;
76
77     if (m_httpBody)
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();
93 }
94
95 bool ResourceRequest::isEmpty() const
96 {
97     return m_url.isEmpty();
98 }
99
100 bool ResourceRequest::isNull() const
101 {
102     return m_url.isNull();
103 }
104
105 const KURL& ResourceRequest::url() const
106 {
107     return m_url;
108 }
109
110 void ResourceRequest::setURL(const KURL& url)
111 {
112     m_url = url;
113 }
114
115 void ResourceRequest::removeCredentials()
116 {
117     if (m_url.user().isEmpty() && m_url.pass().isEmpty())
118         return;
119
120     m_url.setUser(String());
121     m_url.setPass(String());
122 }
123
124 ResourceRequestCachePolicy ResourceRequest::cachePolicy() const
125 {
126     return m_cachePolicy;
127 }
128
129 void ResourceRequest::setCachePolicy(ResourceRequestCachePolicy cachePolicy)
130 {
131     m_cachePolicy = cachePolicy;
132 }
133
134 double ResourceRequest::timeoutInterval() const
135 {
136     return m_timeoutInterval;
137 }
138
139 void ResourceRequest::setTimeoutInterval(double timeoutInterval)
140 {
141     m_timeoutInterval = timeoutInterval;
142 }
143
144 const KURL& ResourceRequest::firstPartyForCookies() const
145 {
146     return m_firstPartyForCookies;
147 }
148
149 void ResourceRequest::setFirstPartyForCookies(const KURL& firstPartyForCookies)
150 {
151     m_firstPartyForCookies = firstPartyForCookies;
152 }
153
154 const AtomicString& ResourceRequest::httpMethod() const
155 {
156     return m_httpMethod;
157 }
158
159 void ResourceRequest::setHTTPMethod(const AtomicString& httpMethod)
160 {
161     m_httpMethod = httpMethod;
162 }
163
164 const HTTPHeaderMap& ResourceRequest::httpHeaderFields() const
165 {
166     return m_httpHeaderFields;
167 }
168
169 const AtomicString& ResourceRequest::httpHeaderField(const AtomicString& name) const
170 {
171     return m_httpHeaderFields.get(name);
172 }
173
174 const AtomicString& ResourceRequest::httpHeaderField(const char* name) const
175 {
176     return m_httpHeaderFields.get(name);
177 }
178
179 void ResourceRequest::setHTTPHeaderField(const AtomicString& name, const AtomicString& value)
180 {
181     m_httpHeaderFields.set(name, value);
182 }
183
184 void ResourceRequest::setHTTPHeaderField(const char* name, const AtomicString& value)
185 {
186     setHTTPHeaderField(AtomicString(name), value);
187 }
188
189 void ResourceRequest::setHTTPReferrer(const Referrer& referrer)
190 {
191     if (referrer.referrer.isEmpty())
192         m_httpHeaderFields.remove("Referer");
193     else
194         setHTTPHeaderField("Referer", referrer.referrer);
195     m_referrerPolicy = referrer.referrerPolicy;
196 }
197
198 void ResourceRequest::clearHTTPAuthorization()
199 {
200     m_httpHeaderFields.remove("Authorization");
201 }
202
203 void ResourceRequest::clearHTTPReferrer()
204 {
205     m_httpHeaderFields.remove("Referer");
206     m_referrerPolicy = ReferrerPolicyDefault;
207 }
208
209 void ResourceRequest::clearHTTPOrigin()
210 {
211     m_httpHeaderFields.remove("Origin");
212 }
213
214 void ResourceRequest::addHTTPOriginIfNeeded(const AtomicString& origin)
215 {
216     if (!httpOrigin().isEmpty())
217         return; // Request already has an Origin header.
218
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
224     // layer.
225     if (httpMethod() == "GET" || httpMethod() == "HEAD")
226         return;
227
228     // For non-GET and non-HEAD methods, always send an Origin header so the
229     // server knows we support this feature.
230
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());
235         return;
236     }
237     setHTTPOrigin(origin);
238 }
239
240 void ResourceRequest::clearHTTPUserAgent()
241 {
242     m_httpHeaderFields.remove("User-Agent");
243 }
244
245 FormData* ResourceRequest::httpBody() const
246 {
247     return m_httpBody.get();
248 }
249
250 void ResourceRequest::setHTTPBody(PassRefPtr<FormData> httpBody)
251 {
252     m_httpBody = httpBody;
253 }
254
255 bool ResourceRequest::allowStoredCredentials() const
256 {
257     return m_allowStoredCredentials;
258 }
259
260 void ResourceRequest::setAllowStoredCredentials(bool allowCredentials)
261 {
262     m_allowStoredCredentials = allowCredentials;
263 }
264
265 ResourceLoadPriority ResourceRequest::priority() const
266 {
267     return m_priority;
268 }
269
270 void ResourceRequest::setPriority(ResourceLoadPriority priority, int intraPriorityValue)
271 {
272     m_priority = priority;
273     m_intraPriorityValue = intraPriorityValue;
274 }
275
276 void ResourceRequest::addHTTPHeaderField(const AtomicString& name, const AtomicString& value)
277 {
278     HTTPHeaderMap::AddResult result = m_httpHeaderFields.add(name, value);
279     if (!result.isNewEntry)
280         result.storedValue->value = result.storedValue->value + ',' + value;
281 }
282
283 void ResourceRequest::addHTTPHeaderFields(const HTTPHeaderMap& headerFields)
284 {
285     HTTPHeaderMap::const_iterator end = headerFields.end();
286     for (HTTPHeaderMap::const_iterator it = headerFields.begin(); it != end; ++it)
287         addHTTPHeaderField(it->key, it->value);
288 }
289
290 void ResourceRequest::clearHTTPHeaderField(const AtomicString& name)
291 {
292     m_httpHeaderFields.remove(name);
293 }
294
295 bool equalIgnoringHeaderFields(const ResourceRequest& a, const ResourceRequest& b)
296 {
297     if (a.url() != b.url())
298         return false;
299
300     if (a.cachePolicy() != b.cachePolicy())
301         return false;
302
303     if (a.timeoutInterval() != b.timeoutInterval())
304         return false;
305
306     if (a.firstPartyForCookies() != b.firstPartyForCookies())
307         return false;
308
309     if (a.httpMethod() != b.httpMethod())
310         return false;
311
312     if (a.allowStoredCredentials() != b.allowStoredCredentials())
313         return false;
314
315     if (a.priority() != b.priority())
316         return false;
317
318     if (a.referrerPolicy() != b.referrerPolicy())
319         return false;
320
321     FormData* formDataA = a.httpBody();
322     FormData* formDataB = b.httpBody();
323
324     if (!formDataA)
325         return !formDataB;
326     if (!formDataB)
327         return !formDataA;
328
329     if (*formDataA != *formDataB)
330         return false;
331
332     return true;
333 }
334
335 bool ResourceRequest::compare(const ResourceRequest& a, const ResourceRequest& b)
336 {
337     if (!equalIgnoringHeaderFields(a, b))
338         return false;
339
340     if (a.httpHeaderFields() != b.httpHeaderFields())
341         return false;
342
343     return true;
344 }
345
346 bool ResourceRequest::isConditional() const
347 {
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"));
353 }
354
355
356 static const AtomicString& cacheControlHeaderString()
357 {
358     DEFINE_STATIC_LOCAL(const AtomicString, cacheControlHeader, ("cache-control", AtomicString::ConstructFromLiteral));
359     return cacheControlHeader;
360 }
361
362 static const AtomicString& pragmaHeaderString()
363 {
364     DEFINE_STATIC_LOCAL(const AtomicString, pragmaHeader, ("pragma", AtomicString::ConstructFromLiteral));
365     return pragmaHeader;
366 }
367
368 const CacheControlHeader& ResourceRequest::cacheControlHeader() const
369 {
370     if (!m_cacheControlHeaderCache.parsed)
371         m_cacheControlHeaderCache = parseCacheControlDirectives(m_httpHeaderFields.get(cacheControlHeaderString()), m_httpHeaderFields.get(pragmaHeaderString()));
372     return m_cacheControlHeaderCache;
373 }
374
375 bool ResourceRequest::cacheControlContainsNoCache() const
376 {
377     return cacheControlHeader().containsNoCache;
378 }
379
380 bool ResourceRequest::cacheControlContainsNoStore() const
381 {
382     return cacheControlHeader().containsNoStore;
383 }
384
385 bool ResourceRequest::hasCacheValidatorFields() const
386 {
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();
390 }
391
392 double ResourceRequest::defaultTimeoutInterval()
393 {
394     return s_defaultTimeoutInterval;
395 }
396
397 void ResourceRequest::setDefaultTimeoutInterval(double timeoutInterval)
398 {
399     s_defaultTimeoutInterval = timeoutInterval;
400 }
401
402 void ResourceRequest::initialize(const KURL& url)
403 {
404     m_url = 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;
416     m_requestorID = 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;
427 }
428
429 // This is used by the loader to control the number of issued parallel load requests.
430 unsigned initializeMaximumHTTPConnectionCountPerHost()
431 {
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.
435     return 10000;
436 }
437
438 } // namespace blink