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/http/http_auth_cache.h" | 5 #include "net/http/http_auth_cache.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
9 #include "base/strings/string_util.h" | 9 #include "base/strings/string_util.h" |
10 | 10 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 void CheckOriginIsValid(const GURL& origin) { | 44 void CheckOriginIsValid(const GURL& origin) { |
45 DCHECK(origin.is_valid()); | 45 DCHECK(origin.is_valid()); |
46 // Note that the scheme may be FTP when we're using a HTTP proxy. | 46 // Note that the scheme may be FTP when we're using a HTTP proxy. |
47 DCHECK(origin.SchemeIsHTTPOrHTTPS() || origin.SchemeIs("ftp") || | 47 DCHECK(origin.SchemeIsHTTPOrHTTPS() || origin.SchemeIs("ftp") || |
48 origin.SchemeIsWSOrWSS()); | 48 origin.SchemeIsWSOrWSS()); |
49 DCHECK(origin.GetOrigin() == origin); | 49 DCHECK(origin.GetOrigin() == origin); |
50 } | 50 } |
51 | 51 |
52 // Functor used by remove_if. | 52 // Functor used by remove_if. |
53 struct IsEnclosedBy { | 53 struct IsEnclosedBy { |
54 explicit IsEnclosedBy(const std::string& path) : path(path) { } | 54 explicit IsEnclosedBy(const std::string& path) : path(path) {} |
55 bool operator() (const std::string& x) const { | 55 bool operator()(const std::string& x) const { |
56 return IsEnclosingPath(path, x); | 56 return IsEnclosingPath(path, x); |
57 } | 57 } |
58 const std::string& path; | 58 const std::string& path; |
59 }; | 59 }; |
60 | 60 |
61 void RecordLookupPosition(int position) { | 61 void RecordLookupPosition(int position) { |
62 UMA_HISTOGRAM_COUNTS_100("Net.HttpAuthCacheLookupPosition", position); | 62 UMA_HISTOGRAM_COUNTS_100("Net.HttpAuthCacheLookupPosition", position); |
63 } | 63 } |
64 | 64 |
65 void RecordLookupByPathPosition(int position) { | 65 void RecordLookupByPathPosition(int position) { |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
144 base::TimeTicks now = base::TimeTicks::Now(); | 144 base::TimeTicks now = base::TimeTicks::Now(); |
145 | 145 |
146 // Check for existing entry (we will re-use it if present). | 146 // Check for existing entry (we will re-use it if present). |
147 HttpAuthCache::Entry* entry = Lookup(origin, realm, scheme); | 147 HttpAuthCache::Entry* entry = Lookup(origin, realm, scheme); |
148 if (!entry) { | 148 if (!entry) { |
149 bool evicted = false; | 149 bool evicted = false; |
150 // Failsafe to prevent unbounded memory growth of the cache. | 150 // Failsafe to prevent unbounded memory growth of the cache. |
151 if (entries_.size() >= kMaxNumRealmEntries) { | 151 if (entries_.size() >= kMaxNumRealmEntries) { |
152 LOG(WARNING) << "Num auth cache entries reached limit -- evicting"; | 152 LOG(WARNING) << "Num auth cache entries reached limit -- evicting"; |
153 UMA_HISTOGRAM_LONG_TIMES("Net.HttpAuthCacheAddEvictedCreation", | 153 UMA_HISTOGRAM_LONG_TIMES("Net.HttpAuthCacheAddEvictedCreation", |
154 now - entries_.back().creation_time_); | 154 now - entries_.back().creation_time_); |
155 UMA_HISTOGRAM_LONG_TIMES("Net.HttpAuthCacheAddEvictedLastUse", | 155 UMA_HISTOGRAM_LONG_TIMES("Net.HttpAuthCacheAddEvictedLastUse", |
156 now - entries_.back().last_use_time_); | 156 now - entries_.back().last_use_time_); |
157 entries_.pop_back(); | 157 entries_.pop_back(); |
158 evicted = true; | 158 evicted = true; |
159 } | 159 } |
160 UMA_HISTOGRAM_BOOLEAN("Net.HttpAuthCacheAddEvicted", evicted); | 160 UMA_HISTOGRAM_BOOLEAN("Net.HttpAuthCacheAddEvicted", evicted); |
161 | 161 |
162 entries_.push_front(Entry()); | 162 entries_.push_front(Entry()); |
163 entry = &entries_.front(); | 163 entry = &entries_.front(); |
164 entry->origin_ = origin; | 164 entry->origin_ = origin; |
165 entry->realm_ = realm; | 165 entry->realm_ = realm; |
166 entry->scheme_ = scheme; | 166 entry->scheme_ = scheme; |
(...skipping 15 matching lines...) Expand all Loading... |
182 HttpAuthCache::Entry::~Entry() { | 182 HttpAuthCache::Entry::~Entry() { |
183 } | 183 } |
184 | 184 |
185 void HttpAuthCache::Entry::UpdateStaleChallenge( | 185 void HttpAuthCache::Entry::UpdateStaleChallenge( |
186 const std::string& auth_challenge) { | 186 const std::string& auth_challenge) { |
187 auth_challenge_ = auth_challenge; | 187 auth_challenge_ = auth_challenge; |
188 nonce_count_ = 1; | 188 nonce_count_ = 1; |
189 } | 189 } |
190 | 190 |
191 HttpAuthCache::Entry::Entry() | 191 HttpAuthCache::Entry::Entry() |
192 : scheme_(HttpAuth::AUTH_SCHEME_MAX), | 192 : scheme_(HttpAuth::AUTH_SCHEME_MAX), nonce_count_(0) { |
193 nonce_count_(0) { | |
194 } | 193 } |
195 | 194 |
196 void HttpAuthCache::Entry::AddPath(const std::string& path) { | 195 void HttpAuthCache::Entry::AddPath(const std::string& path) { |
197 std::string parent_dir = GetParentDirectory(path); | 196 std::string parent_dir = GetParentDirectory(path); |
198 if (!HasEnclosingPath(parent_dir, NULL)) { | 197 if (!HasEnclosingPath(parent_dir, NULL)) { |
199 // Remove any entries that have been subsumed by the new entry. | 198 // Remove any entries that have been subsumed by the new entry. |
200 paths_.remove_if(IsEnclosedBy(parent_dir)); | 199 paths_.remove_if(IsEnclosedBy(parent_dir)); |
201 | 200 |
202 bool evicted = false; | 201 bool evicted = false; |
203 // Failsafe to prevent unbounded memory growth of the cache. | 202 // Failsafe to prevent unbounded memory growth of the cache. |
204 if (paths_.size() >= kMaxNumPathsPerRealmEntry) { | 203 if (paths_.size() >= kMaxNumPathsPerRealmEntry) { |
205 LOG(WARNING) << "Num path entries for " << origin() | 204 LOG(WARNING) << "Num path entries for " << origin() |
206 << " has grown too large -- evicting"; | 205 << " has grown too large -- evicting"; |
207 paths_.pop_back(); | 206 paths_.pop_back(); |
208 evicted = true; | 207 evicted = true; |
209 } | 208 } |
210 UMA_HISTOGRAM_BOOLEAN("Net.HttpAuthCacheAddPathEvicted", evicted); | 209 UMA_HISTOGRAM_BOOLEAN("Net.HttpAuthCacheAddPathEvicted", evicted); |
211 | 210 |
212 // Add new path. | 211 // Add new path. |
213 paths_.push_front(parent_dir); | 212 paths_.push_front(parent_dir); |
214 } | 213 } |
215 } | 214 } |
216 | 215 |
217 bool HttpAuthCache::Entry::HasEnclosingPath(const std::string& dir, | 216 bool HttpAuthCache::Entry::HasEnclosingPath(const std::string& dir, |
218 size_t* path_len) { | 217 size_t* path_len) { |
219 DCHECK(GetParentDirectory(dir) == dir); | 218 DCHECK(GetParentDirectory(dir) == dir); |
220 for (PathList::const_iterator it = paths_.begin(); it != paths_.end(); | 219 for (PathList::const_iterator it = paths_.begin(); it != paths_.end(); ++it) { |
221 ++it) { | |
222 if (IsEnclosingPath(*it, dir)) { | 220 if (IsEnclosingPath(*it, dir)) { |
223 // No element of paths_ may enclose any other element. | 221 // No element of paths_ may enclose any other element. |
224 // Therefore this path is the tightest bound. Important because | 222 // Therefore this path is the tightest bound. Important because |
225 // the length returned is used to determine the cache entry that | 223 // the length returned is used to determine the cache entry that |
226 // has the closest enclosing path in LookupByPath(). | 224 // has the closest enclosing path in LookupByPath(). |
227 if (path_len) | 225 if (path_len) |
228 *path_len = it->length(); | 226 *path_len = it->length(); |
229 return true; | 227 return true; |
230 } | 228 } |
231 } | 229 } |
(...skipping 24 matching lines...) Expand all Loading... |
256 HttpAuthCache::Entry* entry = Lookup(origin, realm, scheme); | 254 HttpAuthCache::Entry* entry = Lookup(origin, realm, scheme); |
257 if (!entry) | 255 if (!entry) |
258 return false; | 256 return false; |
259 entry->UpdateStaleChallenge(auth_challenge); | 257 entry->UpdateStaleChallenge(auth_challenge); |
260 entry->last_use_time_ = base::TimeTicks::Now(); | 258 entry->last_use_time_ = base::TimeTicks::Now(); |
261 return true; | 259 return true; |
262 } | 260 } |
263 | 261 |
264 void HttpAuthCache::UpdateAllFrom(const HttpAuthCache& other) { | 262 void HttpAuthCache::UpdateAllFrom(const HttpAuthCache& other) { |
265 for (EntryList::const_iterator it = other.entries_.begin(); | 263 for (EntryList::const_iterator it = other.entries_.begin(); |
266 it != other.entries_.end(); ++it) { | 264 it != other.entries_.end(); |
| 265 ++it) { |
267 // Add an Entry with one of the original entry's paths. | 266 // Add an Entry with one of the original entry's paths. |
268 DCHECK(it->paths_.size() > 0); | 267 DCHECK(it->paths_.size() > 0); |
269 Entry* entry = Add(it->origin(), it->realm(), it->scheme(), | 268 Entry* entry = Add(it->origin(), |
270 it->auth_challenge(), it->credentials(), | 269 it->realm(), |
| 270 it->scheme(), |
| 271 it->auth_challenge(), |
| 272 it->credentials(), |
271 it->paths_.back()); | 273 it->paths_.back()); |
272 // Copy all other paths. | 274 // Copy all other paths. |
273 for (Entry::PathList::const_reverse_iterator it2 = ++it->paths_.rbegin(); | 275 for (Entry::PathList::const_reverse_iterator it2 = ++it->paths_.rbegin(); |
274 it2 != it->paths_.rend(); ++it2) | 276 it2 != it->paths_.rend(); |
| 277 ++it2) |
275 entry->AddPath(*it2); | 278 entry->AddPath(*it2); |
276 // Copy nonce count (for digest authentication). | 279 // Copy nonce count (for digest authentication). |
277 entry->nonce_count_ = it->nonce_count_; | 280 entry->nonce_count_ = it->nonce_count_; |
278 } | 281 } |
279 } | 282 } |
280 | 283 |
281 } // namespace net | 284 } // namespace net |
OLD | NEW |