ae8316a98201fd0479723a27263dca2a55d5eb32
[WebKit-https.git] / Source / WebCore / platform / network / ResourceRequestBase.cpp
1 /*
2  * Copyright (C) 2003, 2006 Apple Computer, Inc.  All rights reserved.
3  * Copyright (C) 2009 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 #include "config.h"
27
28 #include "ResourceRequestBase.h"
29 #include "ResourceRequest.h"
30
31 using namespace std;
32
33 namespace WebCore {
34
35 inline const ResourceRequest& ResourceRequestBase::asResourceRequest() const
36 {
37     return *static_cast<const ResourceRequest*>(this);
38 }
39
40 PassOwnPtr<ResourceRequest> ResourceRequestBase::adopt(PassOwnPtr<CrossThreadResourceRequestData> data)
41 {
42     OwnPtr<ResourceRequest> request(new ResourceRequest());
43     request->setURL(data->m_url);
44     request->setCachePolicy(data->m_cachePolicy);
45     request->setTimeoutInterval(data->m_timeoutInterval);
46     request->setFirstPartyForCookies(data->m_firstPartyForCookies);
47     request->setHTTPMethod(data->m_httpMethod);
48     request->setTargetType(data->m_targetType);
49
50     request->updateResourceRequest();
51     request->m_httpHeaderFields.adopt(data->m_httpHeaders.release());
52
53     size_t encodingCount = data->m_responseContentDispositionEncodingFallbackArray.size();
54     if (encodingCount > 0) {
55         String encoding1 = data->m_responseContentDispositionEncodingFallbackArray[0];
56         String encoding2;
57         String encoding3;
58         if (encodingCount > 1) {
59             encoding2 = data->m_responseContentDispositionEncodingFallbackArray[1];
60             if (encodingCount > 2)
61                 encoding3 = data->m_responseContentDispositionEncodingFallbackArray[2];
62         }
63         ASSERT(encodingCount <= 3);
64         request->setResponseContentDispositionEncodingFallbackArray(encoding1, encoding2, encoding3);
65     }
66     request->setHTTPBody(data->m_httpBody);
67     request->setAllowCookies(data->m_allowCookies);
68     request->doPlatformAdopt(data);
69     return request.release();
70 }
71
72 PassOwnPtr<CrossThreadResourceRequestData> ResourceRequestBase::copyData() const
73 {
74     OwnPtr<CrossThreadResourceRequestData> data(new CrossThreadResourceRequestData());
75     data->m_url = url().copy();
76     data->m_cachePolicy = cachePolicy();
77     data->m_timeoutInterval = timeoutInterval();
78     data->m_firstPartyForCookies = firstPartyForCookies().copy();
79     data->m_httpMethod = httpMethod().crossThreadString();
80     data->m_httpHeaders = httpHeaderFields().copyData();
81     data->m_targetType = m_targetType;
82
83     data->m_responseContentDispositionEncodingFallbackArray.reserveInitialCapacity(m_responseContentDispositionEncodingFallbackArray.size());
84     size_t encodingArraySize = m_responseContentDispositionEncodingFallbackArray.size();
85     for (size_t index = 0; index < encodingArraySize; ++index) {
86         data->m_responseContentDispositionEncodingFallbackArray.append(m_responseContentDispositionEncodingFallbackArray[index].crossThreadString());
87     }
88     if (m_httpBody)
89         data->m_httpBody = m_httpBody->deepCopy();
90     data->m_allowCookies = m_allowCookies;
91     return asResourceRequest().doPlatformCopyData(data.release());
92 }
93
94 bool ResourceRequestBase::isEmpty() const
95 {
96     updateResourceRequest(); 
97     
98     return m_url.isEmpty(); 
99 }
100
101 bool ResourceRequestBase::isNull() const
102 {
103     updateResourceRequest(); 
104     
105     return m_url.isNull();
106 }
107
108 const KURL& ResourceRequestBase::url() const 
109 {
110     updateResourceRequest(); 
111     
112     return m_url;
113 }
114
115 void ResourceRequestBase::setURL(const KURL& url)
116
117     updateResourceRequest(); 
118
119     m_url = url; 
120     
121     m_platformRequestUpdated = false;
122 }
123
124 void ResourceRequestBase::removeCredentials()
125 {
126     updateResourceRequest(); 
127
128     m_url.setUser(String());
129     m_url.setPass(String());
130
131     m_platformRequestUpdated = false;
132 }
133
134 ResourceRequestCachePolicy ResourceRequestBase::cachePolicy() const
135 {
136     updateResourceRequest(); 
137     
138     return m_cachePolicy; 
139 }
140
141 void ResourceRequestBase::setCachePolicy(ResourceRequestCachePolicy cachePolicy)
142 {
143     updateResourceRequest(); 
144     
145     m_cachePolicy = cachePolicy;
146     
147     if (url().protocolInHTTPFamily())
148         m_platformRequestUpdated = false;
149 }
150
151 double ResourceRequestBase::timeoutInterval() const
152 {
153     updateResourceRequest(); 
154     
155     return m_timeoutInterval; 
156 }
157
158 void ResourceRequestBase::setTimeoutInterval(double timeoutInterval) 
159 {
160     updateResourceRequest(); 
161     
162     m_timeoutInterval = timeoutInterval; 
163     
164     if (url().protocolInHTTPFamily())
165         m_platformRequestUpdated = false;
166 }
167
168 const KURL& ResourceRequestBase::firstPartyForCookies() const
169 {
170     updateResourceRequest(); 
171     
172     return m_firstPartyForCookies;
173 }
174
175 void ResourceRequestBase::setFirstPartyForCookies(const KURL& firstPartyForCookies)
176
177     updateResourceRequest(); 
178     
179     m_firstPartyForCookies = firstPartyForCookies;
180     
181     m_platformRequestUpdated = false;
182 }
183
184 const String& ResourceRequestBase::httpMethod() const
185 {
186     updateResourceRequest(); 
187     
188     return m_httpMethod; 
189 }
190
191 void ResourceRequestBase::setHTTPMethod(const String& httpMethod) 
192 {
193     updateResourceRequest(); 
194
195     m_httpMethod = httpMethod;
196     
197     if (url().protocolInHTTPFamily())
198         m_platformRequestUpdated = false;
199 }
200
201 const HTTPHeaderMap& ResourceRequestBase::httpHeaderFields() const
202 {
203     updateResourceRequest(); 
204
205     return m_httpHeaderFields; 
206 }
207
208 String ResourceRequestBase::httpHeaderField(const AtomicString& name) const
209 {
210     updateResourceRequest(); 
211     
212     return m_httpHeaderFields.get(name);
213 }
214
215 String ResourceRequestBase::httpHeaderField(const char* name) const
216 {
217     updateResourceRequest(); 
218     
219     return m_httpHeaderFields.get(name);
220 }
221
222 void ResourceRequestBase::setHTTPHeaderField(const AtomicString& name, const String& value)
223 {
224     updateResourceRequest(); 
225     
226     m_httpHeaderFields.set(name, value); 
227     
228     if (url().protocolInHTTPFamily())
229         m_platformRequestUpdated = false;
230 }
231
232 void ResourceRequestBase::setHTTPHeaderField(const char* name, const String& value)
233 {
234     setHTTPHeaderField(AtomicString(name), value);
235 }
236
237 void ResourceRequestBase::clearHTTPAuthorization()
238 {
239     updateResourceRequest(); 
240
241     m_httpHeaderFields.remove("Authorization");
242
243     if (url().protocolInHTTPFamily())
244         m_platformRequestUpdated = false;
245 }
246
247 void ResourceRequestBase::clearHTTPReferrer()
248 {
249     updateResourceRequest(); 
250
251     m_httpHeaderFields.remove("Referer");
252
253     if (url().protocolInHTTPFamily())
254         m_platformRequestUpdated = false;
255 }
256
257 void ResourceRequestBase::clearHTTPOrigin()
258 {
259     updateResourceRequest(); 
260
261     m_httpHeaderFields.remove("Origin");
262
263     if (url().protocolInHTTPFamily())
264         m_platformRequestUpdated = false;
265 }
266
267 void ResourceRequestBase::setResponseContentDispositionEncodingFallbackArray(const String& encoding1, const String& encoding2, const String& encoding3)
268 {
269     updateResourceRequest(); 
270     
271     m_responseContentDispositionEncodingFallbackArray.clear();
272     if (!encoding1.isNull())
273         m_responseContentDispositionEncodingFallbackArray.append(encoding1);
274     if (!encoding2.isNull())
275         m_responseContentDispositionEncodingFallbackArray.append(encoding2);
276     if (!encoding3.isNull())
277         m_responseContentDispositionEncodingFallbackArray.append(encoding3);
278     
279     if (url().protocolInHTTPFamily())
280         m_platformRequestUpdated = false;
281 }
282
283 FormData* ResourceRequestBase::httpBody() const 
284
285     updateResourceRequest(); 
286     
287     return m_httpBody.get(); 
288 }
289
290 void ResourceRequestBase::setHTTPBody(PassRefPtr<FormData> httpBody)
291 {
292     updateResourceRequest(); 
293     
294     m_httpBody = httpBody; 
295     
296     if (url().protocolInHTTPFamily())
297         m_platformRequestUpdated = false;
298
299
300 bool ResourceRequestBase::allowCookies() const
301 {
302     updateResourceRequest(); 
303     
304     return m_allowCookies;
305 }
306
307 void ResourceRequestBase::setAllowCookies(bool allowCookies)
308 {
309     updateResourceRequest(); 
310     
311     m_allowCookies = allowCookies;
312     
313     if (url().protocolInHTTPFamily())
314         m_platformRequestUpdated = false;
315 }
316
317 void ResourceRequestBase::addHTTPHeaderField(const AtomicString& name, const String& value) 
318 {
319     updateResourceRequest();
320     pair<HTTPHeaderMap::iterator, bool> result = m_httpHeaderFields.add(name, value); 
321     if (!result.second)
322         result.first->second += "," + value;
323
324     if (url().protocolInHTTPFamily())
325         m_platformRequestUpdated = false;
326 }
327
328 void ResourceRequestBase::addHTTPHeaderFields(const HTTPHeaderMap& headerFields)
329 {
330     HTTPHeaderMap::const_iterator end = headerFields.end();
331     for (HTTPHeaderMap::const_iterator it = headerFields.begin(); it != end; ++it)
332         addHTTPHeaderField(it->first, it->second);
333 }
334
335 bool equalIgnoringHeaderFields(const ResourceRequestBase& a, const ResourceRequestBase& b)
336 {
337     if (a.url() != b.url())
338         return false;
339     
340     if (a.cachePolicy() != b.cachePolicy())
341         return false;
342     
343     if (a.timeoutInterval() != b.timeoutInterval())
344         return false;
345     
346     if (a.firstPartyForCookies() != b.firstPartyForCookies())
347         return false;
348     
349     if (a.httpMethod() != b.httpMethod())
350         return false;
351     
352     if (a.allowCookies() != b.allowCookies())
353         return false;
354     
355     FormData* formDataA = a.httpBody();
356     FormData* formDataB = b.httpBody();
357     
358     if (!formDataA)
359         return !formDataB;
360     if (!formDataB)
361         return !formDataA;
362     
363     if (*formDataA != *formDataB)
364         return false;
365     
366     return true;
367 }
368
369 bool ResourceRequestBase::compare(const ResourceRequest& a, const ResourceRequest& b)
370 {
371     if (!equalIgnoringHeaderFields(a, b))
372         return false;
373     
374     if (a.httpHeaderFields() != b.httpHeaderFields())
375         return false;
376         
377     return ResourceRequest::platformCompare(a, b);
378 }
379
380 bool ResourceRequestBase::isConditional() const
381 {
382     return (m_httpHeaderFields.contains("If-Match") ||
383             m_httpHeaderFields.contains("If-Modified-Since") ||
384             m_httpHeaderFields.contains("If-None-Match") ||
385             m_httpHeaderFields.contains("If-Range") ||
386             m_httpHeaderFields.contains("If-Unmodified-Since"));
387 }
388
389 void ResourceRequestBase::updatePlatformRequest() const
390 {
391     if (m_platformRequestUpdated)
392         return;
393     
394     const_cast<ResourceRequest&>(asResourceRequest()).doUpdatePlatformRequest();
395     m_platformRequestUpdated = true;
396 }
397
398 void ResourceRequestBase::updateResourceRequest() const
399 {
400     if (m_resourceRequestUpdated)
401         return;
402
403     const_cast<ResourceRequest&>(asResourceRequest()).doUpdateResourceRequest();
404     m_resourceRequestUpdated = true;
405 }
406
407 #if !PLATFORM(MAC) && !USE(CFNETWORK) && !USE(SOUP) && !PLATFORM(CHROMIUM) && !PLATFORM(ANDROID) && !PLATFORM(QT)
408 unsigned initializeMaximumHTTPConnectionCountPerHost()
409 {
410     // This is used by the loader to control the number of issued parallel load requests. 
411     // Four seems to be a common default in HTTP frameworks.
412     return 4;
413 }
414 #endif
415
416 }