示例#1
0
BlobRegistry& blobRegistry()
{
    ASSERT(isMainThread());

    static BlobRegistry& instance = *platformStrategies()->loaderStrategy()->createBlobRegistry();
    return instance;
}
示例#2
0
void ResourceLoader::willSendRequest(ResourceRequest& request, const ResourceResponse& redirectResponse)
{
    // Protect this in this delegate method since the additional processing can do
    // anything including possibly derefing this; one example of this is Radar 3266216.
    Ref<ResourceLoader> protect(*this);

    ASSERT(!m_reachedTerminalState);

    // We need a resource identifier for all requests, even if FrameLoader is never going to see it (such as with CORS preflight requests).
    bool createdResourceIdentifier = false;
    if (!m_identifier) {
        m_identifier = m_frame->page()->progress().createUniqueIdentifier();
        createdResourceIdentifier = true;
    }

    if (m_options.sendLoadCallbacks == SendCallbacks) {
        if (createdResourceIdentifier)
            frameLoader()->notifier()->assignIdentifierToInitialRequest(m_identifier, documentLoader(), request);

        frameLoader()->notifier()->willSendRequest(this, request, redirectResponse);
    }
#if ENABLE(INSPECTOR)
    else
        InspectorInstrumentation::willSendRequest(m_frame.get(), m_identifier, m_frame->loader().documentLoader(), request, redirectResponse);
#endif

    if (!redirectResponse.isNull())
        platformStrategies()->loaderStrategy()->resourceLoadScheduler()->crossOriginRedirectReceived(this, request.url());

    m_request = request;

    if (!redirectResponse.isNull() && !m_documentLoader->isCommitted())
        frameLoader()->client().dispatchDidReceiveServerRedirectForProvisionalLoad();
}
示例#3
0
void ResourceLoader::willSwitchToSubstituteResource()
{
    ASSERT(!m_documentLoader->isSubstituteLoadPending(this));
    platformStrategies()->loaderStrategy()->resourceLoadScheduler()->remove(this);
    if (m_handle)
        m_handle->cancel();
}
示例#4
0
void ResourceLoader::releaseResources()
{
    ASSERT(!m_reachedTerminalState);
    
    // It's possible that when we release the handle, it will be
    // deallocated and release the last reference to this object.
    // We need to retain to avoid accessing the object after it
    // has been deallocated and also to avoid reentering this method.
    Ref<ResourceLoader> protect(*this);

    m_frame = 0;
    m_documentLoader = 0;
    
    // We need to set reachedTerminalState to true before we release
    // the resources to prevent a double dealloc of WebView <rdar://problem/4372628>
    m_reachedTerminalState = true;

    platformStrategies()->loaderStrategy()->resourceLoadScheduler()->remove(this);
    m_identifier = 0;

    if (m_handle) {
        // Clear out the ResourceHandle's client so that it doesn't try to call
        // us back after we release it, unless it has been replaced by someone else.
        if (m_handle->client() == this)
            m_handle->setClient(0);
        m_handle = 0;
    }

    m_resourceData = 0;
    m_deferredRequest = ResourceRequest();
}
示例#5
0
ResourceLoadScheduler* resourceLoadScheduler()
{
    ASSERT(isMainThread());
    static ResourceLoadScheduler* globalScheduler = 0;
    
    if (!globalScheduler) {
#if USE(PLATFORM_STRATEGIES)
        static bool isCallingOutToStrategy = false;
        
        // If we're re-entering resourceLoadScheduler() while calling out to the LoaderStrategy,
        // then the LoaderStrategy is trying to use the default resourceLoadScheduler.
        // So we'll create it here and start using it.
        if (isCallingOutToStrategy) {
            globalScheduler = new ResourceLoadScheduler;
            return globalScheduler;
        }
        
        TemporaryChange<bool> recursionGuard(isCallingOutToStrategy, true);
        globalScheduler = platformStrategies()->loaderStrategy()->resourceLoadScheduler();
#else
        globalScheduler = new ResourceLoadScheduler;
#endif
    }

    return globalScheduler;
}
示例#6
0
void ResourceLoader::willSendRequest(ResourceRequest& request, const ResourceResponse& redirectResponse)
{
    // Protect this in this delegate method since the additional processing can do
    // anything including possibly derefing this; one example of this is Radar 3266216.
    RefPtr<ResourceLoader> protector(this);

    ASSERT(!m_reachedTerminalState);

    if (m_options.sendLoadCallbacks == SendCallbacks) {
        if (!m_identifier) {
            m_identifier = m_frame->page()->progress()->createUniqueIdentifier();
            frameLoader()->notifier()->assignIdentifierToInitialRequest(m_identifier, documentLoader(), request);
        }

        frameLoader()->notifier()->willSendRequest(this, request, redirectResponse);
    }

    if (!redirectResponse.isNull()) {
#if USE(PLATFORM_STRATEGIES)
        platformStrategies()->loaderStrategy()->resourceLoadScheduler()->crossOriginRedirectReceived(this, request.url());
#else
        resourceLoadScheduler()->crossOriginRedirectReceived(this, request.url());
#endif
    }
    m_request = request;

    if (!redirectResponse.isNull() && !m_documentLoader->isCommitted())
        frameLoader()->client()->dispatchDidReceiveServerRedirectForProvisionalLoad();
}
示例#7
0
static inline LocalizationStrategy* localizationStrategy()
{
    if (hasPlatformStrategies())
        return platformStrategies()->localizationStrategy();

    return &DefaultLocalizationStrategy::shared();
}
示例#8
0
PassRefPtr<StorageNamespace> StorageNamespace::localStorageNamespace(const String& path, unsigned quota)
{
#if USE(PLATFORM_STRATEGIES)
    return platformStrategies()->storageStrategy()->localStorageNamespace(path, quota);
#else
    return StorageNamespaceImpl::localStorageNamespace(path, quota);
#endif
}
示例#9
0
static void notifyCookiesChangedOnMainThread(void*)
{
    ASSERT(isMainThread());

#if USE(PLATFORM_STRATEGIES)
    platformStrategies()->cookiesStrategy()->notifyCookiesChanged();
#endif
}
示例#10
0
static inline void addVisitedLink(Page* page, const KURL& url)
{
#if USE(PLATFORM_STRATEGIES)
    platformStrategies()->visitedLinkStrategy()->addVisitedLink(page, visitedLinkHash(url.string().characters(), url.string().length()));
#else
    page->group().addVisitedLink(url);
#endif
}
示例#11
0
void ResourceLoader::willSendRequestInternal(ResourceRequest& request, const ResourceResponse& redirectResponse)
{
    // Protect this in this delegate method since the additional processing can do
    // anything including possibly derefing this; one example of this is Radar 3266216.
    Ref<ResourceLoader> protect(*this);

    ASSERT(!m_reachedTerminalState);
#if ENABLE(CONTENT_EXTENSIONS)
    ASSERT(m_resourceType != ResourceType::Invalid);
#endif

    // We need a resource identifier for all requests, even if FrameLoader is never going to see it (such as with CORS preflight requests).
    bool createdResourceIdentifier = false;
    if (!m_identifier) {
        m_identifier = m_frame->page()->progress().createUniqueIdentifier();
        createdResourceIdentifier = true;
    }

#if ENABLE(CONTENT_EXTENSIONS)
    if (frameLoader()) {
        Page* page = frameLoader()->frame().page();
        if (page && m_documentLoader) {
            auto* userContentController = page->userContentController();
            if (userContentController)
                userContentController->processContentExtensionRulesForLoad(*page, request, m_resourceType, *m_documentLoader);
        }
    }
#endif

    if (request.isNull()) {
        didFail(cannotShowURLError());
        return;
    }

    if (m_options.sendLoadCallbacks() == SendCallbacks) {
        if (createdResourceIdentifier)
            frameLoader()->notifier().assignIdentifierToInitialRequest(m_identifier, documentLoader(), request);

#if PLATFORM(IOS)
        // If this ResourceLoader was stopped as a result of assignIdentifierToInitialRequest, bail out
        if (m_reachedTerminalState)
            return;
#endif

        frameLoader()->notifier().willSendRequest(this, request, redirectResponse);
    }
    else
        InspectorInstrumentation::willSendRequest(m_frame.get(), m_identifier, m_frame->loader().documentLoader(), request, redirectResponse);

    if (!redirectResponse.isNull())
        platformStrategies()->loaderStrategy()->resourceLoadScheduler()->crossOriginRedirectReceived(this, request.url());

    m_request = request;

    if (!redirectResponse.isNull() && !m_documentLoader->isCommitted())
        frameLoader()->client().dispatchDidReceiveServerRedirectForProvisionalLoad();
}
示例#12
0
PassRefPtr<StorageNamespace> StorageNamespace::sessionStorageNamespace(Page* page, unsigned quota)
{
#if USE(PLATFORM_STRATEGIES)
    return platformStrategies()->storageStrategy()->sessionStorageNamespace(page, quota);
#else
    UNUSED_PARAM(page);
    return StorageNamespaceImpl::sessionStorageNamespace(quota);
#endif
}
示例#13
0
PostResolutionCallbackDisabler::PostResolutionCallbackDisabler(Document& document)
{
    ++resolutionNestingDepth;

    if (resolutionNestingDepth == 1)
        platformStrategies()->loaderStrategy()->suspendPendingRequests();

    // FIXME: It's strange to build this into the disabler.
    suspendMemoryCacheClientCalls(document);
}
示例#14
0
void ResourceLoader::finishNetworkLoad()
{
    platformStrategies()->loaderStrategy()->resourceLoadScheduler()->remove(this);

    if (m_handle) {
        ASSERT(m_handle->client() == this);
        m_handle->clearClient();
        m_handle = nullptr;
    }
}
示例#15
0
void CachedResourceLoader::performPostLoadActions()
{
    checkForPendingPreloads();

#if USE(PLATFORM_STRATEGIES)
    platformStrategies()->loaderStrategy()->resourceLoadScheduler()->servePendingRequests();
#else
    resourceLoadScheduler()->servePendingRequests();
#endif
}
DatabaseManager::DatabaseManager()
    : m_server(platformStrategies()->databaseStrategy()->getDatabaseServer())
    , m_client(0)
    , m_databaseIsAvailable(true)
#if !ASSERT_DISABLED
    , m_databaseContextRegisteredCount(0)
    , m_databaseContextInstanceCount(0)
#endif
{
    ASSERT(m_server); // We should always have a server to work with.
}
示例#17
0
void ResourceLoader::setDefersLoading(bool defers)
{
    m_defersLoading = defers;
    if (m_handle)
        m_handle->setDefersLoading(defers);
    if (!defers && !m_deferredRequest.isNull()) {
        m_request = m_deferredRequest;
        m_deferredRequest = ResourceRequest();
        start();
    }

    platformStrategies()->loaderStrategy()->resourceLoadScheduler()->setDefersLoading(this, defers);
}
示例#18
0
void PingLoader::startPingLoad(Frame& frame, ResourceRequest& request, ShouldFollowRedirects shouldFollowRedirects)
{
    unsigned long identifier = frame.page()->progress().createUniqueIdentifier();
    // FIXME: Why activeDocumentLoader? I would have expected documentLoader().
    // Itseems like the PingLoader should be associated with the current
    // Document in the Frame, but the activeDocumentLoader will be associated
    // with the provisional DocumentLoader if there is a provisional
    // DocumentLoader.
    bool shouldUseCredentialStorage = frame.loader().client().shouldUseCredentialStorage(frame.loader().activeDocumentLoader(), identifier);

    InspectorInstrumentation::continueAfterPingLoader(frame, identifier, frame.loader().activeDocumentLoader(), request, ResourceResponse());

    platformStrategies()->loaderStrategy()->createPingHandle(frame.loader().networkingContext(), request, shouldUseCredentialStorage, shouldFollowRedirects == ShouldFollowRedirects::Yes);
}
示例#19
0
PostResolutionCallbackDisabler::~PostResolutionCallbackDisabler()
{
    if (resolutionNestingDepth == 1) {
        // Get size each time through the loop because a callback can add more callbacks to the end of the queue.
        auto& queue = postResolutionCallbackQueue();
        for (size_t i = 0; i < queue.size(); ++i)
            queue[i]();
        queue.clear();

        platformStrategies()->loaderStrategy()->resumePendingRequests();
    }

    --resolutionNestingDepth;
}
示例#20
0
DatabaseManager::DatabaseManager()
    : m_client(0)
    , m_databaseIsAvailable(true)
#if !ASSERT_DISABLED
    , m_databaseContextRegisteredCount(0)
    , m_databaseContextInstanceCount(0)
#endif
{
#if USE(PLATFORM_STRATEGIES)
    m_server = platformStrategies()->databaseStrategy()->getDatabaseServer();
#else
    m_server = new DatabaseServer;
#endif
    ASSERT(m_server); // We should always have a server to work with.
}
示例#21
0
void ResourceLoader::willSendRequest(ResourceRequest& request, const ResourceResponse& redirectResponse)
{
    // Protect this in this delegate method since the additional processing can do
    // anything including possibly derefing this; one example of this is Radar 3266216.
    Ref<ResourceLoader> protect(*this);

    ASSERT(!m_reachedTerminalState);
    
#if PLATFORM(IOS)
    // Ensure an identifier is always set. This ensures that this assetion is not hit:
    // <rdar://problem/11059794> ASSERTION FAILED: !HashTranslator::equal(KeyTraits::emptyValue(), key) in WebFrameLoaderClient::canAuthenticateAgainstProtectionSpace loading the attached web archive
    // This is not needed in WebKit2, as it doesn't use m_identifier in WebFrameLoaderClient::canAuthenticateAgainstProtectionSpace
    if (!m_identifier) {
        m_identifier = m_frame->page()->progress().createUniqueIdentifier();
        frameLoader()->notifier().assignIdentifierToInitialRequest(m_identifier, documentLoader(), request);

        // If this ResourceLoader was stopped as a result of assignIdentifierToInitialRequest, bail out
        if (m_reachedTerminalState)
            return;
    }
#endif

    // We need a resource identifier for all requests, even if FrameLoader is never going to see it (such as with CORS preflight requests).
    bool createdResourceIdentifier = false;
    if (!m_identifier) {
        m_identifier = m_frame->page()->progress().createUniqueIdentifier();
        createdResourceIdentifier = true;
    }

    if (m_options.sendLoadCallbacks == SendCallbacks) {
        if (createdResourceIdentifier)
            frameLoader()->notifier().assignIdentifierToInitialRequest(m_identifier, documentLoader(), request);

        frameLoader()->notifier().willSendRequest(this, request, redirectResponse);
    }
#if ENABLE(INSPECTOR)
    else
        InspectorInstrumentation::willSendRequest(m_frame.get(), m_identifier, m_frame->loader().documentLoader(), request, redirectResponse);
#endif

    if (!redirectResponse.isNull())
        platformStrategies()->loaderStrategy()->resourceLoadScheduler()->crossOriginRedirectReceived(this, request.url());

    m_request = request;

    if (!redirectResponse.isNull() && !m_documentLoader->isCommitted())
        frameLoader()->client().dispatchDidReceiveServerRedirectForProvisionalLoad();
}
示例#22
0
void ContainerNode::suspendPostAttachCallbacks()
{
    if (!s_attachDepth) {
        ASSERT(!s_shouldReEnableMemoryCacheCallsAfterAttach);
        if (Page* page = document().page()) {
            // FIXME: How can this call be specific to one Page, while the
            // s_attachDepth is a global? Doesn't make sense.
            if (page->areMemoryCacheClientCallsEnabled()) {
                page->setMemoryCacheClientCallsEnabled(false);
                s_shouldReEnableMemoryCacheCallsAfterAttach = true;
            }
        }
        platformStrategies()->loaderStrategy()->resourceLoadScheduler()->suspendPendingRequests();
    }
    ++s_attachDepth;
}
示例#23
0
void ContainerNode::resumePostAttachCallbacks()
{
    if (s_attachDepth == 1) {
        RefPtr<ContainerNode> protect(this);

        if (s_postAttachCallbackQueue)
            dispatchPostAttachCallbacks();
        if (s_shouldReEnableMemoryCacheCallsAfterAttach) {
            s_shouldReEnableMemoryCacheCallsAfterAttach = false;
            if (Page* page = document().page())
                page->setMemoryCacheClientCallsEnabled(true);
        }
        platformStrategies()->loaderStrategy()->resourceLoadScheduler()->resumePendingRequests();
    }
    --s_attachDepth;
}
示例#24
0
void ResourceLoader::setDefersLoading(bool defers)
{
    if (m_options.defersLoadingPolicy() == DefersLoadingPolicy::DisallowDefersLoading)
        return;

    m_defersLoading = defers;
    if (m_handle)
        m_handle->setDefersLoading(defers);
    if (!defers && !m_deferredRequest.isNull()) {
        m_request = m_deferredRequest;
        m_deferredRequest = ResourceRequest();
        start();
    }

    platformStrategies()->loaderStrategy()->resourceLoadScheduler()->setDefersLoading(this, defers);
}
示例#25
0
void MainResourceLoader::loadNow(ResourceRequest& r)
{
    ASSERT(!m_handle);
    ASSERT(!defersLoading());

#if USE(PLATFORM_STRATEGIES)
    platformStrategies()->loaderStrategy()->resourceLoadScheduler()->addMainResourceLoad(this);
#else
    resourceLoadScheduler()->addMainResourceLoad(this);
#endif

    if (m_substituteData.isValid())
        handleSubstituteDataLoadSoon(r);
    else
        m_handle = ResourceHandle::create(m_frame->loader()->networkingContext(), r, this, false, true);

    return;
}
示例#26
0
bool MainResourceLoader::loadNow(ResourceRequest& r)
{
    bool shouldLoadEmptyBeforeRedirect = shouldLoadAsEmptyDocument(r.url());

    ASSERT(!m_handle);
    ASSERT(shouldLoadEmptyBeforeRedirect || !defersLoading());

    // Send this synthetic delegate callback since clients expect it, and
    // we no longer send the callback from within NSURLConnection for
    // initial requests.
    willSendRequest(r, ResourceResponse());
    ASSERT(!deletionHasBegun());

    // <rdar://problem/4801066>
    // willSendRequest() is liable to make the call to frameLoader() return NULL, so we need to check that here
    if (!frameLoader())
        return false;
    
    const KURL& url = r.url();
    bool shouldLoadEmpty = shouldLoadAsEmptyDocument(url) && !m_substituteData.isValid();

    if (shouldLoadEmptyBeforeRedirect && !shouldLoadEmpty && defersLoading())
        return true;

#if USE(PLATFORM_STRATEGIES)
    platformStrategies()->loaderStrategy()->resourceLoadScheduler()->addMainResourceLoad(this);
#else
    resourceLoadScheduler()->addMainResourceLoad(this);
#endif

    if (m_substituteData.isValid())
        handleSubstituteDataLoadSoon(r);
    else if (shouldLoadEmpty || frameLoader()->client()->representationExistsForURLScheme(url.protocol()))
        handleEmptyLoad(url, !shouldLoadEmpty);
    else
        m_handle = ResourceHandle::create(m_frame->loader()->networkingContext(), r, this, false, true);

    return false;
}
示例#27
0
BlobRegistry& blobRegistry()
{
    ASSERT(isMainThread());
    return *platformStrategies()->blobRegistry();
}
示例#28
0
void CachedResource::load(CachedResourceLoader* cachedResourceLoader, const ResourceLoaderOptions& options)
{
    if (!cachedResourceLoader->frame()) {
        failBeforeStarting();
        return;
    }

    FrameLoader& frameLoader = cachedResourceLoader->frame()->loader();
    if (options.securityCheck() == DoSecurityCheck && (frameLoader.state() == FrameStateProvisional || !frameLoader.activeDocumentLoader() || frameLoader.activeDocumentLoader()->isStopping())) {
        failBeforeStarting();
        return;
    }

    m_options = options;
    m_loading = true;

#if USE(QUICK_LOOK)
    if (!m_resourceRequest.isNull() && m_resourceRequest.url().protocolIs(QLPreviewProtocol())) {
        // When QuickLook is invoked to convert a document, it returns a unique URL in the
        // NSURLReponse for the main document. To make safeQLURLForDocumentURLAndResourceURL()
        // work, we need to use the QL URL not the original URL.
        const URL& documentURL = cachedResourceLoader->frame() ? cachedResourceLoader->frame()->loader().documentLoader()->response().url() : cachedResourceLoader->document()->url();
        m_resourceRequest.setURL(safeQLURLForDocumentURLAndResourceURL(documentURL, url()));
    }
#endif

    if (!accept().isEmpty())
        m_resourceRequest.setHTTPAccept(accept());

    if (isCacheValidator()) {
        CachedResource* resourceToRevalidate = m_resourceToRevalidate;
        ASSERT(resourceToRevalidate->canUseCacheValidator());
        ASSERT(resourceToRevalidate->isLoaded());
        const String& lastModified = resourceToRevalidate->response().httpHeaderField(HTTPHeaderName::LastModified);
        const String& eTag = resourceToRevalidate->response().httpHeaderField(HTTPHeaderName::ETag);
        if (!lastModified.isEmpty() || !eTag.isEmpty()) {
            ASSERT(cachedResourceLoader->cachePolicy(type()) != CachePolicyReload);
            if (cachedResourceLoader->cachePolicy(type()) == CachePolicyRevalidate)
                m_resourceRequest.setHTTPHeaderField(HTTPHeaderName::CacheControl, "max-age=0");
            if (!lastModified.isEmpty())
                m_resourceRequest.setHTTPHeaderField(HTTPHeaderName::IfModifiedSince, lastModified);
            if (!eTag.isEmpty())
                m_resourceRequest.setHTTPHeaderField(HTTPHeaderName::IfNoneMatch, eTag);
        }
    }

#if ENABLE(LINK_PREFETCH)
    if (type() == CachedResource::LinkPrefetch || type() == CachedResource::LinkSubresource)
        m_resourceRequest.setHTTPHeaderField(HTTPHeaderName::Purpose, "prefetch");
#endif
    m_resourceRequest.setPriority(loadPriority());

    if (type() != MainResource)
        addAdditionalRequestHeaders(cachedResourceLoader);

    // FIXME: It's unfortunate that the cache layer and below get to know anything about fragment identifiers.
    // We should look into removing the expectation of that knowledge from the platform network stacks.
    ResourceRequest request(m_resourceRequest);
    if (!m_fragmentIdentifierForRequest.isNull()) {
        URL url = request.url();
        url.setFragmentIdentifier(m_fragmentIdentifierForRequest);
        request.setURL(url);
        m_fragmentIdentifierForRequest = String();
    }

    m_loader = platformStrategies()->loaderStrategy()->resourceLoadScheduler()->scheduleSubresourceLoad(cachedResourceLoader->frame(), this, request, request.priority(), options);
    if (!m_loader) {
        failBeforeStarting();
        return;
    }

    m_status = Pending;
}
示例#29
0
static inline void addVisitedLink(Page* page, const KURL& url)
{
    platformStrategies()->visitedLinkStrategy()->addVisitedLink(page, visitedLinkHash(url.string()));
}
示例#30
0
void PluginData::initPlugins()
{
    ASSERT(m_plugins.isEmpty());
    
    platformStrategies()->pluginStrategy()->getPluginInfo(m_plugins);
}