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

Side by Side Diff: third_party/WebKit/Source/core/loader/modulescript/ModuleScriptLoader.cpp

Issue 2939773005: [POC] Implement "module responses map" concept (Closed)
Patch Set: rebase Created 3 years, 5 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 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/loader/modulescript/ModuleScriptLoader.h" 5 #include "core/loader/modulescript/ModuleScriptLoader.h"
6 6
7 #include "core/dom/ExecutionContext.h" 7 #include "core/dom/ExecutionContext.h"
8 #include "core/dom/Modulator.h" 8 #include "core/dom/Modulator.h"
9 #include "core/dom/ModuleScript.h" 9 #include "core/dom/ModuleScript.h"
10 #include "core/inspector/ConsoleMessage.h" 10 #include "core/inspector/ConsoleMessage.h"
11 #include "core/loader/modulescript/ModuleScriptLoaderClient.h" 11 #include "core/loader/modulescript/ModuleScriptLoaderClient.h"
12 #include "core/loader/modulescript/ModuleScriptLoaderRegistry.h" 12 #include "core/loader/modulescript/ModuleScriptLoaderRegistry.h"
13 #include "platform/loader/fetch/FetchUtils.h" 13 #include "core/loader/modulescript/WorkletModuleScriptFetcher.h"
14 #include "platform/loader/fetch/ResourceFetcher.h" 14 #include "core/workers/MainThreadWorkletGlobalScope.h"
15 #include "platform/loader/fetch/Resource.h"
15 #include "platform/loader/fetch/ResourceLoaderOptions.h" 16 #include "platform/loader/fetch/ResourceLoaderOptions.h"
16 #include "platform/loader/fetch/ResourceLoadingLog.h" 17 #include "platform/loader/fetch/ResourceLoadingLog.h"
17 #include "platform/network/mime/MIMETypeRegistry.h"
18 #include "platform/weborigin/SecurityPolicy.h" 18 #include "platform/weborigin/SecurityPolicy.h"
19 #include "platform/wtf/text/AtomicString.h" 19 #include "platform/wtf/text/AtomicString.h"
20 20
21 namespace blink { 21 namespace blink {
22 22
23 ModuleScriptLoader::ModuleScriptLoader(Modulator* modulator, 23 ModuleScriptLoader::ModuleScriptLoader(Modulator* modulator,
24 ModuleScriptLoaderRegistry* registry, 24 ModuleScriptLoaderRegistry* registry,
25 ModuleScriptLoaderClient* client) 25 ModuleScriptLoaderClient* client)
26 : modulator_(modulator), registry_(registry), client_(client) { 26 : modulator_(modulator), registry_(registry), client_(client) {
27 DCHECK(modulator); 27 DCHECK(modulator);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 #if DCHECK_IS_ON() 62 #if DCHECK_IS_ON()
63 RESOURCE_LOADING_DVLOG(1) 63 RESOURCE_LOADING_DVLOG(1)
64 << "ModuleLoader[" << url_.GetString() << "]::advanceState(" 64 << "ModuleLoader[" << url_.GetString() << "]::advanceState("
65 << StateToString(state_) << " -> " << StateToString(new_state) << ")"; 65 << StateToString(state_) << " -> " << StateToString(new_state) << ")";
66 #endif 66 #endif
67 state_ = new_state; 67 state_ = new_state;
68 68
69 if (state_ == State::kFinished) { 69 if (state_ == State::kFinished) {
70 registry_->ReleaseFinishedLoader(this); 70 registry_->ReleaseFinishedLoader(this);
71 client_->NotifyNewSingleModuleFinished(module_script_); 71 client_->NotifyNewSingleModuleFinished(module_script_);
72 SetResource(nullptr);
73 } 72 }
74 } 73 }
75 74
76 void ModuleScriptLoader::Fetch(const ModuleScriptFetchRequest& module_request, 75 void ModuleScriptLoader::Fetch(const ModuleScriptFetchRequest& module_request,
77 ResourceFetcher* fetcher, 76 ResourceFetcher* fetcher,
78 ModuleGraphLevel level) { 77 ModuleGraphLevel level) {
79 // https://html.spec.whatwg.org/#fetch-a-single-module-script 78 // https://html.spec.whatwg.org/#fetch-a-single-module-script
80 79
81 // Step 4. Set moduleMap[url] to "fetching". 80 // Step 4. Set moduleMap[url] to "fetching".
82 AdvanceState(State::kFetching); 81 AdvanceState(State::kFetching);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 module_request.CredentialsMode()); 126 module_request.CredentialsMode());
128 127
129 // Module scripts are always async. 128 // Module scripts are always async.
130 fetch_params.SetDefer(FetchParameters::kLazyLoad); 129 fetch_params.SetDefer(FetchParameters::kLazyLoad);
131 130
132 // Use UTF-8, according to Step 8: 131 // Use UTF-8, according to Step 8:
133 // "Let source text be the result of UTF-8 decoding response's body." 132 // "Let source text be the result of UTF-8 decoding response's body."
134 fetch_params.SetDecoderOptions( 133 fetch_params.SetDecoderOptions(
135 TextResourceDecoderOptions::CreateAlwaysUseUTF8ForText()); 134 TextResourceDecoderOptions::CreateAlwaysUseUTF8ForText());
136 135
136 nonce_ = module_request.Nonce();
137 parser_state_ = module_request.ParserState();
138
137 // Step 6. If the caller specified custom steps to perform the fetch, 139 // Step 6. If the caller specified custom steps to perform the fetch,
138 // perform them on request, setting the is top-level flag if the top-level 140 // perform them on request, setting the is top-level flag if the top-level
139 // module fetch flag is set. Return from this algorithm, and when the custom 141 // module fetch flag is set. Return from this algorithm, and when the custom
140 // perform the fetch steps complete with response response, run the remaining 142 // perform the fetch steps complete with response response, run the remaining
141 // steps. 143 // steps.
142 // Otherwise, fetch request. Return from this algorithm, and run the remaining 144 // Otherwise, fetch request. Return from this algorithm, and run the remaining
143 // steps as part of the fetch's process response for the response response. 145 // steps as part of the fetch's process response for the response response.
144 // TODO(ServiceWorker team): Perform the "custom steps" for module usage 146 ExecutionContext* execution_context =
145 // inside service worker. 147 ExecutionContext::From(modulator_->GetScriptState());
146 nonce_ = module_request.Nonce(); 148 if (execution_context->IsMainThreadWorkletGlobalScope()) {
147 parser_state_ = module_request.ParserState(); 149 MainThreadWorkletGlobalScope* global_scope =
148 150 ToMainThreadWorkletGlobalScope(execution_context);
149 ScriptResource* resource = ScriptResource::Fetch(fetch_params, fetcher); 151 module_fetcher_ = new WorkletModuleScriptFetcher(
150 if (state_ == State::kFinished) { 152 fetch_params, fetcher, modulator_,
151 // ScriptResource::fetch() has succeeded synchronously, 153 global_scope->GetModuleResponsesMapProxy());
152 // ::notifyFinished() already took care of the |resource|. 154 } else {
153 return; 155 module_fetcher_ =
156 new ModuleScriptFetcher(fetch_params, fetcher, modulator_);
154 } 157 }
155 158 module_fetcher_->Fetch(this);
156 if (!resource) {
157 // ScriptResource::fetch() has failed synchronously.
158 AdvanceState(State::kFinished);
159 return;
160 }
161
162 // ScriptResource::fetch() is processed asynchronously.
163 SetResource(resource);
164 } 159 }
165 160
166 namespace { 161 void ModuleScriptLoader::NotifyFetchFinished(
167 162 WTF::Optional<ModuleScriptCreationParams> params) {
168 bool WasModuleLoadSuccessful(Resource* resource,
169 ConsoleMessage** error_message = nullptr) {
170 // Implements conditions in Step 7 of
171 // https://html.spec.whatwg.org/#fetch-a-single-module-script
172
173 // - response's type is "error"
174 if (resource->ErrorOccurred()) {
175 return false;
176 }
177
178 const auto& response = resource->GetResponse();
179 // - response's status is not an ok status
180 if (response.IsHTTP() && !FetchUtils::IsOkStatus(response.HttpStatusCode())) {
181 return false;
182 }
183
184 // The result of extracting a MIME type from response's header list
185 // (ignoring parameters) is not a JavaScript MIME type
186 // Note: For historical reasons, fetching a classic script does not include
187 // MIME type checking. In contrast, module scripts will fail to load if they
188 // are not of a correct MIME type.
189 // We use ResourceResponse::httpContentType() instead of mimeType(), as
190 // mimeType() may be rewritten by mime sniffer.
191 if (!MIMETypeRegistry::IsSupportedJavaScriptMIMEType(
192 response.HttpContentType())) {
193 if (error_message) {
194 String message =
195 "Failed to load module script: The server responded with a "
196 "non-JavaScript MIME type of \"" +
197 response.HttpContentType() +
198 "\". Strict MIME type checking is enforced for module scripts per "
199 "HTML spec.";
200 *error_message = ConsoleMessage::CreateForRequest(
201 kJSMessageSource, kErrorMessageLevel, message,
202 response.Url().GetString(), resource->Identifier());
203 }
204 return false;
205 }
206
207 return true;
208 }
209
210 } // namespace
211
212 // ScriptResourceClient callback handler
213 void ModuleScriptLoader::NotifyFinished(Resource*) {
214 // Note: "conditions" referred in Step 7 is implemented in 163 // Note: "conditions" referred in Step 7 is implemented in
215 // wasModuleLoadSuccessful(). 164 // wasModuleLoadSuccessful().
216 // Step 7. If any of the following conditions are met, set moduleMap[url] to 165 // Step 7. If any of the following conditions are met, set moduleMap[url] to
217 // null, asynchronously complete this algorithm with null, and abort these 166 // null, asynchronously complete this algorithm with null, and abort these
218 // steps. 167 // steps.
219 ConsoleMessage* error_message = nullptr; 168 if (!params.has_value()) {
220 if (!WasModuleLoadSuccessful(GetResource(), &error_message)) {
221 if (error_message) {
222 ExecutionContext::From(modulator_->GetScriptState())
223 ->AddConsoleMessage(error_message);
224 }
225
226 AdvanceState(State::kFinished); 169 AdvanceState(State::kFinished);
227 return; 170 return;
228 } 171 }
229 172
230 // Step 8. Let source text be the result of UTF-8 decoding response's body. 173 // Step 8. Let source text be the result of UTF-8 decoding response's body.
231 String source_text = GetResource()->SourceText();
232
233 AccessControlStatus access_control_status =
234 GetResource()->CalculateAccessControlStatus();
235
236 // Step 9. Let module script be the result of creating a module script given 174 // Step 9. Let module script be the result of creating a module script given
237 // source text, module map settings object, response's url, cryptographic 175 // source text, module map settings object, response's url, cryptographic
238 // nonce, parser state, and credentials mode. 176 // nonce, parser state, and credentials mode.
239 module_script_ = ModuleScript::Create( 177 module_script_ = ModuleScript::Create(
240 source_text, modulator_, GetResource()->GetResponse().Url(), nonce_, 178 params->GetSourceText(), modulator_, params->GetResponseUrl(), nonce_,
241 parser_state_, 179 parser_state_, params->GetFetchCredentialsMode(),
242 GetResource()->GetResourceRequest().GetFetchCredentialsMode(), 180 params->GetAccessControlStatus());
243 access_control_status);
244 181
245 AdvanceState(State::kFinished); 182 AdvanceState(State::kFinished);
246 } 183 }
247 184
248 DEFINE_TRACE(ModuleScriptLoader) { 185 DEFINE_TRACE(ModuleScriptLoader) {
249 visitor->Trace(modulator_); 186 visitor->Trace(modulator_);
250 visitor->Trace(module_script_); 187 visitor->Trace(module_script_);
251 visitor->Trace(registry_); 188 visitor->Trace(registry_);
252 visitor->Trace(client_); 189 visitor->Trace(client_);
253 ResourceOwner<ScriptResource>::Trace(visitor); 190 visitor->Trace(module_fetcher_);
254 } 191 }
255 192
256 } // namespace blink 193 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698