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

Unified Diff: content/browser/browsing_data/clear_site_data_throttle_browsertest.cc

Issue 2025683003: First experimental implementation of the Clear-Site-Data header (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Comment, file URLs Created 4 years, 6 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 side-by-side diff with in-line comments
Download patch
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.
Mike West 2016/06/20 07:57:38 Please add some tests that test the registrable do
msramek 2016/07/15 16:47:39 Done. I was originally avoiding host_resolver(),
+ 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.
Mike West 2016/06/20 07:57:38 What about when two (or all three) send the header
msramek 2016/07/15 16:47:39 Added tests for that. I'll implement the serializ
+ 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

Powered by Google App Engine
This is Rietveld 408576698