Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(65)

Side by Side Diff: third_party/WebKit/Source/core/dom/ScriptLoader.cpp

Issue 2260303002: Sending an async GET request for doc.written blocked scripts. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Test added, failed bot tests fixed, converted to enum. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2001 Dirk Mueller (mueller@kde.org) 4 * (C) 2001 Dirk Mueller (mueller@kde.org)
5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserv ed. 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserv ed.
6 * Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org> 6 * Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org>
7 * 7 *
8 * This library is free software; you can redistribute it and/or 8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public 9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either 10 * License as published by the Free Software Foundation; either
(...skipping 18 matching lines...) Expand all
29 #include "core/SVGNames.h" 29 #include "core/SVGNames.h"
30 #include "core/dom/Document.h" 30 #include "core/dom/Document.h"
31 #include "core/dom/IgnoreDestructiveWriteCountIncrementer.h" 31 #include "core/dom/IgnoreDestructiveWriteCountIncrementer.h"
32 #include "core/dom/ScriptLoaderClient.h" 32 #include "core/dom/ScriptLoaderClient.h"
33 #include "core/dom/ScriptRunner.h" 33 #include "core/dom/ScriptRunner.h"
34 #include "core/dom/ScriptableDocumentParser.h" 34 #include "core/dom/ScriptableDocumentParser.h"
35 #include "core/dom/Text.h" 35 #include "core/dom/Text.h"
36 #include "core/events/Event.h" 36 #include "core/events/Event.h"
37 #include "core/fetch/AccessControlStatus.h" 37 #include "core/fetch/AccessControlStatus.h"
38 #include "core/fetch/FetchRequest.h" 38 #include "core/fetch/FetchRequest.h"
39 #include "core/fetch/MemoryCache.h"
39 #include "core/fetch/ResourceFetcher.h" 40 #include "core/fetch/ResourceFetcher.h"
40 #include "core/fetch/ScriptResource.h" 41 #include "core/fetch/ScriptResource.h"
41 #include "core/frame/LocalFrame.h" 42 #include "core/frame/LocalFrame.h"
42 #include "core/frame/SubresourceIntegrity.h" 43 #include "core/frame/SubresourceIntegrity.h"
43 #include "core/frame/UseCounter.h" 44 #include "core/frame/UseCounter.h"
44 #include "core/frame/csp/ContentSecurityPolicy.h" 45 #include "core/frame/csp/ContentSecurityPolicy.h"
45 #include "core/html/CrossOriginAttribute.h" 46 #include "core/html/CrossOriginAttribute.h"
46 #include "core/html/HTMLScriptElement.h" 47 #include "core/html/HTMLScriptElement.h"
47 #include "core/html/imports/HTMLImport.h" 48 #include "core/html/imports/HTMLImport.h"
48 #include "core/html/parser/HTMLParserIdioms.h" 49 #include "core/html/parser/HTMLParserIdioms.h"
49 #include "core/inspector/ConsoleMessage.h" 50 #include "core/inspector/ConsoleMessage.h"
50 #include "core/svg/SVGScriptElement.h" 51 #include "core/svg/SVGScriptElement.h"
51 #include "platform/MIMETypeRegistry.h" 52 #include "platform/MIMETypeRegistry.h"
52 #include "platform/weborigin/SecurityOrigin.h" 53 #include "platform/weborigin/SecurityOrigin.h"
54 #include "public/platform/WebCachePolicy.h"
53 #include "public/platform/WebFrameScheduler.h" 55 #include "public/platform/WebFrameScheduler.h"
54 #include "wtf/StdLibExtras.h" 56 #include "wtf/StdLibExtras.h"
55 #include "wtf/text/StringBuilder.h" 57 #include "wtf/text/StringBuilder.h"
56 #include "wtf/text/StringHash.h" 58 #include "wtf/text/StringHash.h"
57 59
58 namespace blink { 60 namespace blink {
59 61
60 ScriptLoader::ScriptLoader(Element* element, bool parserInserted, bool alreadySt arted, bool createdDuringDocumentWrite) 62 ScriptLoader::ScriptLoader(Element* element, bool parserInserted, bool alreadySt arted, bool createdDuringDocumentWrite, bool blockedDocWriteScriptAsyncFetch)
61 : m_element(element) 63 : m_element(element)
62 , m_startLineNumber(WTF::OrdinalNumber::beforeFirst()) 64 , m_startLineNumber(WTF::OrdinalNumber::beforeFirst())
63 , m_parserInserted(parserInserted) 65 , m_parserInserted(parserInserted)
64 , m_isExternalScript(false) 66 , m_isExternalScript(false)
65 , m_alreadyStarted(alreadyStarted) 67 , m_alreadyStarted(alreadyStarted)
66 , m_haveFiredLoad(false) 68 , m_haveFiredLoad(false)
67 , m_willBeParserExecuted(false) 69 , m_willBeParserExecuted(false)
68 , m_readyToBeParserExecuted(false) 70 , m_readyToBeParserExecuted(false)
69 , m_willExecuteInOrder(false) 71 , m_willExecuteInOrder(false)
70 , m_willExecuteWhenDocumentFinishedParsing(false) 72 , m_willExecuteWhenDocumentFinishedParsing(false)
71 , m_forceAsync(!parserInserted) 73 , m_forceAsync(!parserInserted)
72 , m_createdDuringDocumentWrite(createdDuringDocumentWrite) 74 , m_createdDuringDocumentWrite(createdDuringDocumentWrite)
75 , m_documentWriteIntervention(DocumentWriteIntervention::DocumentWriteInterv entionNone)
73 { 76 {
74 DCHECK(m_element); 77 DCHECK(m_element);
75 if (parserInserted && element->document().scriptableDocumentParser() && !ele ment->document().isInDocumentWrite()) 78 if (parserInserted && element->document().scriptableDocumentParser() && !ele ment->document().isInDocumentWrite())
76 m_startLineNumber = element->document().scriptableDocumentParser()->line Number(); 79 m_startLineNumber = element->document().scriptableDocumentParser()->line Number();
80 if (blockedDocWriteScriptAsyncFetch) {
81 DCHECK(!m_createdDuringDocumentWrite);
82 m_documentWriteIntervention = DocumentWriteIntervention::AsyncLowPriorit yFetchForBlockedScript;
83 }
77 } 84 }
78 85
79 ScriptLoader::~ScriptLoader() 86 ScriptLoader::~ScriptLoader()
80 { 87 {
81 } 88 }
82 89
83 DEFINE_TRACE(ScriptLoader) 90 DEFINE_TRACE(ScriptLoader)
84 { 91 {
85 visitor->trace(m_element); 92 visitor->trace(m_element);
86 visitor->trace(m_resource); 93 visitor->trace(m_resource);
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 if (!isScriptForEventSupported()) 238 if (!isScriptForEventSupported())
232 return false; 239 return false;
233 240
234 if (!client->charsetAttributeValue().isEmpty()) 241 if (!client->charsetAttributeValue().isEmpty())
235 m_characterEncoding = client->charsetAttributeValue(); 242 m_characterEncoding = client->charsetAttributeValue();
236 else 243 else
237 m_characterEncoding = elementDocument.characterSet(); 244 m_characterEncoding = elementDocument.characterSet();
238 245
239 if (client->hasSourceAttribute()) { 246 if (client->hasSourceAttribute()) {
240 FetchRequest::DeferOption defer = FetchRequest::NoDefer; 247 FetchRequest::DeferOption defer = FetchRequest::NoDefer;
241 if (!m_parserInserted || client->asyncAttributeValue() || client->deferA ttributeValue()) 248 if (!m_parserInserted || client->asyncAttributeValue() || client->deferA ttributeValue()
249 || m_documentWriteIntervention == DocumentWriteIntervention::AsyncLo wPriorityFetchForBlockedScript)
242 defer = FetchRequest::LazyLoad; 250 defer = FetchRequest::LazyLoad;
243 if (!fetchScript(client->sourceAttributeValue(), defer)) 251 if (!fetchScript(client->sourceAttributeValue(), defer))
244 return false; 252 return false;
245 } 253 }
246 254
255 // Since the asynchronous, low priority fetch for doc.written blocked
256 // script is not for execution, return early from here. Watch for its
257 // completion to be able to remove it from the memory cache.
258 if (m_documentWriteIntervention == DocumentWriteIntervention::AsyncLowPriori tyFetchForBlockedScript) {
259 m_pendingScript = PendingScript::create(m_element, m_resource.get());
260 m_pendingScript->watchForLoad(this);
261 return true;
262 }
263
247 if (client->hasSourceAttribute() && client->deferAttributeValue() && m_parse rInserted && !client->asyncAttributeValue()) { 264 if (client->hasSourceAttribute() && client->deferAttributeValue() && m_parse rInserted && !client->asyncAttributeValue()) {
248 m_willExecuteWhenDocumentFinishedParsing = true; 265 m_willExecuteWhenDocumentFinishedParsing = true;
249 m_willBeParserExecuted = true; 266 m_willBeParserExecuted = true;
250 } else if (client->hasSourceAttribute() && m_parserInserted && !client->asyn cAttributeValue()) { 267 } else if (client->hasSourceAttribute() && m_parserInserted && !client->asyn cAttributeValue()) {
251 m_willBeParserExecuted = true; 268 m_willBeParserExecuted = true;
252 } else if (!client->hasSourceAttribute() && m_parserInserted && !elementDocu ment.isScriptExecutionReady()) { 269 } else if (!client->hasSourceAttribute() && m_parserInserted && !elementDocu ment.isScriptExecutionReady()) {
253 m_willBeParserExecuted = true; 270 m_willBeParserExecuted = true;
254 m_readyToBeParserExecuted = true; 271 m_readyToBeParserExecuted = true;
255 } else if (client->hasSourceAttribute() && !client->asyncAttributeValue() && !m_forceAsync) { 272 } else if (client->hasSourceAttribute() && !client->asyncAttributeValue() && !m_forceAsync) {
256 m_pendingScript = PendingScript::create(m_element, m_resource.get()); 273 m_pendingScript = PendingScript::create(m_element, m_resource.get());
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 } 327 }
311 request.setDefer(defer); 328 request.setDefer(defer);
312 329
313 String integrityAttr = m_element->fastGetAttribute(HTMLNames::integrityA ttr); 330 String integrityAttr = m_element->fastGetAttribute(HTMLNames::integrityA ttr);
314 if (!integrityAttr.isEmpty()) { 331 if (!integrityAttr.isEmpty()) {
315 IntegrityMetadataSet metadataSet; 332 IntegrityMetadataSet metadataSet;
316 SubresourceIntegrity::parseIntegrityAttribute(integrityAttr, metadat aSet, elementDocument); 333 SubresourceIntegrity::parseIntegrityAttribute(integrityAttr, metadat aSet, elementDocument);
317 request.setIntegrityMetadata(metadataSet); 334 request.setIntegrityMetadata(metadataSet);
318 } 335 }
319 336
337 if (m_documentWriteIntervention == DocumentWriteIntervention::AsyncLowPr iorityFetchForBlockedScript) {
338 // Set interventions info in resourceRequest so that priority can
339 // be set accordingly.
340 request.mutableResourceRequest().setInterventionsInfo(InterventionsF lag::InterventionBlockedDocWriteScriptAsyncFetch);
341 request.mutableResourceRequest().setHTTPHeaderField("Intervention", "<https://www.chromestatus.com/feature/5718547946799104>");
342 }
343
320 m_resource = ScriptResource::fetch(request, elementDocument->fetcher()); 344 m_resource = ScriptResource::fetch(request, elementDocument->fetcher());
321 345
322 m_isExternalScript = true; 346 m_isExternalScript = true;
323 } 347 }
324 348
325 if (m_resource) 349 if (!m_resource) {
326 return true; 350 dispatchErrorEvent();
351 return false;
352 }
327 353
328 dispatchErrorEvent(); 354 if (m_createdDuringDocumentWrite && m_resource->resourceRequest().getCachePo licy() == WebCachePolicy::ReturnCacheDataDontLoad) {
329 return false; 355 m_documentWriteIntervention = DocumentWriteIntervention::DisallowedFetch ForDocWrittenScript;
356 }
357
358 return true;
330 } 359 }
331 360
332 bool isHTMLScriptLoader(Element* element) 361 bool isHTMLScriptLoader(Element* element)
333 { 362 {
334 DCHECK(element); 363 DCHECK(element);
335 return isHTMLScriptElement(*element); 364 return isHTMLScriptElement(*element);
336 } 365 }
337 366
338 bool isSVGScriptLoader(Element* element) 367 bool isSVGScriptLoader(Element* element)
339 { 368 {
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
452 else 481 else
453 dispatchErrorEvent(); 482 dispatchErrorEvent();
454 } 483 }
455 m_resource = nullptr; 484 m_resource = nullptr;
456 } 485 }
457 486
458 void ScriptLoader::notifyFinished(Resource* resource) 487 void ScriptLoader::notifyFinished(Resource* resource)
459 { 488 {
460 DCHECK(!m_willBeParserExecuted); 489 DCHECK(!m_willBeParserExecuted);
461 490
491 // We do not need this script in the memory cache. The primary goals of
492 // sending this fetch request are to let the third party server know
493 // about the document.write scripts intervention and populate the http
494 // cache for subsequent uses.
495 if (m_documentWriteIntervention == DocumentWriteIntervention::AsyncLowPriori tyFetchForBlockedScript) {
496 memoryCache()->remove(resource);
497 m_pendingScript->stopWatchingForLoad();
498 return;
499 }
500
462 Document* contextDocument = m_element->document().contextDocument(); 501 Document* contextDocument = m_element->document().contextDocument();
463 if (!contextDocument) { 502 if (!contextDocument) {
464 detach(); 503 detach();
465 return; 504 return;
466 } 505 }
467 506
468 ASSERT_UNUSED(resource, resource == m_resource); 507 ASSERT_UNUSED(resource, resource == m_resource);
469 508
470 ScriptRunner::ExecutionType runOrder = m_willExecuteInOrder ? ScriptRunner:: IN_ORDER_EXECUTION : ScriptRunner::ASYNC_EXECUTION; 509 ScriptRunner::ExecutionType runOrder = m_willExecuteInOrder ? ScriptRunner:: IN_ORDER_EXECUTION : ScriptRunner::ASYNC_EXECUTION;
471 if (m_resource->errorOccurred()) { 510 if (m_resource->errorOccurred()) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
519 if (isHTMLScriptLoader(element)) 558 if (isHTMLScriptLoader(element))
520 return toHTMLScriptElement(element)->loader(); 559 return toHTMLScriptElement(element)->loader();
521 560
522 if (isSVGScriptLoader(element)) 561 if (isSVGScriptLoader(element))
523 return toSVGScriptElement(element)->loader(); 562 return toSVGScriptElement(element)->loader();
524 563
525 return 0; 564 return 0;
526 } 565 }
527 566
528 } // namespace blink 567 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698