Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10)

Side by Side Diff: content/browser/isolated_origin_browsertest.cc

Issue 2831683002: Introduce support for origins that require process isolation. (Closed)
Patch Set: Rebase Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 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 #include "content/browser/site_instance_impl.h"
6 #include "content/browser/web_contents/web_contents_impl.h"
7 #include "content/public/browser/render_process_host.h"
8 #include "content/public/common/content_switches.h"
9 #include "content/public/test/browser_test_utils.h"
10 #include "content/public/test/content_browser_test.h"
11 #include "content/public/test/content_browser_test_utils.h"
12 #include "content/public/test/test_frame_navigation_observer.h"
13 #include "content/public/test/test_navigation_observer.h"
14 #include "content/public/test/test_utils.h"
15 #include "content/shell/browser/shell.h"
16 #include "content/test/content_browser_test_utils_internal.h"
17 #include "net/dns/mock_host_resolver.h"
18 #include "net/test/embedded_test_server/embedded_test_server.h"
19 #include "url/gurl.h"
20
21 namespace content {
22
23 class IsolatedOriginTest : public ContentBrowserTest {
24 public:
25 IsolatedOriginTest() {}
26 ~IsolatedOriginTest() override {}
27
28 void SetUpCommandLine(base::CommandLine* command_line) override {
29 ASSERT_TRUE(embedded_test_server()->InitializeAndListen());
30
31 std::string origin_list =
32 embedded_test_server()->GetURL("isolated.foo.com", "/").spec() + "," +
33 embedded_test_server()->GetURL("isolated.bar.com", "/").spec();
34 command_line->AppendSwitchASCII(switches::kIsolateOrigins, origin_list);
35 }
36
37 void SetUpOnMainThread() override {
38 host_resolver()->AddRule("*", "127.0.0.1");
39 embedded_test_server()->StartAcceptingConnections();
40 }
41
42 WebContentsImpl* web_contents() const {
43 return static_cast<WebContentsImpl*>(shell()->web_contents());
44 }
45 };
46
47 // Check that navigating a main frame from an non-isolated origin to an
48 // isolated origin and vice versa swaps processes and uses a new SiteInstance,
49 // both for browser-initiated and renderer-initiated navigations.
50 IN_PROC_BROWSER_TEST_F(IsolatedOriginTest, MainFrameNavigation) {
51 GURL unisolated_url(
52 embedded_test_server()->GetURL("www.foo.com", "/title1.html"));
53 GURL isolated_url(
54 embedded_test_server()->GetURL("isolated.foo.com", "/title2.html"));
55
56 EXPECT_TRUE(NavigateToURL(shell(), unisolated_url));
57
58 // Open a same-site popup to keep the www.foo.com process alive.
59 Shell* popup = OpenPopup(shell(), GURL(url::kAboutBlankURL), "foo");
60 SiteInstance* unisolated_instance =
61 popup->web_contents()->GetMainFrame()->GetSiteInstance();
62
63 // Navigate to an isolated origin and ensure that this ends up in a new
Charlie Reis 2017/05/05 23:18:51 Let's clarify this is a browser-initiated navigati
alexmos 2017/05/16 17:26:37 Done.
64 // process and SiteInstance for isolated.foo.com.
65 EXPECT_TRUE(NavigateToURL(shell(), isolated_url));
66
67 scoped_refptr<SiteInstance> isolated_instance =
68 web_contents()->GetSiteInstance();
69 EXPECT_NE(isolated_instance, unisolated_instance);
70 EXPECT_NE(web_contents()->GetMainFrame()->GetProcess(),
71 popup->web_contents()->GetMainFrame()->GetProcess());
72
73 // The site URL for isolated.foo.com should be the full origin rather than
74 // eTLD+1.
75 EXPECT_EQ(isolated_url.GetOrigin(), isolated_instance->GetSiteURL());
76
77 // Navigate to www.foo.com. This should end up in the |popup|'s process.
Charlie Reis 2017/05/05 23:18:51 And that this is a renderer-initiated navigation.
alexmos 2017/05/16 17:26:37 Done.
78 {
79 TestNavigationObserver observer(web_contents());
80 EXPECT_TRUE(ExecuteScript(
81 web_contents(), "location.href = '" + unisolated_url.spec() + "'"));
82 observer.Wait();
83 }
84
85 EXPECT_EQ(web_contents()->GetSiteInstance(), unisolated_instance);
86 EXPECT_EQ(web_contents()->GetMainFrame()->GetProcess(),
87 popup->web_contents()->GetMainFrame()->GetProcess());
88
89 // Go back and verify that we end up in an isolated process once again.
90 TestNavigationObserver back_observer(web_contents());
91 web_contents()->GetController().GoBack();
92 back_observer.Wait();
93
94 EXPECT_EQ(web_contents()->GetSiteInstance(), isolated_instance);
Charlie Reis 2017/05/05 23:18:51 nit: Swap order (expected, actual)
alexmos 2017/05/16 17:26:37 Done.
95 EXPECT_NE(web_contents()->GetMainFrame()->GetProcess(),
96 popup->web_contents()->GetMainFrame()->GetProcess());
97
98 // Navigate to another isolated origin and ensure there is a different
99 // isolated process.
100 GURL second_isolated_url(
101 embedded_test_server()->GetURL("isolated.bar.com", "/title3.html"));
102 {
103 TestNavigationObserver observer(web_contents());
104 EXPECT_TRUE(
105 ExecuteScript(web_contents(),
106 "location.href = '" + second_isolated_url.spec() + "'"));
107 observer.Wait();
108 }
109
110 EXPECT_EQ(second_isolated_url.GetOrigin(),
111 web_contents()->GetSiteInstance()->GetSiteURL());
112 EXPECT_NE(web_contents()->GetSiteInstance(), isolated_instance);
113 EXPECT_NE(web_contents()->GetSiteInstance(), unisolated_instance);
114 }
115
116 // Check that opening a popup for an isolated origin puts it into a new process
117 // and its own SiteInstance.
118 IN_PROC_BROWSER_TEST_F(IsolatedOriginTest, Popup) {
119 GURL unisolated_url(
120 embedded_test_server()->GetURL("foo.com", "/title1.html"));
121 GURL isolated_url(
122 embedded_test_server()->GetURL("isolated.foo.com", "/title2.html"));
123
124 EXPECT_TRUE(NavigateToURL(shell(), unisolated_url));
125
126 // Open a popup to a URL with an isolated origin and ensure that there was a
127 // process swap.
128 Shell* popup = OpenPopup(shell(), isolated_url, "foo");
129
130 EXPECT_NE(shell()->web_contents()->GetSiteInstance(),
131 popup->web_contents()->GetSiteInstance());
132
133 // The popup's site URL should match the full isolated origin.
134 EXPECT_EQ(isolated_url.GetOrigin(),
135 popup->web_contents()->GetSiteInstance()->GetSiteURL());
136
137 // Now open a second popup from an isolated origin to a URL with an
138 // unisolated origin and ensure that there was another process swap.
139 Shell* popup2 = OpenPopup(popup, unisolated_url, "bar");
140 EXPECT_EQ(shell()->web_contents()->GetSiteInstance(),
141 popup2->web_contents()->GetSiteInstance());
142 EXPECT_NE(popup->web_contents()->GetSiteInstance(),
143 popup2->web_contents()->GetSiteInstance());
144 }
145
146 // Check that navigating a subframe to an isolated origin puts the subframe
147 // into an OOPIF and its own SiteInstance. Also check that the isolated
148 // frame's subframes also end up in correct SiteInstance.
149 IN_PROC_BROWSER_TEST_F(IsolatedOriginTest, Subframe) {
150 GURL top_url(
151 embedded_test_server()->GetURL("www.foo.com", "/page_with_iframe.html"));
152 EXPECT_TRUE(NavigateToURL(shell(), top_url));
153
154 GURL isolated_url(embedded_test_server()->GetURL("isolated.foo.com",
155 "/page_with_iframe.html"));
156
157 FrameTreeNode* root = web_contents()->GetFrameTree()->root();
158 FrameTreeNode* child = root->child_at(0);
159
160 NavigateIframeToURL(web_contents(), "test_iframe", isolated_url);
161 EXPECT_EQ(child->current_url(), isolated_url);
162
163 // Verify that the child frame is an OOPIF with a different SiteInstance.
164 EXPECT_NE(web_contents()->GetSiteInstance(),
165 child->current_frame_host()->GetSiteInstance());
166 EXPECT_TRUE(child->current_frame_host()->IsCrossProcessSubframe());
167 EXPECT_EQ(isolated_url.GetOrigin(),
168 child->current_frame_host()->GetSiteInstance()->GetSiteURL());
169
170 // Verify that the isolated frame's subframe (which starts out at a relative
171 // path) is kept in the isolated parent's SiteInstance.
172 FrameTreeNode* grandchild = child->child_at(0);
173 EXPECT_EQ(child->current_frame_host()->GetSiteInstance(),
174 grandchild->current_frame_host()->GetSiteInstance());
175
176 // Navigating the grandchild to www.foo.com should put it into the top
177 // frame's SiteInstance.
178 GURL non_isolated_url(
179 embedded_test_server()->GetURL("www.foo.com", "/title3.html"));
180 TestFrameNavigationObserver observer(grandchild);
181 EXPECT_TRUE(ExecuteScript(
182 grandchild, "location.href = '" + non_isolated_url.spec() + "';"));
183 observer.Wait();
184 EXPECT_EQ(grandchild->current_url(), non_isolated_url);
185
186 EXPECT_EQ(root->current_frame_host()->GetSiteInstance(),
187 grandchild->current_frame_host()->GetSiteInstance());
188 EXPECT_NE(child->current_frame_host()->GetSiteInstance(),
189 grandchild->current_frame_host()->GetSiteInstance());
190 }
191
192 // Check that when an non-isolated origin foo.com embeds a subframe from an
193 // isolated origin, which then navigates to a non-isolated origin bar.com,
194 // bar.com goes back to the main frame's SiteInstance. See
195 // https://crbug.com/711006.
196 IN_PROC_BROWSER_TEST_F(IsolatedOriginTest,
197 NoOOPIFWhenIsolatedOriginNavigatesToNonIsolatedOrigin) {
198 if (AreAllSitesIsolatedForTesting())
199 return;
200
201 GURL top_url(
202 embedded_test_server()->GetURL("www.foo.com", "/page_with_iframe.html"));
203 EXPECT_TRUE(NavigateToURL(shell(), top_url));
204
205 FrameTreeNode* root = web_contents()->GetFrameTree()->root();
206 FrameTreeNode* child = root->child_at(0);
207
208 GURL isolated_url(embedded_test_server()->GetURL("isolated.foo.com",
209 "/page_with_iframe.html"));
210
211 NavigateIframeToURL(web_contents(), "test_iframe", isolated_url);
212 EXPECT_EQ(child->current_url(), isolated_url);
213
214 // Verify that the child frame is an OOPIF with a different SiteInstance.
215 EXPECT_NE(web_contents()->GetSiteInstance(),
216 child->current_frame_host()->GetSiteInstance());
217 EXPECT_TRUE(child->current_frame_host()->IsCrossProcessSubframe());
218 EXPECT_EQ(isolated_url.GetOrigin(),
219 child->current_frame_host()->GetSiteInstance()->GetSiteURL());
220
221 // Navigate the child frame cross-site, but to a non-isolated origin. When
222 // not in --site-per-process, this should bring the subframe back into the
223 // main frame's SiteInstance.
224 GURL bar_url(embedded_test_server()->GetURL("bar.com", "/title1.html"));
225 EXPECT_FALSE(SiteInstanceImpl::IsIsolatedOrigin(url::Origin(bar_url)));
226 NavigateIframeToURL(web_contents(), "test_iframe", bar_url);
227 EXPECT_EQ(web_contents()->GetSiteInstance(),
228 child->current_frame_host()->GetSiteInstance());
229 EXPECT_FALSE(child->current_frame_host()->IsCrossProcessSubframe());
230 }
231
232 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698