| Index: third_party/WebKit/Source/core/loader/DocumentLoader.cpp
|
| diff --git a/third_party/WebKit/Source/core/loader/DocumentLoader.cpp b/third_party/WebKit/Source/core/loader/DocumentLoader.cpp
|
| index 9667482b09df3c102c0579b523acdff21b3fdb1a..2cd5e93762e8d441f37b8bb9d0067302a94e46d3 100644
|
| --- a/third_party/WebKit/Source/core/loader/DocumentLoader.cpp
|
| +++ b/third_party/WebKit/Source/core/loader/DocumentLoader.cpp
|
| @@ -41,9 +41,11 @@
|
| #include "core/frame/Settings.h"
|
| #include "core/frame/csp/ContentSecurityPolicy.h"
|
| #include "core/html/HTMLFrameOwnerElement.h"
|
| +#include "core/html/parser/HTMLParserIdioms.h"
|
| #include "core/html/parser/TextResourceDecoder.h"
|
| #include "core/inspector/ConsoleMessage.h"
|
| #include "core/inspector/InspectorInstrumentation.h"
|
| +#include "core/inspector/InspectorTraceEvents.h"
|
| #include "core/inspector/MainThreadDebugger.h"
|
| #include "core/loader/FrameFetchContext.h"
|
| #include "core/loader/FrameLoader.h"
|
| @@ -56,10 +58,12 @@
|
| #include "core/loader/resource/FontResource.h"
|
| #include "core/loader/resource/ImageResource.h"
|
| #include "core/loader/resource/ScriptResource.h"
|
| +#include "core/origin_trials/OriginTrialContext.h"
|
| #include "core/page/FrameTree.h"
|
| #include "core/page/Page.h"
|
| #include "platform/HTTPNames.h"
|
| #include "platform/UserGestureIndicator.h"
|
| +#include "platform/feature_policy/FeaturePolicy.h"
|
| #include "platform/loader/fetch/FetchInitiatorTypeNames.h"
|
| #include "platform/loader/fetch/FetchRequest.h"
|
| #include "platform/loader/fetch/FetchUtils.h"
|
| @@ -567,8 +571,9 @@ void DocumentLoader::ensureWriter(const AtomicString& mimeType,
|
| !Document::threadedParsingEnabledForTesting())
|
| parsingPolicy = ForceSynchronousParsing;
|
|
|
| - m_writer = createWriterFor(init, mimeType, encoding, false, parsingPolicy,
|
| - overridingURL);
|
| + installNewDocument(init, mimeType, encoding,
|
| + InstallNewDocumentReason::kNavigation, parsingPolicy,
|
| + overridingURL);
|
| m_writer->setDocumentWasLoadedAsPartOfNavigation();
|
| m_frame->document()->maybeHandleHttpRefresh(
|
| m_response.httpHeaderField(HTTPNames::Refresh),
|
| @@ -779,39 +784,149 @@ void DocumentLoader::endWriting() {
|
| m_writer.clear();
|
| }
|
|
|
| -DocumentWriter* DocumentLoader::createWriterFor(
|
| +void DocumentLoader::didInstallNewDocument(Document* document) {
|
| + document->setReadyState(Document::Loading);
|
| + document->initContentSecurityPolicy(m_contentSecurityPolicy.release());
|
| +
|
| + frameLoader().didInstallNewDocument();
|
| +
|
| + String suboriginHeader = m_response.httpHeaderField(HTTPNames::Suborigin);
|
| + if (!suboriginHeader.isNull()) {
|
| + Vector<String> messages;
|
| + Suborigin suborigin;
|
| + if (parseSuboriginHeader(suboriginHeader, &suborigin, messages))
|
| + document->enforceSuborigin(suborigin);
|
| +
|
| + for (auto& message : messages) {
|
| + document->addConsoleMessage(
|
| + ConsoleMessage::create(SecurityMessageSource, ErrorMessageLevel,
|
| + "Error with Suborigin header: " + message));
|
| + }
|
| + }
|
| +
|
| + document->clientHintsPreferences().updateFrom(m_clientHintsPreferences);
|
| +
|
| + // TODO(japhet): There's no reason to wait until commit to set these bits.
|
| + Settings* settings = document->settings();
|
| + m_fetcher->setImagesEnabled(settings->getImagesEnabled());
|
| + m_fetcher->setAutoLoadImages(settings->getLoadsImagesAutomatically());
|
| +
|
| + const AtomicString& dnsPrefetchControl =
|
| + m_response.httpHeaderField(HTTPNames::X_DNS_Prefetch_Control);
|
| + if (!dnsPrefetchControl.isEmpty())
|
| + document->parseDNSPrefetchControlHeader(dnsPrefetchControl);
|
| +
|
| + String headerContentLanguage =
|
| + m_response.httpHeaderField(HTTPNames::Content_Language);
|
| + if (!headerContentLanguage.isEmpty()) {
|
| + size_t commaIndex = headerContentLanguage.find(',');
|
| + // kNotFound == -1 == don't truncate
|
| + headerContentLanguage.truncate(commaIndex);
|
| + headerContentLanguage =
|
| + headerContentLanguage.stripWhiteSpace(isHTMLSpace<UChar>);
|
| + if (!headerContentLanguage.isEmpty())
|
| + document->setContentLanguage(AtomicString(headerContentLanguage));
|
| + }
|
| +
|
| + OriginTrialContext::addTokensFromHeader(
|
| + document, m_response.httpHeaderField(HTTPNames::Origin_Trial));
|
| + String referrerPolicyHeader =
|
| + m_response.httpHeaderField(HTTPNames::Referrer_Policy);
|
| + if (!referrerPolicyHeader.isNull()) {
|
| + UseCounter::count(*document, UseCounter::ReferrerPolicyHeader);
|
| + document->parseAndSetReferrerPolicy(referrerPolicyHeader);
|
| + }
|
| +
|
| + localFrameClient().didCreateNewDocument();
|
| +}
|
| +
|
| +void DocumentLoader::didCommitNavigation() {
|
| + if (frameLoader().stateMachine()->creatingInitialEmptyDocument())
|
| + return;
|
| + frameLoader().receivedFirstData();
|
| +
|
| + // didObserveLoadingBehavior() must be called after dispatchDidCommitLoad() is
|
| + // called for the metrics tracking logic to handle it properly.
|
| + if (m_serviceWorkerNetworkProvider &&
|
| + m_serviceWorkerNetworkProvider->isControlledByServiceWorker()) {
|
| + localFrameClient().didObserveLoadingBehavior(
|
| + WebLoadingBehaviorServiceWorkerControlled);
|
| + }
|
| +
|
| + // Links with media values need more information (like viewport information).
|
| + // This happens after the first chunk is parsed in HTMLDocumentParser.
|
| + dispatchLinkHeaderPreloads(nullptr, LinkLoader::OnlyLoadNonMedia);
|
| +
|
| + TRACE_EVENT1("devtools.timeline", "CommitLoad", "data",
|
| + InspectorCommitLoadEvent::data(m_frame));
|
| + probe::didCommitLoad(m_frame, this);
|
| + m_frame->page()->didCommitLoad(m_frame);
|
| +}
|
| +
|
| +void setFeaturePolicy(Document* document, const String& featurePolicyHeader) {
|
| + if (!RuntimeEnabledFeatures::featurePolicyEnabled())
|
| + return;
|
| + LocalFrame* frame = document->frame();
|
| + WebFeaturePolicy* parentFeaturePolicy =
|
| + frame->isMainFrame()
|
| + ? nullptr
|
| + : frame->tree().parent()->securityContext()->getFeaturePolicy();
|
| + Vector<String> messages;
|
| + const WebParsedFeaturePolicy& parsedHeader = parseFeaturePolicy(
|
| + featurePolicyHeader, frame->securityContext()->getSecurityOrigin(),
|
| + &messages);
|
| + WebParsedFeaturePolicy containerPolicy;
|
| + if (frame->owner()) {
|
| + containerPolicy = getContainerPolicyFromAllowedFeatures(
|
| + frame->owner()->allowedFeatures(),
|
| + frame->securityContext()->getSecurityOrigin());
|
| + }
|
| + frame->securityContext()->initializeFeaturePolicy(
|
| + parsedHeader, containerPolicy, parentFeaturePolicy);
|
| +
|
| + for (auto& message : messages) {
|
| + document->addConsoleMessage(
|
| + ConsoleMessage::create(OtherMessageSource, ErrorMessageLevel,
|
| + "Error with Feature-Policy header: " + message));
|
| + }
|
| + if (!parsedHeader.isEmpty())
|
| + frame->client()->didSetFeaturePolicyHeader(parsedHeader);
|
| +}
|
| +
|
| +void DocumentLoader::installNewDocument(
|
| const DocumentInit& init,
|
| const AtomicString& mimeType,
|
| const AtomicString& encoding,
|
| - bool dispatchWindowObjectAvailable,
|
| + InstallNewDocumentReason reason,
|
| ParserSynchronizationPolicy parsingPolicy,
|
| const KURL& overridingURL) {
|
| - LocalFrame* frame = init.frame();
|
| -
|
| - DCHECK(!frame->document() || !frame->document()->isActive());
|
| - DCHECK_EQ(frame->tree().childCount(), 0u);
|
| + DCHECK_EQ(init.frame(), m_frame);
|
| + DCHECK(!m_frame->document() || !m_frame->document()->isActive());
|
| + DCHECK_EQ(m_frame->tree().childCount(), 0u);
|
|
|
| if (!init.shouldReuseDefaultView())
|
| - frame->setDOMWindow(LocalDOMWindow::create(*frame));
|
| + m_frame->setDOMWindow(LocalDOMWindow::create(*m_frame));
|
|
|
| - Document* document = frame->domWindow()->installNewDocument(mimeType, init);
|
| -
|
| - frame->page()->chromeClient().installSupplements(*frame);
|
| -
|
| - // This should be set before receivedFirstData().
|
| + Document* document = m_frame->domWindow()->installNewDocument(mimeType, init);
|
| + m_frame->page()->chromeClient().installSupplements(*m_frame);
|
| if (!overridingURL.isEmpty())
|
| - frame->document()->setBaseURLOverride(overridingURL);
|
| -
|
| - frame->loader().didInstallNewDocument(dispatchWindowObjectAvailable);
|
| + document->setBaseURLOverride(overridingURL);
|
| + didInstallNewDocument(document);
|
|
|
| // This must be called before DocumentWriter is created, otherwise HTML parser
|
| // will use stale values from HTMLParserOption.
|
| - if (!dispatchWindowObjectAvailable)
|
| - frame->loader().receivedFirstData();
|
| + if (reason == InstallNewDocumentReason::kNavigation)
|
| + didCommitNavigation();
|
|
|
| - frame->loader().didBeginDocument();
|
| + m_writer =
|
| + DocumentWriter::create(document, parsingPolicy, mimeType, encoding);
|
|
|
| - return DocumentWriter::create(document, parsingPolicy, mimeType, encoding);
|
| + // FeaturePolicy is reset in the browser process on commit, so this needs to
|
| + // be initialized and replicated to the browser process after commit messages
|
| + // are sent in didCommitNavigation().
|
| + setFeaturePolicy(document,
|
| + m_response.httpHeaderField(HTTPNames::Feature_Policy));
|
| + frameLoader().dispatchDidClearDocumentOfWindowObject();
|
| }
|
|
|
| const AtomicString& DocumentLoader::mimeType() const {
|
| @@ -825,9 +940,10 @@ const AtomicString& DocumentLoader::mimeType() const {
|
| void DocumentLoader::replaceDocumentWhileExecutingJavaScriptURL(
|
| const DocumentInit& init,
|
| const String& source) {
|
| - m_writer = createWriterFor(init, mimeType(),
|
| - m_writer ? m_writer->encoding() : emptyAtom, true,
|
| - ForceSynchronousParsing);
|
| + installNewDocument(init, mimeType(),
|
| + m_writer ? m_writer->encoding() : emptyAtom,
|
| + InstallNewDocumentReason::kJavascriptURL,
|
| + ForceSynchronousParsing, KURL());
|
| if (!source.isNull())
|
| m_writer->appendReplacingData(source);
|
| endWriting();
|
|
|