Chromium Code Reviews| OLD | NEW |
|---|---|
| (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 "base/json/json_reader.h" | |
| 8 #include "base/json/json_string_value_serializer.h" | |
| 9 #include "base/strings/stringprintf.h" | |
| 10 #include "base/values.h" | |
| 11 #include "content/browser/frame_host/navigation_handle_impl.h" | |
| 12 #include "content/public/browser/browser_context.h" | |
| 13 #include "content/public/browser/content_browser_client.h" | |
| 14 #include "content/public/browser/navigation_handle.h" | |
| 15 #include "content/public/browser/web_contents.h" | |
| 16 #include "content/public/common/content_client.h" | |
| 17 #include "net/http/http_response_headers.h" | |
| 18 #include "url/gurl.h" | |
| 19 #include "url/origin.h" | |
| 20 | |
| 21 namespace content { | |
| 22 | |
| 23 namespace { | |
| 24 | |
| 25 static const char* kClearSiteDataHeader = "Clear-Site-Data"; | |
| 26 | |
| 27 static const char* kConsoleMessageFormat = | |
| 28 "Clear-Site-Data header on '%s': %s"; | |
| 29 | |
| 30 static const char* kTypesKey = "types"; | |
| 31 | |
| 32 } // namespace | |
| 33 | |
| 34 // static | |
| 35 std::unique_ptr<NavigationThrottle> | |
| 36 ClearSiteDataThrottle::CreateThrottleFor(NavigationHandle* handle) { | |
| 37 return std::unique_ptr<NavigationThrottle>(new ClearSiteDataThrottle(handle)); | |
| 38 } | |
| 39 | |
| 40 ClearSiteDataThrottle::~ClearSiteDataThrottle() {} | |
| 41 | |
| 42 void ClearSiteDataThrottle::DidFinishNavigation(NavigationHandle* handle) { | |
| 43 // When the navigation is finished, we can access RenderFrameHost | |
| 44 // and output console logs. | |
| 45 DCHECK_EQ(navigation_handle(), handle); | |
| 46 | |
| 47 for (const ConsoleMessage& message : messages_) { | |
| 48 navigation_handle()->GetRenderFrameHost()->AddMessageToConsole( | |
| 49 message.error | |
| 50 ? CONSOLE_MESSAGE_LEVEL_ERROR | |
| 51 : CONSOLE_MESSAGE_LEVEL_LOG, | |
| 52 base::StringPrintf( | |
| 53 kConsoleMessageFormat, handle->GetURL().spec().c_str(), | |
| 54 message.text.c_str())); | |
| 55 } | |
| 56 } | |
| 57 | |
| 58 ClearSiteDataThrottle::ThrottleCheckResult | |
| 59 ClearSiteDataThrottle::WillProcessResponse() { | |
| 60 NavigationHandleImpl* handle = | |
| 61 static_cast<NavigationHandleImpl*>(navigation_handle()); | |
|
Mike West
2016/06/02 07:00:08
We should skip all of this if the URL is insecure.
msramek
2016/06/14 20:12:07
Done.
| |
| 62 | |
| 63 // Extract the header. | |
| 64 std::string header; | |
| 65 handle->GetResponseHeaders()->GetNormalizedHeader( | |
|
Mike West
2016/06/02 07:00:08
This will return a comma separated list if more th
msramek
2016/06/14 20:12:07
EnumerateHeader() will cut the JSON on every comma
| |
| 66 kClearSiteDataHeader, &header); | |
| 67 if (header.empty()) | |
| 68 return PROCEED; | |
| 69 | |
| 70 // Parse the header. | |
| 71 bool clear_cookies; | |
| 72 bool clear_storage; | |
| 73 bool clear_cache; | |
| 74 if (!ParseHeader(header, &clear_cookies, &clear_storage, &clear_cache)) | |
| 75 return PROCEED; | |
| 76 | |
| 77 // Clear the data for this browser context and origin. | |
| 78 BrowserContext* browser_context = | |
| 79 handle->GetWebContents()->GetBrowserContext(); | |
| 80 url::Origin origin(handle->GetURL()); | |
| 81 | |
| 82 GetContentClient()->browser()->ClearSiteData( | |
| 83 browser_context, origin, clear_cookies, clear_storage, clear_cache); | |
| 84 | |
| 85 return PROCEED; | |
| 86 } | |
| 87 | |
| 88 ClearSiteDataThrottle::ClearSiteDataThrottle(NavigationHandle* handle) | |
| 89 : NavigationThrottle(handle), | |
| 90 WebContentsObserver(handle ? handle->GetWebContents() : nullptr) {} | |
| 91 | |
| 92 bool ClearSiteDataThrottle::ParseHeader( | |
| 93 const std::string& header, | |
| 94 bool* clear_cookies, bool* clear_storage, bool* clear_cache) { | |
| 95 std::unique_ptr<base::Value> parsed_header = | |
| 96 base::JSONReader::Read(header); | |
| 97 | |
| 98 if (!parsed_header) { | |
| 99 ConsoleLog("The value is not a valid JSON.", true /* error */); | |
|
Mike West
2016/06/02 07:00:08
Can you output the header value so that it's clear
msramek
2016/06/14 20:12:07
Done.
| |
| 100 return false; | |
| 101 } | |
| 102 | |
| 103 if (!parsed_header->GetAsDictionary(nullptr)) { | |
| 104 ConsoleLog("The value is not a dictionary.", true /* error */); | |
| 105 return false; | |
| 106 } | |
| 107 | |
| 108 const base::ListValue* types; | |
| 109 if (!static_cast<base::DictionaryValue*>(parsed_header.get()) | |
| 110 ->GetListWithoutPathExpansion(kTypesKey, &types)) { | |
| 111 ConsoleLog("No 'types' field present.", true /* error */); | |
| 112 return false; | |
| 113 } | |
| 114 | |
| 115 *clear_cookies = false; | |
| 116 *clear_storage = false; | |
| 117 *clear_cache = false; | |
| 118 | |
| 119 for (const std::unique_ptr<base::Value>& value : *types) { | |
| 120 std::string type; | |
| 121 value->GetAsString(&type); | |
| 122 | |
| 123 if (type == "cookies") { | |
| 124 *clear_cookies = true; | |
| 125 ConsoleLog("Clearing cookies.", false /* error */); | |
|
Mike West
2016/06/02 07:00:08
Can you do the extra work to combine these into on
msramek
2016/06/14 20:12:07
Done.
| |
| 126 } else if (type == "storage") { | |
| 127 *clear_storage = true; | |
| 128 ConsoleLog("Clearing storage.", false /* error */); | |
| 129 } else if (type == "cache") { | |
| 130 *clear_cache = true; | |
| 131 ConsoleLog("Clearing cache.", false /* error */); | |
| 132 } else { | |
| 133 std::string serialized_type; | |
| 134 JSONStringValueSerializer serializer(&serialized_type); | |
| 135 serializer.Serialize(*value); | |
| 136 ConsoleLog("Invalid type: " + serialized_type, true /* error */); | |
| 137 } | |
| 138 } | |
| 139 | |
| 140 if (!*clear_cookies && !*clear_storage && !*clear_cache) { | |
| 141 ConsoleLog("No valid types specified for clearing.", true /* error */); | |
| 142 return false; | |
| 143 } | |
| 144 | |
| 145 return true; | |
| 146 } | |
| 147 | |
| 148 void ClearSiteDataThrottle::ConsoleLog(const std::string& text, bool error) { | |
|
Mike West
2016/06/02 07:00:08
Sprinkling `/* error */` throughout the code is pr
msramek
2016/06/14 20:12:08
Done.
| |
| 149 messages_.push_back({text, error}); | |
| 150 } | |
| 151 | |
| 152 } // namespace content | |
| OLD | NEW |