| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <memory> | 5 #include <memory> |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/files/file_path.h" | 8 #include "base/files/file_path.h" |
| 9 #include "base/files/file_util.h" | 9 #include "base/files/file_util.h" |
| 10 #include "base/files/scoped_temp_dir.h" | 10 #include "base/files/scoped_temp_dir.h" |
| 11 #include "base/macros.h" | 11 #include "base/macros.h" |
| 12 #include "base/strings/stringprintf.h" | 12 #include "base/strings/stringprintf.h" |
| 13 #include "content/browser/child_process_security_policy_impl.h" | 13 #include "content/browser/child_process_security_policy_impl.h" |
| 14 #include "content/browser/loader/resource_dispatcher_host_impl.h" | 14 #include "content/browser/loader/resource_dispatcher_host_impl.h" |
| 15 #include "content/public/browser/navigation_entry.h" | 15 #include "content/public/browser/navigation_entry.h" |
| 16 #include "content/public/browser/render_process_host.h" | 16 #include "content/public/browser/render_process_host.h" |
| 17 #include "content/public/browser/resource_dispatcher_host_delegate.h" | 17 #include "content/public/browser/resource_dispatcher_host_delegate.h" |
| 18 #include "content/public/browser/resource_throttle.h" | 18 #include "content/public/browser/resource_throttle.h" |
| 19 #include "content/public/browser/web_contents.h" | 19 #include "content/public/browser/web_contents.h" |
| 20 #include "content/public/common/content_switches.h" |
| 20 #include "content/public/test/browser_test_utils.h" | 21 #include "content/public/test/browser_test_utils.h" |
| 21 #include "content/public/test/content_browser_test.h" | 22 #include "content/public/test/content_browser_test.h" |
| 22 #include "content/public/test/content_browser_test_utils.h" | 23 #include "content/public/test/content_browser_test_utils.h" |
| 23 #include "content/public/test/test_navigation_observer.h" | 24 #include "content/public/test/test_navigation_observer.h" |
| 24 #include "content/shell/browser/shell.h" | 25 #include "content/shell/browser/shell.h" |
| 25 #include "content/shell/browser/shell_content_browser_client.h" | 26 #include "content/shell/browser/shell_content_browser_client.h" |
| 26 #include "content/shell/browser/shell_resource_dispatcher_host_delegate.h" | 27 #include "content/shell/browser/shell_resource_dispatcher_host_delegate.h" |
| 27 #include "content/test/content_browser_test_utils_internal.h" | 28 #include "content/test/content_browser_test_utils_internal.h" |
| 28 #include "net/base/escape.h" | 29 #include "net/base/escape.h" |
| 29 #include "net/dns/mock_host_resolver.h" | 30 #include "net/dns/mock_host_resolver.h" |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 158 | 159 |
| 159 bool ShouldTransferNavigation(bool is_main_frame_navigation) override { | 160 bool ShouldTransferNavigation(bool is_main_frame_navigation) override { |
| 160 // Intentionally cancel the transfer. | 161 // Intentionally cancel the transfer. |
| 161 return false; | 162 return false; |
| 162 } | 163 } |
| 163 | 164 |
| 164 private: | 165 private: |
| 165 DISALLOW_COPY_AND_ASSIGN(NoTransferRequestDelegate); | 166 DISALLOW_COPY_AND_ASSIGN(NoTransferRequestDelegate); |
| 166 }; | 167 }; |
| 167 | 168 |
| 168 class CrossSiteTransferTest : public ContentBrowserTest { | 169 enum class TestParameter { |
| 170 LOADING_WITHOUT_MOJO, |
| 171 LOADING_WITH_MOJO, |
| 172 }; |
| 173 |
| 174 class CrossSiteTransferTest |
| 175 : public ContentBrowserTest, |
| 176 public ::testing::WithParamInterface<TestParameter> { |
| 169 public: | 177 public: |
| 170 CrossSiteTransferTest() : old_delegate_(nullptr) {} | 178 CrossSiteTransferTest() : old_delegate_(nullptr) {} |
| 171 | 179 |
| 172 // ContentBrowserTest implementation: | 180 // ContentBrowserTest implementation: |
| 173 void SetUpOnMainThread() override { | 181 void SetUpOnMainThread() override { |
| 174 BrowserThread::PostTask( | 182 BrowserThread::PostTask( |
| 175 BrowserThread::IO, FROM_HERE, | 183 BrowserThread::IO, FROM_HERE, |
| 176 base::Bind(&CrossSiteTransferTest::InjectResourceDispatcherHostDelegate, | 184 base::Bind(&CrossSiteTransferTest::InjectResourceDispatcherHostDelegate, |
| 177 base::Unretained(this))); | 185 base::Unretained(this))); |
| 178 host_resolver()->AddRule("*", "127.0.0.1"); | 186 host_resolver()->AddRule("*", "127.0.0.1"); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 200 script = base::StringPrintf("location.href = '%s'", url.spec().c_str()); | 208 script = base::StringPrintf("location.href = '%s'", url.spec().c_str()); |
| 201 TestNavigationObserver load_observer(shell()->web_contents(), 1); | 209 TestNavigationObserver load_observer(shell()->web_contents(), 1); |
| 202 bool result = ExecuteScript(window, script); | 210 bool result = ExecuteScript(window, script); |
| 203 EXPECT_TRUE(result); | 211 EXPECT_TRUE(result); |
| 204 if (should_wait_for_navigation) | 212 if (should_wait_for_navigation) |
| 205 load_observer.Wait(); | 213 load_observer.Wait(); |
| 206 } | 214 } |
| 207 | 215 |
| 208 void SetUpCommandLine(base::CommandLine* command_line) override { | 216 void SetUpCommandLine(base::CommandLine* command_line) override { |
| 209 IsolateAllSitesForTesting(command_line); | 217 IsolateAllSitesForTesting(command_line); |
| 218 if (GetParam() == TestParameter::LOADING_WITH_MOJO) { |
| 219 command_line->AppendSwitchASCII(switches::kEnableBlinkFeatures, |
| 220 "LoadingWithMojo"); |
| 221 } |
| 210 } | 222 } |
| 211 | 223 |
| 212 void InjectResourceDispatcherHostDelegate() { | 224 void InjectResourceDispatcherHostDelegate() { |
| 213 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 225 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 214 old_delegate_ = ResourceDispatcherHostImpl::Get()->delegate(); | 226 old_delegate_ = ResourceDispatcherHostImpl::Get()->delegate(); |
| 215 ResourceDispatcherHostImpl::Get()->SetDelegate(&tracking_delegate_); | 227 ResourceDispatcherHostImpl::Get()->SetDelegate(&tracking_delegate_); |
| 216 } | 228 } |
| 217 | 229 |
| 218 void RestoreResourceDisptcherHostDelegate() { | 230 void RestoreResourceDisptcherHostDelegate() { |
| 219 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 231 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 237 DISABLED_ReplaceEntryCrossProcessThenTransfer | 249 DISABLED_ReplaceEntryCrossProcessThenTransfer |
| 238 #define MAYBE_ReplaceEntryCrossProcessTwice \ | 250 #define MAYBE_ReplaceEntryCrossProcessTwice \ |
| 239 DISABLED_ReplaceEntryCrossProcessTwice | 251 DISABLED_ReplaceEntryCrossProcessTwice |
| 240 #else | 252 #else |
| 241 #define MAYBE_ReplaceEntryCrossProcessThenTransfer \ | 253 #define MAYBE_ReplaceEntryCrossProcessThenTransfer \ |
| 242 ReplaceEntryCrossProcessThenTransfer | 254 ReplaceEntryCrossProcessThenTransfer |
| 243 #define MAYBE_ReplaceEntryCrossProcessTwice ReplaceEntryCrossProcessTwice | 255 #define MAYBE_ReplaceEntryCrossProcessTwice ReplaceEntryCrossProcessTwice |
| 244 #endif | 256 #endif |
| 245 // Tests that the |should_replace_current_entry| flag persists correctly across | 257 // Tests that the |should_replace_current_entry| flag persists correctly across |
| 246 // request transfers that began with a cross-process navigation. | 258 // request transfers that began with a cross-process navigation. |
| 247 IN_PROC_BROWSER_TEST_F(CrossSiteTransferTest, | 259 IN_PROC_BROWSER_TEST_P(CrossSiteTransferTest, |
| 248 MAYBE_ReplaceEntryCrossProcessThenTransfer) { | 260 MAYBE_ReplaceEntryCrossProcessThenTransfer) { |
| 249 const NavigationController& controller = | 261 const NavigationController& controller = |
| 250 shell()->web_contents()->GetController(); | 262 shell()->web_contents()->GetController(); |
| 251 | 263 |
| 252 // Navigate to a starting URL, so there is a history entry to replace. | 264 // Navigate to a starting URL, so there is a history entry to replace. |
| 253 GURL url1 = embedded_test_server()->GetURL("/site_isolation/blank.html?1"); | 265 GURL url1 = embedded_test_server()->GetURL("/site_isolation/blank.html?1"); |
| 254 EXPECT_TRUE(NavigateToURL(shell(), url1)); | 266 EXPECT_TRUE(NavigateToURL(shell(), url1)); |
| 255 | 267 |
| 256 // Force all future navigations to transfer. Note that this includes same-site | 268 // Force all future navigations to transfer. Note that this includes same-site |
| 257 // navigiations which may cause double process swaps (via OpenURL and then via | 269 // navigiations which may cause double process swaps (via OpenURL and then via |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 296 EXPECT_EQ(url3, controller.GetEntryAtIndex(1)->GetURL()); | 308 EXPECT_EQ(url3, controller.GetEntryAtIndex(1)->GetURL()); |
| 297 | 309 |
| 298 // Make sure the request succeeded. | 310 // Make sure the request succeeded. |
| 299 EXPECT_TRUE(tracking_delegate().WaitForTrackedURLAndGetCompleted()); | 311 EXPECT_TRUE(tracking_delegate().WaitForTrackedURLAndGetCompleted()); |
| 300 } | 312 } |
| 301 | 313 |
| 302 // Tests that the |should_replace_current_entry| flag persists correctly across | 314 // Tests that the |should_replace_current_entry| flag persists correctly across |
| 303 // request transfers that began with a content-initiated in-process | 315 // request transfers that began with a content-initiated in-process |
| 304 // navigation. This test is the same as the test above, except transfering from | 316 // navigation. This test is the same as the test above, except transfering from |
| 305 // in-process. | 317 // in-process. |
| 306 IN_PROC_BROWSER_TEST_F(CrossSiteTransferTest, | 318 IN_PROC_BROWSER_TEST_P(CrossSiteTransferTest, |
| 307 ReplaceEntryInProcessThenTransfer) { | 319 ReplaceEntryInProcessThenTransfer) { |
| 308 const NavigationController& controller = | 320 const NavigationController& controller = |
| 309 shell()->web_contents()->GetController(); | 321 shell()->web_contents()->GetController(); |
| 310 | 322 |
| 311 // Navigate to a starting URL, so there is a history entry to replace. | 323 // Navigate to a starting URL, so there is a history entry to replace. |
| 312 GURL url = embedded_test_server()->GetURL("/site_isolation/blank.html?1"); | 324 GURL url = embedded_test_server()->GetURL("/site_isolation/blank.html?1"); |
| 313 EXPECT_TRUE(NavigateToURL(shell(), url)); | 325 EXPECT_TRUE(NavigateToURL(shell(), url)); |
| 314 | 326 |
| 315 // Force all future navigations to transfer. Note that this includes same-site | 327 // Force all future navigations to transfer. Note that this includes same-site |
| 316 // navigiations which may cause double process swaps (via OpenURL and then via | 328 // navigiations which may cause double process swaps (via OpenURL and then via |
| (...skipping 20 matching lines...) Expand all Loading... |
| 337 // should not have replaced url3. | 349 // should not have replaced url3. |
| 338 EXPECT_TRUE(controller.GetPendingEntry() == nullptr); | 350 EXPECT_TRUE(controller.GetPendingEntry() == nullptr); |
| 339 EXPECT_EQ(2, controller.GetEntryCount()); | 351 EXPECT_EQ(2, controller.GetEntryCount()); |
| 340 EXPECT_EQ(1, controller.GetCurrentEntryIndex()); | 352 EXPECT_EQ(1, controller.GetCurrentEntryIndex()); |
| 341 EXPECT_EQ(url2, controller.GetEntryAtIndex(0)->GetURL()); | 353 EXPECT_EQ(url2, controller.GetEntryAtIndex(0)->GetURL()); |
| 342 EXPECT_EQ(url3, controller.GetEntryAtIndex(1)->GetURL()); | 354 EXPECT_EQ(url3, controller.GetEntryAtIndex(1)->GetURL()); |
| 343 } | 355 } |
| 344 | 356 |
| 345 // Tests that the |should_replace_current_entry| flag persists correctly across | 357 // Tests that the |should_replace_current_entry| flag persists correctly across |
| 346 // request transfers that cross processes twice from renderer policy. | 358 // request transfers that cross processes twice from renderer policy. |
| 347 IN_PROC_BROWSER_TEST_F(CrossSiteTransferTest, | 359 IN_PROC_BROWSER_TEST_P(CrossSiteTransferTest, |
| 348 MAYBE_ReplaceEntryCrossProcessTwice) { | 360 MAYBE_ReplaceEntryCrossProcessTwice) { |
| 349 const NavigationController& controller = | 361 const NavigationController& controller = |
| 350 shell()->web_contents()->GetController(); | 362 shell()->web_contents()->GetController(); |
| 351 | 363 |
| 352 // Navigate to a starting URL, so there is a history entry to replace. | 364 // Navigate to a starting URL, so there is a history entry to replace. |
| 353 GURL url1 = embedded_test_server()->GetURL("/site_isolation/blank.html?1"); | 365 GURL url1 = embedded_test_server()->GetURL("/site_isolation/blank.html?1"); |
| 354 EXPECT_TRUE(NavigateToURL(shell(), url1)); | 366 EXPECT_TRUE(NavigateToURL(shell(), url1)); |
| 355 | 367 |
| 356 // Navigate to a page on A.com which redirects to B.com with entry | 368 // Navigate to a page on A.com which redirects to B.com with entry |
| 357 // replacement. This will switch processes via OpenURL twice. First to A.com, | 369 // replacement. This will switch processes via OpenURL twice. First to A.com, |
| (...skipping 24 matching lines...) Expand all Loading... |
| 382 // should not have replaced url2b. | 394 // should not have replaced url2b. |
| 383 EXPECT_TRUE(controller.GetPendingEntry() == nullptr); | 395 EXPECT_TRUE(controller.GetPendingEntry() == nullptr); |
| 384 EXPECT_EQ(2, controller.GetEntryCount()); | 396 EXPECT_EQ(2, controller.GetEntryCount()); |
| 385 EXPECT_EQ(1, controller.GetCurrentEntryIndex()); | 397 EXPECT_EQ(1, controller.GetCurrentEntryIndex()); |
| 386 EXPECT_EQ(url2b, controller.GetEntryAtIndex(0)->GetURL()); | 398 EXPECT_EQ(url2b, controller.GetEntryAtIndex(0)->GetURL()); |
| 387 EXPECT_EQ(url3b, controller.GetEntryAtIndex(1)->GetURL()); | 399 EXPECT_EQ(url3b, controller.GetEntryAtIndex(1)->GetURL()); |
| 388 } | 400 } |
| 389 | 401 |
| 390 // Tests that the request is destroyed when a cross process navigation is | 402 // Tests that the request is destroyed when a cross process navigation is |
| 391 // cancelled. | 403 // cancelled. |
| 392 IN_PROC_BROWSER_TEST_F(CrossSiteTransferTest, NoLeakOnCrossSiteCancel) { | 404 IN_PROC_BROWSER_TEST_P(CrossSiteTransferTest, NoLeakOnCrossSiteCancel) { |
| 393 const NavigationController& controller = | 405 const NavigationController& controller = |
| 394 shell()->web_contents()->GetController(); | 406 shell()->web_contents()->GetController(); |
| 395 | 407 |
| 396 // Navigate to a starting URL, so there is a history entry to replace. | 408 // Navigate to a starting URL, so there is a history entry to replace. |
| 397 GURL url1 = embedded_test_server()->GetURL("/site_isolation/blank.html?1"); | 409 GURL url1 = embedded_test_server()->GetURL("/site_isolation/blank.html?1"); |
| 398 EXPECT_TRUE(NavigateToURL(shell(), url1)); | 410 EXPECT_TRUE(NavigateToURL(shell(), url1)); |
| 399 | 411 |
| 400 // Force all future navigations to transfer. | 412 // Force all future navigations to transfer. |
| 401 ShellContentBrowserClient::SetSwapProcessesForRedirect(true); | 413 ShellContentBrowserClient::SetSwapProcessesForRedirect(true); |
| 402 | 414 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 426 // Make sure the request for url2 did not complete. | 438 // Make sure the request for url2 did not complete. |
| 427 EXPECT_FALSE(tracking_delegate().WaitForTrackedURLAndGetCompleted()); | 439 EXPECT_FALSE(tracking_delegate().WaitForTrackedURLAndGetCompleted()); |
| 428 | 440 |
| 429 shell()->web_contents()->SetDelegate(old_delegate); | 441 shell()->web_contents()->SetDelegate(old_delegate); |
| 430 } | 442 } |
| 431 | 443 |
| 432 // Test that verifies that a cross-process transfer retains ability to read | 444 // Test that verifies that a cross-process transfer retains ability to read |
| 433 // files encapsulated by HTTP POST body that is forwarded to the new renderer. | 445 // files encapsulated by HTTP POST body that is forwarded to the new renderer. |
| 434 // Invalid handling of this scenario has been suspected as the cause of at least | 446 // Invalid handling of this scenario has been suspected as the cause of at least |
| 435 // some of the renderer kills tracked in https://crbug.com/613260. | 447 // some of the renderer kills tracked in https://crbug.com/613260. |
| 436 IN_PROC_BROWSER_TEST_F(CrossSiteTransferTest, PostWithFileData) { | 448 IN_PROC_BROWSER_TEST_P(CrossSiteTransferTest, PostWithFileData) { |
| 437 // Navigate to the page with form that posts via 307 redirection to | 449 // Navigate to the page with form that posts via 307 redirection to |
| 438 // |redirect_target_url| (cross-site from |form_url|). Using 307 (rather than | 450 // |redirect_target_url| (cross-site from |form_url|). Using 307 (rather than |
| 439 // 302) redirection is important to preserve the HTTP method and POST body. | 451 // 302) redirection is important to preserve the HTTP method and POST body. |
| 440 GURL form_url(embedded_test_server()->GetURL( | 452 GURL form_url(embedded_test_server()->GetURL( |
| 441 "a.com", "/form_that_posts_cross_site.html")); | 453 "a.com", "/form_that_posts_cross_site.html")); |
| 442 GURL redirect_target_url(embedded_test_server()->GetURL("x.com", "/echoall")); | 454 GURL redirect_target_url(embedded_test_server()->GetURL("x.com", "/echoall")); |
| 443 EXPECT_TRUE(NavigateToURL(shell(), form_url)); | 455 EXPECT_TRUE(NavigateToURL(shell(), form_url)); |
| 444 | 456 |
| 445 // Prepare a file to upload. | 457 // Prepare a file to upload. |
| 446 base::ThreadRestrictions::ScopedAllowIO allow_io_for_temp_dir; | 458 base::ThreadRestrictions::ScopedAllowIO allow_io_for_temp_dir; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 490 "window.domAutomationController.send(" | 502 "window.domAutomationController.send(" |
| 491 "document.getElementsByTagName('pre')[0].innerText);", | 503 "document.getElementsByTagName('pre')[0].innerText);", |
| 492 &actual_page_body)); | 504 &actual_page_body)); |
| 493 EXPECT_THAT(actual_page_body, ::testing::HasSubstr(file_content)); | 505 EXPECT_THAT(actual_page_body, ::testing::HasSubstr(file_content)); |
| 494 EXPECT_THAT(actual_page_body, | 506 EXPECT_THAT(actual_page_body, |
| 495 ::testing::HasSubstr(file_path.BaseName().AsUTF8Unsafe())); | 507 ::testing::HasSubstr(file_path.BaseName().AsUTF8Unsafe())); |
| 496 EXPECT_THAT(actual_page_body, | 508 EXPECT_THAT(actual_page_body, |
| 497 ::testing::HasSubstr("form-data; name=\"file\"")); | 509 ::testing::HasSubstr("form-data; name=\"file\"")); |
| 498 } | 510 } |
| 499 | 511 |
| 512 INSTANTIATE_TEST_CASE_P(CrossSiteTransferTest, |
| 513 CrossSiteTransferTest, |
| 514 ::testing::Values(TestParameter::LOADING_WITHOUT_MOJO, |
| 515 TestParameter::LOADING_WITH_MOJO)); |
| 516 |
| 500 } // namespace content | 517 } // namespace content |
| OLD | NEW |