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

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: 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 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 "content/public/browser/content_browser_client.h"
13 #include "content/public/browser/web_contents.h"
14 #include "content/public/common/content_switches.h"
15 #include "content/public/test/content_browser_test.h"
16 #include "content/public/test/content_browser_test_utils.h"
17 #include "content/public/test/test_navigation_observer.h"
18 #include "content/shell/browser/shell.h"
19 #include "net/dns/mock_host_resolver.h"
20 #include "net/test/embedded_test_server/http_request.h"
21 #include "net/test/embedded_test_server/http_response.h"
22 #include "testing/gmock/include/gmock/gmock.h"
23 #include "url/origin.h"
24 #include "url/url_constants.h"
25
26 using testing::_;
27
28 namespace content {
29
30 namespace {
31
32 class TestContentBrowserClient : public ContentBrowserClient {
33 public:
34 MOCK_METHOD5(ClearSiteData, void(
35 content::BrowserContext* browser_context, const url::Origin& origin,
36 bool remove_cookies, bool remove_storage, bool remove_cache));
37 };
38
39 } // namespace
40
41
42 class ClearSiteDataThrottleBrowsertest : public ContentBrowserTest {
43 public:
44 void SetUpCommandLine(base::CommandLine* command_line) override {
45 command_line->AppendSwitch(
46 switches::kEnableExperimentalWebPlatformFeatures);
47 }
48
49 void SetUpOnMainThread() override {
50 SetBrowserClientForTesting(&test_client_);
51
52 // Header to be served by default.
53 SetHeaderValue("{ \"types\": [ \"cookies\" ] }");
54
55 // 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(),
56 origin1_server_.reset(new net::EmbeddedTestServer(
57 net::test_server::EmbeddedTestServer::TYPE_HTTPS));
58 origin1_server_->RegisterRequestHandler(
59 base::Bind(&ClearSiteDataThrottleBrowsertest::HandleRequestForOrigin1,
60 base::Unretained(this)));
61
62 origin2_server_.reset(new net::EmbeddedTestServer(
63 net::test_server::EmbeddedTestServer::TYPE_HTTPS));
64 origin2_server_->RegisterRequestHandler(
65 base::Bind(&ClearSiteDataThrottleBrowsertest::HandleRequestForOrigin2,
66 base::Unretained(this)));
67
68 origin3_server_.reset(new net::EmbeddedTestServer(
69 net::test_server::EmbeddedTestServer::TYPE_HTTPS));
70 origin3_server_->RegisterRequestHandler(
71 base::Bind(&ClearSiteDataThrottleBrowsertest::HandleRequestForOrigin3,
72 base::Unretained(this)));
73
74 ASSERT_TRUE(origin1_server_->Start());
75 ASSERT_TRUE(origin2_server_->Start());
76 ASSERT_TRUE(origin3_server_->Start());
77 }
78
79 // Getters for the testing server origins, i.e. http(s)://127.0.0.1:<port>.
80 GURL origin1() { return origin1_server_->base_url(); }
81 GURL origin2() { return origin2_server_->base_url(); }
82 GURL origin3() { return origin3_server_->base_url(); }
83
84 // Defines which of the three origins should send the Clear-Site-Data header.
85 // This is used for testing of the redirect chain where either the start,
86 // 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
87 void SetOriginThatShouldSendClearSiteData(const GURL& origin) {
88 origin_that_should_send_clear_site_data_ = origin;
89 }
90
91 // Finds out which of the three server origins should send Clear-Site-Data.
92 GURL OriginThatShouldSendClearSiteData() {
93 return origin_that_should_send_clear_site_data_;
94 }
95
96 // Sets the desired Clear-Site-Data header value to be sent by the servers.
97 void SetHeaderValue(const std::string& value) {
98 header_value_ = value;
99 }
100
101 TestContentBrowserClient* GetContentBrowserClient() {
102 return &test_client_;
103 }
104
105 // Navigates over the redirect chain origin1()->origin2()->origin3(), sending
106 // the Clear-Site-Data header on |origin_to_test|.
107 void TestRedirectChainWithHeaderOn(const GURL& origin_to_test) {
108 SCOPED_TRACE(
109 "ClearSiteData() should have been called for " + origin_to_test.spec());
110 SetOriginThatShouldSendClearSiteData(origin_to_test);
111
112 // The |tested_origin| is expected to call ClearSiteData(). The other two
113 // origins are not expected to call it.
114 const GURL origins[] = {origin1(), origin2(), origin3()};
115 for (const GURL& origin : origins) {
116 EXPECT_CALL(
117 *GetContentBrowserClient(),
118 ClearSiteData(
119 shell()->web_contents()->GetBrowserContext(),
120 url::Origin(origin),
121 _, _, _)).Times(origin == origin_to_test ? 1 : 0);
122 }
123
124 // Navigate to the first origin of the redirect chain.
125 TestNavigationObserver observer(shell()->web_contents());
126 NavigateToURL(shell(), origin1());
127 observer.Wait();
128
129 // We reached the end of the redirect chain.
130 EXPECT_EQ(origin3(), shell()->web_contents()->GetURL());
131 }
132
133 private:
134 // Requests to origin1() always redirect to origin2().
135 std::unique_ptr<net::test_server::HttpResponse> HandleRequestForOrigin1(
136 const net::test_server::HttpRequest& request) {
137 std::unique_ptr<net::test_server::BasicHttpResponse> response(
138 new net::test_server::BasicHttpResponse());
139 response->set_code(net::HTTP_FOUND);
140 response->AddCustomHeader(
141 "Location", origin2_server_->base_url().spec());
142
143 if (origin1() == OriginThatShouldSendClearSiteData()) {
144 response->AddCustomHeader("Clear-Site-Data", header_value_);
145 }
146
147 return std::move(response);
148 }
149
150 // Requests to origin2() always redirect to origin3().
151 std::unique_ptr<net::test_server::HttpResponse> HandleRequestForOrigin2(
152 const net::test_server::HttpRequest& request) {
153 std::unique_ptr<net::test_server::BasicHttpResponse> response(
154 new net::test_server::BasicHttpResponse());
155 response->set_code(net::HTTP_FOUND);
156 response->AddCustomHeader(
157 "Location", origin3_server_->base_url().spec());
158
159 if (origin2() == OriginThatShouldSendClearSiteData())
160 response->AddCustomHeader("Clear-Site-Data", header_value_);
161
162 return std::move(response);
163 }
164
165 // Requests to origin3() always successfully return an empty content.
166 std::unique_ptr<net::test_server::HttpResponse> HandleRequestForOrigin3(
167 const net::test_server::HttpRequest& request) {
168 std::unique_ptr<net::test_server::BasicHttpResponse> response(
169 new net::test_server::BasicHttpResponse());
170 response->set_code(net::HTTP_OK);
171
172 if (origin3() == OriginThatShouldSendClearSiteData())
173 response->AddCustomHeader("Clear-Site-Data", header_value_);
174
175 return std::move(response);
176 }
177
178 TestContentBrowserClient test_client_;
179 std::unique_ptr<net::EmbeddedTestServer> origin1_server_;
180 std::unique_ptr<net::EmbeddedTestServer> origin2_server_;
181 std::unique_ptr<net::EmbeddedTestServer> origin3_server_;
182 GURL origin_that_should_send_clear_site_data_;
183 std::string header_value_;
184 };
185
186 IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowsertest, RedirectStart) {
187 TestRedirectChainWithHeaderOn(origin1());
188 }
189
190 IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowsertest, RedirectMiddle) {
191 TestRedirectChainWithHeaderOn(origin2());
192 }
193
194 IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowsertest, RedirectEnd) {
195 TestRedirectChainWithHeaderOn(origin3());
196 }
197
198 // Tests that the Clear-Site-Data header is ignored for insecure origins.
199 IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowsertest, Insecure) {
200 // ClearSiteData() should not be called for origin3() ...
201 SetOriginThatShouldSendClearSiteData(origin3());
202 EXPECT_CALL(
203 *GetContentBrowserClient(), ClearSiteData(_, _, _, _, _)).Times(0);
204
205 // ... when we navigate to it on HTTP instead of HTTPS.
206 GURL::Replacements replace_scheme;
207 std::string new_scheme = url::kHttpScheme;
208 replace_scheme.SetSchemeStr(new_scheme);
209 GURL origin3_on_http = origin3().ReplaceComponents(replace_scheme);
210 ASSERT_TRUE(origin3_on_http.is_valid());
211 ASSERT_TRUE(!origin3_on_http.SchemeIsCryptographic());
212
213 TestNavigationObserver observer(shell()->web_contents());
214 NavigateToURL(shell(), origin3_on_http);
215 observer.Wait();
216 }
217
218 // Tests that ClearSiteData() is called for the correct datatypes.
219 IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowsertest, Types) {
220 SetOriginThatShouldSendClearSiteData(origin3());
221
222 struct TestCase {
223 const char* value;
224 bool remove_cookies;
225 bool remove_storage;
226 bool remove_cache;
227 } test_cases[] = {
228 { "{ \"types\": [ \"cookies\" ] }", true, false, false},
229 { "{ \"types\": [ \"storage\" ] }", false, true, false},
230 { "{ \"types\": [ \"cache\" ] }", false, false, true},
231 { "{ \"types\": [ \"cookies\", \"storage\" ] }", true, true, false},
232 { "{ \"types\": [ \"cookies\", \"cache\" ] }", true, false, true},
233 { "{ \"types\": [ \"storage\", \"cache\" ] }", false, true, true},
234 { "{ \"types\": [ \"cookies\", \"storage\", \"cache\" ] }",
235 true, true, true},
236 };
237
238 for (const TestCase& test_case : test_cases) {
239 SetHeaderValue(test_case.value);
240
241 EXPECT_CALL(
242 *GetContentBrowserClient(),
243 ClearSiteData(
244 shell()->web_contents()->GetBrowserContext(),
245 url::Origin(origin3()),
246 test_case.remove_cookies,
247 test_case.remove_storage,
248 test_case.remove_cache));
249
250 TestNavigationObserver observer(shell()->web_contents());
251 NavigateToURL(shell(), origin3());
252 observer.Wait();
253 }
254 }
255
256 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698