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

Side by Side Diff: chrome/browser/browsing_data/clear_site_data_throttle.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: 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 "chrome/browser/browsing_data/clear_site_data_throttle.h"
6
7 #include "base/bind.h"
8 #include "base/callback.h"
9 #include "base/values.h"
10 #include "chrome/browser/browsing_data/browsing_data_helper.h"
11 #include "chrome/browser/browsing_data/browsing_data_remover.h"
12 #include "chrome/browser/browsing_data/browsing_data_remover_factory.h"
13 #include "chrome/browser/browsing_data/registrable_domain_filter_builder.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "components/safe_json/safe_json_parser.h"
16 #include "content/public/browser/browser_thread.h"
17 #include "content/public/browser/web_contents.h"
18 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
19 #include "net/url_request/url_request.h"
20 #include "url/gurl.h"
21
22 namespace {
23
24 const char* kNameForLogging = "ClearSiteDataThrottle";
25
26 const char* kClearSiteDataHeader = "Clear-Site-Data";
27
28 const char* kTypesKey = "types";
29
30 } // namespace
31
32 ClearSiteDataThrottle::ClearSiteDataThrottle(const net::URLRequest* request)
33 : request_(request) {}
34
35 ClearSiteDataThrottle::~ClearSiteDataThrottle() {}
36
37 void ClearSiteDataThrottle::WillProcessResponse(bool* defer) {
38 std::string header;
39 request_->GetResponseHeaderByName(kClearSiteDataHeader, &header);
40 if (header.empty())
41 return;
42
43 std::string domain;
44 if (request_->url().HostIsIPAddress()) {
45 domain = request_->url().host();
46 } else {
47 domain = GetDomainAndRegistry(
Mike West 2016/05/31 05:35:51 This is going to strip `www.example.com` down to `
msramek 2016/06/01 14:20:40 Done. Sorry, forgot to add a comment about this. I
48 request_->url(),
49 net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
50 }
51
52 if (domain.empty())
Mike West 2016/05/31 05:35:51 Another implication is that folks on an intranet w
msramek 2016/06/01 14:20:40 Yes, or even a simpler example: localhost. I think
53 return;
54
55 const content::ResourceRequestInfo* info =
56 content::ResourceRequestInfo::ForRequest(request_);
57 content::BrowserThread::PostTask(
58 content::BrowserThread::UI, FROM_HERE,
59 base::Bind(
60 &ClearSiteDataThrottle::ProcessResponseOnUIThread,
61 info->GetWebContentsGetterForRequest(),
62 domain,
63 header));
64 }
65
66 const char* ClearSiteDataThrottle::GetNameForLogging() const {
67 return kNameForLogging;
68 }
69
70 // static
71 void ClearSiteDataThrottle::ProcessResponseOnUIThread(
72 const content::ResourceRequestInfo::WebContentsGetter& getter,
73 std::string domain,
74 std::string header) {
75 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
76
77 content::WebContents* web_contents = getter.Run();
78 if (!web_contents)
79 return;
80
81 Profile* profile =
82 Profile::FromBrowserContext(
83 web_contents->GetBrowserContext())->GetOriginalProfile();
84
85 safe_json::SafeJsonParser::Parse(
Mike West 2016/05/31 05:35:51 Why do we need to parse JSON on the UI thread? Can
msramek 2016/06/01 14:20:41 N/A, since after moving to content/ were using the
86 header,
87 base::Bind(
88 &ClearSiteDataThrottle::ClearData,
89 base::Unretained(profile),
90 domain),
91 base::Bind(&ClearSiteDataThrottle::OnParseError));
92 }
93
94 // static
95 void ClearSiteDataThrottle::ClearData(
96 Profile* profile,
97 std::string domain,
98 std::unique_ptr<base::Value> header) {
99 if (!header || !header->GetAsDictionary(nullptr)) {
100 DVLOG(1) << "Not a valid dictionary value.";
Mike West 2016/05/31 05:35:52 // TODO(you): Write a console error.
msramek 2016/06/01 14:20:40 Done. (actually implemented the console error)
101 return;
102 }
103
104 const base::ListValue* types;
105 if (!static_cast<base::DictionaryValue*>(header.get())
106 ->GetListWithoutPathExpansion(kTypesKey, &types)) {
107 DVLOG(1) << "No 'types' field present.";
Mike West 2016/05/31 05:35:51 // TODO(you): Write a console error.
msramek 2016/06/01 14:20:40 Done. (actually implemented the console error)
108 return;
109 }
110
111 int remove_mask = 0;
112 for (const base::Value* value : *types) {
Mike West 2016/05/31 05:35:51 Nit: These are `unique_ptr` aren't they?
msramek 2016/06/01 14:20:40 types->begin() is std::vector<base::Value*>::const
msramek 2016/06/01 14:25:30 Ah. Because this is a recent change and I have an
113 std::string type;
114 if (!value->GetAsString(&type)) {
115 DVLOG(1) << "Invalid type: " << *value;
Mike West 2016/05/31 05:35:51 // TODO(you): Write a console error.
msramek 2016/06/01 14:20:40 Done. (actually implemented the console error)
116 continue;
117 }
118
119 if (type == "cache") {
120 remove_mask |= BrowsingDataRemover::REMOVE_CACHE;
121 DVLOG(2) << "Clearing cache.";
122 } else if (type == "cookies") {
123 remove_mask |= BrowsingDataRemover::REMOVE_COOKIES;
124 DVLOG(2) << "Clearing cookies.";
125 } else if (type == "storage") {
126 remove_mask |= BrowsingDataRemover::REMOVE_SITE_DATA;
Mike West 2016/05/31 05:35:51 This includes cookies; it shouldn't. I think you'l
msramek 2016/06/01 14:20:40 Done. Thanks for paying attention to this :)
127 DVLOG(2) << "Clearing storage.";
128 }
129 }
130
131 if (!remove_mask) {
132 DVLOG(2) << "No valid types specified for clearing.";
Mike West 2016/05/31 05:35:51 // TODO(you): Write a console error.
msramek 2016/06/01 14:20:41 Done. (actually implemented the console error)
133 return;
134 }
135
136 BrowsingDataRemover* browsing_data_remover =
137 BrowsingDataRemoverFactory::GetForBrowserContext(profile);
138
139 RegistrableDomainFilterBuilder filter_builder(
140 BrowsingDataFilterBuilder::WHITELIST);
141 filter_builder.AddRegisterableDomain(domain);
Mike West 2016/05/31 05:35:51 Again, we should talk about the registerable domai
msramek 2016/06/01 14:20:40 Please see my current implementation. I'm using or
142
143 browsing_data_remover->RemoveWithFilter(
Mike West 2016/05/31 05:35:51 This eventually hops back to the IO thread, right?
msramek 2016/06/01 14:20:40 N/A, since we're not doing any more thread hopping
144 BrowsingDataRemover::Period(BrowsingDataRemover::TimePeriod::EVERYTHING),
145 remove_mask,
146 BrowsingDataHelper::UNPROTECTED_WEB,
147 filter_builder);
148 }
149
150 // static
151 void ClearSiteDataThrottle::OnParseError(const std::string& error) {
152 DVLOG(1) << "The header value is not a valid JSON.";
153 DVLOG(1) << error;
Mike West 2016/05/31 05:35:52 // TODO(you): write a console error.
msramek 2016/06/01 14:20:41 Done. (actually implemented the console error)
154 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698