This source file includes following definitions.
- registered_from_thread_
- RegisterRequestUrl
- AddToOptOutList
- OverrideEntryForTests
- EraseEntryForTests
- set_enable_thread_checks
- enable_thread_checks
- set_net_log
- net_log
- OnIPAddressChanged
- OnConnectionTypeChanged
- GetIdFromUrl
- GarbageCollectEntriesIfNecessary
- GarbageCollectEntries
- OnNetworkChange
#include "net/url_request/url_request_throttler_manager.h"
#include "base/logging.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
#include "base/strings/string_util.h"
#include "net/base/net_log.h"
#include "net/base/net_util.h"
namespace net {
const unsigned int URLRequestThrottlerManager::kMaximumNumberOfEntries = 1500;
const unsigned int URLRequestThrottlerManager::kRequestsBetweenCollecting = 200;
URLRequestThrottlerManager::URLRequestThrottlerManager()
: requests_since_last_gc_(0),
enable_thread_checks_(false),
logged_for_localhost_disabled_(false),
registered_from_thread_(base::kInvalidThreadId) {
url_id_replacements_.ClearPassword();
url_id_replacements_.ClearUsername();
url_id_replacements_.ClearQuery();
url_id_replacements_.ClearRef();
NetworkChangeNotifier::AddIPAddressObserver(this);
NetworkChangeNotifier::AddConnectionTypeObserver(this);
}
URLRequestThrottlerManager::~URLRequestThrottlerManager() {
NetworkChangeNotifier::RemoveIPAddressObserver(this);
NetworkChangeNotifier::RemoveConnectionTypeObserver(this);
UrlEntryMap::iterator i = url_entries_.begin();
while (i != url_entries_.end()) {
if (i->second.get() != NULL) {
i->second->DetachManager();
}
++i;
}
url_entries_.clear();
}
scoped_refptr<URLRequestThrottlerEntryInterface>
URLRequestThrottlerManager::RegisterRequestUrl(const GURL &url) {
DCHECK(!enable_thread_checks_ || CalledOnValidThread());
std::string url_id = GetIdFromUrl(url);
GarbageCollectEntriesIfNecessary();
scoped_refptr<URLRequestThrottlerEntry>& entry = url_entries_[url_id];
if (entry.get() && entry->IsEntryOutdated()) {
entry = NULL;
}
if (entry.get() == NULL) {
entry = new URLRequestThrottlerEntry(this, url_id);
std::string host = url.host();
if (opt_out_hosts_.find(host) != opt_out_hosts_.end() ||
IsLocalhost(host)) {
if (!logged_for_localhost_disabled_ && IsLocalhost(host)) {
logged_for_localhost_disabled_ = true;
net_log_.AddEvent(NetLog::TYPE_THROTTLING_DISABLED_FOR_HOST,
NetLog::StringCallback("host", &host));
}
entry->DisableBackoffThrottling();
}
}
return entry;
}
void URLRequestThrottlerManager::AddToOptOutList(const std::string& host) {
if (opt_out_hosts_.find(host) == opt_out_hosts_.end()) {
UMA_HISTOGRAM_COUNTS("Throttling.SiteOptedOut", 1);
net_log_.EndEvent(NetLog::TYPE_THROTTLING_DISABLED_FOR_HOST,
NetLog::StringCallback("host", &host));
opt_out_hosts_.insert(host);
}
}
void URLRequestThrottlerManager::OverrideEntryForTests(
const GURL& url,
URLRequestThrottlerEntry* entry) {
std::string url_id = GetIdFromUrl(url);
GarbageCollectEntriesIfNecessary();
url_entries_[url_id] = entry;
}
void URLRequestThrottlerManager::EraseEntryForTests(const GURL& url) {
std::string url_id = GetIdFromUrl(url);
url_entries_.erase(url_id);
}
void URLRequestThrottlerManager::set_enable_thread_checks(bool enable) {
enable_thread_checks_ = enable;
}
bool URLRequestThrottlerManager::enable_thread_checks() const {
return enable_thread_checks_;
}
void URLRequestThrottlerManager::set_net_log(NetLog* net_log) {
DCHECK(net_log);
net_log_ = BoundNetLog::Make(net_log,
NetLog::SOURCE_EXPONENTIAL_BACKOFF_THROTTLING);
}
NetLog* URLRequestThrottlerManager::net_log() const {
return net_log_.net_log();
}
void URLRequestThrottlerManager::OnIPAddressChanged() {
OnNetworkChange();
}
void URLRequestThrottlerManager::OnConnectionTypeChanged(
NetworkChangeNotifier::ConnectionType type) {
OnNetworkChange();
}
std::string URLRequestThrottlerManager::GetIdFromUrl(const GURL& url) const {
if (!url.is_valid())
return url.possibly_invalid_spec();
GURL id = url.ReplaceComponents(url_id_replacements_);
return StringToLowerASCII(id.spec()).c_str();
}
void URLRequestThrottlerManager::GarbageCollectEntriesIfNecessary() {
requests_since_last_gc_++;
if (requests_since_last_gc_ < kRequestsBetweenCollecting)
return;
requests_since_last_gc_ = 0;
GarbageCollectEntries();
}
void URLRequestThrottlerManager::GarbageCollectEntries() {
UrlEntryMap::iterator i = url_entries_.begin();
while (i != url_entries_.end()) {
if ((i->second)->IsEntryOutdated()) {
url_entries_.erase(i++);
} else {
++i;
}
}
while (url_entries_.size() > kMaximumNumberOfEntries) {
url_entries_.erase(url_entries_.begin());
}
}
void URLRequestThrottlerManager::OnNetworkChange() {
url_entries_.clear();
requests_since_last_gc_ = 0;
}
}