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

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

Issue 2838933003: [not-for-commit] kitsune changes + pending kouhei changes (Closed)
Patch Set: Created 3 years, 7 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 // Copyright 2017 The Chromium Authors. All rights reserved.
2 * Copyright (C) 2010 Google, Inc. All Rights Reserved. 2 // Use of this source code is governed by a BSD-style license that can be
3 * 3 // found in the LICENSE file.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25 4
26 #include "core/dom/PendingScript.h" 5 #include "core/dom/ClassicPendingScript.h"
27 6
28 #include "bindings/core/v8/ScriptSourceCode.h" 7 #include "bindings/core/v8/ScriptSourceCode.h"
29 #include "bindings/core/v8/ScriptState.h" 8 #include "bindings/core/v8/ScriptState.h"
9 #include "bindings/core/v8/ScriptStreamer.h"
10 #include "bindings/core/v8/V8Binding.h"
30 #include "bindings/core/v8/V8BindingForCore.h" 11 #include "bindings/core/v8/V8BindingForCore.h"
31 #include "core/dom/ClassicScript.h"
32 #include "core/dom/Document.h" 12 #include "core/dom/Document.h"
33 #include "core/dom/ScriptElementBase.h"
34 #include "core/dom/TaskRunnerHelper.h" 13 #include "core/dom/TaskRunnerHelper.h"
35 #include "core/frame/LocalFrame.h" 14 #include "core/frame/LocalFrame.h"
36 #include "core/frame/SubresourceIntegrity.h" 15 #include "core/frame/SubresourceIntegrity.h"
37 #include "platform/SharedBuffer.h" 16 #include "platform/loader/fetch/MemoryCache.h"
38 #include "platform/wtf/CurrentTime.h"
39 17
40 namespace blink { 18 namespace blink {
41 19
42 PendingScript* PendingScript::Create(ScriptElementBase* element, 20 ClassicPendingScript* ClassicPendingScript::Create(ScriptElementBase* element,
43 ScriptResource* resource) { 21 ScriptResource* resource) {
44 return new PendingScript(element, resource, TextPosition()); 22 return new ClassicPendingScript(element, resource, TextPosition());
45 } 23 }
46 24
47 PendingScript* PendingScript::Create(ScriptElementBase* element, 25 ClassicPendingScript* ClassicPendingScript::Create(
48 const TextPosition& starting_position) { 26 ScriptElementBase* element,
49 return new PendingScript(element, nullptr, starting_position); 27 const TextPosition& starting_position) {
28 return new ClassicPendingScript(element, nullptr, starting_position);
50 } 29 }
51 30
52 PendingScript* PendingScript::CreateForTesting(ScriptResource* resource) { 31 ClassicPendingScript* ClassicPendingScript::CreateForTesting(
53 return new PendingScript(nullptr, resource, TextPosition(), true); 32 ScriptResource* resource) {
33 return new ClassicPendingScript(nullptr, resource, TextPosition(), true);
54 } 34 }
55 35
56 PendingScript::PendingScript(ScriptElementBase* element, 36 ClassicPendingScript::ClassicPendingScript(
57 ScriptResource* resource, 37 ScriptElementBase* element,
58 const TextPosition& starting_position, 38 ScriptResource* resource,
59 bool is_for_testing) 39 const TextPosition& starting_position,
60 : watching_for_load_(false), 40 bool is_for_testing)
61 element_(element), 41 : PendingScript(element, starting_position),
62 starting_position_(starting_position),
63 integrity_failure_(false), 42 integrity_failure_(false),
64 parser_blocking_load_start_time_(0),
65 client_(nullptr),
66 is_for_testing_(is_for_testing) { 43 is_for_testing_(is_for_testing) {
67 CheckState(); 44 CheckState();
68 SetResource(resource); 45 SetResource(resource);
69 MemoryCoordinator::Instance().RegisterClient(this); 46 MemoryCoordinator::Instance().RegisterClient(this);
70 } 47 }
71 48
72 PendingScript::~PendingScript() {} 49 ClassicPendingScript::~ClassicPendingScript() {}
73 50
74 NOINLINE void PendingScript::CheckState() const { 51 NOINLINE void ClassicPendingScript::CheckState() const {
75 // TODO(hiroshige): Turn these CHECK()s into DCHECK() before going to beta. 52 // TODO(hiroshige): Turn these CHECK()s into DCHECK() before going to beta.
76 CHECK(is_for_testing_ || element_); 53 CHECK(is_for_testing_ || GetElement());
77 CHECK(GetResource() || !streamer_); 54 CHECK(GetResource() || !streamer_);
78 CHECK(!streamer_ || streamer_->GetResource() == GetResource()); 55 CHECK(!streamer_ || streamer_->GetResource() == GetResource());
79 } 56 }
80 57
81 void PendingScript::Dispose() { 58 NOINLINE void ClassicPendingScript::Dispose() {
82 StopWatchingForLoad(); 59 PendingScript::Dispose();
83 DCHECK(!client_); 60 }
84 DCHECK(!watching_for_load_);
85 61
62 void ClassicPendingScript::DisposeInternal() {
86 MemoryCoordinator::Instance().UnregisterClient(this); 63 MemoryCoordinator::Instance().UnregisterClient(this);
87 SetResource(nullptr); 64 SetResource(nullptr);
88 starting_position_ = TextPosition::BelowRangePosition();
89 integrity_failure_ = false; 65 integrity_failure_ = false;
90 parser_blocking_load_start_time_ = 0;
91 if (streamer_) 66 if (streamer_)
92 streamer_->Cancel(); 67 streamer_->Cancel();
93 streamer_ = nullptr; 68 streamer_ = nullptr;
94 element_ = nullptr;
95 } 69 }
96 70
97 void PendingScript::WatchForLoad(PendingScriptClient* client) { 71 void ClassicPendingScript::StreamingFinished() {
98 CheckState();
99
100 DCHECK(!watching_for_load_);
101 // addClient() will call streamingFinished() if the load is complete. Callers
102 // who do not expect to be re-entered from this call should not call
103 // watchForLoad for a PendingScript which isReady. We also need to set
104 // m_watchingForLoad early, since addClient() can result in calling
105 // notifyFinished and further stopWatchingForLoad().
106 watching_for_load_ = true;
107 client_ = client;
108 if (IsReady())
109 client_->PendingScriptFinished(this);
110 }
111
112 void PendingScript::StopWatchingForLoad() {
113 if (!watching_for_load_)
114 return;
115 CheckState(); 72 CheckState();
116 DCHECK(GetResource()); 73 DCHECK(GetResource());
117 client_ = nullptr; 74 if (Client())
118 watching_for_load_ = false; 75 Client()->PendingScriptFinished(this);
119 }
120
121 ScriptElementBase* PendingScript::GetElement() const {
122 // As mentioned in the comment at |m_element| declaration,
123 // |m_element| must point to the corresponding ScriptLoader's
124 // client.
125 CHECK(element_);
126 return element_.Get();
127 }
128
129 void PendingScript::StreamingFinished() {
130 CheckState();
131 DCHECK(GetResource());
132 if (client_)
133 client_->PendingScriptFinished(this);
134 }
135
136 void PendingScript::MarkParserBlockingLoadStartTime() {
137 DCHECK_EQ(parser_blocking_load_start_time_, 0.0);
138 parser_blocking_load_start_time_ = MonotonicallyIncreasingTime();
139 } 76 }
140 77
141 // Returns true if SRI check passed. 78 // Returns true if SRI check passed.
142 static bool CheckScriptResourceIntegrity(Resource* resource, 79 static bool CheckScriptResourceIntegrity(Resource* resource,
143 ScriptElementBase* element) { 80 ScriptElementBase* element) {
144 DCHECK_EQ(resource->GetType(), Resource::kScript); 81 DCHECK_EQ(resource->GetType(), Resource::kScript);
145 ScriptResource* script_resource = ToScriptResource(resource); 82 ScriptResource* script_resource = ToScriptResource(resource);
146 String integrity_attr = element->IntegrityAttributeValue(); 83 String integrity_attr = element->IntegrityAttributeValue();
147 84
148 // It is possible to get back a script resource with integrity metadata 85 // It is possible to get back a script resource with integrity metadata
(...skipping 27 matching lines...) Expand all
176 passed ? ResourceIntegrityDisposition::kPassed 113 passed ? ResourceIntegrityDisposition::kPassed
177 : ResourceIntegrityDisposition::kFailed); 114 : ResourceIntegrityDisposition::kFailed);
178 return passed; 115 return passed;
179 } 116 }
180 } 117 }
181 118
182 NOTREACHED(); 119 NOTREACHED();
183 return true; 120 return true;
184 } 121 }
185 122
186 void PendingScript::NotifyFinished(Resource* resource) { 123 void ClassicPendingScript::NotifyFinished(Resource* resource) {
187 // The following SRI checks need to be here because, unfortunately, fetches 124 // The following SRI checks need to be here because, unfortunately, fetches
188 // are not done purely according to the Fetch spec. In particular, 125 // are not done purely according to the Fetch spec. In particular,
189 // different requests for the same resource do not have different 126 // different requests for the same resource do not have different
190 // responses; the memory cache can (and will) return the exact same 127 // responses; the memory cache can (and will) return the exact same
191 // Resource object. 128 // Resource object.
192 // 129 //
193 // For different requests, the same Resource object will be returned and 130 // For different requests, the same Resource object will be returned and
194 // will not be associated with the particular request. Therefore, when the 131 // will not be associated with the particular request. Therefore, when the
195 // body of the response comes in, there's no way to validate the integrity 132 // body of the response comes in, there's no way to validate the integrity
196 // of the Resource object against a particular request (since there may be 133 // of the Resource object against a particular request (since there may be
197 // several pending requests all tied to the identical object, and the 134 // several pending requests all tied to the identical object, and the
198 // actual requests are not stored). 135 // actual requests are not stored).
199 // 136 //
200 // In order to simulate the correct behavior, Blink explicitly does the SRI 137 // In order to simulate the correct behavior, Blink explicitly does the SRI
201 // checks here, when a PendingScript tied to a particular request is 138 // checks here, when a PendingScript tied to a particular request is
202 // finished (and in the case of a StyleSheet, at the point of execution), 139 // finished (and in the case of a StyleSheet, at the point of execution),
203 // while having proper Fetch checks in the fetch module for use in the 140 // while having proper Fetch checks in the fetch module for use in the
204 // fetch JavaScript API. In a future world where the ResourceFetcher uses 141 // fetch JavaScript API. In a future world where the ResourceFetcher uses
205 // the Fetch algorithm, this should be fixed by having separate Response 142 // the Fetch algorithm, this should be fixed by having separate Response
206 // objects (perhaps attached to identical Resource objects) per request. 143 // objects (perhaps attached to identical Resource objects) per request.
207 // 144 //
208 // See https://crbug.com/500701 for more information. 145 // See https://crbug.com/500701 for more information.
209 CheckState(); 146 CheckState();
210 if (element_) { 147 if (!is_for_testing_ && GetElement()) {
211 integrity_failure_ = !CheckScriptResourceIntegrity(resource, element_); 148 integrity_failure_ = !CheckScriptResourceIntegrity(resource, GetElement());
212 } 149 }
213 150
214 // If script streaming is in use, the client will be notified in 151 // If script streaming is in use, the client will be notified in
215 // streamingFinished. 152 // streamingFinished.
216 if (streamer_) 153 if (streamer_)
217 streamer_->NotifyFinished(resource); 154 streamer_->NotifyFinished(resource);
218 else if (client_) 155 else if (Client())
219 client_->PendingScriptFinished(this); 156 Client()->PendingScriptFinished(this);
220 } 157 }
221 158
222 void PendingScript::NotifyAppendData(ScriptResource* resource) { 159 void ClassicPendingScript::NotifyAppendData(ScriptResource* resource) {
223 if (streamer_) 160 if (streamer_)
224 streamer_->NotifyAppendData(resource); 161 streamer_->NotifyAppendData(resource);
225 } 162 }
226 163
227 DEFINE_TRACE(PendingScript) { 164 DEFINE_TRACE(ClassicPendingScript) {
228 visitor->Trace(element_);
229 visitor->Trace(streamer_); 165 visitor->Trace(streamer_);
230 visitor->Trace(client_);
231 ResourceOwner<ScriptResource>::Trace(visitor); 166 ResourceOwner<ScriptResource>::Trace(visitor);
232 MemoryCoordinatorClient::Trace(visitor); 167 MemoryCoordinatorClient::Trace(visitor);
168 PendingScript::Trace(visitor);
233 } 169 }
234 170
235 ClassicScript* PendingScript::GetSource(const KURL& document_url, 171 ClassicScript* ClassicPendingScript::GetSource(const KURL& document_url,
236 bool& error_occurred) const { 172 bool& error_occurred) const {
237 CheckState(); 173 CheckState();
238 174
239 error_occurred = this->ErrorOccurred(); 175 error_occurred = this->ErrorOccurred();
240 if (GetResource()) { 176 if (GetResource()) {
241 DCHECK(GetResource()->IsLoaded()); 177 DCHECK(GetResource()->IsLoaded());
242 if (streamer_ && !streamer_->StreamingSuppressed()) 178 if (streamer_ && !streamer_->StreamingSuppressed())
243 return ClassicScript::Create(ScriptSourceCode(streamer_, GetResource())); 179 return ClassicScript::Create(ScriptSourceCode(streamer_, GetResource()));
244 return ClassicScript::Create(ScriptSourceCode(GetResource())); 180 return ClassicScript::Create(ScriptSourceCode(GetResource()));
245 } 181 }
246 182
247 return ClassicScript::Create(ScriptSourceCode( 183 return ClassicScript::Create(ScriptSourceCode(
248 element_->TextContent(), document_url, StartingPosition())); 184 GetElement()->TextContent(), document_url, StartingPosition()));
249 } 185 }
250 186
251 void PendingScript::SetStreamer(ScriptStreamer* streamer) { 187 void ClassicPendingScript::SetStreamer(ScriptStreamer* streamer) {
252 DCHECK(!streamer_); 188 DCHECK(!streamer_);
253 DCHECK(!watching_for_load_); 189 DCHECK(!IsWatchingForLoad());
254 streamer_ = streamer; 190 streamer_ = streamer;
255 CheckState(); 191 CheckState();
256 } 192 }
257 193
258 bool PendingScript::IsReady() const { 194 bool ClassicPendingScript::IsReady() const {
259 CheckState(); 195 CheckState();
260 if (GetResource()) { 196 if (GetResource()) {
261 return GetResource()->IsLoaded() && (!streamer_ || streamer_->IsFinished()); 197 return GetResource()->IsLoaded() && (!streamer_ || streamer_->IsFinished());
262 } 198 }
263 199
264 return true; 200 return true;
265 } 201 }
266 202
267 bool PendingScript::ErrorOccurred() const { 203 bool ClassicPendingScript::ErrorOccurred() const {
268 CheckState(); 204 CheckState();
269 if (GetResource()) 205 if (GetResource())
270 return GetResource()->ErrorOccurred() || integrity_failure_; 206 return GetResource()->ErrorOccurred() || integrity_failure_;
271 207
272 return false; 208 return false;
273 } 209 }
274 210
275 void PendingScript::OnPurgeMemory() { 211 void ClassicPendingScript::OnPurgeMemory() {
276 CheckState(); 212 CheckState();
277 if (!streamer_) 213 if (!streamer_)
278 return; 214 return;
279 streamer_->Cancel(); 215 streamer_->Cancel();
280 streamer_ = nullptr; 216 streamer_ = nullptr;
281 } 217 }
282 218
283 void PendingScript::StartStreamingIfPossible( 219 void ClassicPendingScript::StartStreamingIfPossible(
284 Document* document, 220 Document* document,
285 ScriptStreamer::Type streamer_type) { 221 ScriptStreamer::Type streamer_type) {
286 if (!document->GetFrame()) 222 if (!document->GetFrame())
287 return; 223 return;
288 224
289 ScriptState* script_state = ToScriptStateForMainWorld(document->GetFrame()); 225 ScriptState* script_state = ToScriptStateForMainWorld(document->GetFrame());
290 if (!script_state) 226 if (!script_state)
291 return; 227 return;
292 228
293 ScriptStreamer::StartStreaming( 229 ScriptStreamer::StartStreaming(
294 this, streamer_type, document->GetFrame()->GetSettings(), script_state, 230 this, streamer_type, document->GetFrame()->GetSettings(), script_state,
295 TaskRunnerHelper::Get(TaskType::kNetworking, document)); 231 TaskRunnerHelper::Get(TaskType::kNetworking, document));
296 } 232 }
297 233
234 bool ClassicPendingScript::WasCanceled() const {
235 return GetResource()->WasCanceled();
236 }
237
238 KURL ClassicPendingScript::UrlForClassicScript() const {
239 return GetResource()->Url();
240 }
241
242 void ClassicPendingScript::RemoveFromMemoryCache() {
243 GetMemoryCache()->Remove(GetResource());
244 }
245
298 } // namespace blink 246 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698