1 // Copyright (c) 2012 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 #ifndef CONTENT_PUBLIC_BROWSER_SITE_INSTANCE_H_
6 #define CONTENT_PUBLIC_BROWSER_SITE_INSTANCE_H_
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 
11 #include "base/memory/ref_counted.h"
12 #include "content/common/content_export.h"
13 #include "url/gurl.h"
14 
15 namespace content {
16 class BrowserContext;
17 class RenderProcessHost;
18 
19 ///////////////////////////////////////////////////////////////////////////////
20 // SiteInstance interface.
21 //
22 // A SiteInstance represents a group of web pages that must live in the same
23 // renderer process.  Pages able to synchronously script each other will always
24 // be placed in the same SiteInstance.  Pages unable to synchronously script
25 // each other may also be placed in the same SiteInstance, as determined by the
26 // process model.
27 //
28 // A page's SiteInstance is determined by a combination of where the page comes
29 // from (the site) and which frames have references to each other (the
30 // instance).  Here, a "site" is similar to the page's origin but includes only
31 // the registered domain name and scheme, not the port or subdomains.  This
32 // accounts for the fact that changes to document.domain allow similar origin
33 // pages with different ports or subdomains to script each other.  An "instance"
34 // includes all frames that might be able to script each other because of how
35 // they were created (e.g., window.open or targeted links).  We represent
36 // instances using the BrowsingInstance class.
37 //
38 // Four process models are currently supported:
39 //
40 // PROCESS PER SITE INSTANCE (the current default): SiteInstances are created
41 // (1) when the user manually creates a new tab (which also creates a new
42 // BrowsingInstance), and (2) when the user navigates across site boundaries
43 // (which uses the same BrowsingInstance).  If the user navigates within a site,
44 // the same SiteInstance is used.  Caveat: we currently allow renderer-initiated
45 // cross-site navigations to stay in the same SiteInstance, to preserve
46 // compatibility in cases like cross-site iframes that open popups.  This means
47 // that most SiteInstances will contain pages from multiple sites.
48 //
49 // SITE PER PROCESS (currently experimental): is the most granular process
50 // model and is made possible by our support for out-of-process iframes.  A
51 // subframe will be given a different SiteInstance if its site differs from the
52 // containing document.  Cross-site navigation of top-level frames or subframes
53 // will trigger a change of SiteInstances, even if the navigation is renderer
54 // initiated.  In this model, each process can be dedicated to documents from
55 // just one site, allowing the same origin policy to be enforced by the sandbox.
56 //
57 // PROCESS PER TAB: SiteInstances are created when the user manually creates a
58 // new tab, but not when navigating across site boundaries (unless a process
59 // swap is required for security reasons, such as navigating from a privileged
60 // WebUI page to a normal web page).  This corresponds to one process per
61 // BrowsingInstance.
62 //
63 // PROCESS PER SITE: We consolidate all SiteInstances for a given site into the
64 // same process, throughout the entire browser context.  This ensures that only
65 // one process will be used for each site.  Note that there is no strict process
66 // isolation of sites in this mode, so a given SiteInstance can still contain
67 // pages from multiple sites.
68 //
69 // Each NavigationEntry for a WebContents points to the SiteInstance that
70 // rendered it.  Each RenderFrameHost also points to the SiteInstance that it is
71 // associated with.  A SiteInstance keeps track of the number of these
72 // references and deletes itself when the count goes to zero.  This means that
73 // a SiteInstance is only live as long as it is accessible, either from new
74 // tabs with no NavigationEntries or in NavigationEntries in the history.
75 //
76 ///////////////////////////////////////////////////////////////////////////////
77 class CONTENT_EXPORT SiteInstance : public base::RefCounted<SiteInstance> {
78  public:
79   // Returns a unique ID for this SiteInstance.
80   virtual int32_t GetId() = 0;
81 
82   // Returns a unique ID for the BrowsingInstance (i.e., group of related
83   // browsing contexts) to which this SiteInstance belongs. This allows callers
84   // to identify which SiteInstances can asynchronously script each other.
85   virtual int32_t GetBrowsingInstanceId() = 0;
86 
87   // Whether this SiteInstance has a running process associated with it.
88   // This may return true before the first call to GetProcess(), in cases where
89   // we use process-per-site and there is an existing process available.
90   virtual bool HasProcess() = 0;
91 
92   // Returns the current RenderProcessHost being used to render pages for this
93   // SiteInstance.  If there is no RenderProcessHost (because either none has
94   // yet been created or there was one but it was cleanly destroyed (e.g. when
95   // it is not actively being used), then this method will create a new
96   // RenderProcessHost (and a new ID).  Note that renderer process crashes leave
97   // the current RenderProcessHost (and ID) in place.
98   //
99   // For sites that require process-per-site mode (e.g., WebUI), this will
100   // ensure only one RenderProcessHost for the site exists within the
101   // BrowserContext.
102   virtual content::RenderProcessHost* GetProcess() = 0;
103 
104   // Browser context to which this SiteInstance (and all related
105   // SiteInstances) belongs.
106   virtual content::BrowserContext* GetBrowserContext() = 0;
107 
108   // Get the web site that this SiteInstance is rendering pages for. This
109   // includes the scheme and registered domain, but not the port.
110   //
111   // NOTE: In most cases, code should be performing checks against the origin
112   // returned by |RenderFrameHost::GetLastCommittedOrigin()|. In contrast, the
113   // GURL returned by |GetSiteURL()| should not be considered authoritative
114   // because:
115   // - a SiteInstance can host pages from multiple sites if "site per process"
116   //   is not enabled and the SiteInstance isn't hosting pages that require
117   //   process isolation (e.g. WebUI or extensions)
118   // - even with site per process, the site URL is not an origin: while often
119   //   derived from the origin, it only contains the scheme and the eTLD + 1,
120   //   i.e. an origin with the host "deeply.nested.subdomain.example.com"
121   //   corresponds to a site URL with the host "example.com".
122   virtual const GURL& GetSiteURL() = 0;
123 
124   // Gets a SiteInstance for the given URL that shares the current
125   // BrowsingInstance, creating a new SiteInstance if necessary.  This ensures
126   // that a BrowsingInstance only has one SiteInstance per site, so that pages
127   // in a BrowsingInstance have the ability to script each other.
128   virtual scoped_refptr<SiteInstance> GetRelatedSiteInstance(
129       const GURL& url) = 0;
130 
131   // Returns whether the given SiteInstance is in the same BrowsingInstance as
132   // this one.  If so, JavaScript interactions that are permitted across
133   // origins (e.g., postMessage) should be supported.
134   virtual bool IsRelatedSiteInstance(const SiteInstance* instance) = 0;
135 
136   // Returns the total active WebContents count for this SiteInstance and all
137   // related SiteInstances in the same BrowsingInstance.
138   virtual size_t GetRelatedActiveContentsCount() = 0;
139 
140   // Returns true if this SiteInstance is for a site that requires a dedicated
141   // process. This only returns true under the "site per process" process model.
142   virtual bool RequiresDedicatedProcess() = 0;
143 
144   // Return whether this SiteInstance and the provided |url| are part of the
145   // same web site, for the purpose of assigning them to processes accordingly.
146   // The decision is currently based on the registered domain of the URLs
147   // (google.com, bbc.co.uk), as well as the scheme (https, http). This ensures
148   // that two pages will be in the same process if they can communicate with
149   // other via JavaScript. (e.g., docs.google.com and mail.google.com have DOM
150   // access to each other if they both set their document.domain properties to
151   // google.com.) Note that if the destination is a blank page, we consider
152   // that to be part of the same web site for the purposes for process
153   // assignment.
154   virtual bool IsSameSiteWithURL(const GURL& url) = 0;
155 
156   // Returns true if this object is used for a <webview> guest.
157   virtual bool IsGuest() = 0;
158 
159   // Factory method to create a new SiteInstance.  This will create a new
160   // new BrowsingInstance, so it should only be used when creating a new tab
161   // from scratch (or similar circumstances).
162   //
163   // The render process host factory may be nullptr.  See SiteInstance
164   // constructor.
165   static scoped_refptr<SiteInstance> Create(
166       content::BrowserContext* browser_context);
167 
168   // Factory method to get the appropriate SiteInstance for the given URL, in
169   // a new BrowsingInstance.  Use this instead of Create when you know the URL,
170   // since it allows special site grouping rules to be applied (for example,
171   // to group chrome-ui pages into the same instance).
172   static scoped_refptr<SiteInstance> CreateForURL(
173       content::BrowserContext* browser_context,
174       const GURL& url);
175 
176   // Factory method to create a SiteInstance for a <webview> guest in a new
177   // BrowsingInstance.
178   // TODO(734722): Replace this method once SecurityPrincipal is available.
179   static scoped_refptr<SiteInstance> CreateForGuest(
180       content::BrowserContext* browser_context,
181       const GURL& guest_site_url);
182 
183   // Determine if a URL should "use up" a site.  URLs such as about:blank or
184   // chrome-native:// leave the site unassigned.
185   static bool ShouldAssignSiteForURL(const GURL& url);
186 
187   // Returns the site for the given URL, which includes only the scheme and
188   // registered domain.  Returns an empty GURL if the URL has no host. Prior to
189   // determining the site, |url| is resolved to an effective URL via
190   // ContentBrowserClient::GetEffectiveURL().
191   static GURL GetSiteForURL(BrowserContext* context, const GURL& url);
192 
193   // Starts requiring a dedicated process for |url|'s site.  On platforms where
194   // strict site isolation is disabled, this may be used as a runtime signal
195   // that a certain site should become process-isolated, because its security
196   // is important to the user (e.g., if the user has typed a password on that
197   // site).  The site will be determined from |url|'s scheme and eTLD+1. If
198   // |context| is non-null, the site will be isolated only within that
199   // BrowserContext; if |context| is null, the site will be isolated globally
200   // for all BrowserContexts.
201   //
202   // Note that this has no effect if site isolation is turned off, such as via
203   // the kDisableSiteIsolation cmdline flag or enterprise policy -- see also
204   // SiteIsolationPolicy::AreDynamicIsolatedOriginsEnabled().
205   //
206   // Currently this function assumes that the site is added *persistently*: it
207   // will ask the embedder to save the site as part of profile data for
208   // |context|, so that it survives restarts.  The site will be cleared from
209   // profile data if the user clears browsing data.  Future uses of this
210   // function may want to avoid persistence by passing in a new flag.
211   static void StartIsolatingSite(BrowserContext* context, const GURL& url);
212 
213  protected:
214   friend class base::RefCounted<SiteInstance>;
215 
SiteInstance()216   SiteInstance() {}
~SiteInstance()217   virtual ~SiteInstance() {}
218 };
219 
220 }  // namespace content.
221 
222 #endif  // CONTENT_PUBLIC_BROWSER_SITE_INSTANCE_H_
223