1/*
2 * Copyright 2009, The Android Open Source Project
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *  * Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 *  * Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "ResourceHandle.h"
28
29#include "CachedResourceLoader.h"
30#include "DocumentLoader.h"
31#include "Frame.h"
32#include "FrameLoader.h"
33#include "MainResourceLoader.h"
34#include "NotImplemented.h"
35#include "ResourceHandleClient.h"
36#include "ResourceHandleInternal.h"
37#include "ResourceLoaderAndroid.h"
38#include "Settings.h"
39#include <wtf/text/CString.h>
40
41namespace WebCore {
42
43ResourceHandleInternal::~ResourceHandleInternal()
44{
45}
46
47ResourceHandle::~ResourceHandle()
48{
49}
50
51bool ResourceHandle::start(NetworkingContext* context)
52{
53    MainResourceLoader* mainLoader = context->mainResourceLoader();
54    bool isMainResource = static_cast<void*>(mainLoader) == static_cast<void*>(client());
55    RefPtr<ResourceLoaderAndroid> loader = ResourceLoaderAndroid::start(this, d->m_firstRequest, context->frameLoaderClient(), isMainResource, false);
56
57    if (loader) {
58        d->m_loader = loader.release();
59        return true;
60    }
61
62    return false;
63}
64
65void ResourceHandle::cancel()
66{
67    if (d->m_loader)
68        d->m_loader->cancel();
69}
70
71PassRefPtr<SharedBuffer> ResourceHandle::bufferedData()
72{
73    notImplemented();
74    return 0;
75}
76
77bool ResourceHandle::supportsBufferedData()
78{
79    // We don't support buffering data on the native side.
80    notImplemented();
81    return false;
82}
83
84#if PLATFORM(ANDROID)
85// TODO: this needs upstreaming.
86void ResourceHandle::pauseLoad(bool pause)
87{
88    if (d->m_loader)
89        d->m_loader->pauseLoad(pause);
90}
91#endif
92
93void ResourceHandle::platformSetDefersLoading(bool)
94{
95    notImplemented();
96}
97
98// This static method is called to check to see if a POST response is in
99// the cache.
100bool ResourceHandle::willLoadFromCache(ResourceRequest& request, Frame*)
101{
102    // set the cache policy correctly, copied from
103    // network/mac/ResourceHandleMac.mm
104    request.setCachePolicy(ReturnCacheDataDontLoad);
105    FormData* formData = request.httpBody();
106    return ResourceLoaderAndroid::willLoadFromCache(request.url(), formData ? formData->identifier() : 0);
107}
108
109bool ResourceHandle::loadsBlocked()
110{
111    // FIXME, need to check whether connection pipe is blocked.
112    // return false for now
113    return false;
114}
115
116// Class to handle synchronized loading of resources.
117class SyncLoader : public ResourceHandleClient {
118public:
119    SyncLoader(ResourceError& error, ResourceResponse& response, WTF::Vector<char>& data)
120    {
121        m_error = &error;
122        m_response = &response;
123        m_data = &data;
124    }
125    ~SyncLoader() {}
126
127    virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse& response)
128    {
129        *m_response = response;
130    }
131
132    virtual void didReceiveData(ResourceHandle*, const char* data, int len, int encodedDataLength)
133    {
134        m_data->append(data, len);
135    }
136
137    virtual void didFail(ResourceHandle*, const ResourceError& error)
138    {
139        *m_error = error;
140    }
141
142private:
143    ResourceError* m_error;
144    ResourceResponse* m_response;
145    WTF::Vector<char>* m_data;
146};
147
148void ResourceHandle::loadResourceSynchronously(NetworkingContext* context, const ResourceRequest& request,
149        StoredCredentials, ResourceError& error, ResourceResponse& response, WTF::Vector<char>& data)
150{
151    SyncLoader s(error, response, data);
152    RefPtr<ResourceHandle> h = adoptRef(new ResourceHandle(request, &s, false, false));
153    // This blocks until the load is finished.
154    // Use the request owned by the ResourceHandle. This has had the username
155    // and password (if present) stripped from the URL in
156    // ResourceHandleInternal::ResourceHandleInternal(). This matches the
157    // behaviour in the asynchronous case.
158    ResourceLoaderAndroid::start(h.get(), request, context->frameLoaderClient(), false, true);
159}
160
161} // namespace WebCore
162