| 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 |