Ejemplo n.º 1
0
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.
  }
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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.
    }
}
Ejemplo n.º 4
0
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();
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
0
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());
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 9
0
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;
}