1 /*
2  * Copyright (C) 2006, 2007, 2008, 2009, 2011 Apple Inc. All rights reserved.
3  * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved.
4  * (http://www.torchmobile.com/)
5  * Copyright (C) Research In Motion Limited 2009. All rights reserved.
6  * Copyright (C) 2011 Google Inc. All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1.  Redistributions of source code must retain the above copyright
13  *     notice, this list of conditions and the following disclaimer.
14  * 2.  Redistributions in binary form must reproduce the above copyright
15  *     notice, this list of conditions and the following disclaimer in the
16  *     documentation and/or other materials provided with the distribution.
17  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
18  *     its contributors may be used to endorse or promote products derived
19  *     from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
22  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
25  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_FRAME_LOADER_H_
34 #define THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_FRAME_LOADER_H_
35 
36 #include <memory>
37 
38 #include "base/callback_helpers.h"
39 #include "base/macros.h"
40 #include "services/network/public/mojom/web_sandbox_flags.mojom-blink-forward.h"
41 #include "third_party/blink/public/common/user_agent/user_agent_metadata.h"
42 #include "third_party/blink/public/mojom/loader/request_context_frame_type.mojom-blink-forward.h"
43 #include "third_party/blink/public/mojom/page_state/page_state.mojom-blink.h"
44 #include "third_party/blink/public/platform/scheduler/web_scoped_virtual_time_pauser.h"
45 #include "third_party/blink/public/platform/web_url_loader.h"
46 #include "third_party/blink/public/web/web_document_loader.h"
47 #include "third_party/blink/public/web/web_frame_load_type.h"
48 #include "third_party/blink/public/web/web_navigation_type.h"
49 #include "third_party/blink/public/web/web_origin_policy.h"
50 #include "third_party/blink/renderer/core/core_export.h"
51 #include "third_party/blink/renderer/core/dom/document.h"
52 #include "third_party/blink/renderer/core/frame/frame_types.h"
53 #include "third_party/blink/renderer/core/loader/frame_loader_types.h"
54 #include "third_party/blink/renderer/core/loader/history_item.h"
55 #include "third_party/blink/renderer/platform/heap/handle.h"
56 #include "third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object.h"
57 #include "third_party/blink/renderer/platform/wtf/forward.h"
58 #include "third_party/blink/renderer/platform/wtf/hash_set.h"
59 
60 namespace blink {
61 
62 class ContentSecurityPolicy;
63 class DocumentLoader;
64 class LocalFrame;
65 class Frame;
66 class LocalFrameClient;
67 class ProgressTracker;
68 class ResourceRequest;
69 class TracedValue;
70 struct FrameLoadRequest;
71 struct WebNavigationInfo;
72 struct WebNavigationParams;
73 
74 CORE_EXPORT bool IsBackForwardLoadType(WebFrameLoadType);
75 CORE_EXPORT bool IsReloadLoadType(WebFrameLoadType);
76 
77 class CORE_EXPORT FrameLoader final {
78   DISALLOW_NEW();
79 
80  public:
81   explicit FrameLoader(LocalFrame*);
82   ~FrameLoader();
83 
84   void Init();
85 
86   ResourceRequest ResourceRequestForReload(
87       WebFrameLoadType,
88       ClientRedirectPolicy = ClientRedirectPolicy::kNotClientRedirect);
89 
Progress()90   ProgressTracker& Progress() const { return *progress_tracker_; }
91 
92   // Starts a navigation. It will eventually send the navigation to the
93   // browser process, or call LoadInSameDocument for same-document navigation.
94   // For reloads, an appropriate WebFrameLoadType should be given. Otherwise,
95   // kStandard should be used (and the final WebFrameLoadType
96   // will be computed).
97   void StartNavigation(FrameLoadRequest&,
98                        WebFrameLoadType = WebFrameLoadType::kStandard);
99 
100   // Called when the browser process has asked this renderer process to commit
101   // a navigation in this frame. This method skips most of the checks assuming
102   // that browser process has already performed any checks necessary.
103   // See WebNavigationParams for details.
104   void CommitNavigation(
105       std::unique_ptr<WebNavigationParams> navigation_params,
106       std::unique_ptr<WebDocumentLoader::ExtraData> extra_data,
107       CommitReason = CommitReason::kRegular);
108 
109   // Called before the browser process is asked to navigate this frame, to mark
110   // the frame as loading and save some navigation information for later use.
111   bool WillStartNavigation(const WebNavigationInfo& info);
112 
113   // This runs the "stop document loading" algorithm in HTML:
114   // https://html.spec.whatwg.org/C/browsing-the-web.html#stop-document-loading
115   // Note, this function only cancels ongoing navigation handled through
116   // FrameLoader.
117   //
118   // If |abort_client| is true, then the frame's client will have
119   // AbortClientNavigation() called if a navigation was aborted. Normally this
120   // should be passed as true, unless the navigation has been migrated to a
121   // provisional frame, while this frame is going away, so the navigation isn't
122   // actually being aborted.
123   //
124   // Warning: StopAllLoaders() may detach the LocalFrame to which this
125   // FrameLoader belongs. Callers need to be careful about checking the
126   // existence of the frame after StopAllLoaders() returns.
127   void StopAllLoaders(bool abort_client);
128 
129   // Notifies the client that the initial empty document has been accessed, and
130   // thus it is no longer safe to show a provisional URL above the document
131   // without risking a URL spoof. The client must not call back into JavaScript.
132   void DidAccessInitialDocument();
133 
GetDocumentLoader()134   DocumentLoader* GetDocumentLoader() const { return document_loader_.Get(); }
135 
136   void SetDefersLoading(WebURLLoader::DeferType defer);
137 
138   void DidExplicitOpen();
139 
140   String UserAgent() const;
141   base::Optional<blink::UserAgentMetadata> UserAgentMetadata() const;
142 
143   void DispatchDidClearWindowObjectInMainWorld();
144   void DispatchDidClearDocumentOfWindowObject();
145   void DispatchDocumentElementAvailable();
146   void RunScriptsAtDocumentElementAvailable();
147 
148   // The following sandbox flags will be forced, regardless of changes to the
149   // sandbox attribute of any parent frames.
150   void ForceSandboxFlags(network::mojom::blink::WebSandboxFlags flags);
151 
GetForcedSandboxFlags()152   network::mojom::blink::WebSandboxFlags GetForcedSandboxFlags() const {
153     return forced_sandbox_flags_;
154   }
155 
156   // Includes the collection of forced, inherited, and FrameOwner's sandbox
157   // flags. Note: with FeaturePolicyForSandbox the frame owner's sandbox flags
158   // only includes the flags which are *not* implemented as feature policies
159   // already present in the FrameOwner's ContainerPolicy.
160   network::mojom::blink::WebSandboxFlags PendingEffectiveSandboxFlags() const;
161 
162   // Modifying itself is done based on |fetch_client_settings_object|.
163   // |document_for_logging| is used only for logging, use counters,
164   // UKM-related things.
165   void ModifyRequestForCSP(
166       ResourceRequest&,
167       const FetchClientSettingsObject* fetch_client_settings_object,
168       LocalDOMWindow* window_for_logging,
169       mojom::RequestContextFrameType) const;
170   void ReportLegacyTLSVersion(const KURL& url,
171                               bool is_subresource,
172                               bool is_ad_resource);
173 
174   Frame* Opener();
175   void SetOpener(LocalFrame*);
176 
RequiredCSP()177   const AtomicString& RequiredCSP() const { return required_csp_; }
178   void RecordLatestRequiredCSP();
179 
180   void Detach();
181 
182   void FinishedParsing();
183   enum class NavigationFinishState { kSuccess, kFailure };
184   void DidFinishNavigation(NavigationFinishState);
185 
186   void DidFinishSameDocumentNavigation(const KURL&,
187                                        WebFrameLoadType,
188                                        HistoryItem*);
189 
190   // This will attempt to detach the current document. It will dispatch unload
191   // events and abort XHR requests. Returns true if the frame is ready to
192   // receive the next document commit, or false otherwise.
193   bool DetachDocument(SecurityOrigin* committing_origin,
194                       base::Optional<Document::UnloadEventTiming>*);
195 
196   bool ShouldClose(bool is_reload = false);
197 
198   // Dispatches the Unload event for the current document. If this is due to the
199   // commit of a navigation, both |committing_origin| and the
200   // Optional<Document::UnloadEventTiming>* should be non null.
201   // |committing_origin| is the origin of the document that is being committed.
202   // If it is allowed to access the unload timings of the current document, the
203   // Document::UnloadEventTiming will be created and populated.
204   // If the dispatch of the unload event is not due to a commit, both parameters
205   // should be null.
206   void DispatchUnloadEvent(SecurityOrigin* committing_origin,
207                            base::Optional<Document::UnloadEventTiming>*);
208 
209   bool AllowPlugins(ReasonForCallingAllowPlugins);
210 
211   void SaveScrollAnchor();
212   void SaveScrollState();
213   void RestoreScrollPositionAndViewState();
214 
HasProvisionalNavigation()215   bool HasProvisionalNavigation() const {
216     return committing_navigation_ || client_navigation_.get();
217   }
218 
219   bool MaybeRenderFallbackContent();
220 
221   // Like ClearClientNavigation, but also notifies the client to actually cancel
222   // the navigation.
223   void CancelClientNavigation();
224 
225   void Trace(Visitor*) const;
226 
227   void DidDropNavigation();
228 
HasAccessedInitialDocument()229   bool HasAccessedInitialDocument() { return has_accessed_initial_document_; }
230 
SetDidLoadNonEmptyDocument()231   void SetDidLoadNonEmptyDocument() {
232     empty_document_status_ = EmptyDocumentStatus::kNonEmpty;
233   }
HasLoadedNonEmptyDocument()234   bool HasLoadedNonEmptyDocument() {
235     return empty_document_status_ == EmptyDocumentStatus::kNonEmpty;
236   }
237 
238   static bool NeedsHistoryItemRestore(WebFrameLoadType type);
239 
240  private:
241   bool AllowRequestForThisFrame(const FrameLoadRequest&);
242   WebFrameLoadType DetermineFrameLoadType(const KURL& url,
243                                           const AtomicString& http_method,
244                                           bool has_origin_window,
245                                           const KURL& failing_url,
246                                           WebFrameLoadType);
247 
248   bool ShouldPerformFragmentNavigation(bool is_form_submission,
249                                        const String& http_method,
250                                        WebFrameLoadType,
251                                        const KURL&);
252   void ProcessFragment(const KURL&, WebFrameLoadType, LoadStartType);
253 
254   // Returns whether we should continue with new navigation.
255   bool CancelProvisionalLoaderForNewNavigation();
256 
257   // Clears any information about client navigation, see client_navigation_.
258   void ClearClientNavigation();
259 
260   void RestoreScrollPositionAndViewState(WebFrameLoadType,
261                                          const HistoryItem::ViewState&,
262                                          mojom::blink::ScrollRestorationType);
263 
264   void DetachDocumentLoader(Member<DocumentLoader>&,
265                             bool flush_microtask_queue = false);
266 
267   std::unique_ptr<TracedValue> ToTracedValue() const;
268   void TakeObjectSnapshot() const;
269 
270   // Commits the given |document_loader|.
271   void CommitDocumentLoader(DocumentLoader* document_loader,
272                             const base::Optional<Document::UnloadEventTiming>&,
273                             HistoryItem* previous_history_item,
274                             CommitReason);
275 
276   // Creates CSP for the initial empty document. They are inherited from the
277   // owner document (parent or opener).
278   ContentSecurityPolicy* CreateCSPForInitialEmptyDocument() const;
279 
280   // Creates CSP based on |response| and checks that they allow loading |url|.
281   // Returns nullptr if the check fails.
282   ContentSecurityPolicy* CreateCSP(
283       const KURL& url,
284       const ResourceResponse& response,
285       const base::Optional<WebOriginPolicy>& origin_policy,
286       ContentSecurityPolicy* initiator_csp,
287       CommitReason);
288 
289   LocalFrameClient* Client() const;
290 
291   Member<LocalFrame> frame_;
292 
293   Member<ProgressTracker> progress_tracker_;
294 
295   // Document loader for frame loading.
296   Member<DocumentLoader> document_loader_;
297 
298   // This struct holds information about a navigation, which is being
299   // initiated by the client through the browser process, until the navigation
300   // is either committed or cancelled.
301   struct ClientNavigationState {
302     KURL url;
303   };
304   std::unique_ptr<ClientNavigationState> client_navigation_;
305 
306   network::mojom::blink::WebSandboxFlags forced_sandbox_flags_;
307 
308   // The state is set to kInitialized when Init() completes, and kDetached
309   // during teardown in Detach().
310   enum class State { kUninitialized, kInitialized, kDetached };
311   State state_ = State::kUninitialized;
312 
313   bool dispatching_did_clear_window_object_in_main_world_;
314   bool committing_navigation_ = false;
315   bool has_accessed_initial_document_ = false;
316 
317   enum class EmptyDocumentStatus {
318     kOnlyEmpty,
319     kOnlyEmptyButExplicitlyOpened,
320     kNonEmpty
321   };
322   EmptyDocumentStatus empty_document_status_ = EmptyDocumentStatus::kOnlyEmpty;
323 
324   WebScopedVirtualTimePauser virtual_time_pauser_;
325 
326   // The CSP of the latest document that has initiated a navigation in this
327   // frame. TODO(arthursonzogni): This looks fragile. The FrameLoader might be
328   // confused by several navigations submitted in a row.
329   Member<ContentSecurityPolicy> last_origin_window_csp_;
330 
331   AtomicString required_csp_;
332 
333   // The origins for which a legacy TLS version warning has been printed. The
334   // size of this set is capped, after which no more warnings are printed.
335   HashSet<String> tls_version_warning_origins_;
336 
337   DISALLOW_COPY_AND_ASSIGN(FrameLoader);
338 };
339 
340 }  // namespace blink
341 
342 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_FRAME_LOADER_H_
343