ResourceHandle.cpp [plain text]
#include "config.h"
#include "ResourceHandle.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 {
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;
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 didFinishLoading(WebURLLoader*);
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;
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();
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);
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;
m_client->didReceiveData(m_owner, data, dataLength, dataLength);
}
void ResourceHandleInternal::didFinishLoading(WebURLLoader*)
{
ASSERT(m_client);
if (m_state != ConnectionStateReceivedResponse && m_state != ConnectionStateReceivingData)
CRASH();
m_state = ConnectionStateFinishedLoading;
m_client->didFinishLoading(m_owner);
}
void ResourceHandleInternal::didFail(WebURLLoader*, const WebURLError& error)
{
ASSERT(m_client);
m_state = ConnectionStateFailed;
m_client->didFail(m_owner, error);
}
ResourceHandle::ResourceHandle(const ResourceRequest& request,
ResourceHandleClient* client,
bool defersLoading,
bool shouldContentSniff)
: d(new ResourceHandleInternal(request, client))
{
d->m_owner = this;
}
PassRefPtr<ResourceHandle> ResourceHandle::create(const ResourceRequest& request,
ResourceHandleClient* client,
Frame* deprecated,
bool defersLoading,
bool shouldContentSniff)
{
RefPtr<ResourceHandle> newHandle = adoptRef(new ResourceHandle(
request, client, defersLoading, shouldContentSniff));
if (newHandle->start(deprecated))
return newHandle.release();
return 0;
}
const ResourceRequest& ResourceHandle::request() const
{
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(Frame* deprecated)
{
d->start();
return true;
}
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; }
bool ResourceHandle::supportsBufferedData()
{
return false; }
void ResourceHandle::loadResourceSynchronously(const ResourceRequest& request,
StoredCredentials storedCredentials,
ResourceError& error,
ResourceResponse& response,
Vector<char>& data,
Frame* deprecated)
{
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());
}
bool ResourceHandle::willLoadFromCache(ResourceRequest& request, Frame*)
{
ASSERT(request.httpMethod() == "POST");
return true;
}
}