Index: third_party/WebKit/Source/core/loader/modulescript/ModuleScriptFetcher.cpp |
diff --git a/third_party/WebKit/Source/core/loader/modulescript/ModuleScriptFetcher.cpp b/third_party/WebKit/Source/core/loader/modulescript/ModuleScriptFetcher.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..98dd7f5d39b084009037fdbc7ac6777d84d845f7 |
--- /dev/null |
+++ b/third_party/WebKit/Source/core/loader/modulescript/ModuleScriptFetcher.cpp |
@@ -0,0 +1,122 @@ |
+// Copyright 2017 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "core/loader/modulescript/ModuleScriptFetcher.h" |
+ |
+#include "core/dom/ExecutionContext.h" |
+#include "core/inspector/ConsoleMessage.h" |
+#include "core/loader/modulescript/ModuleScriptLoader.h" |
+#include "platform/loader/fetch/FetchUtils.h" |
+#include "platform/network/mime/MIMETypeRegistry.h" |
+ |
+namespace blink { |
+ |
+namespace { |
+ |
+bool WasModuleLoadSuccessful(Resource* resource, |
+ ConsoleMessage** error_message) { |
+ // Implements conditions in Step 7 of |
+ // https://html.spec.whatwg.org/#fetch-a-single-module-script |
+ |
+ // - response's type is "error" |
+ if (!resource || resource->ErrorOccurred()) { |
+ return false; |
+ } |
+ |
+ const auto& response = resource->GetResponse(); |
+ // - response's status is not an ok status |
+ if (response.IsHTTP() && !FetchUtils::IsOkStatus(response.HttpStatusCode())) { |
+ return false; |
+ } |
+ |
+ // The result of extracting a MIME type from response's header list |
+ // (ignoring parameters) is not a JavaScript MIME type |
+ // Note: For historical reasons, fetching a classic script does not include |
+ // MIME type checking. In contrast, module scripts will fail to load if they |
+ // are not of a correct MIME type. |
+ // We use ResourceResponse::httpContentType() instead of mimeType(), as |
+ // mimeType() may be rewritten by mime sniffer. |
+ if (!MIMETypeRegistry::IsSupportedJavaScriptMIMEType( |
+ response.HttpContentType())) { |
+ if (error_message) { |
+ String message = |
+ "Failed to load module script: The server responded with a " |
+ "non-JavaScript MIME type of \"" + |
+ response.HttpContentType() + |
+ "\". Strict MIME type checking is enforced for module scripts per " |
+ "HTML spec."; |
+ *error_message = ConsoleMessage::CreateForRequest( |
+ kJSMessageSource, kErrorMessageLevel, message, |
+ response.Url().GetString(), resource->Identifier()); |
+ } |
+ return false; |
+ } |
+ |
+ return true; |
+} |
+ |
+} // namespace |
+ |
+ModuleScriptFetcher::ModuleScriptFetcher(FetchParameters fetch_params, |
+ ResourceFetcher* fetcher, |
+ Modulator* modulator) |
+ : fetch_params_(fetch_params), fetcher_(fetcher), modulator_(modulator) {} |
+ |
+void ModuleScriptFetcher::Fetch(ModuleScriptLoader* loader) { |
+ loader_ = loader; |
+ FetchInternal(); |
+} |
+ |
+void ModuleScriptFetcher::NotifyFinished(Resource* resource) { |
+ ClearResource(); |
+ |
+ ScriptResource* script_resource = ToScriptResource(resource); |
+ ConsoleMessage* error_message = nullptr; |
+ if (!WasModuleLoadSuccessful(script_resource, &error_message)) { |
+ if (error_message) { |
+ ExecutionContext::From(modulator_->GetScriptState()) |
+ ->AddConsoleMessage(error_message); |
+ } |
+ Finalize(WTF::nullopt); |
+ return; |
+ } |
+ |
+ ModuleScriptCreationParams params( |
+ script_resource->GetResponse().Url(), script_resource->SourceText(), |
+ script_resource->GetResourceRequest().GetFetchCredentialsMode(), |
+ script_resource->CalculateAccessControlStatus()); |
+ Finalize(params); |
+} |
+ |
+void ModuleScriptFetcher::FetchInternal() { |
+ ScriptResource* resource = ScriptResource::Fetch(fetch_params_, fetcher_); |
+ if (was_fetched_) { |
+ // ScriptResource::fetch() has succeeded synchronously, |
+ // ::notifyFinished() already took care of the |resource|. |
+ return; |
+ } |
+ if (!resource) { |
+ // ScriptResource::fetch() has failed synchronously. |
+ NotifyFinished(nullptr); |
+ return; |
+ } |
+ |
+ // ScriptResource::fetch() is processed asynchronously. |
+ SetResource(resource); |
+} |
+ |
+void ModuleScriptFetcher::Finalize( |
+ WTF::Optional<ModuleScriptCreationParams> params) { |
+ was_fetched_ = true; |
+ loader_->NotifyFetchFinished(params); |
+} |
+ |
+DEFINE_TRACE(ModuleScriptFetcher) { |
+ visitor->Trace(fetcher_); |
+ visitor->Trace(modulator_); |
+ visitor->Trace(loader_); |
+ ResourceOwner<ScriptResource>::Trace(visitor); |
+} |
+ |
+} // namespace blink |