ResourceHandle.cpp [plain text]
#include "config.h"
#include "ResourceHandle.h"
#include "ResourceHandleInternal.h"
#include "BlobRegistry.h"
#include "Logging.h"
#include "ResourceHandleClient.h"
#include "Timer.h"
#include <algorithm>
#include <wtf/MainThread.h>
#include <wtf/text/CString.h>
namespace WebCore {
static bool shouldForceContentSniffing;
typedef HashMap<AtomicString, ResourceHandle::BuiltinConstructor> BuiltinResourceHandleConstructorMap;
static BuiltinResourceHandleConstructorMap& builtinResourceHandleConstructorMap()
{
ASSERT(isMainThread());
DEFINE_STATIC_LOCAL(BuiltinResourceHandleConstructorMap, map, ());
return map;
}
void ResourceHandle::registerBuiltinConstructor(const AtomicString& protocol, ResourceHandle::BuiltinConstructor constructor)
{
builtinResourceHandleConstructorMap().add(protocol, constructor);
}
ResourceHandle::ResourceHandle(const ResourceRequest& request, ResourceHandleClient* client, bool defersLoading, bool shouldContentSniff)
: d(adoptPtr(new ResourceHandleInternal(this, request, client, defersLoading, shouldContentSniff && shouldContentSniffURL(request.url()))))
{
if (!request.url().isValid()) {
scheduleFailure(InvalidURLFailure);
return;
}
if (!portAllowed(request.url())) {
scheduleFailure(BlockedFailure);
return;
}
}
PassRefPtr<ResourceHandle> ResourceHandle::create(NetworkingContext* context, const ResourceRequest& request, ResourceHandleClient* client, bool defersLoading, bool shouldContentSniff)
{
BuiltinResourceHandleConstructorMap::iterator protocolMapItem = builtinResourceHandleConstructorMap().find(request.url().protocol());
if (protocolMapItem != builtinResourceHandleConstructorMap().end())
return protocolMapItem->second(request, client);
RefPtr<ResourceHandle> newHandle(adoptRef(new ResourceHandle(request, client, defersLoading, shouldContentSniff)));
if (newHandle->d->m_scheduledFailureType != NoFailure)
return newHandle.release();
if (newHandle->start(context))
return newHandle.release();
return 0;
}
void ResourceHandle::scheduleFailure(FailureType type)
{
d->m_scheduledFailureType = type;
d->m_failureTimer.startOneShot(0);
}
void ResourceHandle::fireFailure(Timer<ResourceHandle>*)
{
if (!client())
return;
switch (d->m_scheduledFailureType) {
case NoFailure:
ASSERT_NOT_REACHED();
return;
case BlockedFailure:
d->m_scheduledFailureType = NoFailure;
client()->wasBlocked(this);
return;
case InvalidURLFailure:
d->m_scheduledFailureType = NoFailure;
client()->cannotShowURL(this);
return;
}
ASSERT_NOT_REACHED();
}
ResourceHandleClient* ResourceHandle::client() const
{
return d->m_client;
}
void ResourceHandle::setClient(ResourceHandleClient* client)
{
d->m_client = client;
}
ResourceRequest& ResourceHandle::firstRequest()
{
return d->m_firstRequest;
}
const String& ResourceHandle::lastHTTPMethod() const
{
return d->m_lastHTTPMethod;
}
bool ResourceHandle::hasAuthenticationChallenge() const
{
return !d->m_currentWebChallenge.isNull();
}
void ResourceHandle::clearAuthentication()
{
#if PLATFORM(MAC)
d->m_currentMacChallenge = nil;
#endif
d->m_currentWebChallenge.nullify();
}
bool ResourceHandle::shouldContentSniff() const
{
return d->m_shouldContentSniff;
}
bool ResourceHandle::shouldContentSniffURL(const KURL& url)
{
#if PLATFORM(MAC)
if (shouldForceContentSniffing)
return true;
#endif
return !url.protocolIs("file");
}
void ResourceHandle::forceContentSniffing()
{
shouldForceContentSniffing = true;
}
void ResourceHandle::setDefersLoading(bool defers)
{
LOG(Network, "Handle %p setDefersLoading(%s)", this, defers ? "true" : "false");
ASSERT(d->m_defersLoading != defers); d->m_defersLoading = defers;
if (defers) {
ASSERT(d->m_failureTimer.isActive() == (d->m_scheduledFailureType != NoFailure));
if (d->m_failureTimer.isActive())
d->m_failureTimer.stop();
} else if (d->m_scheduledFailureType != NoFailure) {
ASSERT(!d->m_failureTimer.isActive());
d->m_failureTimer.startOneShot(0);
}
platformSetDefersLoading(defers);
}
void ResourceHandle::cacheMetadata(const ResourceResponse&, const Vector<char>&)
{
}
}