Chromium Code Reviews| OLD | NEW |
|---|---|
| (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 class IsolateTopDocumentBrowserTest : public ContentBrowserTest { | |
| 24 public: | |
| 25 IsolateTopDocumentBrowserTest() {} | |
| 26 | |
| 27 protected: | |
| 28 std::string DepictFrameTree(FrameTreeNode* node) { | |
| 29 return visualizer_.DepictFrameTree(node); | |
| 30 } | |
| 31 | |
| 32 void SetUpCommandLine(base::CommandLine* command_line) override { | |
| 33 command_line->AppendSwitch(switches::kIsolateTopDocument); | |
| 34 } | |
| 35 | |
| 36 void SetUpOnMainThread() { | |
|
Xiaocheng
2016/03/22 04:35:04
Please add |override|.
| |
| 37 host_resolver()->AddRule("*", "127.0.0.1"); | |
| 38 ASSERT_TRUE(embedded_test_server()->Start()); | |
| 39 SetupCrossSiteRedirector(embedded_test_server()); | |
| 40 } | |
| 41 | |
| 42 FrameTreeNode* root() { | |
| 43 return static_cast<WebContentsImpl*>(shell()->web_contents()) | |
| 44 ->GetFrameTree() | |
| 45 ->root(); | |
| 46 } | |
| 47 | |
| 48 void GoBack() { | |
| 49 TestNavigationObserver back_load_observer(shell()->web_contents()); | |
| 50 shell()->web_contents()->GetController().GoBack(); | |
| 51 back_load_observer.Wait(); | |
| 52 } | |
| 53 | |
| 54 private: | |
| 55 FrameTreeVisualizer visualizer_; | |
| 56 }; | |
| 57 | |
| 58 IN_PROC_BROWSER_TEST_F(IsolateTopDocumentBrowserTest, SameSiteDeeplyNested) { | |
| 59 GURL main_url(embedded_test_server()->GetURL( | |
| 60 "a.com", "/cross_site_iframe_factory.html?a(a,a(a,a(a)))")); | |
| 61 | |
| 62 NavigateToURL(shell(), main_url); | |
| 63 | |
| 64 EXPECT_EQ( | |
| 65 " Site A\n" | |
| 66 " |--Site A\n" | |
| 67 " +--Site A\n" | |
| 68 " |--Site A\n" | |
| 69 " +--Site A\n" | |
| 70 " +--Site A\n" | |
| 71 "Where A = http://a.com/", | |
| 72 DepictFrameTree(root())); | |
| 73 } | |
| 74 | |
| 75 IN_PROC_BROWSER_TEST_F(IsolateTopDocumentBrowserTest, CrossSiteDeeplyNested) { | |
| 76 GURL main_url(embedded_test_server()->GetURL( | |
| 77 "a.com", "/cross_site_iframe_factory.html?a(b(c(d(b))))")); | |
| 78 | |
| 79 NavigateToURL(shell(), main_url); | |
| 80 | |
| 81 EXPECT_EQ( | |
| 82 " Site A ------------ proxies for B\n" | |
| 83 " +--Site B ------- proxies for A\n" | |
| 84 " +--Site B -- proxies for A\n" | |
| 85 " +--Site B -- proxies for A\n" | |
| 86 " +--Site B -- proxies for A\n" | |
| 87 "Where A = http://a.com/\n" | |
| 88 " B = http://b.com/ (3rd party)", | |
| 89 DepictFrameTree(root())); | |
| 90 } | |
| 91 | |
| 92 IN_PROC_BROWSER_TEST_F(IsolateTopDocumentBrowserTest, ReturnToTopSite) { | |
| 93 GURL main_url(embedded_test_server()->GetURL( | |
| 94 "a.com", "/cross_site_iframe_factory.html?a(b(a(c)))")); | |
| 95 | |
| 96 NavigateToURL(shell(), main_url); | |
| 97 | |
| 98 EXPECT_EQ( | |
| 99 " Site A ------------ proxies for B\n" | |
| 100 " +--Site B ------- proxies for A\n" | |
| 101 " +--Site A -- proxies for B\n" | |
| 102 " +--Site B -- proxies for A\n" | |
| 103 "Where A = http://a.com/\n" | |
| 104 " B = http://b.com/ (3rd party)", | |
| 105 DepictFrameTree(root())); | |
| 106 } | |
| 107 | |
| 108 IN_PROC_BROWSER_TEST_F(IsolateTopDocumentBrowserTest, NavigateToSubframeSite) { | |
| 109 GURL ab_url(embedded_test_server()->GetURL( | |
| 110 "a.com", "/cross_site_iframe_factory.html?a(b)")); | |
| 111 GURL ba_url(embedded_test_server()->GetURL( | |
| 112 "b.com", "/cross_site_iframe_factory.html?b(a, c)")); | |
| 113 | |
| 114 NavigateToURL(shell(), ab_url); | |
| 115 | |
| 116 EXPECT_EQ( | |
| 117 " Site A ------------ proxies for B\n" | |
| 118 " +--Site B ------- proxies for A\n" | |
| 119 "Where A = http://a.com/\n" | |
| 120 " B = http://b.com/ (3rd party)", | |
| 121 DepictFrameTree(root())); | |
| 122 | |
| 123 NavigateToURL(shell(), ba_url); | |
| 124 | |
| 125 // TODO(nick): The following result is wrong; after navigation, b.com should | |
| 126 // be in a dedicated process; a.com and b.com should share a 3rd party | |
| 127 // subframe process. | |
| 128 EXPECT_EQ( | |
| 129 " Site B ------------ proxies for A\n" | |
| 130 " |--Site A ------- proxies for B\n" | |
| 131 " +--Site B ------- proxies for A\n" | |
| 132 "Where A = http://a.com/\n" | |
| 133 " B = http://b.com/ (3rd party)", | |
| 134 DepictFrameTree(root())); | |
| 135 } | |
| 136 | |
| 137 IN_PROC_BROWSER_TEST_F(IsolateTopDocumentBrowserTest, | |
| 138 NavigateToSubframeSiteWithPopup) { | |
| 139 // A(B) -> B(A), but while a separate B(A) popup exists. | |
| 140 GURL ab_url(embedded_test_server()->GetURL( | |
| 141 "a.com", "/cross_site_iframe_factory.html?a(b)")); | |
| 142 | |
| 143 NavigateToURL(shell(), ab_url); | |
| 144 | |
| 145 EXPECT_EQ( | |
| 146 " Site A ------------ proxies for B\n" | |
| 147 " +--Site B ------- proxies for A\n" | |
| 148 "Where A = http://a.com/\n" | |
| 149 " B = http://b.com/ (3rd party)", | |
| 150 DepictFrameTree(root())); | |
| 151 | |
| 152 ShellAddedObserver new_shell_observer; | |
| 153 EXPECT_TRUE(ExecuteScript( | |
| 154 root()->child_at(0)->current_frame_host(), | |
| 155 "popup = window.open('/cross_site_iframe_factory.html?b(a)');")); | |
| 156 Shell* popup = new_shell_observer.GetShell(); | |
| 157 | |
| 158 FrameTreeNode* popup_root = | |
| 159 static_cast<WebContentsImpl*>(popup->web_contents()) | |
| 160 ->GetFrameTree() | |
| 161 ->root(); | |
| 162 | |
| 163 // TODO(nick): This popup is an example of a main frame that ends up in the | |
| 164 // 3rd party process. This is unavoidable in this case, however. | |
| 165 EXPECT_EQ( | |
| 166 " Site B\n" | |
| 167 "Where B = http://b.com/ (3rd party)", | |
| 168 DepictFrameTree(popup_root)); | |
| 169 | |
| 170 // Because of the existing popup, this navigation needs to stay in the 3rd | |
| 171 // party process as well. | |
| 172 GURL ba_url(embedded_test_server()->GetURL( | |
| 173 "b.com", "/cross_site_iframe_factory.html?b(a, c)")); | |
| 174 NavigateToURL(shell(), ba_url); | |
| 175 | |
| 176 EXPECT_EQ( | |
| 177 " Site B ------------ proxies for A\n" | |
| 178 " +--Site A ------- proxies for B\n" | |
| 179 "Where A = http://a.com/\n" | |
| 180 " B = http://b.com/ (3rd party)", | |
| 181 DepictFrameTree(popup_root)); | |
| 182 EXPECT_EQ( | |
| 183 " Site B ------------ proxies for A\n" | |
| 184 " |--Site A ------- proxies for B\n" | |
| 185 " +--Site B ------- proxies for A\n" | |
| 186 "Where A = http://a.com/\n" | |
| 187 " B = http://b.com/ (3rd party)", | |
| 188 DepictFrameTree(root())); | |
| 189 | |
| 190 // If we navigate the popup to a new site, it ought to leave the 3rd party | |
| 191 // process. | |
| 192 GURL c_url(embedded_test_server()->GetURL( | |
| 193 "c.com", "/cross_site_iframe_factory.html?c(c, c, c, c)")); | |
| 194 NavigateToURL(popup, c_url); | |
| 195 EXPECT_EQ( | |
| 196 " Site C ------------ proxies for A B\n" | |
| 197 " |--Site C ------- proxies for A B\n" | |
| 198 " |--Site C ------- proxies for A B\n" | |
| 199 " |--Site C ------- proxies for A B\n" | |
| 200 " +--Site C ------- proxies for A B\n" | |
| 201 "Where A = http://a.com/\n" | |
| 202 " B = http://b.com/ (3rd party)\n" | |
| 203 " C = http://c.com/", | |
| 204 DepictFrameTree(popup_root)); | |
| 205 NavigateToURL(shell(), c_url); | |
| 206 EXPECT_EQ( | |
| 207 " Site C\n" | |
| 208 " |--Site C\n" | |
| 209 " |--Site C\n" | |
| 210 " |--Site C\n" | |
| 211 " +--Site C\n" | |
| 212 "Where C = http://c.com/", | |
| 213 DepictFrameTree(popup_root)); | |
| 214 EXPECT_EQ( | |
| 215 " Site C\n" | |
| 216 " |--Site C\n" | |
| 217 " |--Site C\n" | |
| 218 " |--Site C\n" | |
| 219 " +--Site C\n" | |
| 220 "Where C = http://c.com/", | |
| 221 DepictFrameTree(root())); | |
| 222 } | |
| 223 | |
| 224 IN_PROC_BROWSER_TEST_F(IsolateTopDocumentBrowserTest, | |
| 225 NavigateToSubframeSiteWithPopup2) { | |
| 226 // A(B, C) -> C(A, B), but while a separate C(A) popup exists. | |
| 227 GURL abb_url(embedded_test_server()->GetURL( | |
| 228 "a.com", "/cross_site_iframe_factory.html?a(b, b)")); | |
| 229 | |
| 230 NavigateToURL(shell(), abb_url); | |
| 231 | |
| 232 EXPECT_EQ( | |
| 233 " Site A ------------ proxies for B\n" | |
| 234 " |--Site B ------- proxies for A\n" | |
| 235 " +--Site B ------- proxies for A\n" | |
| 236 "Where A = http://a.com/\n" | |
| 237 " B = http://b.com/ (3rd party)", | |
| 238 DepictFrameTree(root())); | |
| 239 | |
| 240 // A(B, B) -> A(B, C) | |
| 241 GURL c_url(embedded_test_server()->GetURL( | |
| 242 "c.com", "/cross_site_iframe_factory.html?c")); | |
| 243 NavigateFrameToURL(root()->child_at(1), c_url); | |
| 244 | |
| 245 EXPECT_EQ( | |
| 246 " Site A ------------ proxies for B\n" | |
| 247 " |--Site B ------- proxies for A\n" | |
| 248 " +--Site B ------- proxies for A\n" | |
| 249 "Where A = http://a.com/\n" | |
| 250 " B = http://b.com/ (3rd party)", | |
| 251 DepictFrameTree(root())); | |
| 252 | |
| 253 // Subframe C creates C(A) popup. | |
| 254 ShellAddedObserver new_shell_observer; | |
| 255 EXPECT_TRUE(ExecuteScript( | |
| 256 root()->child_at(0)->current_frame_host(), | |
| 257 "popup = window.open('/cross_site_iframe_factory.html?c(a)');")); | |
| 258 Shell* popup = new_shell_observer.GetShell(); | |
| 259 | |
| 260 FrameTreeNode* popup_root = | |
| 261 static_cast<WebContentsImpl*>(popup->web_contents()) | |
| 262 ->GetFrameTree() | |
| 263 ->root(); | |
| 264 | |
| 265 // TODO(nick): This popup is an example of a main frame that ends up in the | |
| 266 // 3rd party process. This is unavoidable in this case, however. | |
| 267 EXPECT_EQ( | |
| 268 " Site B\n" | |
| 269 "Where B = http://b.com/ (3rd party)", | |
| 270 DepictFrameTree(popup_root)); | |
| 271 | |
| 272 // Because of the existing popup, this navigation needs to stay in the 3rd | |
| 273 // party process as well. | |
| 274 GURL ba_url(embedded_test_server()->GetURL( | |
| 275 "c.com", "/cross_site_iframe_factory.html?c(a, b)")); | |
| 276 NavigateToURL(shell(), ba_url); | |
| 277 | |
| 278 EXPECT_EQ( | |
| 279 " Site B ------------ proxies for A\n" | |
| 280 " +--Site A ------- proxies for B\n" | |
| 281 "Where A = http://a.com/\n" | |
| 282 " B = http://b.com/ (3rd party)", | |
| 283 DepictFrameTree(popup_root)); | |
| 284 | |
| 285 // TODO(nick): This is a bug, caused by the fact that the BrowsingInstance | |
| 286 // didn't record that SiteInstance B is also in use by c.com. | |
| 287 EXPECT_EQ( | |
| 288 " Site C ------------ proxies for A B\n" | |
| 289 " |--Site A ------- proxies for B C\n" | |
| 290 " +--Site B ------- proxies for A C\n" | |
| 291 "Where A = http://a.com/\n" | |
| 292 " B = http://b.com/ (3rd party)\n" | |
| 293 " C = http://c.com/", | |
| 294 DepictFrameTree(root())); | |
| 295 | |
| 296 // If we navigate the popup to a new site, it ought to transfer processes. | |
| 297 GURL d_url(embedded_test_server()->GetURL( | |
| 298 "d.com", "/cross_site_iframe_factory.html?d")); | |
| 299 NavigateToURL(popup, d_url); | |
| 300 EXPECT_EQ( | |
| 301 " Site D ------------ proxies for A B\n" | |
| 302 "Where A = http://a.com/\n" | |
| 303 " B = http://b.com/ (3rd party)\n" | |
| 304 " D = http://d.com/", | |
| 305 DepictFrameTree(popup_root)); | |
| 306 NavigateToURL(shell(), d_url); | |
| 307 EXPECT_EQ( | |
| 308 " Site D\n" | |
| 309 "Where D = http://d.com/", | |
| 310 DepictFrameTree(popup_root)); | |
| 311 EXPECT_EQ( | |
| 312 " Site D\n" | |
| 313 "Where D = http://d.com/", | |
| 314 DepictFrameTree(root())); | |
| 315 } | |
| 316 | |
| 317 IN_PROC_BROWSER_TEST_F(IsolateTopDocumentBrowserTest, FramesForSitesInHistory) { | |
| 318 // First, do a series of navigations. | |
| 319 NavigateToURL(shell(), embedded_test_server()->GetURL( | |
| 320 "a.com", "/cross_site_iframe_factory.html?a")); | |
| 321 EXPECT_EQ( | |
| 322 " Site A\n" | |
| 323 "Where A = http://a.com/", | |
| 324 DepictFrameTree(root())); | |
| 325 NavigateToURL(shell(), embedded_test_server()->GetURL( | |
| 326 "b.com", "/cross_site_iframe_factory.html?b")); | |
| 327 | |
| 328 // TODO(nick): Without --isolate-top-document, we would not swap processes | |
| 329 // for these cross-site navigations. What should the behavior be here, for | |
| 330 // --isolate-top-document? | |
| 331 EXPECT_EQ( | |
| 332 " Site B\n" | |
| 333 "Where B = http://b.com/", | |
| 334 DepictFrameTree(root())); | |
| 335 NavigateToURL(shell(), embedded_test_server()->GetURL( | |
| 336 "c.com", "/cross_site_iframe_factory.html?c")); | |
| 337 EXPECT_EQ( | |
| 338 " Site C\n" | |
| 339 "Where C = http://c.com/", | |
| 340 DepictFrameTree(root())); | |
| 341 | |
| 342 // Now, navigate to a fourth site with iframes to the sites in the history. | |
| 343 NavigateToURL(shell(), | |
| 344 embedded_test_server()->GetURL( | |
| 345 "d.com", "/cross_site_iframe_factory.html?d(a,b,c)")); | |
| 346 | |
| 347 // TODO(nick): These subframes ought to end up in the third-party process, | |
| 348 // but because we cache the SiteInstances in the navigation entries, we | |
| 349 // can't place these subframes into the siteinstance for 3rd party frames. | |
| 350 EXPECT_EQ( | |
| 351 " Site D ------------ proxies for A B C\n" | |
| 352 " |--Site A ------- proxies for B C D\n" | |
| 353 " |--Site B ------- proxies for A C D\n" | |
| 354 " +--Site C ------- proxies for A B D\n" | |
| 355 "Where A = http://a.com/\n" | |
| 356 " B = http://b.com/\n" | |
| 357 " C = http://c.com/\n" | |
| 358 " D = http://d.com/", | |
| 359 DepictFrameTree(root())); | |
| 360 | |
| 361 // Now try going back. | |
| 362 GoBack(); | |
| 363 EXPECT_EQ( | |
| 364 " Site C\n" | |
| 365 "Where C = http://c.com/", | |
| 366 DepictFrameTree(root())); | |
| 367 GoBack(); | |
| 368 EXPECT_EQ( | |
| 369 " Site B\n" | |
| 370 "Where B = http://b.com/", | |
| 371 DepictFrameTree(root())); | |
| 372 GoBack(); | |
| 373 EXPECT_EQ( | |
| 374 " Site A\n" | |
| 375 "Where A = http://a.com/", | |
| 376 DepictFrameTree(root())); | |
| 377 } | |
| 378 | |
| 379 IN_PROC_BROWSER_TEST_F(IsolateTopDocumentBrowserTest, CrossSiteAtLevelTwo) { | |
| 380 GURL main_url(embedded_test_server()->GetURL( | |
| 381 "a.com", "/cross_site_iframe_factory.html?a(a(b, a))")); | |
| 382 | |
| 383 NavigateToURL(shell(), main_url); | |
| 384 | |
| 385 EXPECT_EQ( | |
| 386 " Site A ------------ proxies for B\n" | |
| 387 " +--Site A ------- proxies for B\n" | |
| 388 " |--Site B -- proxies for A\n" | |
| 389 " +--Site A -- proxies for B\n" | |
| 390 "Where A = http://a.com/\n" | |
| 391 " B = http://b.com/ (3rd party)", | |
| 392 DepictFrameTree(root())); | |
| 393 | |
| 394 GURL c_url(embedded_test_server()->GetURL( | |
| 395 "c.com", "/cross_site_iframe_factory.html?c")); | |
| 396 NavigateFrameToURL(root()->child_at(0)->child_at(1), c_url); | |
| 397 | |
| 398 // This navigation should complete using the existing 3rd party SiteInstance. | |
| 399 EXPECT_EQ( | |
| 400 " Site A ------------ proxies for B\n" | |
| 401 " +--Site A ------- proxies for B\n" | |
| 402 " |--Site B -- proxies for A\n" | |
| 403 " +--Site B -- proxies for A\n" | |
| 404 "Where A = http://a.com/\n" | |
| 405 " B = http://b.com/ (3rd party)", | |
| 406 DepictFrameTree(root())); | |
| 407 } | |
| 408 | |
|
Xiaocheng
2016/03/22 04:35:04
Can we add the following test case? It doesn't con
| |
| 409 } // namespace content | |
| OLD | NEW |