1 /* 2 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de) 3 Copyright (C) 2001 Dirk Mueller <mueller@kde.org> 4 Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) 5 Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. 6 7 This library is free software; you can redistribute it and/or 8 modify it under the terms of the GNU Library General Public 9 License as published by the Free Software Foundation; either 10 version 2 of the License, or (at your option) any later version. 11 12 This library is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 Library General Public License for more details. 16 17 You should have received a copy of the GNU Library General Public License 18 along with this library; see the file COPYING.LIB. If not, write to 19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 20 Boston, MA 02110-1301, USA. 21 22 This class provides all functionality needed for loading images, style 23 sheets and html pages from the web. It has a memory cache for these objects. 24 */ 25 26 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_RESOURCE_SCRIPT_RESOURCE_H_ 27 #define THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_RESOURCE_SCRIPT_RESOURCE_H_ 28 29 #include <memory> 30 31 #include "third_party/blink/renderer/bindings/core/v8/script_streamer.h" 32 #include "third_party/blink/renderer/core/core_export.h" 33 #include "third_party/blink/renderer/core/loader/resource/text_resource.h" 34 #include "third_party/blink/renderer/platform/bindings/parkable_string.h" 35 #include "third_party/blink/renderer/platform/loader/fetch/integrity_metadata.h" 36 #include "third_party/blink/renderer/platform/loader/fetch/resource_client.h" 37 #include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h" 38 #include "third_party/blink/renderer/platform/loader/fetch/text_resource_decoder_options.h" 39 40 namespace blink { 41 42 class FetchParameters; 43 class KURL; 44 class ResourceFetcher; 45 class SingleCachedMetadataHandler; 46 47 // ScriptResource is a resource representing a JavaScript, either a classic or 48 // module script. 49 // 50 // In addition to loading the script, a ScriptResource can optionally stream the 51 // script to the JavaScript parser/compiler, using a ScriptStreamer. In this 52 // case, clients of the ScriptResource will not receive the finished 53 // notification until the streaming completes. 54 // Note: ScriptStreamer is only used for "classic" scripts, i.e. not modules. 55 // 56 // See also: 57 // https://docs.google.com/document/d/143GOPl_XVgLPFfO-31b_MdBcnjklLEX2OIg_6eN6fQ4 58 class CORE_EXPORT ScriptResource final : public TextResource { 59 public: 60 // The script resource will always try to start streaming if kAllowStreaming 61 // is passed in. 62 enum StreamingAllowed { kNoStreaming, kAllowStreaming }; 63 64 static ScriptResource* Fetch(FetchParameters&, 65 ResourceFetcher*, 66 ResourceClient*, 67 StreamingAllowed); 68 69 // Public for testing 70 static ScriptResource* CreateForTest(const KURL& url, 71 const WTF::TextEncoding& encoding); 72 73 ScriptResource(const ResourceRequest&, 74 const ResourceLoaderOptions&, 75 const TextResourceDecoderOptions&, 76 StreamingAllowed); 77 ~ScriptResource() override; 78 79 void ResponseBodyReceived( 80 ResponseBodyLoaderDrainableInterface& body_loader, 81 scoped_refptr<base::SingleThreadTaskRunner> loader_task_runner) override; 82 83 void Trace(Visitor*) const override; 84 85 void OnMemoryDump(WebMemoryDumpLevelOfDetail, 86 WebProcessMemoryDump*) const override; 87 88 void SetSerializedCachedMetadata(mojo_base::BigBuffer data) override; 89 90 const ParkableString& SourceText(); 91 92 // Get the resource's current text. This can return partial data, so should 93 // not be used outside of the inspector. 94 String TextForInspector() const; 95 96 SingleCachedMetadataHandler* CacheHandler(); 97 98 // Gets the script streamer from the ScriptResource, clearing the resource's 99 // streamer so that it cannot be used twice. 100 ScriptStreamer* TakeStreamer(); 101 NoStreamerReason()102 ScriptStreamer::NotStreamingReason NoStreamerReason() const { 103 return no_streamer_reason_; 104 } 105 106 // Used in DCHECKs HasStreamer()107 bool HasStreamer() { return !!streamer_; } HasRunningStreamer()108 bool HasRunningStreamer() { return streamer_ && !streamer_->IsFinished(); } HasFinishedStreamer()109 bool HasFinishedStreamer() { return streamer_ && streamer_->IsFinished(); } 110 111 // Visible for tests. 112 void SetRevalidatingRequest(const ResourceRequestHead&) override; 113 114 protected: 115 CachedMetadataHandler* CreateCachedMetadataHandler( 116 std::unique_ptr<CachedMetadataSender> send_callback) override; 117 118 void DestroyDecodedDataForFailedRevalidation() override; 119 120 // ScriptResources are considered finished when either: 121 // 1. Loading + streaming completes, or 122 // 2. Loading completes + streaming is disabled. 123 void NotifyFinished() override; 124 125 private: 126 // Valid state transitions: 127 // 128 // kWaitingForDataPipe DisableStreaming() 129 // |---------------------------. 130 // | | 131 // v v 132 // kStreaming -----------------> kStreamingDisabled 133 // 134 enum class StreamingState { 135 // Streaming is allowed on this resource, but we're waiting to receive a 136 // data pipe. 137 kWaitingForDataPipe, 138 // The script streamer is active, and has the data pipe. 139 kStreaming, 140 141 // Streaming was disabled, either manually or because we got a body with 142 // no data-pipe. 143 kStreamingDisabled, 144 }; 145 146 class ScriptResourceFactory : public ResourceFactory { 147 public: ScriptResourceFactory(StreamingAllowed streaming_allowed)148 explicit ScriptResourceFactory(StreamingAllowed streaming_allowed) 149 : ResourceFactory(ResourceType::kScript, 150 TextResourceDecoderOptions::kPlainTextContent), 151 streaming_allowed_(streaming_allowed) {} 152 Create(const ResourceRequest & request,const ResourceLoaderOptions & options,const TextResourceDecoderOptions & decoder_options)153 Resource* Create( 154 const ResourceRequest& request, 155 const ResourceLoaderOptions& options, 156 const TextResourceDecoderOptions& decoder_options) const override { 157 return MakeGarbageCollected<ScriptResource>( 158 request, options, decoder_options, streaming_allowed_); 159 } 160 161 private: 162 StreamingAllowed streaming_allowed_; 163 }; 164 165 bool CanUseCacheValidator() const override; 166 167 void DisableStreaming(ScriptStreamer::NotStreamingReason no_streamer_reason); 168 169 void AdvanceStreamingState(StreamingState new_state); 170 171 // Check that invariants for the state hold. 172 void CheckStreamingState() const; 173 174 void OnDataPipeReadable(MojoResult result, 175 const mojo::HandleSignalsState& state); 176 177 ParkableString source_text_; 178 179 Member<ScriptStreamer> streamer_; 180 ScriptStreamer::NotStreamingReason no_streamer_reason_ = 181 ScriptStreamer::NotStreamingReason::kInvalid; 182 StreamingState streaming_state_ = StreamingState::kWaitingForDataPipe; 183 }; 184 185 DEFINE_RESOURCE_TYPE_CASTS(Script); 186 187 } // namespace blink 188 189 #endif // THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_RESOURCE_SCRIPT_RESOURCE_H_ 190