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