| 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(being_tested_ || CalledOnValidThread()); | 22 DCHECK(being_tested_ || 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 30 matching lines...) Expand all Loading... |
| 77 url_id_replacements_.ClearPassword(); | 103 url_id_replacements_.ClearPassword(); |
| 78 url_id_replacements_.ClearUsername(); | 104 url_id_replacements_.ClearUsername(); |
| 79 url_id_replacements_.ClearQuery(); | 105 url_id_replacements_.ClearQuery(); |
| 80 url_id_replacements_.ClearRef(); | 106 url_id_replacements_.ClearRef(); |
| 81 } | 107 } |
| 82 | 108 |
| 83 URLRequestThrottlerManager::~URLRequestThrottlerManager() { | 109 URLRequestThrottlerManager::~URLRequestThrottlerManager() { |
| 84 // Destruction is on main thread (AtExit), but real use is on I/O thread. | 110 // Destruction is on main thread (AtExit), but real use is on I/O thread. |
| 85 DetachFromThread(); | 111 DetachFromThread(); |
| 86 | 112 |
| 113 // Since, for now, the manager object might conceivably go away before |
| 114 // the entries, detach the entries' back-pointer to the manager. |
| 115 // |
| 116 // TODO(joi): Revisit whether to make entries non-refcounted. |
| 117 UrlEntryMap::iterator i = url_entries_.begin(); |
| 118 while (i != url_entries_.end()) { |
| 119 if (i->second != NULL) { |
| 120 i->second->DetachManager(); |
| 121 } |
| 122 ++i; |
| 123 } |
| 124 |
| 87 // Delete all entries. | 125 // Delete all entries. |
| 88 url_entries_.clear(); | 126 url_entries_.clear(); |
| 89 } | 127 } |
| 90 | 128 |
| 91 std::string URLRequestThrottlerManager::GetIdFromUrl(const GURL& url) const { | 129 std::string URLRequestThrottlerManager::GetIdFromUrl(const GURL& url) const { |
| 92 if (!url.is_valid()) | 130 if (!url.is_valid()) |
| 93 return url.possibly_invalid_spec(); | 131 return url.possibly_invalid_spec(); |
| 94 | 132 |
| 95 GURL id = url.ReplaceComponents(url_id_replacements_); | 133 GURL id = url.ReplaceComponents(url_id_replacements_); |
| 96 return StringToLowerASCII(id.spec()).c_str(); | 134 return StringToLowerASCII(id.spec()).c_str(); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 121 } | 159 } |
| 122 } | 160 } |
| 123 | 161 |
| 124 // In case something broke we want to make sure not to grow indefinitely. | 162 // In case something broke we want to make sure not to grow indefinitely. |
| 125 while (url_entries_.size() > kMaximumNumberOfEntries) { | 163 while (url_entries_.size() > kMaximumNumberOfEntries) { |
| 126 url_entries_.erase(url_entries_.begin()); | 164 url_entries_.erase(url_entries_.begin()); |
| 127 } | 165 } |
| 128 } | 166 } |
| 129 | 167 |
| 130 } // namespace net | 168 } // namespace net |
| OLD | NEW |