OLD | NEW |
---|---|
(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 | |
OLD | NEW |