[go: nahoru, domu]

blob: 9f9ddb32f85f8545380d490c557fde0c70a9c6c2 [file] [log] [blame]
/*
* Copyright (C) 2006, 2007, 2008, 2009, 2011 Apple Inc. All rights reserved.
* Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved.
* (http://www.torchmobile.com/)
* Copyright (C) Research In Motion Limited 2009. All rights reserved.
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_FRAME_LOADER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_FRAME_LOADER_H_
#include <memory>
#include <optional>
#include "base/functional/callback_helpers.h"
#include "services/network/public/mojom/web_sandbox_flags.mojom-blink-forward.h"
#include "third_party/blink/public/common/tokens/tokens.h"
#include "third_party/blink/public/common/user_agent/user_agent_metadata.h"
#include "third_party/blink/public/mojom/loader/code_cache.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/loader/request_context_frame_type.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/page_state/page_state.mojom-blink-forward.h"
#include "third_party/blink/public/platform/scheduler/web_scoped_virtual_time_pauser.h"
#include "third_party/blink/public/web/web_document_loader.h"
#include "third_party/blink/public/web/web_frame_load_type.h"
#include "third_party/blink/public/web/web_navigation_type.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/frame/frame_types.h"
#include "third_party/blink/renderer/core/loader/frame_loader_types.h"
#include "third_party/blink/renderer/core/loader/history_item.h"
#include "third_party/blink/renderer/core/loader/old_document_info_for_commit.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/loader/fetch/loader_freeze_mode.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
namespace blink {
class DocumentLoader;
class FetchClientSettingsObject;
class LocalFrame;
class LocalFrameClient;
class PolicyContainer;
class ProgressTracker;
class ResourceRequest;
class StorageKey;
class TracedValue;
struct FrameLoadRequest;
struct WebNavigationInfo;
struct WebNavigationParams;
CORE_EXPORT bool IsBackForwardLoadType(WebFrameLoadType);
CORE_EXPORT bool IsReloadLoadType(WebFrameLoadType);
CORE_EXPORT bool IsBackForwardOrRestore(WebFrameLoadType);
class CORE_EXPORT FrameLoader final {
DISALLOW_NEW();
public:
explicit FrameLoader(LocalFrame*);
FrameLoader(const FrameLoader&) = delete;
FrameLoader& operator=(const FrameLoader&) = delete;
~FrameLoader();
void Init(const DocumentToken& document_token,
std::unique_ptr<PolicyContainer> policy_container,
const StorageKey& storage_key,
ukm::SourceId document_ukm_source_id,
const KURL& creator_base_url);
ResourceRequest ResourceRequestForReload(
WebFrameLoadType,
ClientRedirectPolicy = ClientRedirectPolicy::kNotClientRedirect);
ProgressTracker& Progress() const { return *progress_tracker_; }
// This is the entry-point for all renderer-initiated navigations except
// history traversals. It will eventually send the navigation to the browser
// process, or call DocumentLoader::CommitSameDocumentNavigation for
// same-document navigation. For reloads, an appropriate WebFrameLoadType
// should be given. Otherwise, kStandard should be used (and the final
// WebFrameLoadType will be computed).
void StartNavigation(FrameLoadRequest&,
WebFrameLoadType = WebFrameLoadType::kStandard);
// Called when the browser process has asked this renderer process to commit
// a navigation in this frame. This method skips most of the checks assuming
// that browser process has already performed any checks necessary.
// See WebNavigationParams for details.
void CommitNavigation(
std::unique_ptr<WebNavigationParams> navigation_params,
std::unique_ptr<WebDocumentLoader::ExtraData> extra_data,
CommitReason = CommitReason::kRegular);
// Called before the browser process is asked to navigate this frame, to mark
// the frame as loading and save some navigation information for later use.
bool WillStartNavigation(const WebNavigationInfo& info);
// This runs the "stop document loading" algorithm in HTML:
// https://html.spec.whatwg.org/C/browsing-the-web.html#stop-document-loading
// Note, this function only cancels ongoing navigation handled through
// FrameLoader.
//
// If |abort_client| is true, then the frame's client will have
// AbortClientNavigation() called if a navigation was aborted. Normally this
// should be passed as true, unless the navigation has been migrated to a
// provisional frame, while this frame is going away, so the navigation isn't
// actually being aborted.
//
// Warning: StopAllLoaders() may detach the LocalFrame to which this
// FrameLoader belongs. Callers need to be careful about checking the
// existence of the frame after StopAllLoaders() returns.
void StopAllLoaders(bool abort_client);
// Notifies the client that the initial empty document has been accessed, and
// thus it is no longer safe to show a provisional URL above the document
// without risking a URL spoof. The client must not call back into JavaScript.
void DidAccessInitialDocument();
DocumentLoader* GetDocumentLoader() const { return document_loader_.Get(); }
void SetDefersLoading(LoaderFreezeMode mode);
void DidExplicitOpen();
String UserAgent() const;
std::optional<blink::UserAgentMetadata> UserAgentMetadata() const;
void DispatchDidClearWindowObjectInMainWorld();
void DispatchDidClearDocumentOfWindowObject();
void DispatchDocumentElementAvailable();
void RunScriptsAtDocumentElementAvailable();
// See content/browser/renderer_host/sandbox_flags.md
// This contains the sandbox flags to commit for new documents.
// - For main documents, it contains the sandbox inherited from the opener.
// - For nested documents, it contains the sandbox flags inherited from the
// parent and the one defined in the <iframe>'s sandbox attribute.
network::mojom::blink::WebSandboxFlags PendingEffectiveSandboxFlags() const;
// Modifying itself is done based on |fetch_client_settings_object|.
// |document_for_logging| is used only for logging, use counters,
// UKM-related things.
void ModifyRequestForCSP(
ResourceRequest&,
const FetchClientSettingsObject* fetch_client_settings_object,
LocalDOMWindow* window_for_logging,
mojom::RequestContextFrameType) const;
void Detach();
void FinishedParsing();
enum class NavigationFinishState { kSuccess, kFailure };
void DidFinishNavigation(NavigationFinishState);
void ProcessScrollForSameDocumentNavigation(
const KURL&,
WebFrameLoadType,
std::optional<HistoryItem::ViewState>,
mojom::blink::ScrollRestorationType);
// This will attempt to detach the current document. It will dispatch unload
// events and abort XHR requests. Returns true if the frame is ready to
// receive the next document commit, or false otherwise.
bool DetachDocument();
bool ShouldClose(bool is_reload = false);
// Dispatches the Unload event for the current document and fills in this
// document's info in OldDocumentInfoForCommit if
// `will_commit_new_document_in_this_frame` is true (which will only be
// the case when the current document in this frame is being unloaded for
// committing a new document).
void DispatchUnloadEventAndFillOldDocumentInfoIfNeeded(
bool will_commit_new_document_in_this_frame);
bool AllowPlugins();
void SaveScrollAnchor();
void SaveScrollState();
void RestoreScrollPositionAndViewState();
bool HasProvisionalNavigation() const {
return committing_navigation_ || client_navigation_.get();
}
// Like ClearClientNavigation, but also notifies the client to actually cancel
// the navigation.
void CancelClientNavigation(
CancelNavigationReason reason = CancelNavigationReason::kOther);
void Trace(Visitor*) const;
void DidDropNavigation();
bool HasAccessedInitialDocument() { return has_accessed_initial_document_; }
void SetIsNotOnInitialEmptyDocument() {
// The "initial empty document" state can be false if the frame has loaded
// a non-initial/synchronous about:blank document, or if the document has
// done a document.open() before. However, this function can only be called
// when a frame is first re-created in a new renderer, which can only be
// caused by a new document load. So, we know that the state must be set to
// kNotInitialOrSynchronousAboutBlank instead of
// kInitialOrSynchronousAboutBlankButExplicitlyOpened here.
initial_empty_document_status_ =
InitialEmptyDocumentStatus::kNotInitialOrSynchronousAboutBlank;
}
// Whether the frame's current document is still considered as the "initial
// empty document" or not. Might be false even when
// HasLoadedNonInitialEmptyDocument() is false, if the frame is still on the
// first about:blank document that loaded in the frame, but it has done
// a document.open(), causing it to lose its "initial empty document"-ness
// even though it's still on the same document.
bool IsOnInitialEmptyDocument() {
return initial_empty_document_status_ ==
InitialEmptyDocumentStatus::kInitialOrSynchronousAboutBlank;
}
// Whether the frame has loaded a document that is not the initial empty
// document. Might be false even when IsOnInitialEmptyDocument() is false (see
// comment for IsOnInitialEmptyDocument() for details).
bool HasLoadedNonInitialEmptyDocument() {
return initial_empty_document_status_ ==
InitialEmptyDocumentStatus::kNotInitialOrSynchronousAboutBlank;
}
static bool NeedsHistoryItemRestore(WebFrameLoadType type);
void WriteIntoTrace(perfetto::TracedValue context) const;
mojo::PendingRemote<mojom::blink::CodeCacheHost> CreateWorkerCodeCacheHost();
private:
bool AllowRequestForThisFrame(const FrameLoadRequest&);
bool ShouldPerformFragmentNavigation(bool is_form_submission,
const String& http_method,
WebFrameLoadType,
const KURL&);
void ProcessFragment(const KURL&, WebFrameLoadType, LoadStartType);
// Returns whether we should continue with new navigation.
bool CancelProvisionalLoaderForNewNavigation();
// Clears any information about client navigation, see client_navigation_.
void ClearClientNavigation();
void RestoreScrollPositionAndViewState(WebFrameLoadType,
const HistoryItem::ViewState&,
mojom::blink::ScrollRestorationType);
void DetachDocumentLoader(Member<DocumentLoader>&,
bool flush_microtask_queue = false);
void TakeObjectSnapshot() const;
// Commits the given |document_loader|.
void CommitDocumentLoader(DocumentLoader* document_loader,
HistoryItem* previous_history_item,
CommitReason);
LocalFrameClient* Client() const;
String ApplyUserAgentOverride(const String& user_agent) const;
// This struct holds information about a navigation, which is being
// initiated by the client through the browser process, until the navigation
// is either committed or cancelled.
struct ClientNavigationState {
KURL url;
};
std::unique_ptr<ClientNavigationState> client_navigation_;
Member<LocalFrame> frame_;
Member<ProgressTracker> progress_tracker_;
// Document loader for frame loading.
Member<DocumentLoader> document_loader_;
// The state is set to kInitialized when Init() completes, and kDetached
// during teardown in Detach().
enum class State { kUninitialized, kInitialized, kDetached };
State state_ = State::kUninitialized;
bool dispatching_did_clear_window_object_in_main_world_;
bool committing_navigation_ = false;
bool has_accessed_initial_document_ = false;
// Enum to determine the frame's "initial empty document"-ness.
// NOTE: we treat both the "initial about:blank document" and the
// "synchronously committed about:blank document" as the initial empty
// document. In the future, we plan to remove the synchronous about:blank
// commit so that this enum only considers the true "initial about:blank"
// document. See also:
// - https://github.com/whatwg/html/issues/6863
// - https://crbug.com/1215096
enum class InitialEmptyDocumentStatus {
// The document is the initial about:blank document or the synchronously
// committed about:blank document.
kInitialOrSynchronousAboutBlank,
// The document is the initial about:blank document or the synchronously
// committed about:blank document, but the document's input stream has been
// opened with document.open(), so the document lost its "initial empty
// document" status, per the spec:
// https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#opening-the-input-stream:is-initial-about:blank
kInitialOrSynchronousAboutBlankButExplicitlyOpened,
// The document is neither the initial about:blank document nor the
// synchronously committed about:blank document.
kNotInitialOrSynchronousAboutBlank
};
InitialEmptyDocumentStatus initial_empty_document_status_ =
InitialEmptyDocumentStatus::kInitialOrSynchronousAboutBlank;
WebScopedVirtualTimePauser virtual_time_pauser_;
// The origins for which a legacy TLS version warning has been printed. The
// size of this set is capped, after which no more warnings are printed.
HashSet<String> tls_version_warning_origins_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_FRAME_LOADER_H_