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

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

Issue 1797363002: "Top Document Isolation" mode (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add missing override Created 4 years, 9 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 2016 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 <string>
6
7 #include "base/command_line.h"
8 #include "content/browser/frame_host/frame_tree_node.h"
9 #include "content/browser/web_contents/web_contents_impl.h"
10 #include "content/public/common/content_switches.h"
11 #include "content/public/test/browser_test_utils.h"
12 #include "content/public/test/content_browser_test.h"
13 #include "content/public/test/content_browser_test_utils.h"
14 #include "content/public/test/test_navigation_observer.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 // TODO(nick): Rename this class/file to match the new switch name.
Charlie Reis 2016/03/25 19:47:13 Yep, worth doing.
ncarter (slow) 2016/03/28 22:00:29 Done.
24 class IsolateTopDocumentBrowserTest : public ContentBrowserTest {
25 public:
26 IsolateTopDocumentBrowserTest() {}
27
28 protected:
29 std::string DepictFrameTree(FrameTreeNode* node) {
30 return visualizer_.DepictFrameTree(node);
31 }
32
33 void SetUpCommandLine(base::CommandLine* command_line) override {
34 command_line->AppendSwitch(switches::kTopDocumentIsolation);
35 }
36
37 void SetUpOnMainThread() override {
38 host_resolver()->AddRule("*", "127.0.0.1");
39 ASSERT_TRUE(embedded_test_server()->Start());
40 SetupCrossSiteRedirector(embedded_test_server());
41 }
42
43 FrameTreeNode* root() {
44 return static_cast<WebContentsImpl*>(shell()->web_contents())
45 ->GetFrameTree()
46 ->root();
47 }
48
49 void GoBack() {
50 TestNavigationObserver back_load_observer(shell()->web_contents());
51 shell()->web_contents()->GetController().GoBack();
52 back_load_observer.Wait();
53 }
54
55 Shell* OpenPopup(FrameTreeNode* opener, const std::string& url) {
56 GURL gurl =
57 opener->current_frame_host()->GetLastCommittedURL().Resolve(url);
58 return content::OpenPopup(opener->current_frame_host(), gurl, "_blank");
59 }
60
61 private:
62 FrameTreeVisualizer visualizer_;
63 };
64
65 IN_PROC_BROWSER_TEST_F(IsolateTopDocumentBrowserTest, SameSiteDeeplyNested) {
66 GURL main_url(embedded_test_server()->GetURL(
67 "a.com", "/cross_site_iframe_factory.html?a(a,a(a,a(a)))"));
68
69 NavigateToURL(shell(), main_url);
70
71 EXPECT_EQ(
72 " Site A\n"
73 " |--Site A\n"
74 " +--Site A\n"
75 " |--Site A\n"
76 " +--Site A\n"
77 " +--Site A\n"
78 "Where A = http://a.com/",
79 DepictFrameTree(root()));
80 }
81
82 IN_PROC_BROWSER_TEST_F(IsolateTopDocumentBrowserTest, CrossSiteDeeplyNested) {
83 GURL main_url(embedded_test_server()->GetURL(
84 "a.com", "/cross_site_iframe_factory.html?a(b(c(d(b))))"));
85
86 NavigateToURL(shell(), main_url);
87
88 EXPECT_EQ(
89 " Site A ------------ proxies for B\n"
90 " +--Site B ------- proxies for A\n"
91 " +--Site B -- proxies for A\n"
92 " +--Site B -- proxies for A\n"
93 " +--Site B -- proxies for A\n"
94 "Where A = http://a.com/\n"
95 " B = default subframe process",
96 DepictFrameTree(root()));
97 }
98
99 IN_PROC_BROWSER_TEST_F(IsolateTopDocumentBrowserTest, ReturnToTopSite) {
100 GURL main_url(embedded_test_server()->GetURL(
101 "a.com", "/cross_site_iframe_factory.html?a(b(a(c)))"));
102
103 NavigateToURL(shell(), main_url);
104
105 EXPECT_EQ(
106 " Site A ------------ proxies for B\n"
107 " +--Site B ------- proxies for A\n"
108 " +--Site A -- proxies for B\n"
109 " +--Site B -- proxies for A\n"
110 "Where A = http://a.com/\n"
111 " B = default subframe process",
112 DepictFrameTree(root()));
113 }
114
115 IN_PROC_BROWSER_TEST_F(IsolateTopDocumentBrowserTest, NavigateToSubframeSite) {
116 GURL ab_url(embedded_test_server()->GetURL(
117 "a.com", "/cross_site_iframe_factory.html?a(b)"));
118 GURL ba_url(embedded_test_server()->GetURL(
119 "b.com", "/cross_site_iframe_factory.html?b(a, c)"));
120
121 NavigateToURL(shell(), ab_url);
122
123 EXPECT_EQ(
124 " Site A ------------ proxies for B\n"
125 " +--Site B ------- proxies for A\n"
126 "Where A = http://a.com/\n"
127 " B = default subframe process",
128 DepictFrameTree(root()));
129
130 NavigateToURL(shell(), ba_url);
131
132 EXPECT_EQ(
133 " Site C ------------ proxies for B\n"
134 " |--Site B ------- proxies for C\n"
135 " +--Site B ------- proxies for C\n"
136 "Where B = default subframe process\n"
137 " C = http://b.com/",
138 DepictFrameTree(root()));
139 }
140
141 IN_PROC_BROWSER_TEST_F(IsolateTopDocumentBrowserTest,
142 NavigateToSubframeSiteWithPopup) {
143 // A(B) -> B(A), but while a separate B(A) popup exists.
144 GURL ab_url(embedded_test_server()->GetURL(
145 "a.com", "/cross_site_iframe_factory.html?a(b)"));
146
147 NavigateToURL(shell(), ab_url);
148
149 EXPECT_EQ(
150 " Site A ------------ proxies for B\n"
151 " +--Site B ------- proxies for A\n"
152 "Where A = http://a.com/\n"
153 " B = default subframe process",
154 DepictFrameTree(root()));
155
156 Shell* popup =
157 OpenPopup(root()->child_at(0), "/cross_site_iframe_factory.html?b(a)");
158 FrameTreeNode* popup_root =
159 static_cast<WebContentsImpl*>(popup->web_contents())
160 ->GetFrameTree()
161 ->root();
162
163 EXPECT_EQ(
Charlie Reis 2016/03/25 19:47:12 Maybe add a comment about how (at least for now) w
ncarter (slow) 2016/03/28 22:00:29 Done.
164 " Site B\n"
165 " +--Site B\n"
166 "Where B = default subframe process",
167 DepictFrameTree(popup_root));
168
169 GURL ba_url(embedded_test_server()->GetURL(
170 "b.com", "/cross_site_iframe_factory.html?b(a, c)"));
171 NavigateToURL(shell(), ba_url);
172
173 EXPECT_EQ(
Charlie Reis 2016/03/25 19:47:13 Let's add a comment here as well, saying we're ok
ncarter (slow) 2016/03/28 22:00:29 Done.
174 " Site B\n"
175 " +--Site B\n"
176 "Where B = default subframe process",
177 DepictFrameTree(popup_root));
178 EXPECT_EQ(
179 " Site C ------------ proxies for B\n"
180 " |--Site B ------- proxies for C\n"
181 " +--Site B ------- proxies for C\n"
182 "Where B = default subframe process\n"
183 " C = http://b.com/",
184 DepictFrameTree(root()));
185
186 // Navigate the popup to a new site.
187 GURL c_url(embedded_test_server()->GetURL(
188 "c.com", "/cross_site_iframe_factory.html?c(c, c, c, c)"));
189 NavigateToURL(popup, c_url);
190 EXPECT_EQ(
191 " Site D ------------ proxies for B\n"
192 " |--Site D ------- proxies for B\n"
193 " |--Site D ------- proxies for B\n"
194 " |--Site D ------- proxies for B\n"
195 " +--Site D ------- proxies for B\n"
196 "Where B = default subframe process\n"
197 " D = http://c.com/",
198 DepictFrameTree(popup_root));
199 NavigateToURL(shell(), c_url);
200 EXPECT_EQ(
201 " Site D\n"
202 " |--Site D\n"
203 " |--Site D\n"
204 " |--Site D\n"
205 " +--Site D\n"
206 "Where D = http://c.com/",
207 DepictFrameTree(popup_root));
208 EXPECT_EQ(
209 " Site D\n"
210 " |--Site D\n"
211 " |--Site D\n"
212 " |--Site D\n"
213 " +--Site D\n"
214 "Where D = http://c.com/",
215 DepictFrameTree(root()));
216 }
217
218 IN_PROC_BROWSER_TEST_F(IsolateTopDocumentBrowserTest,
219 NavigateToSubframeSiteWithPopup2) {
220 // A(B, C) -> C(A, B), but while a separate C(A) popup exists.
221 GURL abb_url(embedded_test_server()->GetURL(
222 "a.com", "/cross_site_iframe_factory.html?a(b, b)"));
223
224 NavigateToURL(shell(), abb_url);
225
226 EXPECT_EQ(
227 " Site A ------------ proxies for B\n"
228 " |--Site B ------- proxies for A\n"
229 " +--Site B ------- proxies for A\n"
230 "Where A = http://a.com/\n"
231 " B = default subframe process",
232 DepictFrameTree(root()));
233
234 // A(B, B) -> A(B, C)
235 GURL c_url(embedded_test_server()->GetURL(
236 "c.com", "/cross_site_iframe_factory.html?c"));
237 NavigateFrameToURL(root()->child_at(1), c_url);
238
239 EXPECT_EQ(
240 " Site A ------------ proxies for B\n"
241 " |--Site B ------- proxies for A\n"
242 " +--Site B ------- proxies for A\n"
243 "Where A = http://a.com/\n"
244 " B = default subframe process",
245 DepictFrameTree(root()));
246
247 // Subframe C creates C(A) popup.
248 Shell* popup =
249 OpenPopup(root()->child_at(1), "/cross_site_iframe_factory.html?c(a)");
250
251 FrameTreeNode* popup_root =
252 static_cast<WebContentsImpl*>(popup->web_contents())
253 ->GetFrameTree()
254 ->root();
255
256 // The popup must stay in the default subframe process.
257 EXPECT_EQ(
258 " Site B\n"
259 " +--Site B\n"
260 "Where B = default subframe process",
261 DepictFrameTree(popup_root));
262
263 // Because of the existing popup, this navigation needs to stay in the 3rd
264 // party process as well.
Charlie Reis 2016/03/25 19:47:13 s/3rd party/subframe/ Also, this comment disagree
ncarter (slow) 2016/03/28 22:00:29 Done. I also clarified what the difference is bet
265 GURL ba_url(embedded_test_server()->GetURL(
Charlie Reis 2016/03/25 19:47:12 nit: ca_url?
ncarter (slow) 2016/03/28 22:00:28 Done.
266 "c.com", "/cross_site_iframe_factory.html?c(a, b)"));
267 NavigateToURL(shell(), ba_url);
268
269 // TODO(nick): This c.com navigation currently breaks out of the default
270 // subframe process, even though that process houses a c.com pop-up. Bug or
271 // feature?
Charlie Reis 2016/03/25 19:47:12 I think this is probably ok for now. The subframe
ncarter (slow) 2016/03/28 22:00:28 Done.
272 EXPECT_EQ(
273 " Site C ------------ proxies for B\n"
274 " |--Site B ------- proxies for C\n"
275 " +--Site B ------- proxies for C\n"
276 "Where B = default subframe process\n"
277 " C = http://c.com/",
278 DepictFrameTree(root()));
279
280 // c.com popup should remain where it was, in the subframe process.
Charlie Reis 2016/03/25 19:47:12 Is there a reason to check this? We haven't chang
ncarter (slow) 2016/03/28 22:00:29 Yes. Proxies could have been created.
Charlie Reis 2016/03/29 17:17:12 Acknowledged.
281 EXPECT_EQ(
282 " Site B\n"
283 " +--Site B\n"
284 "Where B = default subframe process",
285 DepictFrameTree(popup_root));
286 EXPECT_EQ(nullptr, popup_root->opener());
287
288 // If we navigate the popup to a new site, it ought to transfer processes.
289 GURL d_url(embedded_test_server()->GetURL(
290 "d.com", "/cross_site_iframe_factory.html?d"));
291 NavigateToURL(popup, d_url);
292 EXPECT_EQ(
293 " Site D ------------ proxies for B\n"
294 "Where B = default subframe process\n"
295 " D = http://d.com/",
296 DepictFrameTree(popup_root));
297 NavigateToURL(shell(), d_url);
298 EXPECT_EQ(
299 " Site D\n"
300 "Where D = http://d.com/",
301 DepictFrameTree(popup_root));
302 EXPECT_EQ(
303 " Site D\n"
304 "Where D = http://d.com/",
305 DepictFrameTree(root()));
306 }
307
308 IN_PROC_BROWSER_TEST_F(IsolateTopDocumentBrowserTest, FramesForSitesInHistory) {
309 // First, do a series of navigations.
310 NavigateToURL(shell(), embedded_test_server()->GetURL(
311 "a.com", "/cross_site_iframe_factory.html?a"));
312 EXPECT_EQ(
313 " Site A\n"
314 "Where A = http://a.com/",
315 DepictFrameTree(root()));
316 NavigateToURL(shell(), embedded_test_server()->GetURL(
317 "b.com", "/cross_site_iframe_factory.html?b"));
318
319 // TODO(nick): Without --isolate-top-document, we would not swap processes
Charlie Reis 2016/03/25 19:47:12 nit: --top-document-isolation, here and below.
ncarter (slow) 2016/03/28 22:00:29 Done.
320 // for these cross-site navigations. What should the behavior be here, for
321 // --isolate-top-document?
Charlie Reis 2016/03/25 19:47:12 I don't follow. We do swap processes for top-leve
ncarter (slow) 2016/03/28 22:00:29 My original prototype was based on making the top
322 EXPECT_EQ(
323 " Site B\n"
324 "Where B = http://b.com/",
325 DepictFrameTree(root()));
326 NavigateToURL(shell(), embedded_test_server()->GetURL(
327 "c.com", "/cross_site_iframe_factory.html?c"));
328 EXPECT_EQ(
329 " Site C\n"
330 "Where C = http://c.com/",
331 DepictFrameTree(root()));
332
333 // Now, navigate to a fourth site with iframes to the sites in the history.
334 NavigateToURL(shell(),
335 embedded_test_server()->GetURL(
336 "d.com", "/cross_site_iframe_factory.html?d(a,b,c)"));
337
338 // TODO(nick): These subframes ought to end up in the third-party process,
Xiaocheng 2016/03/25 08:30:52 nit: This TODO can be removed now.
ncarter (slow) 2016/03/28 22:00:29 Done.
339 // but because we cache the SiteInstances in the navigation entries, we
340 // can't place these subframes into the siteinstance for 3rd party frames.
341 EXPECT_EQ(
342 " Site D ------------ proxies for E\n"
343 " |--Site E ------- proxies for D\n"
344 " |--Site E ------- proxies for D\n"
345 " +--Site E ------- proxies for D\n"
346 "Where D = http://d.com/\n"
347 " E = default subframe process",
348 DepictFrameTree(root()));
349
350 // Now try going back.
351 GoBack();
352 EXPECT_EQ(
353 " Site C\n"
354 "Where C = http://c.com/",
355 DepictFrameTree(root()));
356 GoBack();
357 EXPECT_EQ(
358 " Site B\n"
359 "Where B = http://b.com/",
360 DepictFrameTree(root()));
361 GoBack();
362 EXPECT_EQ(
363 " Site A\n"
364 "Where A = http://a.com/",
365 DepictFrameTree(root()));
366 }
367
368 IN_PROC_BROWSER_TEST_F(IsolateTopDocumentBrowserTest, CrossSiteAtLevelTwo) {
369 GURL main_url(embedded_test_server()->GetURL(
370 "a.com", "/cross_site_iframe_factory.html?a(a(b, a))"));
371
372 NavigateToURL(shell(), main_url);
373
374 EXPECT_EQ(
375 " Site A ------------ proxies for B\n"
376 " +--Site A ------- proxies for B\n"
377 " |--Site B -- proxies for A\n"
378 " +--Site A -- proxies for B\n"
379 "Where A = http://a.com/\n"
380 " B = default subframe process",
381 DepictFrameTree(root()));
382
383 GURL c_url(embedded_test_server()->GetURL(
384 "c.com", "/cross_site_iframe_factory.html?c"));
385 NavigateFrameToURL(root()->child_at(0)->child_at(1), c_url);
386
387 // This navigation should complete using the existing 3rd party SiteInstance.
388 EXPECT_EQ(
389 " Site A ------------ proxies for B\n"
390 " +--Site A ------- proxies for B\n"
391 " |--Site B -- proxies for A\n"
392 " +--Site B -- proxies for A\n"
393 "Where A = http://a.com/\n"
394 " B = default subframe process",
395 DepictFrameTree(root()));
396 }
397
398 IN_PROC_BROWSER_TEST_F(IsolateTopDocumentBrowserTest, PopupAndRedirection) {
399 GURL main_url(embedded_test_server()->GetURL(
400 "page.com", "/cross_site_iframe_factory.html?page(adnetwork)"));
401
402 // User opens page on page.com which contains a subframe from adnetwork.com
Charlie Reis 2016/03/25 19:47:12 nit: End with period.
ncarter (slow) 2016/03/28 22:00:29 Done.
403 NavigateToURL(shell(), main_url);
404
405 EXPECT_EQ(
406 " Site A ------------ proxies for B\n"
407 " +--Site B ------- proxies for A\n"
408 "Where A = http://page.com/\n"
409 " B = default subframe process",
410 DepictFrameTree(root()));
411
412 GURL ad_url(embedded_test_server()->GetURL(
413 "ad.com", "/cross_site_iframe_factory.html?ad"));
414
415 // adnetwork.com retrieves an ad from advertiser (ad.com) and redirects the
416 // subframe to C.
Xiaocheng 2016/03/25 08:30:52 nit: C -> ad.com
ncarter (slow) 2016/03/28 22:00:29 Done.
417 // TODO(nick): Make this a renderer-inititated navigation.
Charlie Reis 2016/03/25 19:47:13 Yep, let's do this. Shouldn't change the outcome,
ncarter (slow) 2016/03/28 22:00:29 Done.
418 NavigateFrameToURL(root()->child_at(0), ad_url);
419
420 // The subframe still uses the same third-party SiteInstance after navigation.
421 EXPECT_EQ(
422 " Site A ------------ proxies for B\n"
423 " +--Site B ------- proxies for A\n"
424 "Where A = http://page.com/\n"
425 " B = default subframe process",
426 DepictFrameTree(root()));
427
428 // User clicks the ad in the subframe, which opens a popup on the ad
429 // platform's domain.
Charlie Reis 2016/03/25 19:47:12 s/platform/network/
ncarter (slow) 2016/03/28 22:00:28 Done.
430 GURL popup_url(embedded_test_server()->GetURL(
431 "adnetwork.com", "/cross_site_iframe_factory.html?adnetwork"));
432 Shell* popup = OpenPopup(root()->child_at(0), popup_url.spec());
433
434 FrameTreeNode* popup_root =
435 static_cast<WebContentsImpl*>(popup->web_contents())
436 ->GetFrameTree()
437 ->root();
438
439 EXPECT_EQ(
Charlie Reis 2016/03/25 19:47:12 Let's add a comment about how we think it's ok for
ncarter (slow) 2016/03/28 22:00:29 Done.
440 " Site A ------------ proxies for B C\n"
441 " +--Site B ------- proxies for A C\n"
442 "Where A = http://page.com/\n"
443 " B = default subframe process\n"
444 " C = http://adnetwork.com/",
445 DepictFrameTree(root()));
446 EXPECT_EQ(
447 " Site C ------------ proxies for B\n"
448 "Where B = default subframe process\n"
449 " C = http://adnetwork.com/",
450 DepictFrameTree(popup_root));
451
452 // The popup redirects itself to the advertiser's website (ad.com).
453 NavigateToURL(popup, ad_url);
454
455 // This must join its same-site opener, in the default subframe SiteInstance.
Charlie Reis 2016/03/25 19:47:12 Wow, I'm impressed this passes. That's a cool con
ncarter (slow) 2016/03/28 22:00:29 Acknowledged.
456 EXPECT_EQ(
457 " Site A ------------ proxies for B\n"
458 " +--Site B ------- proxies for A\n"
459 "Where A = http://page.com/\n"
460 " B = default subframe process",
461 DepictFrameTree(root()));
462 EXPECT_EQ(
463 " Site B\n"
464 "Where B = default subframe process",
465 DepictFrameTree(popup_root));
466 }
467
468 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698