• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef NET_HTTP_HTTP_AUTH_CACHE_H_
6 #define NET_HTTP_HTTP_AUTH_CACHE_H_
7 
8 #include <list>
9 #include <string>
10 
11 #include "base/ref_counted.h"
12 #include "googleurl/src/gurl.h"
13 #include "net/http/http_auth_handler.h"
14 // This is needed for the FRIEND_TEST() macro.
15 #include "testing/gtest/include/gtest/gtest_prod.h"
16 
17 namespace net {
18 
19 // TODO(eroman): Can we change the key from (origin, realm) to
20 // (origin, realm, auth_scheme)?
21 
22 // HttpAuthCache stores HTTP authentication identities and challenge info.
23 // For each realm the cache stores a HttpAuthCache::Entry, which holds:
24 //   - the realm name
25 //   - the origin server {scheme, host, port}
26 //   - the last identity used (username/password)
27 //   - the last auth handler used
28 //   - the list of paths which used this realm
29 // Entries can be looked up by either (origin, realm) or (origin, path).
30 class HttpAuthCache {
31  public:
32   class Entry;
33 
34   // Find the realm entry on server |origin| for realm |realm|.
35   //   |origin| - the {scheme, host, port} of the server.
36   //   |realm|  - case sensitive realm string.
37   //   returns  - the matched entry or NULL.
38   Entry* LookupByRealm(const GURL& origin, const std::string& realm);
39 
40   // Find the realm entry on server |origin| whose protection space includes
41   // |path|. This uses the assumption in RFC 2617 section 2 that deeper
42   // paths lie in the same protection space.
43   //   |origin| - the {scheme, host, port} of the server.
44   //   |path|   - absolute path of the resource, or empty string in case of
45   //              proxy auth (which does not use the concept of paths).
46   //   returns  - the matched entry or NULL.
47   Entry* LookupByPath(const GURL& origin, const std::string& path);
48 
49   // Add a realm entry on server |origin| for realm |handler->realm()|, If an
50   // entry for this realm already exists, update it rather than replace it --
51   // this  preserves the realm's paths list.
52   //   |origin|   - the {scheme, host, port} of the server.
53   //   |handler|  - handler for the challenge.
54   //   |username| - login information for the realm.
55   //   |password| - login information for the realm.
56   //   |path|     - absolute path for a resource contained in the protection
57   //                space; this will be added to the list of known paths.
58   //   returns    - the entry that was just added/updated.
59   Entry* Add(const GURL& origin,
60              HttpAuthHandler* handler,
61              const std::wstring& username,
62              const std::wstring& password,
63              const std::string& path);
64 
65   // Remove realm entry on server |origin| for realm |realm| if one exists
66   // AND if the cached identity matches (|username|, |password|).
67   //   |origin|   - the {scheme, host, port} of the server.
68   //   |realm|    - case sensitive realm string.
69   //   |username| - condition to match.
70   //   |password| - condition to match.
71   //   returns    - true if an entry was removed.
72   bool Remove(const GURL& origin,
73               const std::string& realm,
74               const std::wstring& username,
75               const std::wstring& password);
76 
77   // Prevent unbounded memory growth. These are safeguards for abuse; it is
78   // not expected that the limits will be reached in ordinary usage.
79   // This also defines the worst-case lookup times (which grow linearly
80   // with number of elements in the cache).
81   enum { kMaxNumPathsPerRealmEntry = 10 };
82   enum { kMaxNumRealmEntries = 10 };
83 
84  private:
85   typedef std::list<Entry> EntryList;
86   EntryList entries_;
87 };
88 
89 // An authentication realm entry.
90 class HttpAuthCache::Entry {
91  public:
origin()92   const GURL& origin() const {
93     return origin_;
94   }
95 
96   // The case-sensitive realm string of the challenge.
realm()97   const std::string realm() const {
98     return handler_->realm();
99   }
100 
101   // The handler for the challenge.
handler()102   HttpAuthHandler* handler() const {
103     return handler_.get();
104   }
105 
106   // The login username.
username()107   const std::wstring& username() const {
108     return username_;
109   }
110 
111   // The login password.
password()112   const std::wstring& password() const {
113     return password_;
114   }
115 
116  private:
117   friend class HttpAuthCache;
118   FRIEND_TEST(HttpAuthCacheTest, AddPath);
119   FRIEND_TEST(HttpAuthCacheTest, AddToExistingEntry);
120 
Entry()121   Entry() {}
122 
123   // Adds a path defining the realm's protection space. If the path is
124   // already contained in the protection space, is a no-op.
125   void AddPath(const std::string& path);
126 
127   // Returns true if |dir| is contained within the realm's protection space.
128   bool HasEnclosingPath(const std::string& dir);
129 
130   // |origin_| contains the {scheme, host, port} of the server.
131   GURL origin_;
132 
133   // Identity.
134   std::wstring username_;
135   std::wstring password_;
136 
137   // Auth handler for the challenge.
138   scoped_refptr<HttpAuthHandler> handler_;
139 
140   // List of paths that define the realm's protection space.
141   typedef std::list<std::string> PathList;
142   PathList paths_;
143 };
144 
145 } // namespace net
146 
147 #endif  // NET_HTTP_HTTP_AUTH_CACHE_H_
148