| Index: net/http/http_auth_cache.cc
|
| diff --git a/net/http/http_auth_cache.cc b/net/http/http_auth_cache.cc
|
| deleted file mode 100644
|
| index 51f9035cb08e0b6e173357f1e18788428ea6f7a2..0000000000000000000000000000000000000000
|
| --- a/net/http/http_auth_cache.cc
|
| +++ /dev/null
|
| @@ -1,285 +0,0 @@
|
| -// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "net/http/http_auth_cache.h"
|
| -
|
| -#include "base/logging.h"
|
| -#include "base/metrics/histogram.h"
|
| -#include "base/strings/string_util.h"
|
| -
|
| -namespace {
|
| -
|
| -// Helper to find the containing directory of path. In RFC 2617 this is what
|
| -// they call the "last symbolic element in the absolute path".
|
| -// Examples:
|
| -// "/foo/bar.txt" --> "/foo/"
|
| -// "/foo/" --> "/foo/"
|
| -std::string GetParentDirectory(const std::string& path) {
|
| - std::string::size_type last_slash = path.rfind("/");
|
| - if (last_slash == std::string::npos) {
|
| - // No slash (absolute paths always start with slash, so this must be
|
| - // the proxy case which uses empty string).
|
| - DCHECK(path.empty());
|
| - return path;
|
| - }
|
| - return path.substr(0, last_slash + 1);
|
| -}
|
| -
|
| -// Debug helper to check that |path| arguments are properly formed.
|
| -// (should be absolute path, or empty string).
|
| -void CheckPathIsValid(const std::string& path) {
|
| - DCHECK(path.empty() || path[0] == '/');
|
| -}
|
| -
|
| -// Return true if |path| is a subpath of |container|. In other words, is
|
| -// |container| an ancestor of |path|?
|
| -bool IsEnclosingPath(const std::string& container, const std::string& path) {
|
| - DCHECK(container.empty() || *(container.end() - 1) == '/');
|
| - return ((container.empty() && path.empty()) ||
|
| - (!container.empty() && StartsWithASCII(path, container, true)));
|
| -}
|
| -
|
| -// Debug helper to check that |origin| arguments are properly formed.
|
| -void CheckOriginIsValid(const GURL& origin) {
|
| - DCHECK(origin.is_valid());
|
| - // Note that the scheme may be FTP when we're using a HTTP proxy.
|
| - DCHECK(origin.SchemeIsHTTPOrHTTPS() || origin.SchemeIs("ftp") ||
|
| - origin.SchemeIsWSOrWSS());
|
| - DCHECK(origin.GetOrigin() == origin);
|
| -}
|
| -
|
| -// Functor used by remove_if.
|
| -struct IsEnclosedBy {
|
| - explicit IsEnclosedBy(const std::string& path) : path(path) { }
|
| - bool operator() (const std::string& x) const {
|
| - return IsEnclosingPath(path, x);
|
| - }
|
| - const std::string& path;
|
| -};
|
| -
|
| -void RecordLookupPosition(int position) {
|
| - UMA_HISTOGRAM_COUNTS_100("Net.HttpAuthCacheLookupPosition", position);
|
| -}
|
| -
|
| -void RecordLookupByPathPosition(int position) {
|
| - UMA_HISTOGRAM_COUNTS_100("Net.HttpAuthCacheLookupByPathPosition", position);
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -namespace net {
|
| -
|
| -HttpAuthCache::HttpAuthCache() {
|
| -}
|
| -
|
| -HttpAuthCache::~HttpAuthCache() {
|
| -}
|
| -
|
| -// Performance: O(n), where n is the number of realm entries.
|
| -HttpAuthCache::Entry* HttpAuthCache::Lookup(const GURL& origin,
|
| - const std::string& realm,
|
| - HttpAuth::Scheme scheme) {
|
| - CheckOriginIsValid(origin);
|
| -
|
| - int entries_examined = 0;
|
| - // Linear scan through the realm entries.
|
| - for (EntryList::iterator it = entries_.begin(); it != entries_.end(); ++it) {
|
| - ++entries_examined;
|
| - if (it->origin() == origin && it->realm() == realm &&
|
| - it->scheme() == scheme) {
|
| - it->last_use_time_ = base::TimeTicks::Now();
|
| - RecordLookupPosition(entries_examined);
|
| - return &(*it);
|
| - }
|
| - }
|
| - RecordLookupPosition(0);
|
| - return NULL; // No realm entry found.
|
| -}
|
| -
|
| -// Performance: O(n*m), where n is the number of realm entries, m is the number
|
| -// of path entries per realm. Both n amd m are expected to be small; m is
|
| -// kept small because AddPath() only keeps the shallowest entry.
|
| -HttpAuthCache::Entry* HttpAuthCache::LookupByPath(const GURL& origin,
|
| - const std::string& path) {
|
| - HttpAuthCache::Entry* best_match = NULL;
|
| - size_t best_match_length = 0;
|
| - int best_match_position = 0;
|
| - CheckOriginIsValid(origin);
|
| - CheckPathIsValid(path);
|
| -
|
| - // RFC 2617 section 2:
|
| - // A client SHOULD assume that all paths at or deeper than the depth of
|
| - // the last symbolic element in the path field of the Request-URI also are
|
| - // within the protection space ...
|
| - std::string parent_dir = GetParentDirectory(path);
|
| -
|
| - int entries_examined = 0;
|
| - // Linear scan through the realm entries.
|
| - for (EntryList::iterator it = entries_.begin(); it != entries_.end(); ++it) {
|
| - ++entries_examined;
|
| - size_t len = 0;
|
| - if (it->origin() == origin && it->HasEnclosingPath(parent_dir, &len) &&
|
| - (!best_match || len > best_match_length)) {
|
| - best_match = &(*it);
|
| - best_match_length = len;
|
| - best_match_position = entries_examined;
|
| - }
|
| - }
|
| - if (best_match)
|
| - best_match->last_use_time_ = base::TimeTicks::Now();
|
| - RecordLookupByPathPosition(best_match_position);
|
| - return best_match;
|
| -}
|
| -
|
| -HttpAuthCache::Entry* HttpAuthCache::Add(const GURL& origin,
|
| - const std::string& realm,
|
| - HttpAuth::Scheme scheme,
|
| - const std::string& auth_challenge,
|
| - const AuthCredentials& credentials,
|
| - const std::string& path) {
|
| - CheckOriginIsValid(origin);
|
| - CheckPathIsValid(path);
|
| -
|
| - base::TimeTicks now = base::TimeTicks::Now();
|
| -
|
| - // Check for existing entry (we will re-use it if present).
|
| - HttpAuthCache::Entry* entry = Lookup(origin, realm, scheme);
|
| - if (!entry) {
|
| - bool evicted = false;
|
| - // Failsafe to prevent unbounded memory growth of the cache.
|
| - if (entries_.size() >= kMaxNumRealmEntries) {
|
| - LOG(WARNING) << "Num auth cache entries reached limit -- evicting";
|
| - UMA_HISTOGRAM_LONG_TIMES("Net.HttpAuthCacheAddEvictedCreation",
|
| - now - entries_.back().creation_time_);
|
| - UMA_HISTOGRAM_LONG_TIMES("Net.HttpAuthCacheAddEvictedLastUse",
|
| - now - entries_.back().last_use_time_);
|
| - entries_.pop_back();
|
| - evicted = true;
|
| - }
|
| - UMA_HISTOGRAM_BOOLEAN("Net.HttpAuthCacheAddEvicted", evicted);
|
| -
|
| - entries_.push_front(Entry());
|
| - entry = &entries_.front();
|
| - entry->origin_ = origin;
|
| - entry->realm_ = realm;
|
| - entry->scheme_ = scheme;
|
| - entry->creation_time_ = now;
|
| - }
|
| - DCHECK_EQ(origin, entry->origin_);
|
| - DCHECK_EQ(realm, entry->realm_);
|
| - DCHECK_EQ(scheme, entry->scheme_);
|
| -
|
| - entry->auth_challenge_ = auth_challenge;
|
| - entry->credentials_ = credentials;
|
| - entry->nonce_count_ = 1;
|
| - entry->AddPath(path);
|
| - entry->last_use_time_ = now;
|
| -
|
| - return entry;
|
| -}
|
| -
|
| -HttpAuthCache::Entry::~Entry() {
|
| -}
|
| -
|
| -void HttpAuthCache::Entry::UpdateStaleChallenge(
|
| - const std::string& auth_challenge) {
|
| - auth_challenge_ = auth_challenge;
|
| - nonce_count_ = 1;
|
| -}
|
| -
|
| -HttpAuthCache::Entry::Entry()
|
| - : scheme_(HttpAuth::AUTH_SCHEME_MAX),
|
| - nonce_count_(0) {
|
| -}
|
| -
|
| -void HttpAuthCache::Entry::AddPath(const std::string& path) {
|
| - std::string parent_dir = GetParentDirectory(path);
|
| - if (!HasEnclosingPath(parent_dir, NULL)) {
|
| - // Remove any entries that have been subsumed by the new entry.
|
| - paths_.remove_if(IsEnclosedBy(parent_dir));
|
| -
|
| - bool evicted = false;
|
| - // Failsafe to prevent unbounded memory growth of the cache.
|
| - if (paths_.size() >= kMaxNumPathsPerRealmEntry) {
|
| - LOG(WARNING) << "Num path entries for " << origin()
|
| - << " has grown too large -- evicting";
|
| - paths_.pop_back();
|
| - evicted = true;
|
| - }
|
| - UMA_HISTOGRAM_BOOLEAN("Net.HttpAuthCacheAddPathEvicted", evicted);
|
| -
|
| - // Add new path.
|
| - paths_.push_front(parent_dir);
|
| - }
|
| -}
|
| -
|
| -bool HttpAuthCache::Entry::HasEnclosingPath(const std::string& dir,
|
| - size_t* path_len) {
|
| - DCHECK(GetParentDirectory(dir) == dir);
|
| - for (PathList::const_iterator it = paths_.begin(); it != paths_.end();
|
| - ++it) {
|
| - if (IsEnclosingPath(*it, dir)) {
|
| - // No element of paths_ may enclose any other element.
|
| - // Therefore this path is the tightest bound. Important because
|
| - // the length returned is used to determine the cache entry that
|
| - // has the closest enclosing path in LookupByPath().
|
| - if (path_len)
|
| - *path_len = it->length();
|
| - return true;
|
| - }
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -bool HttpAuthCache::Remove(const GURL& origin,
|
| - const std::string& realm,
|
| - HttpAuth::Scheme scheme,
|
| - const AuthCredentials& credentials) {
|
| - for (EntryList::iterator it = entries_.begin(); it != entries_.end(); ++it) {
|
| - if (it->origin() == origin && it->realm() == realm &&
|
| - it->scheme() == scheme) {
|
| - if (credentials.Equals(it->credentials())) {
|
| - entries_.erase(it);
|
| - return true;
|
| - }
|
| - return false;
|
| - }
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -void HttpAuthCache::Clear() {
|
| - entries_.clear();
|
| -}
|
| -
|
| -bool HttpAuthCache::UpdateStaleChallenge(const GURL& origin,
|
| - const std::string& realm,
|
| - HttpAuth::Scheme scheme,
|
| - const std::string& auth_challenge) {
|
| - HttpAuthCache::Entry* entry = Lookup(origin, realm, scheme);
|
| - if (!entry)
|
| - return false;
|
| - entry->UpdateStaleChallenge(auth_challenge);
|
| - entry->last_use_time_ = base::TimeTicks::Now();
|
| - return true;
|
| -}
|
| -
|
| -void HttpAuthCache::UpdateAllFrom(const HttpAuthCache& other) {
|
| - for (EntryList::const_iterator it = other.entries_.begin();
|
| - it != other.entries_.end(); ++it) {
|
| - // Add an Entry with one of the original entry's paths.
|
| - DCHECK(it->paths_.size() > 0);
|
| - Entry* entry = Add(it->origin(), it->realm(), it->scheme(),
|
| - it->auth_challenge(), it->credentials(),
|
| - it->paths_.back());
|
| - // Copy all other paths.
|
| - for (Entry::PathList::const_reverse_iterator it2 = ++it->paths_.rbegin();
|
| - it2 != it->paths_.rend(); ++it2)
|
| - entry->AddPath(*it2);
|
| - // Copy nonce count (for digest authentication).
|
| - entry->nonce_count_ = it->nonce_count_;
|
| - }
|
| -}
|
| -
|
| -} // namespace net
|
|
|