| Index: content/browser/browsing_data/clear_site_data_throttle_browsertest.cc
|
| diff --git a/content/browser/browsing_data/clear_site_data_throttle_browsertest.cc b/content/browser/browsing_data/clear_site_data_throttle_browsertest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..6256327b95620f65bf0bcba8ece0fa37da9d1285
|
| --- /dev/null
|
| +++ b/content/browser/browsing_data/clear_site_data_throttle_browsertest.cc
|
| @@ -0,0 +1,256 @@
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "content/browser/browsing_data/clear_site_data_throttle.h"
|
| +
|
| +#include <memory>
|
| +
|
| +#include "base/bind.h"
|
| +#include "base/callback.h"
|
| +#include "base/command_line.h"
|
| +#include "content/public/browser/content_browser_client.h"
|
| +#include "content/public/browser/web_contents.h"
|
| +#include "content/public/common/content_switches.h"
|
| +#include "content/public/test/content_browser_test.h"
|
| +#include "content/public/test/content_browser_test_utils.h"
|
| +#include "content/public/test/test_navigation_observer.h"
|
| +#include "content/shell/browser/shell.h"
|
| +#include "net/dns/mock_host_resolver.h"
|
| +#include "net/test/embedded_test_server/http_request.h"
|
| +#include "net/test/embedded_test_server/http_response.h"
|
| +#include "testing/gmock/include/gmock/gmock.h"
|
| +#include "url/origin.h"
|
| +#include "url/url_constants.h"
|
| +
|
| +using testing::_;
|
| +
|
| +namespace content {
|
| +
|
| +namespace {
|
| +
|
| +class TestContentBrowserClient : public ContentBrowserClient {
|
| + public:
|
| + MOCK_METHOD5(ClearSiteData, void(
|
| + content::BrowserContext* browser_context, const url::Origin& origin,
|
| + bool remove_cookies, bool remove_storage, bool remove_cache));
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +
|
| +class ClearSiteDataThrottleBrowsertest : public ContentBrowserTest {
|
| + public:
|
| + void SetUpCommandLine(base::CommandLine* command_line) override {
|
| + command_line->AppendSwitch(
|
| + switches::kEnableExperimentalWebPlatformFeatures);
|
| + }
|
| +
|
| + void SetUpOnMainThread() override {
|
| + SetBrowserClientForTesting(&test_client_);
|
| +
|
| + // Header to be served by default.
|
| + SetHeaderValue("{ \"types\": [ \"cookies\" ] }");
|
| +
|
| + // Run three HTTPS servers, each serving 127.0.0.1 on a different port.
|
| + origin1_server_.reset(new net::EmbeddedTestServer(
|
| + net::test_server::EmbeddedTestServer::TYPE_HTTPS));
|
| + origin1_server_->RegisterRequestHandler(
|
| + base::Bind(&ClearSiteDataThrottleBrowsertest::HandleRequestForOrigin1,
|
| + base::Unretained(this)));
|
| +
|
| + origin2_server_.reset(new net::EmbeddedTestServer(
|
| + net::test_server::EmbeddedTestServer::TYPE_HTTPS));
|
| + origin2_server_->RegisterRequestHandler(
|
| + base::Bind(&ClearSiteDataThrottleBrowsertest::HandleRequestForOrigin2,
|
| + base::Unretained(this)));
|
| +
|
| + origin3_server_.reset(new net::EmbeddedTestServer(
|
| + net::test_server::EmbeddedTestServer::TYPE_HTTPS));
|
| + origin3_server_->RegisterRequestHandler(
|
| + base::Bind(&ClearSiteDataThrottleBrowsertest::HandleRequestForOrigin3,
|
| + base::Unretained(this)));
|
| +
|
| + ASSERT_TRUE(origin1_server_->Start());
|
| + ASSERT_TRUE(origin2_server_->Start());
|
| + ASSERT_TRUE(origin3_server_->Start());
|
| + }
|
| +
|
| + // Getters for the testing server origins, i.e. http(s)://127.0.0.1:<port>.
|
| + GURL origin1() { return origin1_server_->base_url(); }
|
| + GURL origin2() { return origin2_server_->base_url(); }
|
| + GURL origin3() { return origin3_server_->base_url(); }
|
| +
|
| + // Defines which of the three origins should send the Clear-Site-Data header.
|
| + // This is used for testing of the redirect chain where either the start,
|
| + // middle, or end of the chain sends the header.
|
| + void SetOriginThatShouldSendClearSiteData(const GURL& origin) {
|
| + origin_that_should_send_clear_site_data_ = origin;
|
| + }
|
| +
|
| + // Finds out which of the three server origins should send Clear-Site-Data.
|
| + GURL OriginThatShouldSendClearSiteData() {
|
| + return origin_that_should_send_clear_site_data_;
|
| + }
|
| +
|
| + // Sets the desired Clear-Site-Data header value to be sent by the servers.
|
| + void SetHeaderValue(const std::string& value) {
|
| + header_value_ = value;
|
| + }
|
| +
|
| + TestContentBrowserClient* GetContentBrowserClient() {
|
| + return &test_client_;
|
| + }
|
| +
|
| + // Navigates over the redirect chain origin1()->origin2()->origin3(), sending
|
| + // the Clear-Site-Data header on |origin_to_test|.
|
| + void TestRedirectChainWithHeaderOn(const GURL& origin_to_test) {
|
| + SCOPED_TRACE(
|
| + "ClearSiteData() should have been called for " + origin_to_test.spec());
|
| + SetOriginThatShouldSendClearSiteData(origin_to_test);
|
| +
|
| + // The |tested_origin| is expected to call ClearSiteData(). The other two
|
| + // origins are not expected to call it.
|
| + const GURL origins[] = {origin1(), origin2(), origin3()};
|
| + for (const GURL& origin : origins) {
|
| + EXPECT_CALL(
|
| + *GetContentBrowserClient(),
|
| + ClearSiteData(
|
| + shell()->web_contents()->GetBrowserContext(),
|
| + url::Origin(origin),
|
| + _, _, _)).Times(origin == origin_to_test ? 1 : 0);
|
| + }
|
| +
|
| + // Navigate to the first origin of the redirect chain.
|
| + TestNavigationObserver observer(shell()->web_contents());
|
| + NavigateToURL(shell(), origin1());
|
| + observer.Wait();
|
| +
|
| + // We reached the end of the redirect chain.
|
| + EXPECT_EQ(origin3(), shell()->web_contents()->GetURL());
|
| + }
|
| +
|
| + private:
|
| + // Requests to origin1() always redirect to origin2().
|
| + std::unique_ptr<net::test_server::HttpResponse> HandleRequestForOrigin1(
|
| + const net::test_server::HttpRequest& request) {
|
| + std::unique_ptr<net::test_server::BasicHttpResponse> response(
|
| + new net::test_server::BasicHttpResponse());
|
| + response->set_code(net::HTTP_FOUND);
|
| + response->AddCustomHeader(
|
| + "Location", origin2_server_->base_url().spec());
|
| +
|
| + if (origin1() == OriginThatShouldSendClearSiteData()) {
|
| + response->AddCustomHeader("Clear-Site-Data", header_value_);
|
| + }
|
| +
|
| + return std::move(response);
|
| + }
|
| +
|
| + // Requests to origin2() always redirect to origin3().
|
| + std::unique_ptr<net::test_server::HttpResponse> HandleRequestForOrigin2(
|
| + const net::test_server::HttpRequest& request) {
|
| + std::unique_ptr<net::test_server::BasicHttpResponse> response(
|
| + new net::test_server::BasicHttpResponse());
|
| + response->set_code(net::HTTP_FOUND);
|
| + response->AddCustomHeader(
|
| + "Location", origin3_server_->base_url().spec());
|
| +
|
| + if (origin2() == OriginThatShouldSendClearSiteData())
|
| + response->AddCustomHeader("Clear-Site-Data", header_value_);
|
| +
|
| + return std::move(response);
|
| + }
|
| +
|
| + // Requests to origin3() always successfully return an empty content.
|
| + std::unique_ptr<net::test_server::HttpResponse> HandleRequestForOrigin3(
|
| + const net::test_server::HttpRequest& request) {
|
| + std::unique_ptr<net::test_server::BasicHttpResponse> response(
|
| + new net::test_server::BasicHttpResponse());
|
| + response->set_code(net::HTTP_OK);
|
| +
|
| + if (origin3() == OriginThatShouldSendClearSiteData())
|
| + response->AddCustomHeader("Clear-Site-Data", header_value_);
|
| +
|
| + return std::move(response);
|
| + }
|
| +
|
| + TestContentBrowserClient test_client_;
|
| + std::unique_ptr<net::EmbeddedTestServer> origin1_server_;
|
| + std::unique_ptr<net::EmbeddedTestServer> origin2_server_;
|
| + std::unique_ptr<net::EmbeddedTestServer> origin3_server_;
|
| + GURL origin_that_should_send_clear_site_data_;
|
| + std::string header_value_;
|
| +};
|
| +
|
| +IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowsertest, RedirectStart) {
|
| + TestRedirectChainWithHeaderOn(origin1());
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowsertest, RedirectMiddle) {
|
| + TestRedirectChainWithHeaderOn(origin2());
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowsertest, RedirectEnd) {
|
| + TestRedirectChainWithHeaderOn(origin3());
|
| +}
|
| +
|
| +// Tests that the Clear-Site-Data header is ignored for insecure origins.
|
| +IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowsertest, Insecure) {
|
| + // ClearSiteData() should not be called for origin3() ...
|
| + SetOriginThatShouldSendClearSiteData(origin3());
|
| + EXPECT_CALL(
|
| + *GetContentBrowserClient(), ClearSiteData(_, _, _, _, _)).Times(0);
|
| +
|
| + // ... when we navigate to it on HTTP instead of HTTPS.
|
| + GURL::Replacements replace_scheme;
|
| + std::string new_scheme = url::kHttpScheme;
|
| + replace_scheme.SetSchemeStr(new_scheme);
|
| + GURL origin3_on_http = origin3().ReplaceComponents(replace_scheme);
|
| + ASSERT_TRUE(origin3_on_http.is_valid());
|
| + ASSERT_TRUE(!origin3_on_http.SchemeIsCryptographic());
|
| +
|
| + TestNavigationObserver observer(shell()->web_contents());
|
| + NavigateToURL(shell(), origin3_on_http);
|
| + observer.Wait();
|
| +}
|
| +
|
| +// Tests that ClearSiteData() is called for the correct datatypes.
|
| +IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowsertest, Types) {
|
| + SetOriginThatShouldSendClearSiteData(origin3());
|
| +
|
| + struct TestCase {
|
| + const char* value;
|
| + bool remove_cookies;
|
| + bool remove_storage;
|
| + bool remove_cache;
|
| + } test_cases[] = {
|
| + { "{ \"types\": [ \"cookies\" ] }", true, false, false},
|
| + { "{ \"types\": [ \"storage\" ] }", false, true, false},
|
| + { "{ \"types\": [ \"cache\" ] }", false, false, true},
|
| + { "{ \"types\": [ \"cookies\", \"storage\" ] }", true, true, false},
|
| + { "{ \"types\": [ \"cookies\", \"cache\" ] }", true, false, true},
|
| + { "{ \"types\": [ \"storage\", \"cache\" ] }", false, true, true},
|
| + { "{ \"types\": [ \"cookies\", \"storage\", \"cache\" ] }",
|
| + true, true, true},
|
| + };
|
| +
|
| + for (const TestCase& test_case : test_cases) {
|
| + SetHeaderValue(test_case.value);
|
| +
|
| + EXPECT_CALL(
|
| + *GetContentBrowserClient(),
|
| + ClearSiteData(
|
| + shell()->web_contents()->GetBrowserContext(),
|
| + url::Origin(origin3()),
|
| + test_case.remove_cookies,
|
| + test_case.remove_storage,
|
| + test_case.remove_cache));
|
| +
|
| + TestNavigationObserver observer(shell()->web_contents());
|
| + NavigateToURL(shell(), origin3());
|
| + observer.Wait();
|
| + }
|
| +}
|
| +
|
| +} // namespace content
|
|
|