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

Side by Side 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: Addressed comments. Created 4 years, 5 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/browser/browsing_data/clear_site_data_throttle.h"
6
7 #include <memory>
8
9 #include "base/bind.h"
10 #include "base/callback.h"
11 #include "base/command_line.h"
12 #include "components/network_session_configurator/switches.h"
13 #include "content/public/browser/content_browser_client.h"
14 #include "content/public/browser/web_contents.h"
15 #include "content/public/common/content_switches.h"
16 #include "content/public/test/content_browser_test.h"
17 #include "content/public/test/content_browser_test_utils.h"
18 #include "content/public/test/test_navigation_observer.h"
19 #include "content/shell/browser/shell.h"
20 #include "net/base/escape.h"
21 #include "net/base/url_util.h"
22 #include "net/dns/mock_host_resolver.h"
23 #include "net/test/embedded_test_server/http_request.h"
24 #include "net/test/embedded_test_server/http_response.h"
25 #include "testing/gmock/include/gmock/gmock.h"
26 #include "url/origin.h"
27 #include "url/url_constants.h"
28
29 using testing::_;
30
31 namespace content {
32
33 namespace {
34
35 class TestContentBrowserClient : public ContentBrowserClient {
36 public:
37 MOCK_METHOD5(ClearSiteData, void(
38 content::BrowserContext* browser_context, const url::Origin& origin,
39 bool remove_cookies, bool remove_storage, bool remove_cache));
40 };
41
42 // Adds a key=value pair to the url's query.
43 void AddQuery(
44 GURL* url, const std::string& key, const std::string& value) {
45 *url = GURL(
46 url->spec() +
47 (url->has_query() ? "&" : "?") +
48 key +
49 "=" +
50 net::EscapeQueryParamValue(value, false));
51 }
52
53 // A value of the Clear-Site-Data header that requests cookie deletion. Reused
54 // in tests that need a valid header but do not depend about its value.
Mike West 2016/07/18 08:48:18 Nit: s/depend about/depend on/
msramek 2016/07/18 10:02:04 Done. (I originally wrote "care about")
55 static const char* kClearCookiesHeader = "{ \"types\": [ \"cookies\" ] }";
56
57 } // namespace
58
59
60 class ClearSiteDataThrottleBrowsertest : public ContentBrowserTest {
61 public:
62 void SetUpCommandLine(base::CommandLine* command_line) override {
63 ContentBrowserTest::SetUpCommandLine(command_line);
64 command_line->AppendSwitch(
65 switches::kEnableExperimentalWebPlatformFeatures);
66
67 // We're redirecting all hosts to localhost even on HTTPS, so we'll get
68 // certificate errors.
69 command_line->AppendSwitch(switches::kIgnoreCertificateErrors);
70 }
71
72 void SetUpOnMainThread() override {
73 ContentBrowserTest::SetUpOnMainThread();
74
75 SetBrowserClientForTesting(&test_client_);
76
77 // Set up HTTP and HTTPS test servers that handle all hosts.
78 host_resolver()->AddRule("*", "127.0.0.1");
79
80 embedded_test_server()->RegisterRequestHandler(
81 base::Bind(&ClearSiteDataThrottleBrowsertest::HandleRequest,
82 base::Unretained(this)));
83 ASSERT_TRUE(embedded_test_server()->Start());
84
85 https_server_.reset(new net::EmbeddedTestServer(
86 net::test_server::EmbeddedTestServer::TYPE_HTTPS));
87 https_server_->SetSSLConfig(net::EmbeddedTestServer::CERT_OK);
88 https_server_->RegisterRequestHandler(
89 base::Bind(&ClearSiteDataThrottleBrowsertest::HandleRequest,
90 base::Unretained(this)));
91 ASSERT_TRUE(https_server_->Start());
92 }
93
94 TestContentBrowserClient* GetContentBrowserClient() {
95 return &test_client_;
96 }
97
98 net::EmbeddedTestServer* https_server() {
99 return https_server_.get();
100 }
101
102 private:
103 // Handles all requests. If the request url query contains a "header" key,
104 // responds with the "Clear-Site-Data" header of the corresponding value.
105 // If the query contains a "redirect" key, responds with a redirect to a url
106 // given by the corresponding value.
107 //
108 // Example: "https://localhost/?header={}&redirect=example.com" will respond
109 // with headers
110 // Clear-Site-Data: {}
111 // Location: example.com
112 std::unique_ptr<net::test_server::HttpResponse> HandleRequest(
113 const net::test_server::HttpRequest& request) {
114 std::unique_ptr<net::test_server::BasicHttpResponse> response(
115 new net::test_server::BasicHttpResponse());
116
117 std::string value;
118 if (net::GetValueForKeyInQuery(request.GetURL(), "header", &value))
119 response->AddCustomHeader("Clear-Site-Data", value);
120
121 if (net::GetValueForKeyInQuery(request.GetURL(), "redirect", &value)) {
122 response->set_code(net::HTTP_FOUND);
123 response->AddCustomHeader("Location", value);
124 } else {
125 response->set_code(net::HTTP_OK);
126 }
127
128 return std::move(response);
129 }
130
131 TestContentBrowserClient test_client_;
132 std::unique_ptr<net::EmbeddedTestServer> https_server_;
133 std::map<GURL, std::string> headers_;
134 std::map<GURL, GURL> redirects_;
135 };
136
137 // Tests that the header is recognized on the beginning, in the middle, and on
138 // the end of a redirect chain. Each of the three parts of the chain may or
139 // may not send the header, so there are 8 configurations to test.
140 IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowsertest, Redirect) {
141 GURL base_urls[3] = {
142 https_server()->GetURL("origin1.com", "/"),
143 https_server()->GetURL("origin2.com", "/foo/bar"),
144 https_server()->GetURL("origin3.com", "/index.html"),
145 };
146
147 // Iterate through the configurations. URLs whose index is matched by the mask
148 // will send the header, the others won't.
149 for (int mask = 0; mask < (1 << 3); ++mask) {
150 GURL urls[3];
151
152 // Set up the expectations.
153 for (int i = 0; i < 3; ++i) {
154 urls[i] = base_urls[i];
155 if (mask & (1 << i))
156 AddQuery(&urls[i], "header", kClearCookiesHeader);
157
158 EXPECT_CALL(
159 *GetContentBrowserClient(),
160 ClearSiteData(
161 shell()->web_contents()->GetBrowserContext(),
162 url::Origin(urls[i]),
163 _, _, _)).Times((mask & (1 << i)) ? 1 : 0);
164 }
165
166 // Set up redirects between urls 0 --> 1 --> 2.
167 AddQuery(&urls[1], "redirect", urls[2].spec());
168 AddQuery(&urls[0], "redirect", urls[1].spec());
169
170 // Navigate to the first url of the redirect chain.
171 NavigateToURL(shell(), urls[0]);
172
173 // We reached the end of the redirect chain.
174 EXPECT_EQ(urls[2], shell()->web_contents()->GetURL());
175
176 testing::Mock::VerifyAndClearExpectations(GetContentBrowserClient());
177 }
178 }
179
180 // Tests that the Clear-Site-Data header is ignored for insecure origins.
181 IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowsertest, Insecure) {
182 // ClearSiteData() should not be called on HTTP.
183 GURL url = embedded_test_server()->GetURL("example.com", "/");
184 AddQuery(&url, "header", kClearCookiesHeader);
185 ASSERT_FALSE(url.SchemeIsCryptographic());
186
187 EXPECT_CALL(
188 *GetContentBrowserClient(), ClearSiteData(_, _, _, _, _)).Times(0);
189
190 NavigateToURL(shell(), url);
191 }
192
193 // Tests that ClearSiteData() is called for the correct datatypes.
194 IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowsertest, Types) {
195 GURL base_url = https_server()->GetURL("example.com", "/");
196
197 struct TestCase {
198 const char* value;
199 bool remove_cookies;
200 bool remove_storage;
201 bool remove_cache;
202 } test_cases[] = {
203 { "{ \"types\": [ \"cookies\" ] }", true, false, false},
204 { "{ \"types\": [ \"storage\" ] }", false, true, false},
205 { "{ \"types\": [ \"cache\" ] }", false, false, true},
206 { "{ \"types\": [ \"cookies\", \"storage\" ] }", true, true, false},
207 { "{ \"types\": [ \"cookies\", \"cache\" ] }", true, false, true},
208 { "{ \"types\": [ \"storage\", \"cache\" ] }", false, true, true},
209 { "{ \"types\": [ \"cookies\", \"storage\", \"cache\" ] }",
210 true, true, true},
211 };
212
213 for (const TestCase& test_case : test_cases) {
214 GURL url = base_url;
215 AddQuery(&url, "header", test_case.value);
216
217 EXPECT_CALL(
218 *GetContentBrowserClient(),
219 ClearSiteData(
220 shell()->web_contents()->GetBrowserContext(),
221 url::Origin(url),
222 test_case.remove_cookies,
223 test_case.remove_storage,
224 test_case.remove_cache));
225
226 NavigateToURL(shell(), url);
227
228 testing::Mock::VerifyAndClearExpectations(GetContentBrowserClient());
229 }
230 }
231
232 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698