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