ResourceHandle.cpp [plain text]
#include "config.h"
#include "ResourceHandle.h"
#include "ResourceHandleInternal.h"
#include "BlobRegistry.h"
#include "DNS.h"
#include "Logging.h"
#include "ResourceHandleClient.h"
#include "Timer.h"
#include <algorithm>
#include <wtf/text/CString.h>
namespace WebCore {
static bool shouldForceContentSniffing;
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)
{
#if ENABLE(BLOB)
if (request.url().protocolIs("blob")) {
PassRefPtr<ResourceHandle> handle = blobRegistry().createResourceHandle(request, client);
if (handle)
return handle;
}
#endif
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);
}
#if !USE(SOUP)
void ResourceHandle::prepareForURL(const KURL& url)
{
return prefetchDNS(url.host());
}
#endif
void ResourceHandle::cacheMetadata(const ResourceResponse&, const Vector<char>&)
{
}
#if USE(CFURLSTORAGESESSIONS)
static RetainPtr<CFURLStorageSessionRef>& privateStorageSession()
{
DEFINE_STATIC_LOCAL(RetainPtr<CFURLStorageSessionRef>, storageSession, ());
return storageSession;
}
static String& privateBrowsingStorageSessionIdentifierBase()
{
DEFINE_STATIC_LOCAL(String, base, ());
return base;
}
void ResourceHandle::setPrivateBrowsingEnabled(bool enabled)
{
if (!enabled) {
privateStorageSession() = nullptr;
return;
}
if (privateStorageSession())
return;
String base = privateBrowsingStorageSessionIdentifierBase().isNull() ? privateBrowsingStorageSessionIdentifierDefaultBase() : privateBrowsingStorageSessionIdentifierBase();
RetainPtr<CFStringRef> cfIdentifier(AdoptCF, String::format("%s.PrivateBrowsing", base.utf8().data()).createCFString());
privateStorageSession() = createPrivateBrowsingStorageSession(cfIdentifier.get());
}
CFURLStorageSessionRef ResourceHandle::privateBrowsingStorageSession()
{
return privateStorageSession().get();
}
void ResourceHandle::setPrivateBrowsingStorageSessionIdentifierBase(const String& identifier)
{
privateBrowsingStorageSessionIdentifierBase() = identifier;
}
#endif // USE(CFURLSTORAGESESSIONS)
}