diff options
author | Ben Murdoch <benm@google.com> | 2011-05-13 16:23:25 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2011-05-16 11:35:02 +0100 |
commit | 65f03d4f644ce73618e5f4f50dd694b26f55ae12 (patch) | |
tree | f478babb801e720de7bfaee23443ffe029f58731 /Source/WebKit/chromium/src/ResourceHandle.cpp | |
parent | 47de4a2fb7262c7ebdb9cd133ad2c54c187454d0 (diff) | |
download | external_webkit-65f03d4f644ce73618e5f4f50dd694b26f55ae12.zip external_webkit-65f03d4f644ce73618e5f4f50dd694b26f55ae12.tar.gz external_webkit-65f03d4f644ce73618e5f4f50dd694b26f55ae12.tar.bz2 |
Merge WebKit at r75993: Initial merge by git.
Change-Id: I602bbdc3974787a3b0450456a30a7868286921c3
Diffstat (limited to 'Source/WebKit/chromium/src/ResourceHandle.cpp')
-rw-r--r-- | Source/WebKit/chromium/src/ResourceHandle.cpp | 336 |
1 files changed, 336 insertions, 0 deletions
diff --git a/Source/WebKit/chromium/src/ResourceHandle.cpp b/Source/WebKit/chromium/src/ResourceHandle.cpp new file mode 100644 index 0000000..83e0017 --- /dev/null +++ b/Source/WebKit/chromium/src/ResourceHandle.cpp @@ -0,0 +1,336 @@ +/* + * Copyright (C) 2009 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "ResourceHandle.h" + +#include "ChromiumBridge.h" +#include "ResourceHandleClient.h" +#include "ResourceRequest.h" +#include "SharedBuffer.h" + +#include "WebKit.h" +#include "WebKitClient.h" +#include "WebURLError.h" +#include "WebURLLoader.h" +#include "WebURLLoaderClient.h" +#include "WebURLRequest.h" +#include "WebURLResponse.h" +#include "WrappedResourceRequest.h" +#include "WrappedResourceResponse.h" + +using namespace WebKit; + +namespace WebCore { + +// ResourceHandleInternal ----------------------------------------------------- + +class ResourceHandleInternal : public WebURLLoaderClient { +public: + ResourceHandleInternal(const ResourceRequest& request, ResourceHandleClient* client) + : m_request(request) + , m_owner(0) + , m_client(client) + , m_state(ConnectionStateNew) + { + } + + void start(); + void cancel(); + void setDefersLoading(bool); + bool allowStoredCredentials() const; + + // WebURLLoaderClient methods: + virtual void willSendRequest(WebURLLoader*, WebURLRequest&, const WebURLResponse&); + virtual void didSendData( + WebURLLoader*, unsigned long long bytesSent, unsigned long long totalBytesToBeSent); + virtual void didReceiveResponse(WebURLLoader*, const WebURLResponse&); + virtual void didReceiveData(WebURLLoader*, const char* data, int dataLength); + virtual void didReceiveCachedMetadata(WebURLLoader*, const char* data, int dataLength); + virtual void didFinishLoading(WebURLLoader*, double finishTime); + virtual void didFail(WebURLLoader*, const WebURLError&); + + enum ConnectionState { + ConnectionStateNew, + ConnectionStateStarted, + ConnectionStateReceivedResponse, + ConnectionStateReceivingData, + ConnectionStateFinishedLoading, + ConnectionStateCanceled, + ConnectionStateFailed, + }; + + ResourceRequest m_request; + ResourceHandle* m_owner; + ResourceHandleClient* m_client; + OwnPtr<WebURLLoader> m_loader; + + // Used for sanity checking to make sure we don't experience illegal state + // transitions. + ConnectionState m_state; +}; + +void ResourceHandleInternal::start() +{ + if (m_state != ConnectionStateNew) + CRASH(); + m_state = ConnectionStateStarted; + + m_loader.set(webKitClient()->createURLLoader()); + ASSERT(m_loader.get()); + + WrappedResourceRequest wrappedRequest(m_request); + wrappedRequest.setAllowStoredCredentials(allowStoredCredentials()); + m_loader->loadAsynchronously(wrappedRequest, this); +} + +void ResourceHandleInternal::cancel() +{ + m_state = ConnectionStateCanceled; + m_loader->cancel(); + + // Do not make any further calls to the client. + m_client = 0; +} + +void ResourceHandleInternal::setDefersLoading(bool value) +{ + m_loader->setDefersLoading(value); +} + +bool ResourceHandleInternal::allowStoredCredentials() const +{ + return m_client && m_client->shouldUseCredentialStorage(m_owner); +} + +void ResourceHandleInternal::willSendRequest( + WebURLLoader*, WebURLRequest& request, const WebURLResponse& response) +{ + ASSERT(m_client); + ASSERT(!request.isNull()); + ASSERT(!response.isNull()); + m_client->willSendRequest(m_owner, request.toMutableResourceRequest(), response.toResourceResponse()); +} + +void ResourceHandleInternal::didSendData( + WebURLLoader*, unsigned long long bytesSent, unsigned long long totalBytesToBeSent) +{ + ASSERT(m_client); + m_client->didSendData(m_owner, bytesSent, totalBytesToBeSent); +} + +void ResourceHandleInternal::didReceiveResponse(WebURLLoader*, const WebURLResponse& response) +{ + ASSERT(m_client); + ASSERT(!response.isNull()); + bool isMultipart = response.isMultipartPayload(); + bool isValidStateTransition = (m_state == ConnectionStateStarted || m_state == ConnectionStateReceivedResponse); + // In the case of multipart loads, calls to didReceiveData & didReceiveResponse can be interleaved. + if (!isMultipart && !isValidStateTransition) + CRASH(); + m_state = ConnectionStateReceivedResponse; + m_client->didReceiveResponse(m_owner, response.toResourceResponse()); +} + +void ResourceHandleInternal::didReceiveData( + WebURLLoader*, const char* data, int dataLength) +{ + ASSERT(m_client); + if (m_state != ConnectionStateReceivedResponse && m_state != ConnectionStateReceivingData) + CRASH(); + m_state = ConnectionStateReceivingData; + + // FIXME(yurys): it looks like lengthReceived is always the same as + // dataLength and that the latter parameter can be eliminated. + // See WebKit bug: https://bugs.webkit.org/show_bug.cgi?id=31019 + m_client->didReceiveData(m_owner, data, dataLength, dataLength); +} + +void ResourceHandleInternal::didReceiveCachedMetadata(WebURLLoader*, const char* data, int dataLength) +{ + ASSERT(m_client); + if (m_state != ConnectionStateReceivedResponse && m_state != ConnectionStateReceivingData) + CRASH(); + + m_client->didReceiveCachedMetadata(m_owner, data, dataLength); +} + +void ResourceHandleInternal::didFinishLoading(WebURLLoader*, double finishTime) +{ + ASSERT(m_client); + if (m_state != ConnectionStateReceivedResponse && m_state != ConnectionStateReceivingData) + CRASH(); + m_state = ConnectionStateFinishedLoading; + m_client->didFinishLoading(m_owner, finishTime); +} + +void ResourceHandleInternal::didFail(WebURLLoader*, const WebURLError& error) +{ + ASSERT(m_client); + m_state = ConnectionStateFailed; + m_client->didFail(m_owner, error); +} + +// ResourceHandle ------------------------------------------------------------- + +ResourceHandle::ResourceHandle(const ResourceRequest& request, + ResourceHandleClient* client, + bool defersLoading, + bool shouldContentSniff) + : d(new ResourceHandleInternal(request, client)) +{ + d->m_owner = this; + + // FIXME: Figure out what to do with the bool params. +} + +PassRefPtr<ResourceHandle> ResourceHandle::create(NetworkingContext* context, + const ResourceRequest& request, + ResourceHandleClient* client, + bool defersLoading, + bool shouldContentSniff) +{ + RefPtr<ResourceHandle> newHandle = adoptRef(new ResourceHandle( + request, client, defersLoading, shouldContentSniff)); + + if (newHandle->start(context)) + return newHandle.release(); + + return 0; +} + +ResourceRequest& ResourceHandle::firstRequest() +{ + return d->m_request; +} + +ResourceHandleClient* ResourceHandle::client() const +{ + return d->m_client; +} + +void ResourceHandle::setClient(ResourceHandleClient* client) +{ + d->m_client = client; +} + +void ResourceHandle::setDefersLoading(bool value) +{ + d->setDefersLoading(value); +} + +bool ResourceHandle::start(NetworkingContext* context) +{ + d->start(); + return true; +} + +bool ResourceHandle::hasAuthenticationChallenge() const +{ + return false; +} + +void ResourceHandle::clearAuthentication() +{ +} + +void ResourceHandle::cancel() +{ + d->cancel(); +} + +ResourceHandle::~ResourceHandle() +{ + d->m_owner = 0; +} + +PassRefPtr<SharedBuffer> ResourceHandle::bufferedData() +{ + return 0; +} + +bool ResourceHandle::loadsBlocked() +{ + return false; // This seems to be related to sync XMLHttpRequest... +} + +// static +bool ResourceHandle::supportsBufferedData() +{ + return false; // The loader will buffer manually if it needs to. +} + +// static +void ResourceHandle::loadResourceSynchronously(NetworkingContext* context, + const ResourceRequest& request, + StoredCredentials storedCredentials, + ResourceError& error, + ResourceResponse& response, + Vector<char>& data) +{ + OwnPtr<WebURLLoader> loader(webKitClient()->createURLLoader()); + ASSERT(loader.get()); + + WrappedResourceRequest requestIn(request); + requestIn.setAllowStoredCredentials(storedCredentials == AllowStoredCredentials); + WrappedResourceResponse responseOut(response); + WebURLError errorOut; + WebData dataOut; + + loader->loadSynchronously(requestIn, responseOut, errorOut, dataOut); + + error = errorOut; + data.clear(); + data.append(dataOut.data(), dataOut.size()); +} + +// static +bool ResourceHandle::willLoadFromCache(ResourceRequest& request, Frame*) +{ + // This method is used to determine if a POST request can be repeated from + // cache, but you cannot really know until you actually try to read from the + // cache. Even if we checked now, something else could come along and wipe + // out the cache entry by the time we fetch it. + // + // So, we always say yes here, to prevent the FrameLoader from initiating a + // reload. Then in FrameLoaderClientImpl::dispatchWillSendRequest, we + // fix-up the cache policy of the request to force a load from the cache. + // + ASSERT(request.httpMethod() == "POST"); + return true; +} + +// static +void ResourceHandle::cacheMetadata(const ResourceResponse& response, const Vector<char>& data) +{ + ChromiumBridge::cacheMetadata(response.url(), response.responseTime(), data); +} + +} // namespace WebCore |