initial import
[vuplus_webkit] / 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 #if !PLATFORM(MAC) || USE(CFNETWORK)
36 double ResourceRequestBase::s_defaultTimeoutInterval = INT_MAX;
37 #else
38 // Will use NSURLRequest default timeout unless set to a non-zero value with setDefaultTimeoutInterval().
39 double ResourceRequestBase::s_defaultTimeoutInterval = 0;
40 #endif
41
42 inline const ResourceRequest& ResourceRequestBase::asResourceRequest() const
43 {
44     return *static_cast<const ResourceRequest*>(this);
45 }
46
47 PassOwnPtr<ResourceRequest> ResourceRequestBase::adopt(PassOwnPtr<CrossThreadResourceRequestData> data)
48 {
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);
56
57     request->updateResourceRequest();
58     request->m_httpHeaderFields.adopt(data->m_httpHeaders.release());
59
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];
64         String encoding2;
65         String encoding3;
66         if (encodingCount > 1) {
67             encoding2 = data->m_responseContentDispositionEncodingFallbackArray[1];
68             if (encodingCount > 2)
69                 encoding3 = data->m_responseContentDispositionEncodingFallbackArray[2];
70         }
71         ASSERT(encodingCount <= 3);
72         request->setResponseContentDispositionEncodingFallbackArray(encoding1, encoding2, encoding3);
73     }
74 #endif
75     request->setHTTPBody(data->m_httpBody);
76     request->setAllowCookies(data->m_allowCookies);
77     request->doPlatformAdopt(data);
78     return request.release();
79 }
80
81 PassOwnPtr<CrossThreadResourceRequestData> ResourceRequestBase::copyData() const
82 {
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();
91
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());
97     }
98 #endif
99     if (m_httpBody)
100         data->m_httpBody = m_httpBody->deepCopy();
101     data->m_allowCookies = m_allowCookies;
102     return asResourceRequest().doPlatformCopyData(data.release());
103 }
104
105 bool ResourceRequestBase::isEmpty() const
106 {
107     updateResourceRequest(); 
108     
109     return m_url.isEmpty(); 
110 }
111
112 bool ResourceRequestBase::isNull() const
113 {
114     updateResourceRequest(); 
115     
116     return m_url.isNull();
117 }
118
119 const KURL& ResourceRequestBase::url() const 
120 {
121     updateResourceRequest(); 
122     
123     return m_url;
124 }
125
126 void ResourceRequestBase::setURL(const KURL& url)
127
128     updateResourceRequest(); 
129
130     m_url = url; 
131     
132     m_platformRequestUpdated = false;
133 }
134
135 void ResourceRequestBase::removeCredentials()
136 {
137     updateResourceRequest(); 
138
139     m_url.setUser(String());
140     m_url.setPass(String());
141
142     m_platformRequestUpdated = false;
143 }
144
145 ResourceRequestCachePolicy ResourceRequestBase::cachePolicy() const
146 {
147     updateResourceRequest(); 
148     
149     return m_cachePolicy; 
150 }
151
152 void ResourceRequestBase::setCachePolicy(ResourceRequestCachePolicy cachePolicy)
153 {
154     updateResourceRequest(); 
155     
156     m_cachePolicy = cachePolicy;
157     
158     if (url().protocolInHTTPFamily())
159         m_platformRequestUpdated = false;
160 }
161
162 double ResourceRequestBase::timeoutInterval() const
163 {
164     updateResourceRequest(); 
165     
166     return m_timeoutInterval; 
167 }
168
169 void ResourceRequestBase::setTimeoutInterval(double timeoutInterval) 
170 {
171     updateResourceRequest(); 
172     
173     m_timeoutInterval = timeoutInterval; 
174     
175     if (url().protocolInHTTPFamily())
176         m_platformRequestUpdated = false;
177 }
178
179 const KURL& ResourceRequestBase::firstPartyForCookies() const
180 {
181     updateResourceRequest(); 
182     
183     return m_firstPartyForCookies;
184 }
185
186 void ResourceRequestBase::setFirstPartyForCookies(const KURL& firstPartyForCookies)
187
188     updateResourceRequest(); 
189     
190     m_firstPartyForCookies = firstPartyForCookies;
191     
192     m_platformRequestUpdated = false;
193 }
194
195 const String& ResourceRequestBase::httpMethod() const
196 {
197     updateResourceRequest(); 
198     
199     return m_httpMethod; 
200 }
201
202 void ResourceRequestBase::setHTTPMethod(const String& httpMethod) 
203 {
204     updateResourceRequest(); 
205
206     m_httpMethod = httpMethod;
207     
208     if (url().protocolInHTTPFamily())
209         m_platformRequestUpdated = false;
210 }
211
212 const HTTPHeaderMap& ResourceRequestBase::httpHeaderFields() const
213 {
214     updateResourceRequest(); 
215
216     return m_httpHeaderFields; 
217 }
218
219 String ResourceRequestBase::httpHeaderField(const AtomicString& name) const
220 {
221     updateResourceRequest(); 
222     
223     return m_httpHeaderFields.get(name);
224 }
225
226 String ResourceRequestBase::httpHeaderField(const char* name) const
227 {
228     updateResourceRequest(); 
229     
230     return m_httpHeaderFields.get(name);
231 }
232
233 void ResourceRequestBase::setHTTPHeaderField(const AtomicString& name, const String& value)
234 {
235     updateResourceRequest(); 
236     
237     m_httpHeaderFields.set(name, value); 
238     
239     if (url().protocolInHTTPFamily())
240         m_platformRequestUpdated = false;
241 }
242
243 void ResourceRequestBase::setHTTPHeaderField(const char* name, const String& value)
244 {
245     setHTTPHeaderField(AtomicString(name), value);
246 }
247
248 void ResourceRequestBase::clearHTTPAuthorization()
249 {
250     updateResourceRequest(); 
251
252     m_httpHeaderFields.remove("Authorization");
253
254     if (url().protocolInHTTPFamily())
255         m_platformRequestUpdated = false;
256 }
257
258 void ResourceRequestBase::clearHTTPReferrer()
259 {
260     updateResourceRequest(); 
261
262     m_httpHeaderFields.remove("Referer");
263
264     if (url().protocolInHTTPFamily())
265         m_platformRequestUpdated = false;
266 }
267
268 void ResourceRequestBase::clearHTTPOrigin()
269 {
270     updateResourceRequest(); 
271
272     m_httpHeaderFields.remove("Origin");
273
274     if (url().protocolInHTTPFamily())
275         m_platformRequestUpdated = false;
276 }
277
278 #if PLATFORM(MAC) || PLATFORM(WIN)
279 void ResourceRequestBase::setResponseContentDispositionEncodingFallbackArray(const String& encoding1, const String& encoding2, const String& encoding3)
280 {
281     updateResourceRequest(); 
282     
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);
290     
291     if (url().protocolInHTTPFamily())
292         m_platformRequestUpdated = false;
293 }
294 #endif
295
296 FormData* ResourceRequestBase::httpBody() const 
297
298     updateResourceRequest(); 
299     
300     return m_httpBody.get(); 
301 }
302
303 void ResourceRequestBase::setHTTPBody(PassRefPtr<FormData> httpBody)
304 {
305     updateResourceRequest(); 
306     
307     m_httpBody = httpBody; 
308     
309     if (url().protocolInHTTPFamily())
310         m_platformRequestUpdated = false;
311
312
313 bool ResourceRequestBase::allowCookies() const
314 {
315     updateResourceRequest(); 
316     
317     return m_allowCookies;
318 }
319
320 void ResourceRequestBase::setAllowCookies(bool allowCookies)
321 {
322     updateResourceRequest(); 
323     
324     m_allowCookies = allowCookies;
325     
326     if (url().protocolInHTTPFamily())
327         m_platformRequestUpdated = false;
328 }
329
330 ResourceLoadPriority ResourceRequestBase::priority() const
331 {
332     updateResourceRequest();
333
334     return m_priority;
335 }
336
337 void ResourceRequestBase::setPriority(ResourceLoadPriority priority)
338 {
339     updateResourceRequest();
340
341     m_priority = priority;
342
343     if (url().protocolInHTTPFamily())
344         m_platformRequestUpdated = false;
345 }
346
347 void ResourceRequestBase::addHTTPHeaderField(const AtomicString& name, const String& value) 
348 {
349     updateResourceRequest();
350     pair<HTTPHeaderMap::iterator, bool> result = m_httpHeaderFields.add(name, value); 
351     if (!result.second)
352         result.first->second += "," + value;
353
354     if (url().protocolInHTTPFamily())
355         m_platformRequestUpdated = false;
356 }
357
358 void ResourceRequestBase::addHTTPHeaderFields(const HTTPHeaderMap& headerFields)
359 {
360     HTTPHeaderMap::const_iterator end = headerFields.end();
361     for (HTTPHeaderMap::const_iterator it = headerFields.begin(); it != end; ++it)
362         addHTTPHeaderField(it->first, it->second);
363 }
364
365 bool equalIgnoringHeaderFields(const ResourceRequestBase& a, const ResourceRequestBase& b)
366 {
367     if (a.url() != b.url())
368         return false;
369     
370     if (a.cachePolicy() != b.cachePolicy())
371         return false;
372     
373     if (a.timeoutInterval() != b.timeoutInterval())
374         return false;
375     
376     if (a.firstPartyForCookies() != b.firstPartyForCookies())
377         return false;
378     
379     if (a.httpMethod() != b.httpMethod())
380         return false;
381     
382     if (a.allowCookies() != b.allowCookies())
383         return false;
384     
385     if (a.priority() != b.priority())
386         return false;
387
388     FormData* formDataA = a.httpBody();
389     FormData* formDataB = b.httpBody();
390     
391     if (!formDataA)
392         return !formDataB;
393     if (!formDataB)
394         return !formDataA;
395     
396     if (*formDataA != *formDataB)
397         return false;
398     
399     return true;
400 }
401
402 bool ResourceRequestBase::compare(const ResourceRequest& a, const ResourceRequest& b)
403 {
404     if (!equalIgnoringHeaderFields(a, b))
405         return false;
406     
407     if (a.httpHeaderFields() != b.httpHeaderFields())
408         return false;
409         
410     return ResourceRequest::platformCompare(a, b);
411 }
412
413 bool ResourceRequestBase::isConditional() const
414 {
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"));
420 }
421
422 double ResourceRequestBase::defaultTimeoutInterval()
423 {
424     return s_defaultTimeoutInterval;
425 }
426
427 void ResourceRequestBase::setDefaultTimeoutInterval(double timeoutInterval)
428 {
429     s_defaultTimeoutInterval = timeoutInterval;
430 }
431
432 void ResourceRequestBase::updatePlatformRequest() const
433 {
434     if (m_platformRequestUpdated)
435         return;
436
437     ASSERT(m_resourceRequestUpdated);
438     const_cast<ResourceRequest&>(asResourceRequest()).doUpdatePlatformRequest();
439     m_platformRequestUpdated = true;
440 }
441
442 void ResourceRequestBase::updateResourceRequest() const
443 {
444     if (m_resourceRequestUpdated)
445         return;
446
447     ASSERT(m_platformRequestUpdated);
448     const_cast<ResourceRequest&>(asResourceRequest()).doUpdateResourceRequest();
449     m_resourceRequestUpdated = true;
450 }
451
452 #if !PLATFORM(MAC) && !USE(CFNETWORK) && !USE(SOUP) && !PLATFORM(CHROMIUM) && !PLATFORM(QT)
453 unsigned initializeMaximumHTTPConnectionCountPerHost()
454 {
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.
457     return 4;
458 }
459 #endif
460
461 }