| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "net/url_request/url_request_throttler_manager.h" | 5 #include "net/url_request/url_request_throttler_manager.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/string_util.h" | 8 #include "base/string_util.h" |
| 9 #include "net/base/net_util.h" |
| 9 | 10 |
| 10 namespace net { | 11 namespace net { |
| 11 | 12 |
| 12 const unsigned int URLRequestThrottlerManager::kMaximumNumberOfEntries = 1500; | 13 const unsigned int URLRequestThrottlerManager::kMaximumNumberOfEntries = 1500; |
| 13 const unsigned int URLRequestThrottlerManager::kRequestsBetweenCollecting = 200; | 14 const unsigned int URLRequestThrottlerManager::kRequestsBetweenCollecting = 200; |
| 14 | 15 |
| 15 URLRequestThrottlerManager* URLRequestThrottlerManager::GetInstance() { | 16 URLRequestThrottlerManager* URLRequestThrottlerManager::GetInstance() { |
| 16 return Singleton<URLRequestThrottlerManager>::get(); | 17 return Singleton<URLRequestThrottlerManager>::get(); |
| 17 } | 18 } |
| 18 | 19 |
| 19 scoped_refptr<URLRequestThrottlerEntryInterface> | 20 scoped_refptr<URLRequestThrottlerEntryInterface> |
| 20 URLRequestThrottlerManager::RegisterRequestUrl(const GURL &url) { | 21 URLRequestThrottlerManager::RegisterRequestUrl(const GURL &url) { |
| 21 DCHECK(!enable_thread_checks_ || CalledOnValidThread()); | 22 DCHECK(!enable_thread_checks_ || CalledOnValidThread()); |
| 22 | 23 |
| 23 // Normalize the url. | 24 // Normalize the url. |
| 24 std::string url_id = GetIdFromUrl(url); | 25 std::string url_id = GetIdFromUrl(url); |
| 25 | 26 |
| 26 // Periodically garbage collect old entries. | 27 // Periodically garbage collect old entries. |
| 27 GarbageCollectEntriesIfNecessary(); | 28 GarbageCollectEntriesIfNecessary(); |
| 28 | 29 |
| 29 // Find the entry in the map or create it. | 30 // Find the entry in the map or create it. |
| 30 scoped_refptr<URLRequestThrottlerEntry>& entry = url_entries_[url_id]; | 31 scoped_refptr<URLRequestThrottlerEntry>& entry = url_entries_[url_id]; |
| 31 if (entry.get() == NULL) | 32 if (entry.get() == NULL) { |
| 32 entry = new URLRequestThrottlerEntry(); | 33 entry = new URLRequestThrottlerEntry(this); |
| 34 |
| 35 // We only disable back-off throttling on an entry that we have |
| 36 // just constructed. This is to allow unit tests to explicitly override |
| 37 // the entry for localhost URLs. Given that we do not attempt to |
| 38 // disable throttling for entries already handed out (see comment |
| 39 // in AddToOptOutList), this is not a problem. |
| 40 std::string host = url.host(); |
| 41 if (opt_out_hosts_.find(host) != opt_out_hosts_.end() || |
| 42 IsLocalhost(host)) { |
| 43 // TODO(joi): Once sliding window is separate from back-off throttling, |
| 44 // we can simply return a dummy implementation of |
| 45 // URLRequestThrottlerEntryInterface here that never blocks anything (and |
| 46 // not keep entries in url_entries_ for opted-out sites). |
| 47 entry->DisableBackoffThrottling(); |
| 48 } |
| 49 } |
| 33 | 50 |
| 34 return entry; | 51 return entry; |
| 35 } | 52 } |
| 36 | 53 |
| 54 void URLRequestThrottlerManager::AddToOptOutList(const std::string& host) { |
| 55 // There is an edge case here that we are not handling, to keep things |
| 56 // simple. If a host starts adding the opt-out header to its responses |
| 57 // after there are already one or more entries in url_entries_ for that |
| 58 // host, the pre-existing entries may still perform back-off throttling. |
| 59 // In practice, this would almost never occur. |
| 60 opt_out_hosts_.insert(host); |
| 61 } |
| 62 |
| 37 void URLRequestThrottlerManager::OverrideEntryForTests( | 63 void URLRequestThrottlerManager::OverrideEntryForTests( |
| 38 const GURL& url, | 64 const GURL& url, |
| 39 URLRequestThrottlerEntry* entry) { | 65 URLRequestThrottlerEntry* entry) { |
| 40 // Normalize the url. | 66 // Normalize the url. |
| 41 std::string url_id = GetIdFromUrl(url); | 67 std::string url_id = GetIdFromUrl(url); |
| 42 | 68 |
| 43 // Periodically garbage collect old entries. | 69 // Periodically garbage collect old entries. |
| 44 GarbageCollectEntriesIfNecessary(); | 70 GarbageCollectEntriesIfNecessary(); |
| 45 | 71 |
| 46 url_entries_[url_id] = entry; | 72 url_entries_[url_id] = entry; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 url_id_replacements_.ClearPassword(); | 107 url_id_replacements_.ClearPassword(); |
| 82 url_id_replacements_.ClearUsername(); | 108 url_id_replacements_.ClearUsername(); |
| 83 url_id_replacements_.ClearQuery(); | 109 url_id_replacements_.ClearQuery(); |
| 84 url_id_replacements_.ClearRef(); | 110 url_id_replacements_.ClearRef(); |
| 85 } | 111 } |
| 86 | 112 |
| 87 URLRequestThrottlerManager::~URLRequestThrottlerManager() { | 113 URLRequestThrottlerManager::~URLRequestThrottlerManager() { |
| 88 // Destruction is on main thread (AtExit), but real use is on I/O thread. | 114 // Destruction is on main thread (AtExit), but real use is on I/O thread. |
| 89 DetachFromThread(); | 115 DetachFromThread(); |
| 90 | 116 |
| 117 // Since, for now, the manager object might conceivably go away before |
| 118 // the entries, detach the entries' back-pointer to the manager. |
| 119 // |
| 120 // TODO(joi): Revisit whether to make entries non-refcounted. |
| 121 UrlEntryMap::iterator i = url_entries_.begin(); |
| 122 while (i != url_entries_.end()) { |
| 123 if (i->second != NULL) { |
| 124 i->second->DetachManager(); |
| 125 } |
| 126 ++i; |
| 127 } |
| 128 |
| 91 // Delete all entries. | 129 // Delete all entries. |
| 92 url_entries_.clear(); | 130 url_entries_.clear(); |
| 93 } | 131 } |
| 94 | 132 |
| 95 std::string URLRequestThrottlerManager::GetIdFromUrl(const GURL& url) const { | 133 std::string URLRequestThrottlerManager::GetIdFromUrl(const GURL& url) const { |
| 96 if (!url.is_valid()) | 134 if (!url.is_valid()) |
| 97 return url.possibly_invalid_spec(); | 135 return url.possibly_invalid_spec(); |
| 98 | 136 |
| 99 GURL id = url.ReplaceComponents(url_id_replacements_); | 137 GURL id = url.ReplaceComponents(url_id_replacements_); |
| 100 return StringToLowerASCII(id.spec()).c_str(); | 138 return StringToLowerASCII(id.spec()).c_str(); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 125 } | 163 } |
| 126 } | 164 } |
| 127 | 165 |
| 128 // In case something broke we want to make sure not to grow indefinitely. | 166 // In case something broke we want to make sure not to grow indefinitely. |
| 129 while (url_entries_.size() > kMaximumNumberOfEntries) { | 167 while (url_entries_.size() > kMaximumNumberOfEntries) { |
| 130 url_entries_.erase(url_entries_.begin()); | 168 url_entries_.erase(url_entries_.begin()); |
| 131 } | 169 } |
| 132 } | 170 } |
| 133 | 171 |
| 134 } // namespace net | 172 } // namespace net |
| OLD | NEW |