blob: 832d8dbf1bbb6297ff3451716d041129b507aec1 [file] [log] [blame]
license.botbf09a502008-08-24 00:55:551// Copyright (c) 2006-2008 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.
initial.commit09911bf2008-07-26 23:55:294
[email protected]f3ec7742009-01-15 00:59:165#include "chrome/browser/tab_contents/site_instance.h"
initial.commit09911bf2008-07-26 23:55:296
[email protected]8c8657d62009-01-16 18:31:267#include "chrome/browser/renderer_host/browser_render_process_host.h"
initial.commit09911bf2008-07-26 23:55:298#include "net/base/registry_controlled_domain.h"
9
10SiteInstance::~SiteInstance() {
11 // Now that no one is referencing us, we can safely remove ourselves from
12 // the BrowsingInstance. Any future visits to a page from this site
13 // (within the same BrowsingInstance) can safely create a new SiteInstance.
14 if (has_site_)
15 browsing_instance_->UnregisterSiteInstance(this);
16}
17
18RenderProcessHost* SiteInstance::GetProcess() {
19 RenderProcessHost* process = NULL;
20 if (process_host_id_ != -1)
21 process = RenderProcessHost::FromID(process_host_id_);
22
23 // Create a new process if ours went away or was reused.
24 if (!process) {
25 // See if we should reuse an old process
26 if (RenderProcessHost::ShouldTryToUseExistingProcessHost())
27 process = RenderProcessHost::GetExistingProcessHost(
28 browsing_instance_->profile());
29
30 // Otherwise (or if that fails), create a new one.
[email protected]a6df5112009-01-21 23:50:1531 if (!process) {
32 if (render_process_host_factory_) {
33 process = render_process_host_factory_->CreateRenderProcessHost(
34 browsing_instance_->profile());
35 } else {
36 process = new BrowserRenderProcessHost(browsing_instance_->profile());
37 }
38 }
initial.commit09911bf2008-07-26 23:55:2939
40 // Update our host ID, so all pages in this SiteInstance will use
41 // the correct process.
42 process_host_id_ = process->host_id();
43
44 // Make sure the process starts at the right max_page_id
45 process->UpdateMaxPageID(max_page_id_);
46 }
47 DCHECK(process);
48
49 return process;
50}
51
52void SiteInstance::SetSite(const GURL& url) {
53 // A SiteInstance's site should not change.
54 // TODO(creis): When following links or script navigations, we can currently
55 // render pages from other sites in this SiteInstance. This will eventually
56 // be fixed, but until then, we should still not set the site of a
57 // SiteInstance more than once.
58 DCHECK(!has_site_);
59
60 // Remember that this SiteInstance has been used to load a URL, even if the
61 // URL is invalid.
62 has_site_ = true;
63 site_ = GetSiteForURL(url);
64
65 // Now that we have a site, register it with the BrowsingInstance. This
66 // ensures that we won't create another SiteInstance for this site within
67 // the same BrowsingInstance, because all same-site pages within a
68 // BrowsingInstance can script each other.
69 browsing_instance_->RegisterSiteInstance(this);
70}
71
72bool SiteInstance::HasRelatedSiteInstance(const GURL& url) {
73 return browsing_instance_->HasSiteInstance(url);
74}
75
76SiteInstance* SiteInstance::GetRelatedSiteInstance(const GURL& url) {
77 return browsing_instance_->GetSiteInstanceForURL(url);
78}
79
80/*static*/
81SiteInstance* SiteInstance::CreateSiteInstance(Profile* profile) {
82 return new SiteInstance(new BrowsingInstance(profile));
83}
84
85/*static*/
86GURL SiteInstance::GetSiteForURL(const GURL& url) {
87 // URLs with no host should have an empty site.
88 GURL site;
89
90 // TODO(creis): For many protocols, we should just treat the scheme as the
[email protected]76a010b2008-12-07 23:48:0391 // site, since there is no host. e.g., file:, about:, chrome:
initial.commit09911bf2008-07-26 23:55:2992
93 // If the url has a host, then determine the site.
94 if (url.has_host()) {
[email protected]6705b232008-11-26 00:16:5195 // Only keep the scheme and registered domain as given by GetOrigin. This
96 // may also include a port, which we need to drop.
initial.commit09911bf2008-07-26 23:55:2997 site = url.GetOrigin();
98
[email protected]6705b232008-11-26 00:16:5199 // Remove port, if any.
100 if (site.has_port()) {
101 GURL::Replacements rep;
102 rep.ClearPort();
103 site = site.ReplaceComponents(rep);
104 }
105
initial.commit09911bf2008-07-26 23:55:29106 // If this URL has a registered domain, we only want to remember that part.
107 std::string domain =
[email protected]8ac1a752008-07-31 19:40:37108 net::RegistryControlledDomainService::GetDomainAndRegistry(url);
initial.commit09911bf2008-07-26 23:55:29109 if (!domain.empty()) {
110 GURL::Replacements rep;
111 rep.SetHostStr(domain);
112 site = site.ReplaceComponents(rep);
113 }
114 }
115 return site;
116}
117
118/*static*/
119bool SiteInstance::IsSameWebSite(const GURL& url1, const GURL& url2) {
120 // We infer web site boundaries based on the registered domain name of the
[email protected]6705b232008-11-26 00:16:51121 // top-level page and the scheme. We do not pay attention to the port if
122 // one is present, because pages served from different ports can still
123 // access each other if they change their document.domain variable.
initial.commit09911bf2008-07-26 23:55:29124
125 // We must treat javascript: URLs as part of the same site, regardless of
126 // the site.
127 if (url1.SchemeIs("javascript") || url2.SchemeIs("javascript"))
128 return true;
129
130 // We treat about:crash, about:hang, and about:shorthang as the same site as
131 // any URL, since they are used as demos for crashing/hanging a process.
132 GURL about_crash = GURL("about:crash");
133 GURL about_hang = GURL("about:hang");
134 GURL about_shorthang = GURL("about:shorthang");
135 if (url1 == about_crash || url2 == about_crash ||
136 url1 == about_hang || url2 == about_hang ||
137 url1 == about_shorthang || url2 == about_shorthang)
138 return true;
139
140 // If either URL is invalid, they aren't part of the same site.
141 if (!url1.is_valid() || !url2.is_valid()) {
142 return false;
143 }
144
[email protected]6705b232008-11-26 00:16:51145 // If the schemes differ, they aren't part of the same site.
146 if (url1.scheme() != url2.scheme()) {
initial.commit09911bf2008-07-26 23:55:29147 return false;
148 }
149
[email protected]8ac1a752008-07-31 19:40:37150 return net::RegistryControlledDomainService::SameDomainOrHost(url1, url2);
initial.commit09911bf2008-07-26 23:55:29151}
license.botbf09a502008-08-24 00:55:55152