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 #include "ResourceRequestBase.h"
28 #include "ResourceRequest.h"
29
30 using namespace std;
31
32 namespace WebCore {
33
asResourceRequest() const34 inline const ResourceRequest& ResourceRequestBase::asResourceRequest() const
35 {
36 return *static_cast<const ResourceRequest*>(this);
37 }
38
adopt(auto_ptr<CrossThreadResourceRequestData> data)39 auto_ptr<ResourceRequest> ResourceRequestBase::adopt(auto_ptr<CrossThreadResourceRequestData> data)
40 {
41 auto_ptr<ResourceRequest> request(new ResourceRequest());
42 request->setURL(data->m_url);
43 request->setCachePolicy(data->m_cachePolicy);
44 request->setTimeoutInterval(data->m_timeoutInterval);
45 request->setMainDocumentURL(data->m_mainDocumentURL);
46 request->setHTTPMethod(data->m_httpMethod);
47
48 request->updateResourceRequest();
49 request->m_httpHeaderFields.adopt(auto_ptr<CrossThreadHTTPHeaderMapData>(data->m_httpHeaders.release()));
50
51 size_t encodingCount = data->m_responseContentDispositionEncodingFallbackArray.size();
52 if (encodingCount > 0) {
53 String encoding1 = data->m_responseContentDispositionEncodingFallbackArray[0];
54 String encoding2;
55 String encoding3;
56 if (encodingCount > 1) {
57 encoding2 = data->m_responseContentDispositionEncodingFallbackArray[1];
58 if (encodingCount > 2)
59 encoding3 = data->m_responseContentDispositionEncodingFallbackArray[2];
60 }
61 ASSERT(encodingCount <= 3);
62 request->setResponseContentDispositionEncodingFallbackArray(encoding1, encoding2, encoding3);
63 }
64 request->setHTTPBody(data->m_httpBody);
65 request->setAllowHTTPCookies(data->m_allowHTTPCookies);
66 return request;
67 }
68
copyData() const69 auto_ptr<CrossThreadResourceRequestData> ResourceRequestBase::copyData() const
70 {
71 auto_ptr<CrossThreadResourceRequestData> data(new CrossThreadResourceRequestData());
72 data->m_url = url().copy();
73 data->m_cachePolicy = cachePolicy();
74 data->m_timeoutInterval = timeoutInterval();
75 data->m_mainDocumentURL = mainDocumentURL().copy();
76 data->m_httpMethod = httpMethod().copy();
77 data->m_httpHeaders.adopt(httpHeaderFields().copyData());
78
79 data->m_responseContentDispositionEncodingFallbackArray.reserveCapacity(m_responseContentDispositionEncodingFallbackArray.size());
80 size_t encodingArraySize = m_responseContentDispositionEncodingFallbackArray.size();
81 for (size_t index = 0; index < encodingArraySize; ++index) {
82 data->m_responseContentDispositionEncodingFallbackArray.append(m_responseContentDispositionEncodingFallbackArray[index].copy());
83 }
84 if (m_httpBody)
85 data->m_httpBody = m_httpBody->deepCopy();
86 data->m_allowHTTPCookies = m_allowHTTPCookies;
87 return data;
88 }
89
isEmpty() const90 bool ResourceRequestBase::isEmpty() const
91 {
92 updateResourceRequest();
93
94 return m_url.isEmpty();
95 }
96
isNull() const97 bool ResourceRequestBase::isNull() const
98 {
99 updateResourceRequest();
100
101 return m_url.isNull();
102 }
103
url() const104 const KURL& ResourceRequestBase::url() const
105 {
106 updateResourceRequest();
107
108 return m_url;
109 }
110
setURL(const KURL & url)111 void ResourceRequestBase::setURL(const KURL& url)
112 {
113 updateResourceRequest();
114
115 m_url = url;
116
117 m_platformRequestUpdated = false;
118 }
119
cachePolicy() const120 ResourceRequestCachePolicy ResourceRequestBase::cachePolicy() const
121 {
122 updateResourceRequest();
123
124 return m_cachePolicy;
125 }
126
setCachePolicy(ResourceRequestCachePolicy cachePolicy)127 void ResourceRequestBase::setCachePolicy(ResourceRequestCachePolicy cachePolicy)
128 {
129 updateResourceRequest();
130
131 m_cachePolicy = cachePolicy;
132
133 m_platformRequestUpdated = false;
134 }
135
timeoutInterval() const136 double ResourceRequestBase::timeoutInterval() const
137 {
138 updateResourceRequest();
139
140 return m_timeoutInterval;
141 }
142
setTimeoutInterval(double timeoutInterval)143 void ResourceRequestBase::setTimeoutInterval(double timeoutInterval)
144 {
145 updateResourceRequest();
146
147 m_timeoutInterval = timeoutInterval;
148
149 m_platformRequestUpdated = false;
150 }
151
mainDocumentURL() const152 const KURL& ResourceRequestBase::mainDocumentURL() const
153 {
154 updateResourceRequest();
155
156 return m_mainDocumentURL;
157 }
158
setMainDocumentURL(const KURL & mainDocumentURL)159 void ResourceRequestBase::setMainDocumentURL(const KURL& mainDocumentURL)
160 {
161 updateResourceRequest();
162
163 m_mainDocumentURL = mainDocumentURL;
164
165 m_platformRequestUpdated = false;
166 }
167
httpMethod() const168 const String& ResourceRequestBase::httpMethod() const
169 {
170 updateResourceRequest();
171
172 return m_httpMethod;
173 }
174
setHTTPMethod(const String & httpMethod)175 void ResourceRequestBase::setHTTPMethod(const String& httpMethod)
176 {
177 updateResourceRequest();
178
179 m_httpMethod = httpMethod;
180
181 m_platformRequestUpdated = false;
182 }
183
httpHeaderFields() const184 const HTTPHeaderMap& ResourceRequestBase::httpHeaderFields() const
185 {
186 updateResourceRequest();
187
188 return m_httpHeaderFields;
189 }
190
httpHeaderField(const AtomicString & name) const191 String ResourceRequestBase::httpHeaderField(const AtomicString& name) const
192 {
193 updateResourceRequest();
194
195 return m_httpHeaderFields.get(name);
196 }
197
setHTTPHeaderField(const AtomicString & name,const String & value)198 void ResourceRequestBase::setHTTPHeaderField(const AtomicString& name, const String& value)
199 {
200 updateResourceRequest();
201
202 m_httpHeaderFields.set(name, value);
203
204 m_platformRequestUpdated = false;
205 }
206
setResponseContentDispositionEncodingFallbackArray(const String & encoding1,const String & encoding2,const String & encoding3)207 void ResourceRequestBase::setResponseContentDispositionEncodingFallbackArray(const String& encoding1, const String& encoding2, const String& encoding3)
208 {
209 updateResourceRequest();
210
211 m_responseContentDispositionEncodingFallbackArray.clear();
212 if (!encoding1.isNull())
213 m_responseContentDispositionEncodingFallbackArray.append(encoding1);
214 if (!encoding2.isNull())
215 m_responseContentDispositionEncodingFallbackArray.append(encoding2);
216 if (!encoding3.isNull())
217 m_responseContentDispositionEncodingFallbackArray.append(encoding3);
218
219 m_platformRequestUpdated = false;
220 }
221
httpBody() const222 FormData* ResourceRequestBase::httpBody() const
223 {
224 updateResourceRequest();
225
226 return m_httpBody.get();
227 }
228
setHTTPBody(PassRefPtr<FormData> httpBody)229 void ResourceRequestBase::setHTTPBody(PassRefPtr<FormData> httpBody)
230 {
231 updateResourceRequest();
232
233 m_httpBody = httpBody;
234
235 m_platformRequestUpdated = false;
236 }
237
allowHTTPCookies() const238 bool ResourceRequestBase::allowHTTPCookies() const
239 {
240 updateResourceRequest();
241
242 return m_allowHTTPCookies;
243 }
244
setAllowHTTPCookies(bool allowHTTPCookies)245 void ResourceRequestBase::setAllowHTTPCookies(bool allowHTTPCookies)
246 {
247 updateResourceRequest();
248
249 m_allowHTTPCookies = allowHTTPCookies;
250
251 m_platformRequestUpdated = false;
252 }
253
addHTTPHeaderField(const AtomicString & name,const String & value)254 void ResourceRequestBase::addHTTPHeaderField(const AtomicString& name, const String& value)
255 {
256 updateResourceRequest();
257 pair<HTTPHeaderMap::iterator, bool> result = m_httpHeaderFields.add(name, value);
258 if (!result.second)
259 result.first->second += "," + value;
260 }
261
addHTTPHeaderFields(const HTTPHeaderMap & headerFields)262 void ResourceRequestBase::addHTTPHeaderFields(const HTTPHeaderMap& headerFields)
263 {
264 HTTPHeaderMap::const_iterator end = headerFields.end();
265 for (HTTPHeaderMap::const_iterator it = headerFields.begin(); it != end; ++it)
266 addHTTPHeaderField(it->first, it->second);
267 }
268
equalIgnoringHeaderFields(const ResourceRequestBase & a,const ResourceRequestBase & b)269 bool equalIgnoringHeaderFields(const ResourceRequestBase& a, const ResourceRequestBase& b)
270 {
271 if (a.url() != b.url())
272 return false;
273
274 if (a.cachePolicy() != b.cachePolicy())
275 return false;
276
277 if (a.timeoutInterval() != b.timeoutInterval())
278 return false;
279
280 if (a.mainDocumentURL() != b.mainDocumentURL())
281 return false;
282
283 if (a.httpMethod() != b.httpMethod())
284 return false;
285
286 if (a.allowHTTPCookies() != b.allowHTTPCookies())
287 return false;
288
289 FormData* formDataA = a.httpBody();
290 FormData* formDataB = b.httpBody();
291
292 if (!formDataA)
293 return !formDataB;
294 if (!formDataB)
295 return !formDataA;
296
297 if (*formDataA != *formDataB)
298 return false;
299
300 return true;
301 }
302
operator ==(const ResourceRequestBase & a,const ResourceRequestBase & b)303 bool operator==(const ResourceRequestBase& a, const ResourceRequestBase& b)
304 {
305 if (!equalIgnoringHeaderFields(a, b))
306 return false;
307
308 if (a.httpHeaderFields() != b.httpHeaderFields())
309 return false;
310
311 return true;
312 }
313
isConditional() const314 bool ResourceRequestBase::isConditional() const
315 {
316 return (m_httpHeaderFields.contains("If-Match") ||
317 m_httpHeaderFields.contains("If-Modified-Since") ||
318 m_httpHeaderFields.contains("If-None-Match") ||
319 m_httpHeaderFields.contains("If-Range") ||
320 m_httpHeaderFields.contains("If-Unmodified-Since"));
321 }
322
updatePlatformRequest() const323 void ResourceRequestBase::updatePlatformRequest() const
324 {
325 if (m_platformRequestUpdated)
326 return;
327
328 const_cast<ResourceRequest&>(asResourceRequest()).doUpdatePlatformRequest();
329 m_platformRequestUpdated = true;
330 }
331
updateResourceRequest() const332 void ResourceRequestBase::updateResourceRequest() const
333 {
334 if (m_resourceRequestUpdated)
335 return;
336
337 const_cast<ResourceRequest&>(asResourceRequest()).doUpdateResourceRequest();
338 m_resourceRequestUpdated = true;
339 }
340
341 }
342