Home | History | Annotate | Download | only in src
      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 "ResourceHandle.h"
     33 
     34 #include "ResourceHandleClient.h"
     35 #include "ResourceRequest.h"
     36 
     37 #include "WebKit.h"
     38 #include "WebKitClient.h"
     39 #include "WebURLError.h"
     40 #include "WebURLLoader.h"
     41 #include "WebURLLoaderClient.h"
     42 #include "WebURLRequest.h"
     43 #include "WebURLResponse.h"
     44 #include "WrappedResourceRequest.h"
     45 #include "WrappedResourceResponse.h"
     46 
     47 using namespace WebKit;
     48 
     49 namespace WebCore {
     50 
     51 // ResourceHandleInternal -----------------------------------------------------
     52 
     53 class ResourceHandleInternal : public WebURLLoaderClient {
     54 public:
     55     ResourceHandleInternal(const ResourceRequest& request, ResourceHandleClient* client)
     56         : m_request(request)
     57         , m_owner(0)
     58         , m_client(client)
     59     {
     60     }
     61 
     62     void start();
     63     void cancel();
     64     void setDefersLoading(bool);
     65     bool allowStoredCredentials() const;
     66 
     67     // WebURLLoaderClient methods:
     68     virtual void willSendRequest(WebURLLoader*, WebURLRequest&, const WebURLResponse&);
     69     virtual void didSendData(
     70         WebURLLoader*, unsigned long long bytesSent, unsigned long long totalBytesToBeSent);
     71     virtual void didReceiveResponse(WebURLLoader*, const WebURLResponse&);
     72     virtual void didReceiveData(WebURLLoader*, const char* data, int dataLength);
     73     virtual void didFinishLoading(WebURLLoader*);
     74     virtual void didFail(WebURLLoader*, const WebURLError&);
     75 
     76     ResourceRequest m_request;
     77     ResourceHandle* m_owner;
     78     ResourceHandleClient* m_client;
     79     OwnPtr<WebURLLoader> m_loader;
     80 };
     81 
     82 void ResourceHandleInternal::start()
     83 {
     84     m_loader.set(webKitClient()->createURLLoader());
     85     ASSERT(m_loader.get());
     86 
     87     WrappedResourceRequest wrappedRequest(m_request);
     88     wrappedRequest.setAllowStoredCredentials(allowStoredCredentials());
     89     m_loader->loadAsynchronously(wrappedRequest, this);
     90 }
     91 
     92 void ResourceHandleInternal::cancel()
     93 {
     94     m_loader->cancel();
     95 
     96     // Do not make any further calls to the client.
     97     m_client = 0;
     98 }
     99 
    100 void ResourceHandleInternal::setDefersLoading(bool value)
    101 {
    102     m_loader->setDefersLoading(value);
    103 }
    104 
    105 bool ResourceHandleInternal::allowStoredCredentials() const
    106 {
    107     return m_client && m_client->shouldUseCredentialStorage(m_owner);
    108 }
    109 
    110 void ResourceHandleInternal::willSendRequest(
    111     WebURLLoader*, WebURLRequest& request, const WebURLResponse& response)
    112 {
    113     ASSERT(m_client);
    114     ASSERT(!request.isNull());
    115     ASSERT(!response.isNull());
    116     m_client->willSendRequest(m_owner, request.toMutableResourceRequest(), response.toResourceResponse());
    117 }
    118 
    119 void ResourceHandleInternal::didSendData(
    120     WebURLLoader*, unsigned long long bytesSent, unsigned long long totalBytesToBeSent)
    121 {
    122     ASSERT(m_client);
    123     m_client->didSendData(m_owner, bytesSent, totalBytesToBeSent);
    124 }
    125 
    126 void ResourceHandleInternal::didReceiveResponse(WebURLLoader*, const WebURLResponse& response)
    127 {
    128     ASSERT(m_client);
    129     ASSERT(!response.isNull());
    130     m_client->didReceiveResponse(m_owner, response.toResourceResponse());
    131 }
    132 
    133 void ResourceHandleInternal::didReceiveData(
    134     WebURLLoader*, const char* data, int dataLength)
    135 {
    136     ASSERT(m_client);
    137 
    138     // FIXME(yurys): it looks like lengthReceived is always the same as
    139     // dataLength and that the latter parameter can be eliminated.
    140     // See WebKit bug: https://bugs.webkit.org/show_bug.cgi?id=31019
    141     m_client->didReceiveData(m_owner, data, dataLength, dataLength);
    142 }
    143 
    144 void ResourceHandleInternal::didFinishLoading(WebURLLoader*)
    145 {
    146     ASSERT(m_client);
    147     m_client->didFinishLoading(m_owner);
    148 }
    149 
    150 void ResourceHandleInternal::didFail(WebURLLoader*, const WebURLError& error)
    151 {
    152     ASSERT(m_client);
    153     m_client->didFail(m_owner, error);
    154 }
    155 
    156 // ResourceHandle -------------------------------------------------------------
    157 
    158 ResourceHandle::ResourceHandle(const ResourceRequest& request,
    159                                ResourceHandleClient* client,
    160                                bool defersLoading,
    161                                bool shouldContentSniff,
    162                                bool mightDownloadFromHandle)
    163     : d(new ResourceHandleInternal(request, client))
    164 {
    165     d->m_owner = this;
    166 
    167     // FIXME: Figure out what to do with the bool params.
    168 }
    169 
    170 PassRefPtr<ResourceHandle> ResourceHandle::create(const ResourceRequest& request,
    171                                                   ResourceHandleClient* client,
    172                                                   Frame* deprecated,
    173                                                   bool defersLoading,
    174                                                   bool shouldContentSniff,
    175                                                   bool mightDownloadFromHandle)
    176 {
    177     RefPtr<ResourceHandle> newHandle = adoptRef(new ResourceHandle(
    178         request, client, defersLoading, shouldContentSniff, mightDownloadFromHandle));
    179 
    180     if (newHandle->start(deprecated))
    181         return newHandle.release();
    182 
    183     return 0;
    184 }
    185 
    186 const ResourceRequest& ResourceHandle::request() const
    187 {
    188     return d->m_request;
    189 }
    190 
    191 ResourceHandleClient* ResourceHandle::client() const
    192 {
    193     return d->m_client;
    194 }
    195 
    196 void ResourceHandle::setClient(ResourceHandleClient* client)
    197 {
    198     d->m_client = client;
    199 }
    200 
    201 void ResourceHandle::setDefersLoading(bool value)
    202 {
    203     d->setDefersLoading(value);
    204 }
    205 
    206 bool ResourceHandle::start(Frame* deprecated)
    207 {
    208     d->start();
    209     return true;
    210 }
    211 
    212 void ResourceHandle::clearAuthentication()
    213 {
    214 }
    215 
    216 void ResourceHandle::cancel()
    217 {
    218     d->cancel();
    219 }
    220 
    221 ResourceHandle::~ResourceHandle()
    222 {
    223     d->m_owner = 0;
    224 }
    225 
    226 PassRefPtr<SharedBuffer> ResourceHandle::bufferedData()
    227 {
    228     return 0;
    229 }
    230 
    231 bool ResourceHandle::loadsBlocked()
    232 {
    233     return false;  // This seems to be related to sync XMLHttpRequest...
    234 }
    235 
    236 // static
    237 bool ResourceHandle::supportsBufferedData()
    238 {
    239     return false;  // The loader will buffer manually if it needs to.
    240 }
    241 
    242 // static
    243 void ResourceHandle::loadResourceSynchronously(const ResourceRequest& request,
    244                                                StoredCredentials storedCredentials,
    245                                                ResourceError& error,
    246                                                ResourceResponse& response,
    247                                                Vector<char>& data,
    248                                                Frame* deprecated)
    249 {
    250     OwnPtr<WebURLLoader> loader(webKitClient()->createURLLoader());
    251     ASSERT(loader.get());
    252 
    253     WrappedResourceRequest requestIn(request);
    254     requestIn.setAllowStoredCredentials(storedCredentials == AllowStoredCredentials);
    255     WrappedResourceResponse responseOut(response);
    256     WebURLError errorOut;
    257     WebData dataOut;
    258 
    259     loader->loadSynchronously(requestIn, responseOut, errorOut, dataOut);
    260 
    261     error = errorOut;
    262     data.clear();
    263     data.append(dataOut.data(), dataOut.size());
    264 }
    265 
    266 // static
    267 bool ResourceHandle::willLoadFromCache(ResourceRequest& request, Frame*)
    268 {
    269     // This method is used to determine if a POST request can be repeated from
    270     // cache, but you cannot really know until you actually try to read from the
    271     // cache.  Even if we checked now, something else could come along and wipe
    272     // out the cache entry by the time we fetch it.
    273     //
    274     // So, we always say yes here, to prevent the FrameLoader from initiating a
    275     // reload.  Then in FrameLoaderClientImpl::dispatchWillSendRequest, we
    276     // fix-up the cache policy of the request to force a load from the cache.
    277     //
    278     ASSERT(request.httpMethod() == "POST");
    279     return true;
    280 }
    281 
    282 } // namespace WebCore
    283