blob: af5fbc4150ef30e94b5e0a993278b288f37d7931 [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2015 The Chromium Authors
danakjc492bf82020-09-09 20:02:442// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CONTENT_BROWSER_RENDERER_HOST_FRAME_NAVIGATION_ENTRY_H_
6#define CONTENT_BROWSER_RENDERER_HOST_FRAME_NAVIGATION_ENTRY_H_
7
8#include <stdint.h>
9
Arthur Sonzognic686e8f2024-01-11 08:36:3710#include <optional>
11
danakjc492bf82020-09-09 20:02:4412#include "base/memory/ref_counted.h"
Antonio Sartori78a749f2020-11-30 12:03:3913#include "content/browser/renderer_host/policy_container_host.h"
danakjc492bf82020-09-09 20:02:4414#include "content/browser/site_instance_impl.h"
Lei Zhang7ab313752021-11-17 01:26:0015#include "content/common/content_export.h"
Avi Drissman78865bbb2024-08-22 20:57:1916#include "content/public/common/bindings_policy.h"
danakjc492bf82020-09-09 20:02:4417#include "content/public/common/referrer.h"
danakjc492bf82020-09-09 20:02:4418#include "services/network/public/cpp/shared_url_loader_factory.h"
Miyoung Shin5d77f72072020-10-09 15:14:2019#include "third_party/blink/public/common/page_state/page_state.h"
danakjc492bf82020-09-09 20:02:4420#include "url/gurl.h"
21#include "url/origin.h"
22
Lei Zhangb7fc2462022-09-09 23:27:4823namespace network {
24class ResourceRequestBody;
25}
26
danakjc492bf82020-09-09 20:02:4427namespace content {
28
danakjc492bf82020-09-09 20:02:4429// Represents a session history item for a particular frame. It is matched with
30// corresponding FrameTreeNodes using unique name (or by the root position).
Nate Chapin9f169072021-06-09 19:32:3731// There is a tree of FrameNavigationEntries in each NavigationEntry, one per
danakjc492bf82020-09-09 20:02:4432// frame.
33//
Nate Chapin9f169072021-06-09 19:32:3734// This class is refcounted and can be shared across multiple NavigationEntries.
Charlie Reisa474fb62022-03-17 02:31:3635// Each RenderFrameHost also keeps a scoped_refptr to its last committed
36// FrameNavigationEntry, to accurately track its current state in cases when the
37// last committed NavigationEntry may not match (e.g., when missing the
38// relevant FrameNavigationEntry or during a history navigation targeting
39// multiple frames while only some have committed.)
danakjc492bf82020-09-09 20:02:4440class CONTENT_EXPORT FrameNavigationEntry
41 : public base::RefCounted<FrameNavigationEntry> {
42 public:
danakjc492bf82020-09-09 20:02:4443 FrameNavigationEntry(
44 const std::string& frame_unique_name,
45 int64_t item_sequence_number,
46 int64_t document_sequence_number,
Domenic Denicolacc094fb2022-03-16 23:40:5747 const std::string& navigation_api_key,
danakjc492bf82020-09-09 20:02:4448 scoped_refptr<SiteInstanceImpl> site_instance,
49 scoped_refptr<SiteInstanceImpl> source_site_instance,
50 const GURL& url,
Arthur Sonzognic686e8f2024-01-11 08:36:3751 const std::optional<url::Origin>& origin,
danakjc492bf82020-09-09 20:02:4452 const Referrer& referrer,
Arthur Sonzognic686e8f2024-01-11 08:36:3753 const std::optional<url::Origin>& initiator_origin,
54 const std::optional<GURL>& initiator_base_url,
danakjc492bf82020-09-09 20:02:4455 const std::vector<GURL>& redirect_chain,
Miyoung Shin5d77f72072020-10-09 15:14:2056 const blink::PageState& page_state,
danakjc492bf82020-09-09 20:02:4457 const std::string& method,
58 int64_t post_id,
59 scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
Nate Chapin63db0d12022-01-20 22:03:3060 std::unique_ptr<PolicyContainerPolicies> policy_container_policies,
Domenic Denicolacc094fb2022-03-16 23:40:5761 bool protect_url_in_navigation_api);
danakjc492bf82020-09-09 20:02:4462
Peter Boström9b036532021-10-28 23:37:2863 FrameNavigationEntry(const FrameNavigationEntry&) = delete;
64 FrameNavigationEntry& operator=(const FrameNavigationEntry&) = delete;
65
danakjc492bf82020-09-09 20:02:4466 // Creates a copy of this FrameNavigationEntry that can be modified
67 // independently from the original.
68 scoped_refptr<FrameNavigationEntry> Clone() const;
69
70 // Updates all the members of this entry.
71 void UpdateEntry(
72 const std::string& frame_unique_name,
73 int64_t item_sequence_number,
74 int64_t document_sequence_number,
Domenic Denicolacc094fb2022-03-16 23:40:5775 const std::string& navigation_api_key,
danakjc492bf82020-09-09 20:02:4476 SiteInstanceImpl* site_instance,
77 scoped_refptr<SiteInstanceImpl> source_site_instance,
78 const GURL& url,
Arthur Sonzognic686e8f2024-01-11 08:36:3779 const std::optional<url::Origin>& origin,
danakjc492bf82020-09-09 20:02:4480 const Referrer& referrer,
Arthur Sonzognic686e8f2024-01-11 08:36:3781 const std::optional<url::Origin>& initiator_origin,
82 const std::optional<GURL>& initiator_base_url,
danakjc492bf82020-09-09 20:02:4483 const std::vector<GURL>& redirect_chain,
Miyoung Shin5d77f72072020-10-09 15:14:2084 const blink::PageState& page_state,
danakjc492bf82020-09-09 20:02:4485 const std::string& method,
86 int64_t post_id,
87 scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
Nate Chapin63db0d12022-01-20 22:03:3088 std::unique_ptr<PolicyContainerPolicies> policy_container_policies,
Domenic Denicolacc094fb2022-03-16 23:40:5789 bool protect_url_in_navigation_api);
danakjc492bf82020-09-09 20:02:4490
91 // The unique name of the frame this entry is for. This is a stable name for
92 // the frame based on its position in the tree and relation to other named
93 // frames, which does not change after cross-process navigations or restores.
94 // Only the main frame can have an empty name.
95 //
96 // This is unique relative to other frames in the same page, but not among
97 // other pages (i.e., not globally unique).
98 const std::string& frame_unique_name() const { return frame_unique_name_; }
99 void set_frame_unique_name(const std::string& frame_unique_name) {
100 frame_unique_name_ = frame_unique_name;
101 }
102
103 // Keeps track of where this entry belongs in the frame's session history.
104 // The item sequence number identifies each stop in the back/forward history
105 // and is globally unique. The document sequence number increments for each
106 // new document and is also globally unique. In-page navigations get a new
107 // item sequence number but the same document sequence number. These numbers
108 // should not change once assigned.
109 void set_item_sequence_number(int64_t item_sequence_number);
110 int64_t item_sequence_number() const { return item_sequence_number_; }
111 void set_document_sequence_number(int64_t document_sequence_number);
112 int64_t document_sequence_number() const { return document_sequence_number_; }
113
Domenic Denicolacc094fb2022-03-16 23:40:57114 // Identifies a "slot" in the frame's session history for the
115 // window.navigation API.
116 void set_navigation_api_key(const std::string& navigation_api_key);
117 const std::string& navigation_api_key() const { return navigation_api_key_; }
Nate Chapinfbfe5af2021-06-10 17:22:08118
danakjc492bf82020-09-09 20:02:44119 // The SiteInstance, as assigned at commit time, responsible for rendering
120 // this frame. All frames sharing a SiteInstance must live in the same
121 // process. This is a refcounted pointer that keeps the SiteInstance (not
122 // necessarily the process) alive as long as this object remains in the
123 // session history.
danakjc492bf82020-09-09 20:02:44124 SiteInstanceImpl* site_instance() const { return site_instance_.get(); }
125
126 // The |source_site_instance| is used to identify the SiteInstance of the
127 // frame that initiated the navigation. It is present only for
128 // renderer-initiated navigations and is cleared once the navigation has
129 // committed.
130 void set_source_site_instance(
131 scoped_refptr<SiteInstanceImpl> source_site_instance) {
132 source_site_instance_ = std::move(source_site_instance);
133 }
134 SiteInstanceImpl* source_site_instance() const {
135 return source_site_instance_.get();
136 }
137
138 // The actual URL loaded in the frame. This is in contrast to the virtual
139 // URL, which is shown to the user.
140 void set_url(const GURL& url) { url_ = url; }
141 const GURL& url() const { return url_; }
142
143 // The referring URL. Can be empty.
144 void set_referrer(const Referrer& referrer) { referrer_ = referrer; }
145 const Referrer& referrer() const { return referrer_; }
146
Arthur Sonzognic686e8f2024-01-11 08:36:37147 // The origin that initiated the original navigation. std::nullopt means
danakjc492bf82020-09-09 20:02:44148 // that the original navigation was browser-initiated (e.g. initiated from a
149 // trusted surface like the omnibox or the bookmarks bar).
Arthur Sonzognic686e8f2024-01-11 08:36:37150 const std::optional<url::Origin>& initiator_origin() const {
danakjc492bf82020-09-09 20:02:44151 return initiator_origin_;
152 }
153
W. James MacLean23e90a12022-12-21 04:38:21154 // The base url of the initiator of the navigation. This is only set if the
155 // url is about:blank or about:srcdoc.
Arthur Sonzognic686e8f2024-01-11 08:36:37156 const std::optional<GURL>& initiator_base_url() const {
W. James MacLean23e90a12022-12-21 04:38:21157 return initiator_base_url_;
158 }
159
danakjc492bf82020-09-09 20:02:44160 // The origin of the document the frame has committed. It is optional, since
161 // pending entries do not have an origin associated with them and the real
162 // origin is set at commit time.
163 void set_committed_origin(const url::Origin& origin) {
164 committed_origin_ = origin;
165 }
Arthur Sonzognic686e8f2024-01-11 08:36:37166 const std::optional<url::Origin>& committed_origin() const {
danakjc492bf82020-09-09 20:02:44167 return committed_origin_;
168 }
169
170 // The redirect chain traversed during this frame navigation, from the initial
171 // redirecting URL to the final non-redirecting current URL.
172 void set_redirect_chain(const std::vector<GURL>& redirect_chain) {
173 redirect_chain_ = redirect_chain;
174 }
175 const std::vector<GURL>& redirect_chain() const { return redirect_chain_; }
176
Miyoung Shin5d77f72072020-10-09 15:14:20177 void SetPageState(const blink::PageState& page_state);
178 const blink::PageState& page_state() const { return page_state_; }
danakjc492bf82020-09-09 20:02:44179
180 // Remember the set of bindings granted to this FrameNavigationEntry at the
181 // time of commit, to ensure that we do not grant it additional bindings if we
182 // navigate back to it in the future. This can only be changed once.
Avi Drissman78865bbb2024-08-22 20:57:19183 // bindings() will return nullopt before the bindings are set.
184 void SetBindings(BindingsPolicySet bindings);
185 std::optional<BindingsPolicySet> bindings() const { return bindings_; }
danakjc492bf82020-09-09 20:02:44186
187 // The HTTP method used to navigate.
188 const std::string& method() const { return method_; }
189 void set_method(const std::string& method) { method_ = method; }
190
191 // Returns true if the HTTP method was POST.
192 bool get_has_post_data() { return method() == "POST"; }
193
194 // The id of the post corresponding to this navigation or -1 if the
195 // navigation was not a POST.
196 int64_t post_id() const { return post_id_; }
197 void set_post_id(int64_t post_id) { post_id_ = post_id; }
198
199 // The data sent during a POST navigation. Returns nullptr if the navigation
200 // is not a POST.
201 scoped_refptr<network::ResourceRequestBody> GetPostData(
202 std::string* content_type) const;
203
Titouan Rigoudy6ec70402021-02-02 15:42:19204 // The policy container policies for this entry. This is needed for local
205 // schemes, since for them the policy container was inherited by the creator,
206 // while for network schemes we can reconstruct the policy container by
207 // parsing the network response.
208 void set_policy_container_policies(
209 std::unique_ptr<PolicyContainerPolicies> policies) {
210 policy_container_policies_ = std::move(policies);
Antonio Sartori78a749f2020-11-30 12:03:39211 }
Titouan Rigoudy6ec70402021-02-02 15:42:19212 const PolicyContainerPolicies* policy_container_policies() const {
213 return policy_container_policies_.get();
Antonio Sartori78a749f2020-11-30 12:03:39214 }
215
danakjc492bf82020-09-09 20:02:44216 // Optional URLLoaderFactory to facilitate blob URL loading.
217 scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory()
218 const {
219 return blob_url_loader_factory_;
220 }
221 void set_blob_url_loader_factory(
222 scoped_refptr<network::SharedURLLoaderFactory> factory) {
223 blob_url_loader_factory_ = std::move(factory);
224 }
225
Domenic Denicolacc094fb2022-03-16 23:40:57226 bool protect_url_in_navigation_api() {
227 return protect_url_in_navigation_api_;
228 }
229 void set_protect_url_in_navigation_api(bool protect) {
230 protect_url_in_navigation_api_ = protect;
Nate Chapin63db0d12022-01-20 22:03:30231 }
232
Baran Erfani2e9e2ad52024-11-07 19:57:43233 void set_item_sequence_number_for_testing(int64_t item_sequence_number) {
234 item_sequence_number_ = item_sequence_number;
235 }
236
danakjc492bf82020-09-09 20:02:44237 private:
238 friend class base::RefCounted<FrameNavigationEntry>;
239 virtual ~FrameNavigationEntry();
240
241 // WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
242 // Add all new fields to |UpdateEntry|.
243 // TODO(creis): These fields have implications for session restore. This is
244 // currently managed by NavigationEntry, but the logic will move here.
245 // WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
246
247 // See the accessors above for descriptions.
248 std::string frame_unique_name_;
Nate Chapinfbfe5af2021-06-10 17:22:08249
Domenic Denicolacc094fb2022-03-16 23:40:57250 // sequence numbers and the navigation API key are also stored in
251 // |page_state_|. When SetPageState() is called as part of a restore, it also
252 // initializes these.
danakjc492bf82020-09-09 20:02:44253 int64_t item_sequence_number_;
254 int64_t document_sequence_number_;
Domenic Denicolacc094fb2022-03-16 23:40:57255 std::string navigation_api_key_;
Nate Chapinfbfe5af2021-06-10 17:22:08256
Kevin McNee803757472023-08-22 20:50:11257 // TODO(nasko, creis): The SiteInstance of a FrameNavigationEntry should
258 // not change once it has been assigned. See https://crbug.com/849430.
danakjc492bf82020-09-09 20:02:44259 scoped_refptr<SiteInstanceImpl> site_instance_;
260 // This member is cleared at commit time and is not persisted.
261 scoped_refptr<SiteInstanceImpl> source_site_instance_;
262 GURL url_;
263 // For a committed navigation, holds the origin of the resulting document.
264 // TODO(nasko): This should be possible to calculate at ReadyToCommit time
265 // and verified when receiving the DidCommit IPC.
Arthur Sonzognic686e8f2024-01-11 08:36:37266 std::optional<url::Origin> committed_origin_;
danakjc492bf82020-09-09 20:02:44267 Referrer referrer_;
Arthur Sonzognic686e8f2024-01-11 08:36:37268 std::optional<url::Origin> initiator_origin_;
269 std::optional<GURL> initiator_base_url_;
danakjc492bf82020-09-09 20:02:44270 // This is used when transferring a pending entry from one process to another.
271 // We also send the main frame's redirect chain through session sync for
272 // offline analysis.
273 // It is preserved after commit but should not be persisted.
274 std::vector<GURL> redirect_chain_;
275 // TODO(creis): Change this to FrameState.
Miyoung Shin5d77f72072020-10-09 15:14:20276 blink::PageState page_state_;
Avi Drissman78865bbb2024-08-22 20:57:19277 // TODO(creis): Persist bindings_. https://crbug.com/40076915.
278 std::optional<BindingsPolicySet> bindings_;
danakjc492bf82020-09-09 20:02:44279 std::string method_;
280 int64_t post_id_;
281 scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory_;
282
Alison Gale770f3fc2024-04-27 00:39:58283 // TODO(crbug.com/40053667): Persist these policies.
Titouan Rigoudy6ec70402021-02-02 15:42:19284 std::unique_ptr<PolicyContainerPolicies> policy_container_policies_;
Nate Chapin63db0d12022-01-20 22:03:30285
286 // If the document represented by this FNE hid its full url from appearing
287 // in a referrer via a "no-referrer" or "origin" referrer policy, this URL
Domenic Denicolacc094fb2022-03-16 23:40:57288 // will be hidden from navigation API history entries as well.
289 bool protect_url_in_navigation_api_;
danakjc492bf82020-09-09 20:02:44290};
291
292} // namespace content
293
294#endif // CONTENT_BROWSER_RENDERER_HOST_FRAME_NAVIGATION_ENTRY_H_