OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "core/loader/modulescript/ModuleScriptFetcher.h" |
| 6 |
| 7 #include "core/dom/ExecutionContext.h" |
| 8 #include "core/inspector/ConsoleMessage.h" |
| 9 #include "core/loader/modulescript/ModuleScriptLoader.h" |
| 10 #include "platform/loader/fetch/FetchUtils.h" |
| 11 #include "platform/network/mime/MIMETypeRegistry.h" |
| 12 |
| 13 namespace blink { |
| 14 |
| 15 namespace { |
| 16 |
| 17 bool WasModuleLoadSuccessful(Resource* resource, |
| 18 ConsoleMessage** error_message) { |
| 19 // Implements conditions in Step 7 of |
| 20 // https://html.spec.whatwg.org/#fetch-a-single-module-script |
| 21 |
| 22 // - response's type is "error" |
| 23 if (!resource || resource->ErrorOccurred()) { |
| 24 return false; |
| 25 } |
| 26 |
| 27 const auto& response = resource->GetResponse(); |
| 28 // - response's status is not an ok status |
| 29 if (response.IsHTTP() && !FetchUtils::IsOkStatus(response.HttpStatusCode())) { |
| 30 return false; |
| 31 } |
| 32 |
| 33 // The result of extracting a MIME type from response's header list |
| 34 // (ignoring parameters) is not a JavaScript MIME type |
| 35 // Note: For historical reasons, fetching a classic script does not include |
| 36 // MIME type checking. In contrast, module scripts will fail to load if they |
| 37 // are not of a correct MIME type. |
| 38 // We use ResourceResponse::httpContentType() instead of mimeType(), as |
| 39 // mimeType() may be rewritten by mime sniffer. |
| 40 if (!MIMETypeRegistry::IsSupportedJavaScriptMIMEType( |
| 41 response.HttpContentType())) { |
| 42 if (error_message) { |
| 43 String message = |
| 44 "Failed to load module script: The server responded with a " |
| 45 "non-JavaScript MIME type of \"" + |
| 46 response.HttpContentType() + |
| 47 "\". Strict MIME type checking is enforced for module scripts per " |
| 48 "HTML spec."; |
| 49 *error_message = ConsoleMessage::CreateForRequest( |
| 50 kJSMessageSource, kErrorMessageLevel, message, |
| 51 response.Url().GetString(), resource->Identifier()); |
| 52 } |
| 53 return false; |
| 54 } |
| 55 |
| 56 return true; |
| 57 } |
| 58 |
| 59 } // namespace |
| 60 |
| 61 ModuleScriptFetcher::ModuleScriptFetcher(FetchParameters fetch_params, |
| 62 ResourceFetcher* fetcher, |
| 63 Modulator* modulator) |
| 64 : fetch_params_(fetch_params), fetcher_(fetcher), modulator_(modulator) {} |
| 65 |
| 66 void ModuleScriptFetcher::Fetch(ModuleScriptLoader* loader) { |
| 67 loader_ = loader; |
| 68 FetchInternal(); |
| 69 } |
| 70 |
| 71 void ModuleScriptFetcher::NotifyFinished(Resource* resource) { |
| 72 ClearResource(); |
| 73 |
| 74 ScriptResource* script_resource = ToScriptResource(resource); |
| 75 ConsoleMessage* error_message = nullptr; |
| 76 if (!WasModuleLoadSuccessful(script_resource, &error_message)) { |
| 77 if (error_message) { |
| 78 ExecutionContext::From(modulator_->GetScriptState()) |
| 79 ->AddConsoleMessage(error_message); |
| 80 } |
| 81 Finalize(WTF::nullopt); |
| 82 return; |
| 83 } |
| 84 |
| 85 ModuleScriptCreationParams params( |
| 86 script_resource->GetResponse().Url(), script_resource->SourceText(), |
| 87 script_resource->GetResourceRequest().GetFetchCredentialsMode(), |
| 88 script_resource->CalculateAccessControlStatus()); |
| 89 Finalize(params); |
| 90 } |
| 91 |
| 92 void ModuleScriptFetcher::FetchInternal() { |
| 93 ScriptResource* resource = ScriptResource::Fetch(fetch_params_, fetcher_); |
| 94 if (was_fetched_) { |
| 95 // ScriptResource::fetch() has succeeded synchronously, |
| 96 // ::notifyFinished() already took care of the |resource|. |
| 97 return; |
| 98 } |
| 99 if (!resource) { |
| 100 // ScriptResource::fetch() has failed synchronously. |
| 101 NotifyFinished(nullptr); |
| 102 return; |
| 103 } |
| 104 |
| 105 // ScriptResource::fetch() is processed asynchronously. |
| 106 SetResource(resource); |
| 107 } |
| 108 |
| 109 void ModuleScriptFetcher::Finalize( |
| 110 WTF::Optional<ModuleScriptCreationParams> params) { |
| 111 was_fetched_ = true; |
| 112 loader_->NotifyFetchFinished(params); |
| 113 } |
| 114 |
| 115 DEFINE_TRACE(ModuleScriptFetcher) { |
| 116 visitor->Trace(fetcher_); |
| 117 visitor->Trace(modulator_); |
| 118 visitor->Trace(loader_); |
| 119 ResourceOwner<ScriptResource>::Trace(visitor); |
| 120 } |
| 121 |
| 122 } // namespace blink |
OLD | NEW |