Пример #1
0
void SVGUseElement::updateExternalDocument()
{
    URL externalDocumentURL;
    if (inDocument() && isExternalURIReference(href(), document())) {
        externalDocumentURL = document().completeURL(href());
        if (!externalDocumentURL.hasFragmentIdentifier())
            externalDocumentURL = URL();
    }

    if (externalDocumentURL == (m_externalDocument ? m_externalDocument->url() : URL()))
        return;

    if (m_externalDocument)
        m_externalDocument->removeClient(this);

    if (externalDocumentURL.isNull())
        m_externalDocument = nullptr;
    else {
        ResourceLoaderOptions options = CachedResourceLoader::defaultCachedResourceOptions();
        options.setContentSecurityPolicyImposition(isInUserAgentShadowTree() ? ContentSecurityPolicyImposition::SkipPolicyCheck : ContentSecurityPolicyImposition::DoPolicyCheck);

        CachedResourceRequest request { ResourceRequest { externalDocumentURL }, options };
        request.setInitiator(this);
        m_externalDocument = document().cachedResourceLoader().requestSVGDocument(request);
        if (m_externalDocument)
            m_externalDocument->addClient(this);
    }

    invalidateShadowTree();
}
Пример #2
0
void SVGUseElement::updateExternalDocument()
{
    URL externalDocumentURL;
    if (inDocument() && isExternalURIReference(href(), document())) {
        externalDocumentURL = document().completeURL(href());
        if (!externalDocumentURL.hasFragmentIdentifier())
            externalDocumentURL = URL();
    }

    if (externalDocumentURL == (m_externalDocument ? m_externalDocument->url() : URL()))
        return;

    if (m_externalDocument)
        m_externalDocument->removeClient(this);

    if (externalDocumentURL.isNull())
        m_externalDocument = nullptr;
    else {
        CachedResourceRequest request { ResourceRequest { externalDocumentURL } };
        request.setInitiator(this);
        m_externalDocument = document().cachedResourceLoader().requestSVGDocument(request);
        if (m_externalDocument) {
            // FIXME: Is it really OK for us to set this to false for a document that might be shared by another client?
            m_externalDocument->setShouldCreateFrameForDocument(false); // No frame needed, we just want the elements.
            m_externalDocument->addClient(this);
        }
    }

    invalidateShadowTree();
}
Пример #3
0
CachedResourceHandle<CachedImage> CachedResourceLoader::requestImage(CachedResourceRequest& request)
{
    if (Frame* f = frame()) {
        if (f->loader()->pageDismissalEventBeingDispatched() != FrameLoader::NoDismissal) {
            KURL requestURL = request.resourceRequest().url();
            if (requestURL.isValid() && canRequest(CachedResource::ImageResource, requestURL))
                PingLoader::loadImage(f, requestURL);
            return 0;
        }
    }
    request.setDefer(clientDefersImage(request.resourceRequest().url()) ? CachedResourceRequest::DeferredByClient : CachedResourceRequest::NoDefer);
    return static_cast<CachedImage*>(requestResource(CachedResource::ImageResource, request).get());
}
Пример #4
0
CachedResourceHandle<CachedResource> CachedResourceLoader::loadResource(CachedResource::Type type, CachedResourceRequest& request, const String& charset)
{
    ASSERT(!memoryCache()->resourceForRequest(request.resourceRequest()));

    LOG(ResourceLoading, "Loading CachedResource for '%s'.", request.resourceRequest().url().elidedString().latin1().data());

    CachedResourceHandle<CachedResource> resource = createResource(type, request.mutableResourceRequest(), charset);

    if (!memoryCache()->add(resource.get()))
        resource->setOwningCachedResourceLoader(this);
#if ENABLE(RESOURCE_TIMING)
    storeResourceTimingInitiatorInformation(resource, request);
#endif
    return resource;
}
Пример #5
0
CachedResourceHandle<CachedCSSStyleSheet> CachedResourceLoader::requestUserCSSStyleSheet(CachedResourceRequest& request)
{
    KURL url = MemoryCache::removeFragmentIdentifierIfNeeded(request.resourceRequest().url());

#if ENABLE(CACHE_PARTITIONING)
    request.mutableResourceRequest().setCachePartition(document()->topOrigin()->cachePartition());
#endif

    if (CachedResource* existing = memoryCache()->resourceForRequest(request.resourceRequest())) {
        if (existing->type() == CachedResource::CSSStyleSheet)
            return static_cast<CachedCSSStyleSheet*>(existing);
        memoryCache()->remove(existing);
    }
    if (url.string() != request.resourceRequest().url())
        request.mutableResourceRequest().setURL(url);

    CachedResourceHandle<CachedCSSStyleSheet> userSheet = new CachedCSSStyleSheet(request.resourceRequest(), request.charset());

    memoryCache()->add(userSheet.get());
    // FIXME: loadResource calls setOwningCachedResourceLoader() if the resource couldn't be added to cache. Does this function need to call it, too?

    userSheet->load(this, ResourceLoaderOptions(DoNotSendCallbacks, SniffContent, BufferData, AllowStoredCredentials, AskClientForCrossOriginCredentials, SkipSecurityCheck));
    
    return userSheet;
}
Пример #6
0
void CachedResourceLoader::requestPreload(CachedResource::Type type, CachedResourceRequest& request, const String& charset)
{
    String encoding;
    if (type == CachedResource::Script || type == CachedResource::CSSStyleSheet)
        encoding = charset.isEmpty() ? m_document->charset() : charset;

    request.setCharset(encoding);
    request.setForPreload(true);

    CachedResourceHandle<CachedResource> resource = requestResource(type, request);
    if (!resource || (m_preloads && m_preloads->contains(resource.get())))
        return;
    resource->increasePreloadCount();

    if (!m_preloads)
        m_preloads = adoptPtr(new ListHashSet<CachedResource*>);
    m_preloads->add(resource.get());

#if PRELOAD_DEBUG
    printf("PRELOADING %s\n",  resource->url().latin1().data());
#endif
}
Пример #7
0
void CachedResourceLoader::storeResourceTimingInitiatorInformation(const CachedResourceHandle<CachedResource>& resource, const CachedResourceRequest& request)
{
    if (resource->type() == CachedResource::MainResource) {
        // <iframe>s should report the initial navigation requested by the parent document, but not subsequent navigations.
        if (frame()->ownerElement() && m_documentLoader->frameLoader()->stateMachine()->committingFirstRealLoad()) {
            InitiatorInfo info = { frame()->ownerElement()->localName(), monotonicallyIncreasingTime() };
            m_initiatorMap.add(resource.get(), info);
        }
    } else {
        InitiatorInfo info = { request.initiatorName(), monotonicallyIncreasingTime() };
        m_initiatorMap.add(resource.get(), info);
    }
}
void ResourceTimingInformation::storeResourceTimingInitiatorInformation(const CachedResourceHandle<CachedResource>& resource, const CachedResourceRequest& request, Frame* frame)
{
    ASSERT(RuntimeEnabledFeatures::sharedFeatures().resourceTimingEnabled());
    ASSERT(resource.get());
    if (resource->type() == CachedResource::MainResource) {
        // <iframe>s should report the initial navigation requested by the parent document, but not subsequent navigations.
        ASSERT(frame);
        if (frame->ownerElement()) {
            InitiatorInfo info = { frame->ownerElement()->localName(), monotonicallyIncreasingTime(), NotYetAdded };
            m_initiatorMap.add(resource.get(), info);
        }
    } else {
        InitiatorInfo info = { request.initiatorName(), monotonicallyIncreasingTime(), NotYetAdded };
        m_initiatorMap.add(resource.get(), info);
    }
}
Пример #9
0
void CachedResourceLoader::preload(CachedResource::Type type, CachedResourceRequest& request, const String& charset)
{
    bool delaySubresourceLoad = true;
#if PLATFORM(IOS) || PLATFORM(CHROMIUM)
    delaySubresourceLoad = false;
#endif
#if PLATFORM(CHROMIUM)
    // FIXME: All ports should take advantage of this, but first must support ResourceHandle::didChangePriority().
    if (type == CachedResource::ImageResource)
        request.setPriority(ResourceLoadPriorityVeryLow);
#endif
    if (delaySubresourceLoad) {
        bool hasRendering = m_document->body() && m_document->body()->renderer();
        bool canBlockParser = type == CachedResource::Script || type == CachedResource::CSSStyleSheet;
        if (!hasRendering && !canBlockParser) {
            // Don't preload subresources that can't block the parser before we have something to draw.
            // This helps prevent preloads from delaying first display when bandwidth is limited.
            PendingPreload pendingPreload = { type, request, charset };
            m_pendingPreloads.append(pendingPreload);
            return;
        }
    }
    requestPreload(type, request, charset);
}
Пример #10
0
CachedResourceHandle<CachedResource> CachedResourceLoader::requestResource(CachedResource::Type type, CachedResourceRequest& request)
{
    KURL url = request.resourceRequest().url();
    
    LOG(ResourceLoading, "CachedResourceLoader::requestResource '%s', charset '%s', priority=%d, forPreload=%u", url.elidedString().latin1().data(), request.charset().latin1().data(), request.priority(), request.forPreload());
    
    // If only the fragment identifiers differ, it is the same resource.
    url = MemoryCache::removeFragmentIdentifierIfNeeded(url);

    if (!url.isValid())
        return 0;

    if (!canRequest(type, url, request.forPreload()))
        return 0;

    if (Frame* f = frame())
        f->loader()->client()->dispatchWillRequestResource(&request);

    if (memoryCache()->disabled()) {
        DocumentResourceMap::iterator it = m_documentResources.find(url.string());
        if (it != m_documentResources.end()) {
            it->value->setOwningCachedResourceLoader(0);
            m_documentResources.remove(it);
        }
    }

    // See if we can use an existing resource from the cache.
    CachedResourceHandle<CachedResource> resource;
#if ENABLE(CACHE_PARTITIONING)
    if (document())
        request.mutableResourceRequest().setCachePartition(document()->topOrigin()->cachePartition());
#endif

    resource = memoryCache()->resourceForRequest(request.resourceRequest());

    const RevalidationPolicy policy = determineRevalidationPolicy(type, request.mutableResourceRequest(), request.forPreload(), resource.get(), request.defer());
    switch (policy) {
    case Reload:
        memoryCache()->remove(resource.get());
        // Fall through
    case Load:
        resource = loadResource(type, request, request.charset());
        break;
    case Revalidate:
        resource = revalidateResource(request, resource.get());
        break;
    case Use:
        memoryCache()->resourceAccessed(resource.get());
        notifyLoadedFromMemoryCache(resource.get());
        break;
    }

    if (!resource)
        return 0;

    if (!request.forPreload() || policy != Use)
        resource->setLoadPriority(request.priority());

    if ((policy != Use || resource->stillNeedsLoad()) && CachedResourceRequest::NoDefer == request.defer()) {
        resource->load(this, request.options());

        // We don't support immediate loads, but we do support immediate failure.
        if (resource->errorOccurred()) {
            if (resource->inCache())
                memoryCache()->remove(resource.get());
            return 0;
        }
    }

#if PLATFORM(CHROMIUM)
    // FIXME: Temporarily leave main resource caching disabled for chromium, see https://bugs.webkit.org/show_bug.cgi?id=107962
    // Ensure main resources aren't preloaded, and other main resource loads are removed from cache to prevent reuse.
    if (type == CachedResource::MainResource) {
        ASSERT(policy != Use);
        ASSERT(policy != Revalidate);
        memoryCache()->remove(resource.get());
        if (request.forPreload())
            return 0;
    }
#endif

    if (!request.resourceRequest().url().protocolIsData())
        m_validatedURLs.add(request.resourceRequest().url());

    ASSERT(resource->url() == url.string());
    m_documentResources.set(resource->url(), resource);
    return resource;
}