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
3 // found in the LICENSE file.
7 #include "base/strings/string16.h"
8 #include "base/strings/string_util.h"
9 #include "base/strings/stringprintf.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "net/base/net_errors.h"
12 #include "net/http/http_auth_cache.h"
13 #include "net/http/http_auth_handler.h"
14 #include "testing/gtest/include/gtest/gtest.h"
20 class MockAuthHandler
: public HttpAuthHandler
{
22 MockAuthHandler(HttpAuth::Scheme scheme
,
23 const std::string
& realm
,
24 HttpAuth::Target target
) {
25 // Can't use initializer list since these are members of the base class.
26 auth_scheme_
= scheme
;
33 virtual HttpAuth::AuthorizationResult
HandleAnotherChallenge(
34 HttpAuth::ChallengeTokenizer
* challenge
) OVERRIDE
{
35 return HttpAuth::AUTHORIZATION_RESULT_REJECT
;
39 virtual bool Init(HttpAuth::ChallengeTokenizer
* challenge
) OVERRIDE
{
40 return false; // Unused.
43 virtual int GenerateAuthTokenImpl(const AuthCredentials
*,
44 const HttpRequestInfo
*,
45 const CompletionCallback
& callback
,
46 std::string
* auth_token
) OVERRIDE
{
47 *auth_token
= "mock-credentials";
53 virtual ~MockAuthHandler() {}
56 const char* kRealm1
= "Realm1";
57 const char* kRealm2
= "Realm2";
58 const char* kRealm3
= "Realm3";
59 const char* kRealm4
= "Realm4";
60 const char* kRealm5
= "Realm5";
61 const base::string16
k123(ASCIIToUTF16("123"));
62 const base::string16
k1234(ASCIIToUTF16("1234"));
63 const base::string16
kAdmin(ASCIIToUTF16("admin"));
64 const base::string16
kAlice(ASCIIToUTF16("alice"));
65 const base::string16
kAlice2(ASCIIToUTF16("alice2"));
66 const base::string16
kPassword(ASCIIToUTF16("password"));
67 const base::string16
kRoot(ASCIIToUTF16("root"));
68 const base::string16
kUsername(ASCIIToUTF16("username"));
69 const base::string16
kWileCoyote(ASCIIToUTF16("wilecoyote"));
71 AuthCredentials
CreateASCIICredentials(const char* username
,
72 const char* password
) {
73 return AuthCredentials(ASCIIToUTF16(username
), ASCIIToUTF16(password
));
78 // Test adding and looking-up cache entries (both by realm and by path).
79 TEST(HttpAuthCacheTest
, Basic
) {
80 GURL
origin("http://www.google.com");
82 HttpAuthCache::Entry
* entry
;
84 // Add cache entries for 4 realms: "Realm1", "Realm2", "Realm3" and
87 scoped_ptr
<HttpAuthHandler
> realm1_handler(
88 new MockAuthHandler(HttpAuth::AUTH_SCHEME_BASIC
,
90 HttpAuth::AUTH_SERVER
));
91 cache
.Add(origin
, realm1_handler
->realm(), realm1_handler
->auth_scheme(),
93 CreateASCIICredentials("realm1-user", "realm1-password"),
94 "/foo/bar/index.html");
96 scoped_ptr
<HttpAuthHandler
> realm2_handler(
97 new MockAuthHandler(HttpAuth::AUTH_SCHEME_BASIC
,
99 HttpAuth::AUTH_SERVER
));
100 cache
.Add(origin
, realm2_handler
->realm(), realm2_handler
->auth_scheme(),
101 "Basic realm=Realm2",
102 CreateASCIICredentials("realm2-user", "realm2-password"),
105 scoped_ptr
<HttpAuthHandler
> realm3_basic_handler(
106 new MockAuthHandler(HttpAuth::AUTH_SCHEME_BASIC
,
108 HttpAuth::AUTH_PROXY
));
111 realm3_basic_handler
->realm(),
112 realm3_basic_handler
->auth_scheme(),
113 "Basic realm=Realm3",
114 CreateASCIICredentials("realm3-basic-user", "realm3-basic-password"),
117 scoped_ptr
<HttpAuthHandler
> realm3_digest_handler(
118 new MockAuthHandler(HttpAuth::AUTH_SCHEME_DIGEST
,
120 HttpAuth::AUTH_PROXY
));
121 cache
.Add(origin
, realm3_digest_handler
->realm(),
122 realm3_digest_handler
->auth_scheme(), "Digest realm=Realm3",
123 CreateASCIICredentials("realm3-digest-user",
124 "realm3-digest-password"),
127 scoped_ptr
<HttpAuthHandler
> realm4_basic_handler(
128 new MockAuthHandler(HttpAuth::AUTH_SCHEME_BASIC
,
130 HttpAuth::AUTH_SERVER
));
131 cache
.Add(origin
, realm4_basic_handler
->realm(),
132 realm4_basic_handler
->auth_scheme(), "Basic realm=Realm4",
133 CreateASCIICredentials("realm4-basic-user",
134 "realm4-basic-password"),
137 // There is no Realm5
138 entry
= cache
.Lookup(origin
, kRealm5
, HttpAuth::AUTH_SCHEME_BASIC
);
139 EXPECT_TRUE(NULL
== entry
);
141 // While Realm3 does exist, the origin scheme is wrong.
142 entry
= cache
.Lookup(GURL("https://www.google.com"), kRealm3
,
143 HttpAuth::AUTH_SCHEME_BASIC
);
144 EXPECT_TRUE(NULL
== entry
);
146 // Realm, origin scheme ok, authentication scheme wrong
148 (GURL("http://www.google.com"), kRealm1
, HttpAuth::AUTH_SCHEME_DIGEST
);
149 EXPECT_TRUE(NULL
== entry
);
151 // Valid lookup by origin, realm, scheme.
152 entry
= cache
.Lookup(
153 GURL("http://www.google.com:80"), kRealm3
, HttpAuth::AUTH_SCHEME_BASIC
);
154 ASSERT_FALSE(NULL
== entry
);
155 EXPECT_EQ(HttpAuth::AUTH_SCHEME_BASIC
, entry
->scheme());
156 EXPECT_EQ(kRealm3
, entry
->realm());
157 EXPECT_EQ("Basic realm=Realm3", entry
->auth_challenge());
158 EXPECT_EQ(ASCIIToUTF16("realm3-basic-user"), entry
->credentials().username());
159 EXPECT_EQ(ASCIIToUTF16("realm3-basic-password"),
160 entry
->credentials().password());
162 // Valid lookup by origin, realm, scheme when there's a duplicate
163 // origin, realm in the cache
164 entry
= cache
.Lookup(
165 GURL("http://www.google.com:80"), kRealm3
, HttpAuth::AUTH_SCHEME_DIGEST
);
166 ASSERT_FALSE(NULL
== entry
);
167 EXPECT_EQ(HttpAuth::AUTH_SCHEME_DIGEST
, entry
->scheme());
168 EXPECT_EQ(kRealm3
, entry
->realm());
169 EXPECT_EQ("Digest realm=Realm3", entry
->auth_challenge());
170 EXPECT_EQ(ASCIIToUTF16("realm3-digest-user"),
171 entry
->credentials().username());
172 EXPECT_EQ(ASCIIToUTF16("realm3-digest-password"),
173 entry
->credentials().password());
175 // Valid lookup by realm.
176 entry
= cache
.Lookup(origin
, kRealm2
, HttpAuth::AUTH_SCHEME_BASIC
);
177 ASSERT_FALSE(NULL
== entry
);
178 EXPECT_EQ(HttpAuth::AUTH_SCHEME_BASIC
, entry
->scheme());
179 EXPECT_EQ(kRealm2
, entry
->realm());
180 EXPECT_EQ("Basic realm=Realm2", entry
->auth_challenge());
181 EXPECT_EQ(ASCIIToUTF16("realm2-user"), entry
->credentials().username());
182 EXPECT_EQ(ASCIIToUTF16("realm2-password"), entry
->credentials().password());
184 // Check that subpaths are recognized.
185 HttpAuthCache::Entry
* realm2_entry
= cache
.Lookup(
186 origin
, kRealm2
, HttpAuth::AUTH_SCHEME_BASIC
);
187 HttpAuthCache::Entry
* realm4_entry
= cache
.Lookup(
188 origin
, kRealm4
, HttpAuth::AUTH_SCHEME_BASIC
);
189 EXPECT_FALSE(NULL
== realm2_entry
);
190 EXPECT_FALSE(NULL
== realm4_entry
);
191 // Realm4 applies to '/' and Realm2 applies to '/foo2/'.
192 // LookupByPath() should return the closest enclosing path.
194 entry
= cache
.LookupByPath(origin
, "/foo2/index.html");
195 EXPECT_TRUE(realm2_entry
== entry
);
196 entry
= cache
.LookupByPath(origin
, "/foo2/foobar.html");
197 EXPECT_TRUE(realm2_entry
== entry
);
198 entry
= cache
.LookupByPath(origin
, "/foo2/bar/index.html");
199 EXPECT_TRUE(realm2_entry
== entry
);
200 entry
= cache
.LookupByPath(origin
, "/foo2/");
201 EXPECT_TRUE(realm2_entry
== entry
);
202 entry
= cache
.LookupByPath(origin
, "/foo2");
203 EXPECT_TRUE(realm4_entry
== entry
);
204 entry
= cache
.LookupByPath(origin
, "/");
205 EXPECT_TRUE(realm4_entry
== entry
);
208 entry
= cache
.LookupByPath(origin
, "/foo3/index.html");
209 EXPECT_FALSE(realm2_entry
== entry
);
210 entry
= cache
.LookupByPath(origin
, std::string());
211 EXPECT_FALSE(realm2_entry
== entry
);
213 // Confirm we find the same realm, different auth scheme by path lookup
214 HttpAuthCache::Entry
* realm3_digest_entry
=
215 cache
.Lookup(origin
, kRealm3
, HttpAuth::AUTH_SCHEME_DIGEST
);
216 EXPECT_FALSE(NULL
== realm3_digest_entry
);
217 entry
= cache
.LookupByPath(origin
, "/baz/index.html");
218 EXPECT_TRUE(realm3_digest_entry
== entry
);
219 entry
= cache
.LookupByPath(origin
, "/baz/");
220 EXPECT_TRUE(realm3_digest_entry
== entry
);
221 entry
= cache
.LookupByPath(origin
, "/baz");
222 EXPECT_FALSE(realm3_digest_entry
== entry
);
224 // Confirm we find the same realm, different auth scheme by path lookup
225 HttpAuthCache::Entry
* realm3DigestEntry
=
226 cache
.Lookup(origin
, kRealm3
, HttpAuth::AUTH_SCHEME_DIGEST
);
227 EXPECT_FALSE(NULL
== realm3DigestEntry
);
228 entry
= cache
.LookupByPath(origin
, "/baz/index.html");
229 EXPECT_TRUE(realm3DigestEntry
== entry
);
230 entry
= cache
.LookupByPath(origin
, "/baz/");
231 EXPECT_TRUE(realm3DigestEntry
== entry
);
232 entry
= cache
.LookupByPath(origin
, "/baz");
233 EXPECT_FALSE(realm3DigestEntry
== entry
);
235 // Lookup using empty path (may be used for proxy).
236 entry
= cache
.LookupByPath(origin
, std::string());
237 EXPECT_FALSE(NULL
== entry
);
238 EXPECT_EQ(HttpAuth::AUTH_SCHEME_BASIC
, entry
->scheme());
239 EXPECT_EQ(kRealm3
, entry
->realm());
242 TEST(HttpAuthCacheTest
, AddPath
) {
243 HttpAuthCache::Entry entry
;
245 // All of these paths have a common root /1/2/2/4/5/
246 entry
.AddPath("/1/2/3/4/5/x.txt");
247 entry
.AddPath("/1/2/3/4/5/y.txt");
248 entry
.AddPath("/1/2/3/4/5/z.txt");
250 EXPECT_EQ(1U, entry
.paths_
.size());
251 EXPECT_EQ("/1/2/3/4/5/", entry
.paths_
.front());
253 // Add a new entry (not a subpath).
254 entry
.AddPath("/1/XXX/q");
255 EXPECT_EQ(2U, entry
.paths_
.size());
256 EXPECT_EQ("/1/XXX/", entry
.paths_
.front());
257 EXPECT_EQ("/1/2/3/4/5/", entry
.paths_
.back());
259 // Add containing paths of /1/2/3/4/5/ -- should swallow up the deeper paths.
260 entry
.AddPath("/1/2/3/4/x.txt");
261 EXPECT_EQ(2U, entry
.paths_
.size());
262 EXPECT_EQ("/1/2/3/4/", entry
.paths_
.front());
263 EXPECT_EQ("/1/XXX/", entry
.paths_
.back());
264 entry
.AddPath("/1/2/3/x");
265 EXPECT_EQ(2U, entry
.paths_
.size());
266 EXPECT_EQ("/1/2/3/", entry
.paths_
.front());
267 EXPECT_EQ("/1/XXX/", entry
.paths_
.back());
269 entry
.AddPath("/index.html");
270 EXPECT_EQ(1U, entry
.paths_
.size());
271 EXPECT_EQ("/", entry
.paths_
.front());
274 // Calling Add when the realm entry already exists, should append that
276 TEST(HttpAuthCacheTest
, AddToExistingEntry
) {
278 GURL
origin("http://www.foobar.com:70");
279 const std::string auth_challenge
= "Basic realm=MyRealm";
281 scoped_ptr
<HttpAuthHandler
> handler(
283 HttpAuth::AUTH_SCHEME_BASIC
, "MyRealm", HttpAuth::AUTH_SERVER
));
284 HttpAuthCache::Entry
* orig_entry
= cache
.Add(
285 origin
, handler
->realm(), handler
->auth_scheme(), auth_challenge
,
286 CreateASCIICredentials("user1", "password1"), "/x/y/z/");
287 cache
.Add(origin
, handler
->realm(), handler
->auth_scheme(), auth_challenge
,
288 CreateASCIICredentials("user2", "password2"), "/z/y/x/");
289 cache
.Add(origin
, handler
->realm(), handler
->auth_scheme(), auth_challenge
,
290 CreateASCIICredentials("user3", "password3"), "/z/y");
292 HttpAuthCache::Entry
* entry
= cache
.Lookup(
293 origin
, "MyRealm", HttpAuth::AUTH_SCHEME_BASIC
);
295 EXPECT_TRUE(entry
== orig_entry
);
296 EXPECT_EQ(ASCIIToUTF16("user3"), entry
->credentials().username());
297 EXPECT_EQ(ASCIIToUTF16("password3"), entry
->credentials().password());
299 EXPECT_EQ(2U, entry
->paths_
.size());
300 EXPECT_EQ("/z/", entry
->paths_
.front());
301 EXPECT_EQ("/x/y/z/", entry
->paths_
.back());
304 TEST(HttpAuthCacheTest
, Remove
) {
305 GURL
origin("http://foobar2.com");
307 scoped_ptr
<HttpAuthHandler
> realm1_handler(
309 HttpAuth::AUTH_SCHEME_BASIC
, kRealm1
, HttpAuth::AUTH_SERVER
));
311 scoped_ptr
<HttpAuthHandler
> realm2_handler(
313 HttpAuth::AUTH_SCHEME_BASIC
, kRealm2
, HttpAuth::AUTH_SERVER
));
315 scoped_ptr
<HttpAuthHandler
> realm3_basic_handler(
317 HttpAuth::AUTH_SCHEME_BASIC
, kRealm3
, HttpAuth::AUTH_SERVER
));
319 scoped_ptr
<HttpAuthHandler
> realm3_digest_handler(
321 HttpAuth::AUTH_SCHEME_DIGEST
, kRealm3
, HttpAuth::AUTH_SERVER
));
324 cache
.Add(origin
, realm1_handler
->realm(), realm1_handler
->auth_scheme(),
325 "basic realm=Realm1", AuthCredentials(kAlice
, k123
), "/");
326 cache
.Add(origin
, realm2_handler
->realm(), realm2_handler
->auth_scheme(),
327 "basic realm=Realm2", CreateASCIICredentials("bob", "princess"),
329 cache
.Add(origin
, realm3_basic_handler
->realm(),
330 realm3_basic_handler
->auth_scheme(), "basic realm=Realm3",
331 AuthCredentials(kAdmin
, kPassword
), "/");
332 cache
.Add(origin
, realm3_digest_handler
->realm(),
333 realm3_digest_handler
->auth_scheme(), "digest realm=Realm3",
334 AuthCredentials(kRoot
, kWileCoyote
), "/");
336 // Fails, because there is no realm "Realm5".
337 EXPECT_FALSE(cache
.Remove(
338 origin
, kRealm5
, HttpAuth::AUTH_SCHEME_BASIC
,
339 AuthCredentials(kAlice
, k123
)));
341 // Fails because the origin is wrong.
342 EXPECT_FALSE(cache
.Remove(GURL("http://foobar2.com:100"),
344 HttpAuth::AUTH_SCHEME_BASIC
,
345 AuthCredentials(kAlice
, k123
)));
347 // Fails because the username is wrong.
348 EXPECT_FALSE(cache
.Remove(
349 origin
, kRealm1
, HttpAuth::AUTH_SCHEME_BASIC
,
350 AuthCredentials(kAlice2
, k123
)));
352 // Fails because the password is wrong.
353 EXPECT_FALSE(cache
.Remove(
354 origin
, kRealm1
, HttpAuth::AUTH_SCHEME_BASIC
,
355 AuthCredentials(kAlice
, k1234
)));
357 // Fails because the authentication type is wrong.
358 EXPECT_FALSE(cache
.Remove(
359 origin
, kRealm1
, HttpAuth::AUTH_SCHEME_DIGEST
,
360 AuthCredentials(kAlice
, k123
)));
363 EXPECT_TRUE(cache
.Remove(
364 origin
, kRealm1
, HttpAuth::AUTH_SCHEME_BASIC
,
365 AuthCredentials(kAlice
, k123
)));
367 // Fails because we just deleted the entry!
368 EXPECT_FALSE(cache
.Remove(
369 origin
, kRealm1
, HttpAuth::AUTH_SCHEME_BASIC
,
370 AuthCredentials(kAlice
, k123
)));
372 // Succeed when there are two authentication types for the same origin,realm.
373 EXPECT_TRUE(cache
.Remove(
374 origin
, kRealm3
, HttpAuth::AUTH_SCHEME_DIGEST
,
375 AuthCredentials(kRoot
, kWileCoyote
)));
377 // Succeed as above, but when entries were added in opposite order
378 cache
.Add(origin
, realm3_digest_handler
->realm(),
379 realm3_digest_handler
->auth_scheme(), "digest realm=Realm3",
380 AuthCredentials(kRoot
, kWileCoyote
), "/");
381 EXPECT_TRUE(cache
.Remove(
382 origin
, kRealm3
, HttpAuth::AUTH_SCHEME_BASIC
,
383 AuthCredentials(kAdmin
, kPassword
)));
385 // Make sure that removing one entry still leaves the other available for
387 HttpAuthCache::Entry
* entry
= cache
.Lookup(
388 origin
, kRealm3
, HttpAuth::AUTH_SCHEME_DIGEST
);
389 EXPECT_FALSE(NULL
== entry
);
392 TEST(HttpAuthCacheTest
, UpdateStaleChallenge
) {
394 GURL
origin("http://foobar2.com");
395 scoped_ptr
<HttpAuthHandler
> digest_handler(
397 HttpAuth::AUTH_SCHEME_DIGEST
, kRealm1
, HttpAuth::AUTH_PROXY
));
398 HttpAuthCache::Entry
* entry_pre
= cache
.Add(
400 digest_handler
->realm(),
401 digest_handler
->auth_scheme(),
402 "Digest realm=Realm1,"
403 "nonce=\"s3MzvFhaBAA=4c520af5acd9d8d7ae26947529d18c8eae1e98f4\"",
404 CreateASCIICredentials("realm-digest-user", "realm-digest-password"),
406 ASSERT_TRUE(entry_pre
!= NULL
);
408 EXPECT_EQ(2, entry_pre
->IncrementNonceCount());
409 EXPECT_EQ(3, entry_pre
->IncrementNonceCount());
410 EXPECT_EQ(4, entry_pre
->IncrementNonceCount());
412 bool update_success
= cache
.UpdateStaleChallenge(
414 digest_handler
->realm(),
415 digest_handler
->auth_scheme(),
416 "Digest realm=Realm1,"
417 "nonce=\"claGgoRXBAA=7583377687842fdb7b56ba0555d175baa0b800e3\","
419 EXPECT_TRUE(update_success
);
421 // After the stale update, the entry should still exist in the cache and
422 // the nonce count should be reset to 0.
423 HttpAuthCache::Entry
* entry_post
= cache
.Lookup(
425 digest_handler
->realm(),
426 digest_handler
->auth_scheme());
427 ASSERT_TRUE(entry_post
!= NULL
);
428 EXPECT_EQ(2, entry_post
->IncrementNonceCount());
430 // UpdateStaleChallenge will fail if an entry doesn't exist in the cache.
431 bool update_failure
= cache
.UpdateStaleChallenge(
434 digest_handler
->auth_scheme(),
435 "Digest realm=Realm2,"
436 "nonce=\"claGgoRXBAA=7583377687842fdb7b56ba0555d175baa0b800e3\","
438 EXPECT_FALSE(update_failure
);
441 TEST(HttpAuthCacheTest
, UpdateAllFrom
) {
442 GURL
origin("http://example.com");
443 std::string
path("/some/path");
444 std::string
another_path("/another/path");
446 scoped_ptr
<HttpAuthHandler
> realm1_handler(
448 HttpAuth::AUTH_SCHEME_BASIC
, kRealm1
, HttpAuth::AUTH_SERVER
));
450 scoped_ptr
<HttpAuthHandler
> realm2_handler(
452 HttpAuth::AUTH_SCHEME_BASIC
, kRealm2
, HttpAuth::AUTH_PROXY
));
454 scoped_ptr
<HttpAuthHandler
> realm3_digest_handler(
456 HttpAuth::AUTH_SCHEME_DIGEST
, kRealm3
, HttpAuth::AUTH_SERVER
));
458 scoped_ptr
<HttpAuthHandler
> realm4_handler(
460 HttpAuth::AUTH_SCHEME_BASIC
, kRealm4
, HttpAuth::AUTH_SERVER
));
462 HttpAuthCache first_cache
;
463 HttpAuthCache::Entry
* entry
;
465 first_cache
.Add(origin
, realm1_handler
->realm(),
466 realm1_handler
->auth_scheme(), "basic realm=Realm1",
467 AuthCredentials(kAlice
, k123
), path
);
468 first_cache
.Add(origin
, realm2_handler
->realm(),
469 realm2_handler
->auth_scheme(), "basic realm=Realm2",
470 AuthCredentials(kAlice2
, k1234
), path
);
471 first_cache
.Add(origin
, realm3_digest_handler
->realm(),
472 realm3_digest_handler
->auth_scheme(), "digest realm=Realm3",
473 AuthCredentials(kRoot
, kWileCoyote
), path
);
474 entry
= first_cache
.Add(
475 origin
, realm3_digest_handler
->realm(),
476 realm3_digest_handler
->auth_scheme(), "digest realm=Realm3",
477 AuthCredentials(kRoot
, kWileCoyote
), another_path
);
479 EXPECT_EQ(2, entry
->IncrementNonceCount());
481 HttpAuthCache second_cache
;
482 // Will be overwritten by kRoot:kWileCoyote.
483 second_cache
.Add(origin
, realm3_digest_handler
->realm(),
484 realm3_digest_handler
->auth_scheme(), "digest realm=Realm3",
485 AuthCredentials(kAlice2
, k1234
), path
);
486 // Should be left intact.
487 second_cache
.Add(origin
, realm4_handler
->realm(),
488 realm4_handler
->auth_scheme(), "basic realm=Realm4",
489 AuthCredentials(kAdmin
, kRoot
), path
);
491 second_cache
.UpdateAllFrom(first_cache
);
493 // Copied from first_cache.
494 entry
= second_cache
.Lookup(origin
, kRealm1
, HttpAuth::AUTH_SCHEME_BASIC
);
495 EXPECT_TRUE(NULL
!= entry
);
496 EXPECT_EQ(kAlice
, entry
->credentials().username());
497 EXPECT_EQ(k123
, entry
->credentials().password());
499 // Copied from first_cache.
500 entry
= second_cache
.Lookup(origin
, kRealm2
, HttpAuth::AUTH_SCHEME_BASIC
);
501 EXPECT_TRUE(NULL
!= entry
);
502 EXPECT_EQ(kAlice2
, entry
->credentials().username());
503 EXPECT_EQ(k1234
, entry
->credentials().password());
505 // Overwritten from first_cache.
506 entry
= second_cache
.Lookup(origin
, kRealm3
, HttpAuth::AUTH_SCHEME_DIGEST
);
507 EXPECT_TRUE(NULL
!= entry
);
508 EXPECT_EQ(kRoot
, entry
->credentials().username());
509 EXPECT_EQ(kWileCoyote
, entry
->credentials().password());
510 // Nonce count should get copied.
511 EXPECT_EQ(3, entry
->IncrementNonceCount());
513 // All paths should get copied.
514 entry
= second_cache
.LookupByPath(origin
, another_path
);
515 EXPECT_TRUE(NULL
!= entry
);
516 EXPECT_EQ(kRoot
, entry
->credentials().username());
517 EXPECT_EQ(kWileCoyote
, entry
->credentials().password());
519 // Left intact in second_cache.
520 entry
= second_cache
.Lookup(origin
, kRealm4
, HttpAuth::AUTH_SCHEME_BASIC
);
521 EXPECT_TRUE(NULL
!= entry
);
522 EXPECT_EQ(kAdmin
, entry
->credentials().username());
523 EXPECT_EQ(kRoot
, entry
->credentials().password());
526 // Test fixture class for eviction tests (contains helpers for bulk
527 // insertion and existence testing).
528 class HttpAuthCacheEvictionTest
: public testing::Test
{
530 HttpAuthCacheEvictionTest() : origin_("http://www.google.com") { }
532 std::string
GenerateRealm(int realm_i
) {
533 return base::StringPrintf("Realm %d", realm_i
);
536 std::string
GeneratePath(int realm_i
, int path_i
) {
537 return base::StringPrintf("/%d/%d/x/y", realm_i
, path_i
);
540 void AddRealm(int realm_i
) {
541 AddPathToRealm(realm_i
, 0);
544 void AddPathToRealm(int realm_i
, int path_i
) {
546 GenerateRealm(realm_i
),
547 HttpAuth::AUTH_SCHEME_BASIC
,
549 AuthCredentials(kUsername
, kPassword
),
550 GeneratePath(realm_i
, path_i
));
553 void CheckRealmExistence(int realm_i
, bool exists
) {
554 const HttpAuthCache::Entry
* entry
=
556 origin_
, GenerateRealm(realm_i
), HttpAuth::AUTH_SCHEME_BASIC
);
558 EXPECT_FALSE(entry
== NULL
);
559 EXPECT_EQ(GenerateRealm(realm_i
), entry
->realm());
561 EXPECT_TRUE(entry
== NULL
);
565 void CheckPathExistence(int realm_i
, int path_i
, bool exists
) {
566 const HttpAuthCache::Entry
* entry
=
567 cache_
.LookupByPath(origin_
, GeneratePath(realm_i
, path_i
));
569 EXPECT_FALSE(entry
== NULL
);
570 EXPECT_EQ(GenerateRealm(realm_i
), entry
->realm());
572 EXPECT_TRUE(entry
== NULL
);
577 HttpAuthCache cache_
;
579 static const int kMaxPaths
= HttpAuthCache::kMaxNumPathsPerRealmEntry
;
580 static const int kMaxRealms
= HttpAuthCache::kMaxNumRealmEntries
;
583 // Add the maxinim number of realm entries to the cache. Each of these entries
584 // must still be retrievable. Next add three more entries -- since the cache is
585 // full this causes FIFO eviction of the first three entries.
586 TEST_F(HttpAuthCacheEvictionTest
, RealmEntryEviction
) {
587 for (int i
= 0; i
< kMaxRealms
; ++i
)
590 for (int i
= 0; i
< kMaxRealms
; ++i
)
591 CheckRealmExistence(i
, true);
593 for (int i
= 0; i
< 3; ++i
)
594 AddRealm(i
+ kMaxRealms
);
596 for (int i
= 0; i
< 3; ++i
)
597 CheckRealmExistence(i
, false);
599 for (int i
= 0; i
< kMaxRealms
; ++i
)
600 CheckRealmExistence(i
+ 3, true);
603 // Add the maximum number of paths to a single realm entry. Each of these
604 // paths should be retrievable. Next add 3 more paths -- since the cache is
605 // full this causes FIFO eviction of the first three paths.
606 TEST_F(HttpAuthCacheEvictionTest
, RealmPathEviction
) {
607 for (int i
= 0; i
< kMaxPaths
; ++i
)
608 AddPathToRealm(0, i
);
610 for (int i
= 1; i
< kMaxRealms
; ++i
)
613 for (int i
= 0; i
< 3; ++i
)
614 AddPathToRealm(0, i
+ kMaxPaths
);
616 for (int i
= 0; i
< 3; ++i
)
617 CheckPathExistence(0, i
, false);
619 for (int i
= 0; i
< kMaxPaths
; ++i
)
620 CheckPathExistence(0, i
+ 3, true);
622 for (int i
= 0; i
< kMaxRealms
; ++i
)
623 CheckRealmExistence(i
, true);