bool LinkLoader::loadLink(const LinkRelAttribute& relAttribute, const AtomicString& crossOriginMode, const String& type, const String& as, const KURL& href, Document& document) { // TODO(yoav): Convert all uses of the CrossOriginAttribute to CrossOriginAttributeValue. crbug.com/486689 // FIXME(crbug.com/463266): We're ignoring type here. Maybe we shouldn't. dnsPrefetchIfNeeded(relAttribute, href, document); preconnectIfNeeded(relAttribute, href, document, crossOriginAttributeValue(crossOriginMode)); preloadIfNeeded(relAttribute, href, document, as); // FIXME(crbug.com/323096): Should take care of import. if ((relAttribute.isLinkPrefetch() || relAttribute.isLinkSubresource() || relAttribute.isTransitionExitingStylesheet()) && href.isValid() && document.frame()) { if (!m_client->shouldLoadLink()) return false; Resource::Type type = relAttribute.isLinkSubresource() ? Resource::LinkSubresource : Resource::LinkPrefetch; FetchRequest linkRequest(ResourceRequest(document.completeURL(href)), FetchInitiatorTypeNames::link); if (!crossOriginMode.isNull()) linkRequest.setCrossOriginAccessControl(document.securityOrigin(), crossOriginMode); setResource(document.fetcher()->fetchLinkResource(type, linkRequest)); } if (const unsigned prerenderRelTypes = prerenderRelTypesFromRelAttribute(relAttribute)) { if (!m_prerender) { m_prerender = PrerenderHandle::create(document, this, href, prerenderRelTypes); } else if (m_prerender->url() != href) { m_prerender->cancel(); m_prerender = PrerenderHandle::create(document, this, href, prerenderRelTypes); } // TODO(gavinp): Handle changes to rel types of existing prerenders. } else if (m_prerender) { m_prerender->cancel(); m_prerender.clear(); } return true; }
bool LinkLoader::loadLinkFromHeader(const String& headerValue, const KURL& baseURL, Document* document, const NetworkHintsInterface& networkHintsInterface, CanLoadResources canLoadResources) { if (!document) return false; LinkHeaderSet headerSet(headerValue); for (auto& header : headerSet) { if (!header.valid() || header.url().isEmpty() || header.rel().isEmpty()) return false; LinkRelAttribute relAttribute(header.rel()); KURL url(baseURL, header.url()); if (canLoadResources != OnlyLoadResources) { if (RuntimeEnabledFeatures::linkHeaderEnabled()) dnsPrefetchIfNeeded(relAttribute, url, *document, networkHintsInterface, LinkCalledFromHeader); if (RuntimeEnabledFeatures::linkPreconnectEnabled()) preconnectIfNeeded(relAttribute, url, *document, header.crossOrigin(), networkHintsInterface, LinkCalledFromHeader); } if (canLoadResources != DoNotLoadResources) { bool errorOccurred = false; if (RuntimeEnabledFeatures::linkPreloadEnabled()) preloadIfNeeded(relAttribute, url, *document, header.as(), header.mimeType(), header.crossOrigin(), LinkCalledFromHeader, errorOccurred); } // TODO(yoav): Add more supported headers as needed. } return true; }
void LinkLoader::loadLinksFromHeader(const String& headerValue, const KURL& baseURL, Document* document, const NetworkHintsInterface& networkHintsInterface, CanLoadResources canLoadResources, ViewportDescriptionWrapper* viewportDescriptionWrapper) { if (!document || headerValue.isEmpty()) return; LinkHeaderSet headerSet(headerValue); for (auto& header : headerSet) { if (!header.valid() || header.url().isEmpty() || header.rel().isEmpty()) continue; LinkRelAttribute relAttribute(header.rel()); KURL url(baseURL, header.url()); if (canLoadResources != OnlyLoadResources) { if (RuntimeEnabledFeatures::linkHeaderEnabled()) dnsPrefetchIfNeeded(relAttribute, url, *document, networkHintsInterface, LinkCalledFromHeader); if (RuntimeEnabledFeatures::linkPreconnectEnabled()) preconnectIfNeeded(relAttribute, url, *document, crossOriginAttributeValue(header.crossOrigin()), networkHintsInterface, LinkCalledFromHeader); } if (canLoadResources != DoNotLoadResources) { bool errorOccurred = false; if (RuntimeEnabledFeatures::linkPreloadEnabled()) { ViewportDescription* viewportDescription = (viewportDescriptionWrapper && viewportDescriptionWrapper->set) ? &(viewportDescriptionWrapper->description) : nullptr; preloadIfNeeded(relAttribute, url, *document, header.as(), header.mimeType(), header.media(), crossOriginAttributeValue(header.crossOrigin()), LinkCalledFromHeader, errorOccurred, viewportDescription); } } // TODO(yoav): Add more supported headers as needed. } }
void LinkLoader::loadLinksFromHeader( const String& headerValue, const KURL& baseURL, Document* document, const NetworkHintsInterface& networkHintsInterface, CanLoadResources canLoadResources, MediaPreloadPolicy mediaPolicy, ViewportDescriptionWrapper* viewportDescriptionWrapper) { if (!document || headerValue.isEmpty()) return; LinkHeaderSet headerSet(headerValue); for (auto& header : headerSet) { if (!header.valid() || header.url().isEmpty() || header.rel().isEmpty()) continue; if (mediaPolicy == OnlyLoadMedia && header.media().isEmpty()) continue; if (mediaPolicy == OnlyLoadNonMedia && !header.media().isEmpty()) continue; LinkRelAttribute relAttribute(header.rel()); KURL url(baseURL, header.url()); // Sanity check to avoid re-entrancy here. if (url == baseURL) continue; if (canLoadResources != OnlyLoadResources) { dnsPrefetchIfNeeded(relAttribute, url, *document, networkHintsInterface, LinkCalledFromHeader); preconnectIfNeeded(relAttribute, url, *document, crossOriginAttributeValue(header.crossOrigin()), networkHintsInterface, LinkCalledFromHeader); } if (canLoadResources != DoNotLoadResources) { bool errorOccurred = false; ViewportDescription* viewportDescription = (viewportDescriptionWrapper && viewportDescriptionWrapper->set) ? &(viewportDescriptionWrapper->description) : nullptr; preloadIfNeeded(relAttribute, url, *document, header.as(), header.mimeType(), header.media(), crossOriginAttributeValue(header.crossOrigin()), LinkCalledFromHeader, errorOccurred, viewportDescription, ReferrerPolicyDefault); } if (relAttribute.isServiceWorker()) { UseCounter::count(*document, UseCounter::LinkHeaderServiceWorker); } // TODO(yoav): Add more supported headers as needed. } }
bool LinkLoader::loadLink(const LinkRelAttribute& relAttribute, CrossOriginAttributeValue crossOrigin, const String& type, const String& as, const String& media, ReferrerPolicy referrerPolicy, const KURL& href, Document& document, const NetworkHintsInterface& networkHintsInterface) { if (!m_client->shouldLoadLink()) return false; dnsPrefetchIfNeeded(relAttribute, href, document, networkHintsInterface, LinkCalledFromMarkup); preconnectIfNeeded(relAttribute, href, document, crossOrigin, networkHintsInterface, LinkCalledFromMarkup); bool errorOccurred = false; createLinkPreloadResourceClient(preloadIfNeeded( relAttribute, href, document, as, type, media, crossOrigin, LinkCalledFromMarkup, errorOccurred, nullptr, referrerPolicy)); if (errorOccurred) m_linkLoadingErrorTimer.startOneShot(0, BLINK_FROM_HERE); if (href.isEmpty() || !href.isValid()) released(); prefetchIfNeeded(document, href, relAttribute, crossOrigin, referrerPolicy); if (const unsigned prerenderRelTypes = prerenderRelTypesFromRelAttribute(relAttribute, document)) { if (!m_prerender) { m_prerender = PrerenderHandle::create(document, this, href, prerenderRelTypes); } else if (m_prerender->url() != href) { m_prerender->cancel(); m_prerender = PrerenderHandle::create(document, this, href, prerenderRelTypes); } // TODO(gavinp): Handle changes to rel types of existing prerenders. } else if (m_prerender) { m_prerender->cancel(); m_prerender.clear(); } return true; }
bool LinkLoader::loadLink(const LinkRelAttribute& relAttribute, CrossOriginAttributeValue crossOrigin, const String& type, const String& as, const String& media, const KURL& href, Document& document, const NetworkHintsInterface& networkHintsInterface) { // TODO(yoav): Do all links need to load only after they're in document??? // TODO(yoav): Convert all uses of the CrossOriginAttribute to CrossOriginAttributeValue. crbug.com/486689 // FIXME(crbug.com/463266): We're ignoring type here, for everything but preload. Maybe we shouldn't. dnsPrefetchIfNeeded(relAttribute, href, document, networkHintsInterface, LinkCalledFromMarkup); preconnectIfNeeded(relAttribute, href, document, crossOrigin, networkHintsInterface, LinkCalledFromMarkup); bool errorOccurred = false; if (m_client->shouldLoadLink()) createLinkPreloadResourceClient(preloadIfNeeded(relAttribute, href, document, as, type, media, crossOrigin, LinkCalledFromMarkup, errorOccurred, nullptr)); if (errorOccurred) m_linkLoadingErrorTimer.startOneShot(0, BLINK_FROM_HERE); if (href.isEmpty() || !href.isValid()) released(); // FIXME(crbug.com/323096): Should take care of import. if (relAttribute.isLinkPrefetch() && href.isValid() && document.frame()) { if (!m_client->shouldLoadLink()) return false; UseCounter::count(document, UseCounter::LinkRelPrefetch); FetchRequest linkRequest(ResourceRequest(document.completeURL(href)), FetchInitiatorTypeNames::link); if (crossOrigin != CrossOriginAttributeNotSet) linkRequest.setCrossOriginAccessControl(document.getSecurityOrigin(), crossOrigin); setResource(LinkFetchResource::fetch(Resource::LinkPrefetch, linkRequest, document.fetcher())); } if (const unsigned prerenderRelTypes = prerenderRelTypesFromRelAttribute(relAttribute, document)) { if (!m_prerender) { m_prerender = PrerenderHandle::create(document, this, href, prerenderRelTypes); } else if (m_prerender->url() != href) { m_prerender->cancel(); m_prerender = PrerenderHandle::create(document, this, href, prerenderRelTypes); } // TODO(gavinp): Handle changes to rel types of existing prerenders. } else if (m_prerender) { m_prerender->cancel(); m_prerender.clear(); } return true; }
bool LinkLoader::loadLinkFromHeader(const String& headerValue, Document* document) { if (!document) return false; LinkHeaderSet headerSet(headerValue); for (auto& header : headerSet) { if (!header.valid() || header.url().isEmpty() || header.rel().isEmpty()) return false; LinkRelAttribute relAttribute(header.rel()); KURL url = document->completeURL(header.url()); if (RuntimeEnabledFeatures::linkHeaderEnabled()) dnsPrefetchIfNeeded(relAttribute, url, *document); if (RuntimeEnabledFeatures::linkPreconnectEnabled()) preconnectIfNeeded(relAttribute, url, *document, header.crossOrigin()); // FIXME: Add more supported headers as needed. } return true; }