Chromium Code Reviews| 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 "base/command_line.h" | |
| 5 #include "base/memory/ref_counted.h" | 6 #include "base/memory/ref_counted.h" |
| 7 #include "base/run_loop.h" | |
| 6 #include "base/strings/string_util.h" | 8 #include "base/strings/string_util.h" |
| 7 #include "base/strings/stringprintf.h" | 9 #include "base/strings/stringprintf.h" |
| 8 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
| 9 #include "content/browser/download/download_manager_impl.h" | 11 #include "content/browser/download/download_manager_impl.h" |
| 10 #include "content/browser/web_contents/web_contents_impl.h" | 12 #include "content/browser/web_contents/web_contents_impl.h" |
| 11 #include "content/public/browser/browser_context.h" | 13 #include "content/public/browser/browser_context.h" |
| 12 #include "content/public/browser/browser_thread.h" | 14 #include "content/public/browser/browser_thread.h" |
| 13 #include "content/public/browser/resource_dispatcher_host.h" | 15 #include "content/public/browser/resource_dispatcher_host.h" |
| 14 #include "content/public/browser/resource_dispatcher_host_delegate.h" | 16 #include "content/public/browser/resource_dispatcher_host_delegate.h" |
| 15 #include "content/public/browser/resource_request_info.h" | 17 #include "content/public/browser/resource_request_info.h" |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 257 // Navigate to a cross-site page that loads immediately without making a | 259 // Navigate to a cross-site page that loads immediately without making a |
| 258 // network request. The unload event should still be run. | 260 // network request. The unload event should still be run. |
| 259 NavigateToURL(shell(), GURL(url::kAboutBlankURL)); | 261 NavigateToURL(shell(), GURL(url::kAboutBlankURL)); |
| 260 | 262 |
| 261 // Check that the cookie was set. | 263 // Check that the cookie was set. |
| 262 EXPECT_EQ("onunloadCookie=foo", GetCookies(url)); | 264 EXPECT_EQ("onunloadCookie=foo", GetCookies(url)); |
| 263 } | 265 } |
| 264 | 266 |
| 265 namespace { | 267 namespace { |
| 266 | 268 |
| 269 using net::test_server::HttpResponse; | |
| 270 using net::test_server::HttpRequest; | |
| 271 using net::test_server::BasicHttpResponse; | |
| 272 | |
| 267 // Handles |request| by serving a redirect response. | 273 // Handles |request| by serving a redirect response. |
| 268 scoped_ptr<net::test_server::HttpResponse> NoContentResponseHandler( | 274 scoped_ptr<HttpResponse> NoContentResponseHandler(const std::string& path, |
| 269 const std::string& path, | 275 const HttpRequest& request) { |
| 270 const net::test_server::HttpRequest& request) { | |
| 271 if (!base::StartsWith(path, request.relative_url, | 276 if (!base::StartsWith(path, request.relative_url, |
| 272 base::CompareCase::SENSITIVE)) | 277 base::CompareCase::SENSITIVE)) |
| 273 return scoped_ptr<net::test_server::HttpResponse>(); | 278 return scoped_ptr<HttpResponse>(); |
| 274 | 279 |
| 275 scoped_ptr<net::test_server::BasicHttpResponse> http_response( | 280 scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse); |
| 276 new net::test_server::BasicHttpResponse); | |
| 277 http_response->set_code(net::HTTP_NO_CONTENT); | 281 http_response->set_code(net::HTTP_NO_CONTENT); |
| 278 return http_response.Pass(); | 282 return http_response.Pass(); |
| 279 } | 283 } |
| 280 | 284 |
| 281 } // namespace | 285 } // namespace |
| 282 | 286 |
| 283 // Tests that the unload handler is not run for 204 responses. | 287 // Tests that the unload handler is not run for 204 responses. |
| 284 // If this flakes use http://crbug.com/80596. | 288 // If this flakes use http://crbug.com/80596. |
| 285 IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest, | 289 IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest, |
| 286 CrossSiteNoUnloadOn204) { | 290 CrossSiteNoUnloadOn204) { |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 440 // Visit another URL first to trigger a cross-site navigation. | 444 // Visit another URL first to trigger a cross-site navigation. |
| 441 NavigateToURL(shell(), GetTestUrl("", "simple_page.html")); | 445 NavigateToURL(shell(), GetTestUrl("", "simple_page.html")); |
| 442 | 446 |
| 443 // Visit a URL that fails without calling ResourceDispatcherHost::Read. | 447 // Visit a URL that fails without calling ResourceDispatcherHost::Read. |
| 444 GURL broken_url("chrome://theme"); | 448 GURL broken_url("chrome://theme"); |
| 445 NavigateToURL(shell(), broken_url); | 449 NavigateToURL(shell(), broken_url); |
| 446 } | 450 } |
| 447 | 451 |
| 448 namespace { | 452 namespace { |
| 449 | 453 |
| 450 scoped_ptr<net::test_server::HttpResponse> HandleRedirectRequest( | 454 scoped_ptr<HttpResponse> HandleRedirectRequest(const std::string& request_path, |
| 451 const std::string& request_path, | 455 const HttpRequest& request) { |
| 452 const net::test_server::HttpRequest& request) { | |
| 453 if (!base::StartsWith(request.relative_url, request_path, | 456 if (!base::StartsWith(request.relative_url, request_path, |
| 454 base::CompareCase::SENSITIVE)) | 457 base::CompareCase::SENSITIVE)) |
| 455 return scoped_ptr<net::test_server::HttpResponse>(); | 458 return scoped_ptr<HttpResponse>(); |
| 456 | 459 |
| 457 scoped_ptr<net::test_server::BasicHttpResponse> http_response( | 460 scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse); |
| 458 new net::test_server::BasicHttpResponse); | |
| 459 http_response->set_code(net::HTTP_FOUND); | 461 http_response->set_code(net::HTTP_FOUND); |
| 460 http_response->AddCustomHeader( | 462 http_response->AddCustomHeader( |
| 461 "Location", request.relative_url.substr(request_path.length())); | 463 "Location", request.relative_url.substr(request_path.length())); |
| 462 return http_response.Pass(); | 464 return http_response.Pass(); |
| 463 } | 465 } |
| 464 | 466 |
| 465 } // namespace | 467 } // namespace |
| 466 | 468 |
| 467 // Test that we update the cookie policy URLs correctly when transferring | 469 // Test that we update the cookie policy URLs correctly when transferring |
| 468 // navigations. | 470 // navigations. |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 519 | 521 |
| 520 NavigateToURLBlockUntilNavigationsComplete( | 522 NavigateToURLBlockUntilNavigationsComplete( |
| 521 shell(), | 523 shell(), |
| 522 embedded_test_server()->GetURL("/client_redirect.html"), | 524 embedded_test_server()->GetURL("/client_redirect.html"), |
| 523 2); | 525 2); |
| 524 | 526 |
| 525 EXPECT_TRUE( | 527 EXPECT_TRUE( |
| 526 delegate.page_transition() & ui::PAGE_TRANSITION_CLIENT_REDIRECT); | 528 delegate.page_transition() & ui::PAGE_TRANSITION_CLIENT_REDIRECT); |
| 527 } | 529 } |
| 528 | 530 |
| 531 class ResourceDispatcherHostBrowserStaleWhileRevalidateTest | |
| 532 : public ResourceDispatcherHostBrowserTest { | |
| 533 protected: | |
| 534 ResourceDispatcherHostBrowserStaleWhileRevalidateTest() {} | |
| 535 ~ResourceDispatcherHostBrowserStaleWhileRevalidateTest() override {} | |
| 536 | |
| 537 base::RunLoop* run_loop() { return &run_loop_; } | |
| 538 int requests_counted() { return requests_counted_; } | |
| 539 | |
| 540 void RegisterCountingRequestHandler() { | |
| 541 embedded_test_server()->RegisterRequestHandler( | |
| 542 base::Bind(&ResourceDispatcherHostBrowserStaleWhileRevalidateTest:: | |
| 543 CountingRequestHandler, | |
| 544 this)); | |
| 545 } | |
| 546 | |
| 547 void RegisterCookieRequestHandler() { | |
| 548 embedded_test_server()->RegisterRequestHandler( | |
| 549 base::Bind(&ResourceDispatcherHostBrowserStaleWhileRevalidateTest:: | |
| 550 CookieRequestHandler, | |
| 551 this)); | |
| 552 } | |
| 553 | |
| 554 void SetUpCommandLine(base::CommandLine* command_line) override { | |
| 555 // TODO(ricea): Remove this once it becomes the default. | |
| 556 command_line->AppendSwitch("enable-stale-while-revalidate"); | |
| 557 } | |
| 558 | |
| 559 private: | |
| 560 // A request handler which increases the number in the title tag on every | |
| 561 // request. | |
| 562 scoped_ptr<HttpResponse> CountingRequestHandler(const HttpRequest& request) { | |
|
tyoshino (SeeGerritForStatus)
2015/08/31 09:37:46
this is special to StaleWhileRevalidateIsApplied f
Adam Rice
2015/09/01 00:38:09
I have just documented it in comments for now. If
| |
| 563 if (request.relative_url != "/counted.html") | |
| 564 return nullptr; | |
| 565 | |
| 566 int version = ++requests_counted_; | |
| 567 | |
| 568 scoped_ptr<BasicHttpResponse> http_response(StaleWhileRevalidateHeaders()); | |
| 569 http_response->set_content( | |
| 570 base::StringPrintf("<title>Version %d</title>", version)); | |
| 571 | |
| 572 if (version == 2) | |
| 573 run_loop_.Quit(); | |
| 574 return http_response.Pass(); | |
| 575 } | |
| 576 | |
| 577 // A request handler which increases a cookie value on every request. | |
| 578 scoped_ptr<HttpResponse> CookieRequestHandler(const HttpRequest& request) { | |
| 579 static const char kHtml[] = | |
| 580 "<script>\n" | |
| 581 "var intervalId;\n" | |
| 582 "function checkCookie() {\n" | |
| 583 " if (document.cookie.search(/version=2/) != -1) {\n" | |
| 584 " clearInterval(intervalId);\n" | |
| 585 " document.title = \"PASS\";\n" | |
| 586 " }\n" | |
| 587 "}\n" | |
| 588 "intervalId = setInterval(checkCookie, 10);\n" | |
| 589 "</script>\n" | |
| 590 "<title>Loaded</title>\n"; | |
| 591 | |
| 592 if (request.relative_url != "/cookie.html") | |
| 593 return nullptr; | |
| 594 | |
| 595 int version = ++requests_counted_; | |
| 596 | |
| 597 scoped_ptr<BasicHttpResponse> http_response(StaleWhileRevalidateHeaders()); | |
| 598 http_response->AddCustomHeader("Set-Cookie", | |
| 599 base::StringPrintf("version=%d", version)); | |
| 600 http_response->set_content(kHtml); | |
| 601 return http_response.Pass(); | |
| 602 } | |
| 603 | |
| 604 // Generate the standard response headers common to all request handlers. | |
| 605 scoped_ptr<BasicHttpResponse> StaleWhileRevalidateHeaders() { | |
| 606 scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse); | |
| 607 http_response->set_code(net::HTTP_OK); | |
| 608 http_response->set_content_type("text/html; charset=utf-8"); | |
| 609 http_response->AddCustomHeader("Cache-Control", | |
| 610 "max-age=0, stale-while-revalidate=86400"); | |
| 611 // A validator is needed for revalidations, and hence | |
| 612 // stale-while-revalidate, to work. | |
| 613 std::string etag = base::StringPrintf( | |
| 614 "\"ResourceDispatcherHostBrowserStaleWhileRevalidateTest%d\"", | |
| 615 requests_counted_); | |
| 616 http_response->AddCustomHeader("ETag", etag); | |
| 617 return http_response.Pass(); | |
| 618 } | |
| 619 | |
| 620 base::RunLoop run_loop_; | |
| 621 int requests_counted_ = 0; | |
| 622 | |
| 623 DISALLOW_COPY_AND_ASSIGN( | |
| 624 ResourceDispatcherHostBrowserStaleWhileRevalidateTest); | |
| 625 }; | |
| 626 | |
| 627 // Verify that the "Cache-Control: stale-while-revalidate" directive correctly | |
| 628 // triggers an async revalidation. | |
| 629 IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserStaleWhileRevalidateTest, | |
| 630 StaleWhileRevalidateIsApplied) { | |
| 631 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); | |
| 632 RegisterCountingRequestHandler(); | |
| 633 GURL url(embedded_test_server()->GetURL("/counted.html")); | |
| 634 | |
| 635 CheckTitleTest(url, "Version 1"); | |
| 636 | |
| 637 // Force the renderer to be destroyed so that the Blink cache doesn't | |
| 638 // interfere with the result. | |
| 639 NavigateToURL(shell(), GURL("about:blank")); | |
| 640 | |
| 641 // Load the page again. We should get the stale version from the cache. | |
| 642 CheckTitleTest(url, "Version 1"); | |
| 643 | |
| 644 // Wait for the async revalidation to complete. | |
| 645 run_loop()->Run(); | |
| 646 EXPECT_EQ(2, requests_counted()); | |
| 647 } | |
| 648 | |
| 649 // The fresh cache entry must become visible eventually. | |
| 650 IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserStaleWhileRevalidateTest, | |
| 651 CacheIsUpdated) { | |
| 652 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); | |
| 653 RegisterCountingRequestHandler(); | |
| 654 GURL url(embedded_test_server()->GetURL("/counted.html")); | |
| 655 | |
| 656 CheckTitleTest(url, "Version 1"); | |
| 657 | |
| 658 // Reset the renderer cache. | |
| 659 NavigateToURL(shell(), GURL("about:blank")); | |
| 660 | |
| 661 // Load the page again. We should get the stale version from the cache. | |
| 662 CheckTitleTest(url, "Version 1"); | |
| 663 | |
| 664 // Load the page repeatedly until we see the new version. | |
| 665 const int kMaxLoads = 100; | |
| 666 int actual_loads = 0; | |
| 667 bool matched = false; | |
| 668 | |
| 669 for (; actual_loads < kMaxLoads && !matched; ++actual_loads) { | |
| 670 TitleWatcher title_watcher(shell()->web_contents(), | |
| 671 ASCIIToUTF16("Version 2")); | |
| 672 title_watcher.AlsoWaitForTitle(ASCIIToUTF16("Version 1")); | |
| 673 NavigateToURL(shell(), GURL("about:blank")); | |
| 674 NavigateToURL(shell(), url); | |
| 675 matched = (title_watcher.WaitAndGetTitle() == ASCIIToUTF16("Version 2")); | |
| 676 } | |
| 677 | |
| 678 EXPECT_TRUE(matched); | |
| 679 // actual_loads is usually 1 but larger numbers are not an error. | |
| 680 DVLOG(1) << "Number of loads: " << actual_loads; | |
| 681 } | |
| 682 | |
| 683 // When the asynchronous revalidation arrives, any cookies it contains must be | |
| 684 // applied immediately. | |
| 685 IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserStaleWhileRevalidateTest, | |
| 686 CookieSetAsynchronously) { | |
| 687 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); | |
| 688 RegisterCookieRequestHandler(); | |
| 689 GURL url(embedded_test_server()->GetURL("/cookie.html")); | |
| 690 | |
| 691 // Set cookie to version=1 | |
| 692 NavigateToURL(shell(), url); | |
| 693 | |
| 694 // Reset render cache. | |
| 695 NavigateToURL(shell(), GURL("about:blank")); | |
| 696 | |
| 697 // The page will load from the cache, then when the async revalidation | |
| 698 // completes the cookie will update. | |
| 699 CheckTitleTest(url, "PASS"); | |
| 700 } | |
| 701 | |
| 529 } // namespace content | 702 } // namespace content |
| OLD | NEW |