1/*
2 * Copyright (C) 2009 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 *     * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *     * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 *     * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include "config.h"
32#include "public/platform/WebURLResponse.h"
33
34#include "platform/exported/WebURLResponsePrivate.h"
35#include "platform/network/ResourceLoadTiming.h"
36#include "platform/network/ResourceResponse.h"
37#include "public/platform/WebHTTPHeaderVisitor.h"
38#include "public/platform/WebHTTPLoadInfo.h"
39#include "public/platform/WebString.h"
40#include "public/platform/WebURL.h"
41#include "public/platform/WebURLLoadTiming.h"
42#include "wtf/RefPtr.h"
43
44namespace blink {
45
46namespace {
47
48class ExtraDataContainer : public ResourceResponse::ExtraData {
49public:
50    static PassRefPtr<ExtraDataContainer> create(WebURLResponse::ExtraData* extraData) { return adoptRef(new ExtraDataContainer(extraData)); }
51
52    virtual ~ExtraDataContainer() { }
53
54    WebURLResponse::ExtraData* extraData() const { return m_extraData.get(); }
55
56private:
57    explicit ExtraDataContainer(WebURLResponse::ExtraData* extraData)
58        : m_extraData(adoptPtr(extraData))
59    {
60    }
61
62    OwnPtr<WebURLResponse::ExtraData> m_extraData;
63};
64
65} // namespace
66
67// The standard implementation of WebURLResponsePrivate, which maintains
68// ownership of a ResourceResponse instance.
69class WebURLResponsePrivateImpl : public WebURLResponsePrivate {
70public:
71    WebURLResponsePrivateImpl()
72    {
73        m_resourceResponse = &m_resourceResponseAllocation;
74    }
75
76    WebURLResponsePrivateImpl(const WebURLResponsePrivate* p)
77        : m_resourceResponseAllocation(*p->m_resourceResponse)
78    {
79        m_resourceResponse = &m_resourceResponseAllocation;
80    }
81
82    virtual void dispose() { delete this; }
83
84private:
85    virtual ~WebURLResponsePrivateImpl() { }
86
87    ResourceResponse m_resourceResponseAllocation;
88};
89
90void WebURLResponse::initialize()
91{
92    assign(new WebURLResponsePrivateImpl());
93}
94
95void WebURLResponse::reset()
96{
97    assign(0);
98}
99
100void WebURLResponse::assign(const WebURLResponse& r)
101{
102    if (&r != this)
103        assign(r.m_private ? new WebURLResponsePrivateImpl(r.m_private) : 0);
104}
105
106bool WebURLResponse::isNull() const
107{
108    return !m_private || m_private->m_resourceResponse->isNull();
109}
110
111WebURL WebURLResponse::url() const
112{
113    return m_private->m_resourceResponse->url();
114}
115
116void WebURLResponse::setURL(const WebURL& url)
117{
118    m_private->m_resourceResponse->setURL(url);
119}
120
121unsigned WebURLResponse::connectionID() const
122{
123    return m_private->m_resourceResponse->connectionID();
124}
125
126void WebURLResponse::setConnectionID(unsigned connectionID)
127{
128    m_private->m_resourceResponse->setConnectionID(connectionID);
129}
130
131bool WebURLResponse::connectionReused() const
132{
133    return m_private->m_resourceResponse->connectionReused();
134}
135
136void WebURLResponse::setConnectionReused(bool connectionReused)
137{
138    m_private->m_resourceResponse->setConnectionReused(connectionReused);
139}
140
141WebURLLoadTiming WebURLResponse::loadTiming()
142{
143    return WebURLLoadTiming(m_private->m_resourceResponse->resourceLoadTiming());
144}
145
146void WebURLResponse::setLoadTiming(const WebURLLoadTiming& timing)
147{
148    RefPtr<ResourceLoadTiming> loadTiming = PassRefPtr<ResourceLoadTiming>(timing);
149    m_private->m_resourceResponse->setResourceLoadTiming(loadTiming.release());
150}
151
152WebHTTPLoadInfo WebURLResponse::httpLoadInfo()
153{
154    return WebHTTPLoadInfo(m_private->m_resourceResponse->resourceLoadInfo());
155}
156
157void WebURLResponse::setHTTPLoadInfo(const WebHTTPLoadInfo& value)
158{
159    m_private->m_resourceResponse->setResourceLoadInfo(value);
160}
161
162double WebURLResponse::responseTime() const
163{
164    return m_private->m_resourceResponse->responseTime();
165}
166
167void WebURLResponse::setResponseTime(double responseTime)
168{
169    m_private->m_resourceResponse->setResponseTime(responseTime);
170}
171
172WebString WebURLResponse::mimeType() const
173{
174    return m_private->m_resourceResponse->mimeType();
175}
176
177void WebURLResponse::setMIMEType(const WebString& mimeType)
178{
179    m_private->m_resourceResponse->setMimeType(mimeType);
180}
181
182long long WebURLResponse::expectedContentLength() const
183{
184    return m_private->m_resourceResponse->expectedContentLength();
185}
186
187void WebURLResponse::setExpectedContentLength(long long expectedContentLength)
188{
189    m_private->m_resourceResponse->setExpectedContentLength(expectedContentLength);
190}
191
192WebString WebURLResponse::textEncodingName() const
193{
194    return m_private->m_resourceResponse->textEncodingName();
195}
196
197void WebURLResponse::setTextEncodingName(const WebString& textEncodingName)
198{
199    m_private->m_resourceResponse->setTextEncodingName(textEncodingName);
200}
201
202WebString WebURLResponse::suggestedFileName() const
203{
204    return m_private->m_resourceResponse->suggestedFilename();
205}
206
207void WebURLResponse::setSuggestedFileName(const WebString& suggestedFileName)
208{
209    m_private->m_resourceResponse->setSuggestedFilename(suggestedFileName);
210}
211
212WebURLResponse::HTTPVersion WebURLResponse::httpVersion() const
213{
214    return static_cast<HTTPVersion>(m_private->m_resourceResponse->httpVersion());
215}
216
217void WebURLResponse::setHTTPVersion(HTTPVersion version)
218{
219    m_private->m_resourceResponse->setHTTPVersion(static_cast<ResourceResponse::HTTPVersion>(version));
220}
221
222int WebURLResponse::httpStatusCode() const
223{
224    return m_private->m_resourceResponse->httpStatusCode();
225}
226
227void WebURLResponse::setHTTPStatusCode(int httpStatusCode)
228{
229    m_private->m_resourceResponse->setHTTPStatusCode(httpStatusCode);
230}
231
232WebString WebURLResponse::httpStatusText() const
233{
234    return m_private->m_resourceResponse->httpStatusText();
235}
236
237void WebURLResponse::setHTTPStatusText(const WebString& httpStatusText)
238{
239    m_private->m_resourceResponse->setHTTPStatusText(httpStatusText);
240}
241
242WebString WebURLResponse::httpHeaderField(const WebString& name) const
243{
244    return m_private->m_resourceResponse->httpHeaderField(name);
245}
246
247void WebURLResponse::setHTTPHeaderField(const WebString& name, const WebString& value)
248{
249    m_private->m_resourceResponse->setHTTPHeaderField(name, value);
250}
251
252void WebURLResponse::addHTTPHeaderField(const WebString& name, const WebString& value)
253{
254    if (name.isNull() || value.isNull())
255        return;
256
257    m_private->m_resourceResponse->addHTTPHeaderField(name, value);
258}
259
260void WebURLResponse::clearHTTPHeaderField(const WebString& name)
261{
262    m_private->m_resourceResponse->clearHTTPHeaderField(name);
263}
264
265void WebURLResponse::visitHTTPHeaderFields(WebHTTPHeaderVisitor* visitor) const
266{
267    const HTTPHeaderMap& map = m_private->m_resourceResponse->httpHeaderFields();
268    for (HTTPHeaderMap::const_iterator it = map.begin(); it != map.end(); ++it)
269        visitor->visitHeader(it->key, it->value);
270}
271
272double WebURLResponse::lastModifiedDate() const
273{
274    return static_cast<double>(m_private->m_resourceResponse->lastModifiedDate());
275}
276
277void WebURLResponse::setLastModifiedDate(double lastModifiedDate)
278{
279    m_private->m_resourceResponse->setLastModifiedDate(static_cast<time_t>(lastModifiedDate));
280}
281
282long long WebURLResponse::appCacheID() const
283{
284    return m_private->m_resourceResponse->appCacheID();
285}
286
287void WebURLResponse::setAppCacheID(long long appCacheID)
288{
289    m_private->m_resourceResponse->setAppCacheID(appCacheID);
290}
291
292WebURL WebURLResponse::appCacheManifestURL() const
293{
294    return m_private->m_resourceResponse->appCacheManifestURL();
295}
296
297void WebURLResponse::setAppCacheManifestURL(const WebURL& url)
298{
299    m_private->m_resourceResponse->setAppCacheManifestURL(url);
300}
301
302WebCString WebURLResponse::securityInfo() const
303{
304    // FIXME: getSecurityInfo is misnamed.
305    return m_private->m_resourceResponse->getSecurityInfo();
306}
307
308void WebURLResponse::setSecurityInfo(const WebCString& securityInfo)
309{
310    m_private->m_resourceResponse->setSecurityInfo(securityInfo);
311}
312
313ResourceResponse& WebURLResponse::toMutableResourceResponse()
314{
315    ASSERT(m_private);
316    ASSERT(m_private->m_resourceResponse);
317
318    return *m_private->m_resourceResponse;
319}
320
321const ResourceResponse& WebURLResponse::toResourceResponse() const
322{
323    ASSERT(m_private);
324    ASSERT(m_private->m_resourceResponse);
325
326    return *m_private->m_resourceResponse;
327}
328
329bool WebURLResponse::wasCached() const
330{
331    return m_private->m_resourceResponse->wasCached();
332}
333
334void WebURLResponse::setWasCached(bool value)
335{
336    m_private->m_resourceResponse->setWasCached(value);
337}
338
339bool WebURLResponse::wasFetchedViaSPDY() const
340{
341    return m_private->m_resourceResponse->wasFetchedViaSPDY();
342}
343
344void WebURLResponse::setWasFetchedViaSPDY(bool value)
345{
346    m_private->m_resourceResponse->setWasFetchedViaSPDY(value);
347}
348
349bool WebURLResponse::wasNpnNegotiated() const
350{
351    return m_private->m_resourceResponse->wasNpnNegotiated();
352}
353
354void WebURLResponse::setWasNpnNegotiated(bool value)
355{
356    m_private->m_resourceResponse->setWasNpnNegotiated(value);
357}
358
359bool WebURLResponse::wasAlternateProtocolAvailable() const
360{
361    return m_private->m_resourceResponse->wasAlternateProtocolAvailable();
362}
363
364void WebURLResponse::setWasAlternateProtocolAvailable(bool value)
365{
366    m_private->m_resourceResponse->setWasAlternateProtocolAvailable(value);
367}
368
369bool WebURLResponse::wasFetchedViaProxy() const
370{
371    return m_private->m_resourceResponse->wasFetchedViaProxy();
372}
373
374void WebURLResponse::setWasFetchedViaProxy(bool value)
375{
376    m_private->m_resourceResponse->setWasFetchedViaProxy(value);
377}
378
379bool WebURLResponse::wasFetchedViaServiceWorker() const
380{
381    return m_private->m_resourceResponse->wasFetchedViaServiceWorker();
382}
383
384void WebURLResponse::setWasFetchedViaServiceWorker(bool value)
385{
386    m_private->m_resourceResponse->setWasFetchedViaServiceWorker(value);
387}
388
389bool WebURLResponse::isMultipartPayload() const
390{
391    return m_private->m_resourceResponse->isMultipartPayload();
392}
393
394void WebURLResponse::setIsMultipartPayload(bool value)
395{
396    m_private->m_resourceResponse->setIsMultipartPayload(value);
397}
398
399WebString WebURLResponse::downloadFilePath() const
400{
401    return m_private->m_resourceResponse->downloadedFilePath();
402}
403
404void WebURLResponse::setDownloadFilePath(const WebString& downloadFilePath)
405{
406    m_private->m_resourceResponse->setDownloadedFilePath(downloadFilePath);
407}
408
409WebString WebURLResponse::remoteIPAddress() const
410{
411    return m_private->m_resourceResponse->remoteIPAddress();
412}
413
414void WebURLResponse::setRemoteIPAddress(const WebString& remoteIPAddress)
415{
416    m_private->m_resourceResponse->setRemoteIPAddress(remoteIPAddress);
417}
418
419unsigned short WebURLResponse::remotePort() const
420{
421    return m_private->m_resourceResponse->remotePort();
422}
423
424void WebURLResponse::setRemotePort(unsigned short remotePort)
425{
426    m_private->m_resourceResponse->setRemotePort(remotePort);
427}
428
429WebURLResponse::ExtraData* WebURLResponse::extraData() const
430{
431    RefPtr<ResourceResponse::ExtraData> data = m_private->m_resourceResponse->extraData();
432    if (!data)
433        return 0;
434    return static_cast<ExtraDataContainer*>(data.get())->extraData();
435}
436
437void WebURLResponse::setExtraData(WebURLResponse::ExtraData* extraData)
438{
439    m_private->m_resourceResponse->setExtraData(ExtraDataContainer::create(extraData));
440}
441
442void WebURLResponse::assign(WebURLResponsePrivate* p)
443{
444    // Subclasses may call this directly so a self-assignment check is needed
445    // here as well as in the public assign method.
446    if (m_private == p)
447        return;
448    if (m_private)
449        m_private->dispose();
450    m_private = p;
451}
452
453} // namespace blink
454