| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/supervised_user/experimental/supervised_user_async_url_
checker.h" | 5 #include "chrome/browser/supervised_user/experimental/supervised_user_async_url_
checker.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/callback.h" | 9 #include "base/callback.h" |
| 10 #include "base/json/json_reader.h" | 10 #include "base/json/json_reader.h" |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 using net::URLRequestContextGetter; | 28 using net::URLRequestContextGetter; |
| 29 using net::URLRequestStatus; | 29 using net::URLRequestStatus; |
| 30 | 30 |
| 31 namespace { | 31 namespace { |
| 32 | 32 |
| 33 const char kApiUrl[] = "https://safesearch.googleapis.com/v1:classify"; | 33 const char kApiUrl[] = "https://safesearch.googleapis.com/v1:classify"; |
| 34 const char kDataContentType[] = "application/x-www-form-urlencoded"; | 34 const char kDataContentType[] = "application/x-www-form-urlencoded"; |
| 35 const char kDataFormat[] = "key=%s&urls=%s"; | 35 const char kDataFormat[] = "key=%s&urls=%s"; |
| 36 | 36 |
| 37 const size_t kDefaultCacheSize = 1000; | 37 const size_t kDefaultCacheSize = 1000; |
| 38 const size_t kDefaultCacheTimeoutSeconds = 3600; |
| 38 | 39 |
| 39 // Builds the POST data for SafeSearch API requests. | 40 // Builds the POST data for SafeSearch API requests. |
| 40 std::string BuildRequestData(const std::string& api_key, const GURL& url) { | 41 std::string BuildRequestData(const std::string& api_key, const GURL& url) { |
| 41 std::string query = net::EscapeQueryParamValue(url.spec(), true); | 42 std::string query = net::EscapeQueryParamValue(url.spec(), true); |
| 42 return base::StringPrintf(kDataFormat, api_key.c_str(), query.c_str()); | 43 return base::StringPrintf(kDataFormat, api_key.c_str(), query.c_str()); |
| 43 } | 44 } |
| 44 | 45 |
| 45 // Creates a URLFetcher to call the SafeSearch API for |url|. | 46 // Creates a URLFetcher to call the SafeSearch API for |url|. |
| 46 scoped_ptr<net::URLFetcher> CreateFetcher(URLFetcherDelegate* delegate, | 47 scoped_ptr<net::URLFetcher> CreateFetcher(URLFetcherDelegate* delegate, |
| 47 URLRequestContextGetter* context, | 48 URLRequestContextGetter* context, |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 | 88 |
| 88 struct SupervisedUserAsyncURLChecker::Check { | 89 struct SupervisedUserAsyncURLChecker::Check { |
| 89 Check(const GURL& url, | 90 Check(const GURL& url, |
| 90 scoped_ptr<net::URLFetcher> fetcher, | 91 scoped_ptr<net::URLFetcher> fetcher, |
| 91 const CheckCallback& callback); | 92 const CheckCallback& callback); |
| 92 ~Check(); | 93 ~Check(); |
| 93 | 94 |
| 94 GURL url; | 95 GURL url; |
| 95 scoped_ptr<net::URLFetcher> fetcher; | 96 scoped_ptr<net::URLFetcher> fetcher; |
| 96 std::vector<CheckCallback> callbacks; | 97 std::vector<CheckCallback> callbacks; |
| 97 base::Time start_time; | 98 base::TimeTicks start_time; |
| 98 }; | 99 }; |
| 99 | 100 |
| 100 SupervisedUserAsyncURLChecker::Check::Check( | 101 SupervisedUserAsyncURLChecker::Check::Check( |
| 101 const GURL& url, | 102 const GURL& url, |
| 102 scoped_ptr<net::URLFetcher> fetcher, | 103 scoped_ptr<net::URLFetcher> fetcher, |
| 103 const CheckCallback& callback) | 104 const CheckCallback& callback) |
| 104 : url(url), | 105 : url(url), |
| 105 fetcher(fetcher.Pass()), | 106 fetcher(fetcher.Pass()), |
| 106 callbacks(1, callback), | 107 callbacks(1, callback), |
| 107 start_time(base::Time::Now()) { | 108 start_time(base::TimeTicks::Now()) { |
| 108 } | 109 } |
| 109 | 110 |
| 110 SupervisedUserAsyncURLChecker::Check::~Check() {} | 111 SupervisedUserAsyncURLChecker::Check::~Check() {} |
| 111 | 112 |
| 112 SupervisedUserAsyncURLChecker::CheckResult::CheckResult( | 113 SupervisedUserAsyncURLChecker::CheckResult::CheckResult( |
| 113 SupervisedUserURLFilter::FilteringBehavior behavior, bool uncertain) | 114 SupervisedUserURLFilter::FilteringBehavior behavior, |
| 114 : behavior(behavior), uncertain(uncertain) { | 115 bool uncertain) |
| 115 } | 116 : behavior(behavior), |
| 117 uncertain(uncertain), |
| 118 timestamp(base::TimeTicks::Now()) {} |
| 116 | 119 |
| 117 SupervisedUserAsyncURLChecker::SupervisedUserAsyncURLChecker( | 120 SupervisedUserAsyncURLChecker::SupervisedUserAsyncURLChecker( |
| 118 URLRequestContextGetter* context) | 121 URLRequestContextGetter* context) |
| 119 : context_(context), cache_(kDefaultCacheSize) { | 122 : SupervisedUserAsyncURLChecker(context, kDefaultCacheSize) {} |
| 120 } | |
| 121 | 123 |
| 122 SupervisedUserAsyncURLChecker::SupervisedUserAsyncURLChecker( | 124 SupervisedUserAsyncURLChecker::SupervisedUserAsyncURLChecker( |
| 123 URLRequestContextGetter* context, | 125 URLRequestContextGetter* context, |
| 124 size_t cache_size) | 126 size_t cache_size) |
| 125 : context_(context), cache_(cache_size) { | 127 : context_(context), |
| 126 } | 128 cache_(cache_size), |
| 129 cache_timeout_( |
| 130 base::TimeDelta::FromSeconds(kDefaultCacheTimeoutSeconds)) {} |
| 127 | 131 |
| 128 SupervisedUserAsyncURLChecker::~SupervisedUserAsyncURLChecker() {} | 132 SupervisedUserAsyncURLChecker::~SupervisedUserAsyncURLChecker() {} |
| 129 | 133 |
| 130 bool SupervisedUserAsyncURLChecker::CheckURL(const GURL& url, | 134 bool SupervisedUserAsyncURLChecker::CheckURL(const GURL& url, |
| 131 const CheckCallback& callback) { | 135 const CheckCallback& callback) { |
| 132 // TODO(treib): Hack: For now, allow all Google URLs to save search QPS. If we | 136 // TODO(treib): Hack: For now, allow all Google URLs to save QPS. If we ever |
| 133 // ever remove this, we should find a way to allow at least the NTP. | 137 // remove this, we should find a way to allow at least the NTP. |
| 134 if (google_util::IsGoogleDomainUrl(url, | 138 if (google_util::IsGoogleDomainUrl(url, |
| 135 google_util::ALLOW_SUBDOMAIN, | 139 google_util::ALLOW_SUBDOMAIN, |
| 136 google_util::ALLOW_NON_STANDARD_PORTS)) { | 140 google_util::ALLOW_NON_STANDARD_PORTS)) { |
| 137 callback.Run(url, SupervisedUserURLFilter::ALLOW, false); | 141 callback.Run(url, SupervisedUserURLFilter::ALLOW, false); |
| 138 return true; | 142 return true; |
| 139 } | 143 } |
| 140 // TODO(treib): Hack: For now, allow all YouTube URLs since YouTube has its | 144 // TODO(treib): Hack: For now, allow all YouTube URLs since YouTube has its |
| 141 // own Safety Mode anyway. | 145 // own Safety Mode anyway. |
| 142 if (google_util::IsYoutubeDomainUrl(url, | 146 if (google_util::IsYoutubeDomainUrl(url, |
| 143 google_util::ALLOW_SUBDOMAIN, | 147 google_util::ALLOW_SUBDOMAIN, |
| 144 google_util::ALLOW_NON_STANDARD_PORTS)) { | 148 google_util::ALLOW_NON_STANDARD_PORTS)) { |
| 145 callback.Run(url, SupervisedUserURLFilter::ALLOW, false); | 149 callback.Run(url, SupervisedUserURLFilter::ALLOW, false); |
| 146 return true; | 150 return true; |
| 147 } | 151 } |
| 148 | 152 |
| 149 auto cache_it = cache_.Get(url); | 153 auto cache_it = cache_.Get(url); |
| 150 if (cache_it != cache_.end()) { | 154 if (cache_it != cache_.end()) { |
| 151 const CheckResult& result = cache_it->second; | 155 const CheckResult& result = cache_it->second; |
| 152 DVLOG(1) << "Cache hit! " << url.spec() << " is " | 156 base::TimeDelta age = base::TimeTicks::Now() - result.timestamp; |
| 153 << (result.behavior == SupervisedUserURLFilter::BLOCK ? "NOT" : "") | 157 if (age < cache_timeout_) { |
| 154 << " safe; certain: " << !result.uncertain; | 158 DVLOG(1) << "Cache hit! " << url.spec() << " is " |
| 155 callback.Run(url, result.behavior, result.uncertain); | 159 << (result.behavior == SupervisedUserURLFilter::BLOCK ? "NOT" |
| 156 return true; | 160 : "") |
| 161 << " safe; certain: " << !result.uncertain; |
| 162 callback.Run(url, result.behavior, result.uncertain); |
| 163 return true; |
| 164 } |
| 165 DVLOG(1) << "Outdated cache entry for " << url.spec() << ", purging"; |
| 166 cache_.Erase(cache_it); |
| 157 } | 167 } |
| 158 | 168 |
| 159 // See if we already have a check in progress for this URL. | 169 // See if we already have a check in progress for this URL. |
| 160 for (Check* check : checks_in_progress_) { | 170 for (Check* check : checks_in_progress_) { |
| 161 if (check->url == url) { | 171 if (check->url == url) { |
| 162 DVLOG(1) << "Adding to pending check for " << url.spec(); | 172 DVLOG(1) << "Adding to pending check for " << url.spec(); |
| 163 check->callbacks.push_back(callback); | 173 check->callbacks.push_back(callback); |
| 164 return false; | 174 return false; |
| 165 } | 175 } |
| 166 } | 176 } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 194 } | 204 } |
| 195 | 205 |
| 196 std::string response_body; | 206 std::string response_body; |
| 197 source->GetResponseAsString(&response_body); | 207 source->GetResponseAsString(&response_body); |
| 198 bool is_porn = false; | 208 bool is_porn = false; |
| 199 bool uncertain = !ParseResponse(response_body, &is_porn); | 209 bool uncertain = !ParseResponse(response_body, &is_porn); |
| 200 SupervisedUserURLFilter::FilteringBehavior behavior = | 210 SupervisedUserURLFilter::FilteringBehavior behavior = |
| 201 is_porn ? SupervisedUserURLFilter::BLOCK : SupervisedUserURLFilter::ALLOW; | 211 is_porn ? SupervisedUserURLFilter::BLOCK : SupervisedUserURLFilter::ALLOW; |
| 202 | 212 |
| 203 UMA_HISTOGRAM_TIMES("ManagedUsers.SafeSitesDelay", | 213 UMA_HISTOGRAM_TIMES("ManagedUsers.SafeSitesDelay", |
| 204 base::Time::Now() - check->start_time); | 214 base::TimeTicks::Now() - check->start_time); |
| 205 | 215 |
| 206 cache_.Put(check->url, CheckResult(behavior, uncertain)); | 216 cache_.Put(check->url, CheckResult(behavior, uncertain)); |
| 207 | 217 |
| 208 for (size_t i = 0; i < check->callbacks.size(); i++) | 218 for (size_t i = 0; i < check->callbacks.size(); i++) |
| 209 check->callbacks[i].Run(check->url, behavior, uncertain); | 219 check->callbacks[i].Run(check->url, behavior, uncertain); |
| 210 checks_in_progress_.erase(it); | 220 checks_in_progress_.erase(it); |
| 211 } | 221 } |
| OLD | NEW |