Commit 69e586cb authored by Martin Sramek's avatar Martin Sramek Committed by Commit Bot

Add the wildcard ("*") pseudo-datatype to Clear-Site-Data.

Corresponding spec change:
https://github.com/w3c/webappsec-clear-site-data/pull/43

Bug: 607897
Change-Id: Ib9d0c994917ff801dd64404734efdcb34c9507e1
Reviewed-on: https://chromium-review.googlesource.com/771890Reviewed-by: default avatarMike West <mkwst@chromium.org>
Commit-Queue: Martin Šrámek <msramek@chromium.org>
Cr-Commit-Position: refs/heads/master@{#517047}
parent 3dac05a1
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "content/browser/browsing_data/clear_site_data_throttle.h" #include "content/browser/browsing_data/clear_site_data_throttle.h"
#include "base/command_line.h"
#include "base/memory/ptr_util.h" #include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
#include "base/scoped_observer.h" #include "base/scoped_observer.h"
...@@ -18,6 +19,7 @@ ...@@ -18,6 +19,7 @@
#include "content/public/browser/browsing_data_remover.h" #include "content/public/browser/browsing_data_remover.h"
#include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/origin_util.h" #include "content/public/common/origin_util.h"
#include "content/public/common/resource_response_info.h" #include "content/public/common/resource_response_info.h"
#include "content/public/common/resource_type.h" #include "content/public/common/resource_type.h"
...@@ -37,6 +39,7 @@ const char kNameForLogging[] = "ClearSiteDataThrottle"; ...@@ -37,6 +39,7 @@ const char kNameForLogging[] = "ClearSiteDataThrottle";
const char kClearSiteDataHeader[] = "Clear-Site-Data"; const char kClearSiteDataHeader[] = "Clear-Site-Data";
// Datatypes. // Datatypes.
const char kDatatypeWildcard[] = "\"*\"";
const char kDatatypeCookies[] = "\"cookies\""; const char kDatatypeCookies[] = "\"cookies\"";
const char kDatatypeStorage[] = "\"storage\""; const char kDatatypeStorage[] = "\"storage\"";
const char kDatatypeCache[] = "\"cache\""; const char kDatatypeCache[] = "\"cache\"";
...@@ -46,6 +49,11 @@ const char kConsoleMessageTemplate[] = "Clear-Site-Data header on '%s': %s"; ...@@ -46,6 +49,11 @@ const char kConsoleMessageTemplate[] = "Clear-Site-Data header on '%s': %s";
const char kConsoleMessageCleared[] = "Cleared data types: %s."; const char kConsoleMessageCleared[] = "Cleared data types: %s.";
const char kConsoleMessageDatatypeSeparator[] = ", "; const char kConsoleMessageDatatypeSeparator[] = ", ";
bool AreExperimentalFeaturesEnabled() {
return base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableExperimentalWebPlatformFeatures);
}
bool IsNavigationRequest(net::URLRequest* request) { bool IsNavigationRequest(net::URLRequest* request) {
const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request); const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request);
return info && IsResourceTypeFrame(info->GetResourceType()); return info && IsResourceTypeFrame(info->GetResourceType());
...@@ -447,25 +455,33 @@ bool ClearSiteDataThrottle::ParseHeader(const std::string& header, ...@@ -447,25 +455,33 @@ bool ClearSiteDataThrottle::ParseHeader(const std::string& header,
*clear_storage = false; *clear_storage = false;
*clear_cache = false; *clear_cache = false;
std::string type_names; std::vector<std::string> input_types = base::SplitString(
for (const base::StringPiece& type : base::SplitStringPiece( header, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
header, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) { std::string output_types;
for (unsigned i = 0; i < input_types.size(); i++) {
bool* data_type = nullptr; bool* data_type = nullptr;
if (type == kDatatypeCookies) { if (AreExperimentalFeaturesEnabled() &&
input_types[i] == kDatatypeWildcard) {
input_types.push_back(kDatatypeCookies);
input_types.push_back(kDatatypeStorage);
input_types.push_back(kDatatypeCache);
continue;
} else if (input_types[i] == kDatatypeCookies) {
data_type = clear_cookies; data_type = clear_cookies;
} else if (type == kDatatypeStorage) { } else if (input_types[i] == kDatatypeStorage) {
data_type = clear_storage; data_type = clear_storage;
} else if (type == kDatatypeCache) { } else if (input_types[i] == kDatatypeCache) {
delegate->AddMessage( delegate->AddMessage(
current_url, "The \"cache\" datatype is temporarily not supported.", current_url, "The \"cache\" datatype is temporarily not supported.",
CONSOLE_MESSAGE_LEVEL_ERROR); CONSOLE_MESSAGE_LEVEL_ERROR);
continue; continue;
} else { } else {
delegate->AddMessage(current_url, delegate->AddMessage(
base::StringPrintf("Unrecognized type: %s.", current_url,
type.as_string().c_str()), base::StringPrintf("Unrecognized type: %s.", input_types[i].c_str()),
CONSOLE_MESSAGE_LEVEL_ERROR); CONSOLE_MESSAGE_LEVEL_ERROR);
continue; continue;
} }
...@@ -475,9 +491,9 @@ bool ClearSiteDataThrottle::ParseHeader(const std::string& header, ...@@ -475,9 +491,9 @@ bool ClearSiteDataThrottle::ParseHeader(const std::string& header,
continue; continue;
*data_type = true; *data_type = true;
if (!type_names.empty()) if (!output_types.empty())
type_names += kConsoleMessageDatatypeSeparator; output_types += kConsoleMessageDatatypeSeparator;
type_names += type.as_string(); output_types += input_types[i];
} }
if (!*clear_cookies && !*clear_storage && !*clear_cache) { if (!*clear_cookies && !*clear_storage && !*clear_cache) {
...@@ -489,7 +505,7 @@ bool ClearSiteDataThrottle::ParseHeader(const std::string& header, ...@@ -489,7 +505,7 @@ bool ClearSiteDataThrottle::ParseHeader(const std::string& header,
// Pretty-print which types are to be cleared. // Pretty-print which types are to be cleared.
delegate->AddMessage( delegate->AddMessage(
current_url, current_url,
base::StringPrintf(kConsoleMessageCleared, type_names.c_str()), base::StringPrintf(kConsoleMessageCleared, output_types.c_str()),
CONSOLE_MESSAGE_LEVEL_INFO); CONSOLE_MESSAGE_LEVEL_INFO);
return true; return true;
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "base/test/scoped_command_line.h" #include "base/test/scoped_command_line.h"
#include "base/test/scoped_task_environment.h" #include "base/test/scoped_task_environment.h"
#include "content/public/browser/resource_request_info.h" #include "content/public/browser/resource_request_info.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/test_browser_thread.h" #include "content/public/test/test_browser_thread.h"
#include "content/public/test/test_browser_thread_bundle.h" #include "content/public/test/test_browser_thread_bundle.h"
#include "net/base/load_flags.h" #include "net/base/load_flags.h"
...@@ -172,7 +173,9 @@ TEST_F(ClearSiteDataThrottleTest, ParseHeaderAndExecuteClearingTask) { ...@@ -172,7 +173,9 @@ TEST_F(ClearSiteDataThrottleTest, ParseHeaderAndExecuteClearingTask) {
bool cookies; bool cookies;
bool storage; bool storage;
bool cache; bool cache;
} test_cases[] = { };
std::vector<TestCase> standard_test_cases = {
// One data type. // One data type.
{"\"cookies\"", true, false, false}, {"\"cookies\"", true, false, false},
{"\"storage\"", false, true, false}, {"\"storage\"", false, true, false},
...@@ -195,6 +198,11 @@ TEST_F(ClearSiteDataThrottleTest, ParseHeaderAndExecuteClearingTask) { ...@@ -195,6 +198,11 @@ TEST_F(ClearSiteDataThrottleTest, ParseHeaderAndExecuteClearingTask) {
{"\"cache\", \"cookies\", \"storage\"", true, true, false}, {"\"cache\", \"cookies\", \"storage\"", true, true, false},
{"\"cookies\", \"storage\", \"cache\"", true, true, false}, {"\"cookies\", \"storage\", \"cache\"", true, true, false},
// The wildcard datatype is not yet shipped.
{"\"*\", \"storage\"", false, true, false},
{"\"cookies\", \"*\", \"storage\"", true, true, false},
{"\"*\", \"cookies\", \"*\"", true, false, false},
// Different formatting. // Different formatting.
{"\"cookies\"", true, false, false}, {"\"cookies\"", true, false, false},
...@@ -209,45 +217,65 @@ TEST_F(ClearSiteDataThrottleTest, ParseHeaderAndExecuteClearingTask) { ...@@ -209,45 +217,65 @@ TEST_F(ClearSiteDataThrottleTest, ParseHeaderAndExecuteClearingTask) {
{"\"storage\", \"foo\"", false, true, false}, {"\"storage\", \"foo\"", false, true, false},
}; };
for (const TestCase& test_case : test_cases) { std::vector<TestCase> experimental_test_cases = {
SCOPED_TRACE(test_case.header); // Wildcard.
// TODO(crbug.com/762417): The "cache" parameter is temporarily disabled.
{"\"*\"", true, true, false},
{"\"*\", \"storage\"", true, true, false},
{"\"cache\", \"*\", \"storage\"", true, true, false},
{"\"*\", \"cookies\", \"*\"", true, true, false},
};
// Test that ParseHeader works correctly. const std::vector<TestCase>* test_case_sets[] = {&standard_test_cases,
bool actual_cookies; &experimental_test_cases};
bool actual_storage;
bool actual_cache;
GURL url("https://example.com"); for (const std::vector<TestCase>* test_cases : test_case_sets) {
ConsoleMessagesDelegate console_delegate; base::test::ScopedCommandLine scoped_command_line;
if (test_cases == &experimental_test_cases) {
scoped_command_line.GetProcessCommandLine()->AppendSwitch(
switches::kEnableExperimentalWebPlatformFeatures);
}
EXPECT_TRUE(ClearSiteDataThrottle::ParseHeaderForTesting( for (const TestCase& test_case : *test_cases) {
test_case.header, &actual_cookies, &actual_storage, &actual_cache, SCOPED_TRACE(test_case.header);
&console_delegate, url));
EXPECT_EQ(test_case.cookies, actual_cookies); // Test that ParseHeader works correctly.
EXPECT_EQ(test_case.storage, actual_storage); bool actual_cookies;
EXPECT_EQ(test_case.cache, actual_cache); bool actual_storage;
bool actual_cache;
// Test that a call with the above parameters actually reaches GURL url("https://example.com");
// ExecuteClearingTask(). ConsoleMessagesDelegate console_delegate;
net::TestURLRequestContext context;
std::unique_ptr<net::URLRequest> request(context.CreateRequest(
url, net::DEFAULT_PRIORITY, nullptr, TRAFFIC_ANNOTATION_FOR_TESTS));
TestThrottle throttle(request.get(),
std::make_unique<ConsoleMessagesDelegate>());
MockResourceThrottleDelegate delegate;
throttle.set_delegate_for_testing(&delegate);
throttle.SetResponseHeaders(std::string(kClearSiteDataHeaderPrefix) +
test_case.header);
EXPECT_CALL(throttle, EXPECT_TRUE(ClearSiteDataThrottle::ParseHeaderForTesting(
ClearSiteData(url::Origin::Create(url), test_case.cookies, test_case.header, &actual_cookies, &actual_storage, &actual_cache,
test_case.storage, test_case.cache)); &console_delegate, url));
bool defer;
throttle.WillProcessResponse(&defer);
EXPECT_TRUE(defer);
testing::Mock::VerifyAndClearExpectations(&throttle); EXPECT_EQ(test_case.cookies, actual_cookies);
EXPECT_EQ(test_case.storage, actual_storage);
EXPECT_EQ(test_case.cache, actual_cache);
// Test that a call with the above parameters actually reaches
// ExecuteClearingTask().
net::TestURLRequestContext context;
std::unique_ptr<net::URLRequest> request(context.CreateRequest(
url, net::DEFAULT_PRIORITY, nullptr, TRAFFIC_ANNOTATION_FOR_TESTS));
TestThrottle throttle(request.get(),
std::make_unique<ConsoleMessagesDelegate>());
MockResourceThrottleDelegate delegate;
throttle.set_delegate_for_testing(&delegate);
throttle.SetResponseHeaders(std::string(kClearSiteDataHeaderPrefix) +
test_case.header);
EXPECT_CALL(throttle,
ClearSiteData(url::Origin::Create(url), test_case.cookies,
test_case.storage, test_case.cache));
bool defer;
throttle.WillProcessResponse(&defer);
EXPECT_TRUE(defer);
testing::Mock::VerifyAndClearExpectations(&throttle);
}
} }
} }
...@@ -265,8 +293,9 @@ TEST_F(ClearSiteDataThrottleTest, InvalidHeader) { ...@@ -265,8 +293,9 @@ TEST_F(ClearSiteDataThrottleTest, InvalidHeader) {
{"\"cache\"", {"\"cache\"",
"The \"cache\" datatype is temporarily not supported.\n" "The \"cache\" datatype is temporarily not supported.\n"
"No recognized types specified.\n"}, "No recognized types specified.\n"},
{"[ \"list\" ]", // The wildcard datatype is not yet shipped.
"Unrecognized type: [ \"list\" ].\n" {"[ \"*\" ]",
"Unrecognized type: [ \"*\" ].\n"
"No recognized types specified.\n"}, "No recognized types specified.\n"},
{"[ \"list\" ]", {"[ \"list\" ]",
"Unrecognized type: [ \"list\" ].\n" "Unrecognized type: [ \"list\" ].\n"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment