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, 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; }
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 HTMLTrackElement::loadTimerFired(TimerBase*) { DVLOG(TRACK_LOG_LEVEL) << "loadTimerFired"; // 6. [X] Set the text track readiness state to loading. setReadyState(kLoading); // 7. [X] Let URL be the track URL of the track element. KURL url = getNonEmptyURLAttribute(srcAttr); // 8. [X] If the track element's parent is a media element then let CORS mode // be the state of the parent media element's crossorigin content attribute. // Otherwise, let CORS mode be No CORS. const AtomicString& corsMode = mediaElementCrossOriginAttribute(); // 9. End the synchronous section, continuing the remaining steps in parallel. // 10. If URL is not the empty string, perform a potentially CORS-enabled // fetch of URL, with the mode being CORS mode, the origin being the origin of // the track element's node document, and the default origin behaviour set to // fail. if (!canLoadUrl(url)) { didCompleteLoad(Failure); return; } if (url == m_url) { DCHECK(m_loader); switch (m_loader->loadState()) { case TextTrackLoader::Idle: case TextTrackLoader::Loading: // If loading of the resource from this URL is in progress, return // early. break; case TextTrackLoader::Finished: didCompleteLoad(Success); break; case TextTrackLoader::Failed: didCompleteLoad(Failure); break; default: NOTREACHED(); } return; } m_url = url; if (m_loader) m_loader->cancelLoad(); m_loader = TextTrackLoader::create(*this, document()); if (!m_loader->load(m_url, crossOriginAttributeValue(corsMode))) didCompleteLoad(Failure); }
void LinkHeader::setValue(LinkParameterName name, String value) { // FIXME: Add support for more header parameters as neccessary. if (name == LinkParameterRel && !m_rel) m_rel = value.lower(); else if (name == LinkParameterAnchor) m_isValid = false; else if (name == LinkParameterCrossOrigin) m_crossOrigin = crossOriginAttributeValue(value); else if (name == LinkParameterAs) m_as = value.lower(); else if (name == LinkParameterType) m_mimeType = value.lower(); else if (name == LinkParameterMedia) m_media = value.lower(); }
bool ScriptLoader::fetchScript(const String& sourceUrl, FetchRequest::DeferOption defer) { DCHECK(m_element); Document* elementDocument = &(m_element->document()); if (!m_element->inShadowIncludingDocument() || m_element->document() != elementDocument) return false; DCHECK(!m_resource); if (!stripLeadingAndTrailingHTMLSpaces(sourceUrl).isEmpty()) { FetchRequest request(ResourceRequest(elementDocument->completeURL(sourceUrl)), m_element->localName()); CrossOriginAttributeValue crossOrigin = crossOriginAttributeValue(m_element->fastGetAttribute(HTMLNames::crossoriginAttr)); if (crossOrigin != CrossOriginAttributeNotSet) request.setCrossOriginAccessControl(elementDocument->getSecurityOrigin(), crossOrigin); request.setCharset(scriptCharset()); // Skip fetch-related CSP checks if dynamically injected script is whitelisted and this script is not parser-inserted. bool scriptPassesCSPDynamic = (!isParserInserted() && elementDocument->contentSecurityPolicy()->allowDynamic()); request.setContentSecurityPolicyNonce(m_element->fastGetAttribute(HTMLNames::nonceAttr)); if (scriptPassesCSPDynamic) { UseCounter::count(elementDocument->frame(), UseCounter::ScriptPassesCSPDynamic); request.setContentSecurityCheck(DoNotCheckContentSecurityPolicy); } request.setDefer(defer); String integrityAttr = m_element->fastGetAttribute(HTMLNames::integrityAttr); if (!integrityAttr.isEmpty()) { IntegrityMetadataSet metadataSet; SubresourceIntegrity::parseIntegrityAttribute(integrityAttr, metadataSet, elementDocument); request.setIntegrityMetadata(metadataSet); } m_resource = ScriptResource::fetch(request, elementDocument->fetcher()); m_isExternalScript = true; } if (m_resource) return true; dispatchErrorEvent(); return false; }
static void configureRequest( FetchRequest& request, ImageLoader::BypassMainWorldBehavior bypassBehavior, Element& element, const ClientHintsPreferences& clientHintsPreferences) { if (bypassBehavior == ImageLoader::BypassMainWorldCSP) request.setContentSecurityCheck(DoNotCheckContentSecurityPolicy); CrossOriginAttributeValue crossOrigin = crossOriginAttributeValue( element.fastGetAttribute(HTMLNames::crossoriginAttr)); if (crossOrigin != CrossOriginAttributeNotSet) { request.setCrossOriginAccessControl(element.document().getSecurityOrigin(), crossOrigin); } if (clientHintsPreferences.shouldSendResourceWidth() && isHTMLImageElement(element)) request.setResourceWidth(toHTMLImageElement(element).getResourceWidth()); }
bool ScriptLoader::fetchScript(const String& sourceUrl, FetchRequest::DeferOption defer) { ASSERT(m_element); RefPtrWillBeRawPtr<Document> elementDocument(m_element->document()); if (!m_element->inDocument() || m_element->document() != elementDocument) return false; ASSERT(!m_resource); if (!stripLeadingAndTrailingHTMLSpaces(sourceUrl).isEmpty()) { FetchRequest request(ResourceRequest(elementDocument->completeURL(sourceUrl)), m_element->localName()); CrossOriginAttributeValue crossOrigin = crossOriginAttributeValue(m_element->fastGetAttribute(HTMLNames::crossoriginAttr)); if (crossOrigin != CrossOriginAttributeNotSet) request.setCrossOriginAccessControl(elementDocument->securityOrigin(), crossOrigin); request.setCharset(scriptCharset()); bool scriptPassesCSP = elementDocument->contentSecurityPolicy()->allowScriptWithNonce(m_element->fastGetAttribute(HTMLNames::nonceAttr)); if (scriptPassesCSP) request.setContentSecurityCheck(DoNotCheckContentSecurityPolicy); request.setDefer(defer); String integrityAttr = m_element->fastGetAttribute(HTMLNames::integrityAttr); IntegrityMetadataSet metadataSet; if (!integrityAttr.isEmpty()) { SubresourceIntegrity::parseIntegrityAttribute(integrityAttr, metadataSet, elementDocument.get()); request.setIntegrityMetadata(metadataSet); } m_resource = ScriptResource::fetch(request, elementDocument->fetcher()); if (m_resource && !integrityAttr.isEmpty()) m_resource->setIntegrityMetadata(metadataSet); m_isExternalScript = true; } if (m_resource) return true; dispatchErrorEvent(); return false; }
bool ScriptLoader::fetchScript(const String& sourceUrl, FetchRequest::DeferOption defer) { DCHECK(m_element); Document* elementDocument = &(m_element->document()); if (!m_element->isConnected() || m_element->document() != elementDocument) return false; DCHECK(!m_resource); if (!stripLeadingAndTrailingHTMLSpaces(sourceUrl).isEmpty()) { FetchRequest request( ResourceRequest(elementDocument->completeURL(sourceUrl)), m_element->localName()); CrossOriginAttributeValue crossOrigin = crossOriginAttributeValue( m_element->fastGetAttribute(HTMLNames::crossoriginAttr)); if (crossOrigin != CrossOriginAttributeNotSet) request.setCrossOriginAccessControl(elementDocument->getSecurityOrigin(), crossOrigin); request.setCharset(scriptCharset()); if (ContentSecurityPolicy::isNonceableElement(m_element.get())) { request.setContentSecurityPolicyNonce( m_element->fastGetAttribute(HTMLNames::nonceAttr)); } request.setParserDisposition(isParserInserted() ? ParserInserted : NotParserInserted); request.setDefer(defer); String integrityAttr = m_element->fastGetAttribute(HTMLNames::integrityAttr); if (!integrityAttr.isEmpty()) { IntegrityMetadataSet metadataSet; SubresourceIntegrity::parseIntegrityAttribute(integrityAttr, metadataSet, elementDocument); request.setIntegrityMetadata(metadataSet); } if (m_documentWriteIntervention == DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle) { request.mutableResourceRequest().setHTTPHeaderField( "Intervention", "<https://www.chromestatus.com/feature/5718547946799104>"); } m_resource = ScriptResource::fetch(request, elementDocument->fetcher()); m_isExternalScript = true; } if (!m_resource) { dispatchErrorEvent(); return false; } if (m_createdDuringDocumentWrite && m_resource->resourceRequest().getCachePolicy() == WebCachePolicy::ReturnCacheDataDontLoad) { m_documentWriteIntervention = DocumentWriteIntervention::DoNotFetchDocWrittenScript; } return true; }