1 // Copyright 2014 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.
9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/strings/stringprintf.h"
12 #include "base/test/simple_test_clock.h"
13 #include "net/base/sdch_manager.h"
14 #include "net/base/sdch_observer.h"
15 #include "net/log/net_log.h"
16 #include "testing/gtest/include/gtest/gtest.h"
21 //------------------------------------------------------------------------------
22 // Provide sample data and compression results with a sample VCDIFF dictionary.
23 // Note an SDCH dictionary has extra meta-data before the VCDIFF dictionary.
24 static const char kTestVcdiffDictionary
[] = "DictionaryFor"
25 "SdchCompression1SdchCompression2SdchCompression3SdchCompression\n";
27 //------------------------------------------------------------------------------
29 class MockSdchObserver
: public SdchObserver
{
32 : dictionary_used_notifications_(0),
33 get_dictionary_notifications_(0),
34 clear_dictionaries_notifications_(0) {}
36 std::string
last_server_hash() const { return last_server_hash_
; }
37 int dictionary_used_notifications() const {
38 return dictionary_used_notifications_
;
40 const GURL
& last_dictionary_request_url() const {
41 return last_dictionary_request_url_
;
43 const GURL
& last_dictionary_url() const { return last_dictionary_url_
; }
44 int get_dictionary_notifications() const {
45 return get_dictionary_notifications_
;
48 int clear_dictionary_notifications() const {
49 return clear_dictionaries_notifications_
;
52 // SdchObserver implementation
53 void OnDictionaryUsed(SdchManager
* manager
,
54 const std::string
& server_hash
) override
{
55 last_server_hash_
= server_hash
;
56 ++dictionary_used_notifications_
;
59 void OnGetDictionary(SdchManager
* manager
,
60 const GURL
& request_url
,
61 const GURL
& dictionary_url
) override
{
62 ++get_dictionary_notifications_
;
63 last_dictionary_request_url_
= request_url
;
64 last_dictionary_url_
= dictionary_url
;
66 void OnClearDictionaries(SdchManager
* manager
) override
{
67 ++clear_dictionaries_notifications_
;
71 int dictionary_used_notifications_
;
72 int get_dictionary_notifications_
;
73 int clear_dictionaries_notifications_
;
75 std::string last_server_hash_
;
76 GURL last_dictionary_request_url_
;
77 GURL last_dictionary_url_
;
79 DISALLOW_COPY_AND_ASSIGN(MockSdchObserver
);
82 class SdchManagerTest
: public testing::Test
{
85 : sdch_manager_(new SdchManager
),
86 default_support_(false),
87 default_https_support_(false) {
88 default_support_
= sdch_manager_
->sdch_enabled();
89 default_https_support_
= sdch_manager_
->secure_scheme_supported();
92 ~SdchManagerTest() override
{}
94 SdchManager
* sdch_manager() { return sdch_manager_
.get(); }
96 // Reset globals back to default state.
97 void TearDown() override
{
98 SdchManager::EnableSdchSupport(default_support_
);
99 SdchManager::EnableSecureSchemeSupport(default_https_support_
);
102 // Attempt to add a dictionary to the manager and probe for success or
104 bool AddSdchDictionary(const std::string
& dictionary_text
,
106 return sdch_manager_
->AddSdchDictionary(dictionary_text
, gurl
, nullptr) ==
111 scoped_ptr
<SdchManager
> sdch_manager_
;
112 bool default_support_
;
113 bool default_https_support_
;
116 static std::string
NewSdchDictionary(const std::string
& domain
) {
117 std::string dictionary
;
118 if (!domain
.empty()) {
119 dictionary
.append("Domain: ");
120 dictionary
.append(domain
);
121 dictionary
.append("\n");
123 dictionary
.append("\n");
124 dictionary
.append(kTestVcdiffDictionary
, sizeof(kTestVcdiffDictionary
) - 1);
128 TEST_F(SdchManagerTest
, DomainSupported
) {
129 GURL
google_url("http://www.google.com");
131 SdchManager::EnableSdchSupport(false);
132 EXPECT_EQ(SDCH_DISABLED
, sdch_manager()->IsInSupportedDomain(google_url
));
133 SdchManager::EnableSdchSupport(true);
134 EXPECT_EQ(SDCH_OK
, sdch_manager()->IsInSupportedDomain(google_url
));
137 TEST_F(SdchManagerTest
, DomainBlacklisting
) {
138 GURL
test_url("http://www.test.com");
139 GURL
google_url("http://www.google.com");
141 sdch_manager()->BlacklistDomain(test_url
, SDCH_OK
);
142 EXPECT_EQ(SDCH_DOMAIN_BLACKLIST_INCLUDES_TARGET
,
143 sdch_manager()->IsInSupportedDomain(test_url
));
144 EXPECT_EQ(SDCH_OK
, sdch_manager()->IsInSupportedDomain(google_url
));
146 sdch_manager()->BlacklistDomain(google_url
, SDCH_OK
);
147 EXPECT_EQ(SDCH_DOMAIN_BLACKLIST_INCLUDES_TARGET
,
148 sdch_manager()->IsInSupportedDomain(google_url
));
151 TEST_F(SdchManagerTest
, DomainBlacklistingCaseSensitivity
) {
152 GURL
test_url("http://www.TesT.com");
153 GURL
test2_url("http://www.tEst.com");
155 EXPECT_EQ(SDCH_OK
, sdch_manager()->IsInSupportedDomain(test_url
));
156 EXPECT_EQ(SDCH_OK
, sdch_manager()->IsInSupportedDomain(test2_url
));
157 sdch_manager()->BlacklistDomain(test_url
, SDCH_OK
);
158 EXPECT_EQ(SDCH_DOMAIN_BLACKLIST_INCLUDES_TARGET
,
159 sdch_manager()->IsInSupportedDomain(test2_url
));
162 TEST_F(SdchManagerTest
, BlacklistingReset
) {
163 GURL
gurl("http://mytest.DoMain.com");
164 std::string
domain(gurl
.host());
166 sdch_manager()->ClearBlacklistings();
167 EXPECT_EQ(sdch_manager()->BlackListDomainCount(domain
), 0);
168 EXPECT_EQ(sdch_manager()->BlacklistDomainExponential(domain
), 0);
169 EXPECT_EQ(SDCH_OK
, sdch_manager()->IsInSupportedDomain(gurl
));
172 TEST_F(SdchManagerTest
, BlacklistingSingleBlacklist
) {
173 GURL
gurl("http://mytest.DoMain.com");
174 std::string
domain(gurl
.host());
175 sdch_manager()->ClearBlacklistings();
177 sdch_manager()->BlacklistDomain(gurl
, SDCH_OK
);
178 EXPECT_EQ(sdch_manager()->BlackListDomainCount(domain
), 1);
179 EXPECT_EQ(sdch_manager()->BlacklistDomainExponential(domain
), 1);
181 // Check that any domain lookup reduces the blacklist counter.
182 EXPECT_EQ(SDCH_DOMAIN_BLACKLIST_INCLUDES_TARGET
,
183 sdch_manager()->IsInSupportedDomain(gurl
));
184 EXPECT_EQ(sdch_manager()->BlackListDomainCount(domain
), 0);
185 EXPECT_EQ(SDCH_OK
, sdch_manager()->IsInSupportedDomain(gurl
));
188 TEST_F(SdchManagerTest
, BlacklistingExponential
) {
189 GURL
gurl("http://mytest.DoMain.com");
190 std::string
domain(gurl
.host());
191 sdch_manager()->ClearBlacklistings();
194 for (int i
= 1; i
< 100; ++i
) {
195 sdch_manager()->BlacklistDomain(gurl
, SDCH_OK
);
196 EXPECT_EQ(sdch_manager()->BlacklistDomainExponential(domain
), exponential
);
198 EXPECT_EQ(sdch_manager()->BlackListDomainCount(domain
), exponential
);
199 EXPECT_EQ(SDCH_DOMAIN_BLACKLIST_INCLUDES_TARGET
,
200 sdch_manager()->IsInSupportedDomain(gurl
));
201 EXPECT_EQ(sdch_manager()->BlackListDomainCount(domain
), exponential
- 1);
203 // Simulate a large number of domain checks (which eventually remove the
205 sdch_manager()->ClearDomainBlacklisting(domain
);
206 EXPECT_EQ(sdch_manager()->BlackListDomainCount(domain
), 0);
207 EXPECT_EQ(SDCH_OK
, sdch_manager()->IsInSupportedDomain(gurl
));
209 // Predict what exponential backoff will be.
210 exponential
= 1 + 2 * exponential
;
212 exponential
= INT_MAX
; // We don't wrap.
216 TEST_F(SdchManagerTest
, CanSetExactMatchDictionary
) {
217 std::string
dictionary_domain("x.y.z.google.com");
218 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
220 // Perfect match should work.
221 EXPECT_TRUE(AddSdchDictionary(dictionary_text
,
222 GURL("http://" + dictionary_domain
)));
225 TEST_F(SdchManagerTest
, CanAdvertiseDictionaryOverHTTP
) {
226 std::string
dictionary_domain("x.y.z.google.com");
227 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
229 EXPECT_TRUE(AddSdchDictionary(dictionary_text
,
230 GURL("http://" + dictionary_domain
)));
232 // HTTP target URL can advertise dictionary.
233 EXPECT_TRUE(sdch_manager()->GetDictionarySet(
234 GURL("http://" + dictionary_domain
+ "/test")));
237 TEST_F(SdchManagerTest
, CanNotAdvertiseDictionaryOverHTTPS
) {
238 std::string
dictionary_domain("x.y.z.google.com");
239 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
241 EXPECT_TRUE(AddSdchDictionary(dictionary_text
,
242 GURL("http://" + dictionary_domain
)));
244 // HTTPS target URL should NOT advertise dictionary.
245 EXPECT_FALSE(sdch_manager()->GetDictionarySet(
246 GURL("https://" + dictionary_domain
+ "/test")));
249 TEST_F(SdchManagerTest
, CanUseHTTPSDictionaryOverHTTPSIfEnabled
) {
250 std::string
dictionary_domain("x.y.z.google.com");
251 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
253 SdchManager::EnableSecureSchemeSupport(false);
254 EXPECT_FALSE(AddSdchDictionary(dictionary_text
,
255 GURL("https://" + dictionary_domain
)));
256 SdchManager::EnableSecureSchemeSupport(true);
257 EXPECT_TRUE(AddSdchDictionary(dictionary_text
,
258 GURL("https://" + dictionary_domain
)));
260 GURL
target_url("https://" + dictionary_domain
+ "/test");
261 // HTTPS target URL should advertise dictionary if secure scheme support is
263 EXPECT_TRUE(sdch_manager()->GetDictionarySet(target_url
));
265 // Dictionary should be available.
266 std::string client_hash
;
267 std::string server_hash
;
268 sdch_manager()->GenerateHash(dictionary_text
, &client_hash
, &server_hash
);
269 SdchProblemCode problem_code
;
270 scoped_ptr
<SdchManager::DictionarySet
> dict_set(
271 sdch_manager()->GetDictionarySetByHash(
272 target_url
, server_hash
, &problem_code
));
273 EXPECT_EQ(SDCH_OK
, problem_code
);
274 EXPECT_TRUE(dict_set
.get());
275 EXPECT_TRUE(dict_set
->GetDictionary(server_hash
));
278 TEST_F(SdchManagerTest
, CanNotUseHTTPDictionaryOverHTTPS
) {
279 std::string
dictionary_domain("x.y.z.google.com");
280 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
282 EXPECT_TRUE(AddSdchDictionary(dictionary_text
,
283 GURL("http://" + dictionary_domain
)));
285 GURL
target_url("https://" + dictionary_domain
+ "/test");
286 // HTTPS target URL should not advertise dictionary acquired over HTTP even if
287 // secure scheme support is enabled.
288 SdchManager::EnableSecureSchemeSupport(true);
289 EXPECT_FALSE(sdch_manager()->GetDictionarySet(target_url
));
291 std::string client_hash
;
292 std::string server_hash
;
293 sdch_manager()->GenerateHash(dictionary_text
, &client_hash
, &server_hash
);
294 SdchProblemCode problem_code
;
295 scoped_ptr
<SdchManager::DictionarySet
> dict_set(
296 sdch_manager()->GetDictionarySetByHash(
297 target_url
, server_hash
, &problem_code
));
298 EXPECT_FALSE(dict_set
.get());
299 EXPECT_EQ(SDCH_DICTIONARY_FOUND_HAS_WRONG_SCHEME
, problem_code
);
302 TEST_F(SdchManagerTest
, CanNotUseHTTPSDictionaryOverHTTP
) {
303 std::string
dictionary_domain("x.y.z.google.com");
304 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
306 SdchManager::EnableSecureSchemeSupport(true);
307 EXPECT_TRUE(AddSdchDictionary(dictionary_text
,
308 GURL("https://" + dictionary_domain
)));
310 GURL
target_url("http://" + dictionary_domain
+ "/test");
311 // HTTP target URL should not advertise dictionary acquired over HTTPS even if
312 // secure scheme support is enabled.
313 EXPECT_FALSE(sdch_manager()->GetDictionarySet(target_url
));
315 std::string client_hash
;
316 std::string server_hash
;
317 sdch_manager()->GenerateHash(dictionary_text
, &client_hash
, &server_hash
);
318 SdchProblemCode problem_code
;
319 scoped_ptr
<SdchManager::DictionarySet
> dict_set(
320 sdch_manager()->GetDictionarySetByHash(
321 target_url
, server_hash
, &problem_code
));
322 EXPECT_FALSE(dict_set
.get());
323 EXPECT_EQ(SDCH_DICTIONARY_FOUND_HAS_WRONG_SCHEME
, problem_code
);
326 TEST_F(SdchManagerTest
, FailToSetDomainMismatchDictionary
) {
327 std::string
dictionary_domain("x.y.z.google.com");
328 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
330 // Fail the "domain match" requirement.
331 EXPECT_FALSE(AddSdchDictionary(dictionary_text
,
332 GURL("http://y.z.google.com")));
335 TEST_F(SdchManagerTest
, FailToSetDotHostPrefixDomainDictionary
) {
336 std::string
dictionary_domain("x.y.z.google.com");
337 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
339 // Fail the HD with D being the domain and H having a dot requirement.
340 EXPECT_FALSE(AddSdchDictionary(dictionary_text
,
341 GURL("http://w.x.y.z.google.com")));
344 TEST_F(SdchManagerTest
, FailToSetDotHostPrefixDomainDictionaryTrailingDot
) {
345 std::string
dictionary_domain("x.y.z.google.com");
346 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
348 // Fail the HD with D being the domain and H having a dot requirement.
349 EXPECT_FALSE(AddSdchDictionary(dictionary_text
,
350 GURL("http://w.x.y.z.google.com.")));
353 TEST_F(SdchManagerTest
, FailToSetRepeatPrefixWithDotDictionary
) {
354 // Make sure that a prefix that matches the domain postfix won't confuse
355 // the validation checks.
356 std::string
dictionary_domain("www.google.com");
357 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
359 // Fail the HD with D being the domain and H having a dot requirement.
360 EXPECT_FALSE(AddSdchDictionary(dictionary_text
,
361 GURL("http://www.google.com.www.google.com")));
364 TEST_F(SdchManagerTest
, CanSetLeadingDotDomainDictionary
) {
365 // Make sure that a prefix that matches the domain postfix won't confuse
366 // the validation checks.
367 std::string
dictionary_domain(".google.com");
368 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
370 // Verify that a leading dot in the domain is acceptable, as long as the host
371 // name does not contain any dots preceding the matched domain name.
372 EXPECT_TRUE(AddSdchDictionary(dictionary_text
, GURL("http://www.google.com")));
375 TEST_F(SdchManagerTest
,
376 CanSetLeadingDotDomainDictionaryFromURLWithTrailingDot
) {
377 // Make sure that a prefix that matches the domain postfix won't confuse
378 // the validation checks.
379 std::string
dictionary_domain(".google.com");
380 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
382 // Verify that a leading dot in the domain is acceptable, as long as the host
383 // name does not contain any dots preceding the matched domain name.
384 EXPECT_TRUE(AddSdchDictionary(dictionary_text
,
385 GURL("http://www.google.com.")));
388 TEST_F(SdchManagerTest
, CannotSetLeadingDotDomainDictionary
) {
389 // Make sure that a prefix that matches the domain postfix won't confuse
390 // the validation checks.
391 std::string
dictionary_domain(".google.com");
392 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
394 // Verify that a leading dot in the domain does not affect the name containing
396 EXPECT_FALSE(AddSdchDictionary(dictionary_text
,
397 GURL("http://www.subdomain.google.com")));
400 TEST_F(SdchManagerTest
, CannotSetLeadingDotDomainDictionaryTrailingDot
) {
401 // Make sure that a prefix that matches the domain postfix won't confuse
402 // the validation checks.
403 std::string
dictionary_domain(".google.com");
404 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
406 // Verify that a trailing period in the URL doesn't affect the check.
407 EXPECT_FALSE(AddSdchDictionary(dictionary_text
,
408 GURL("http://www.subdomain.google.com.")));
411 // Make sure the order of the tests is not helping us or confusing things.
412 // See test CanSetExactMatchDictionary above for first try.
413 TEST_F(SdchManagerTest
, CanStillSetExactMatchDictionary
) {
414 std::string
dictionary_domain("x.y.z.google.com");
415 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
417 // Perfect match should *STILL* work.
418 EXPECT_TRUE(AddSdchDictionary(dictionary_text
,
419 GURL("http://" + dictionary_domain
)));
422 TEST_F(SdchManagerTest
, PathMatch
) {
423 bool (*PathMatch
)(const std::string
& path
, const std::string
& restriction
) =
424 SdchManager::Dictionary::PathMatch
;
425 // Perfect match is supported.
426 EXPECT_TRUE(PathMatch("/search", "/search"));
427 EXPECT_TRUE(PathMatch("/search/", "/search/"));
429 // Prefix only works if last character of restriction is a slash, or first
430 // character in path after a match is a slash. Validate each case separately.
432 // Rely on the slash in the path (not at the end of the restriction).
433 EXPECT_TRUE(PathMatch("/search/something", "/search"));
434 EXPECT_TRUE(PathMatch("/search/s", "/search"));
435 EXPECT_TRUE(PathMatch("/search/other", "/search"));
436 EXPECT_TRUE(PathMatch("/search/something", "/search"));
438 // Rely on the slash at the end of the restriction.
439 EXPECT_TRUE(PathMatch("/search/something", "/search/"));
440 EXPECT_TRUE(PathMatch("/search/s", "/search/"));
441 EXPECT_TRUE(PathMatch("/search/other", "/search/"));
442 EXPECT_TRUE(PathMatch("/search/something", "/search/"));
444 // Make sure less that sufficient prefix match is false.
445 EXPECT_FALSE(PathMatch("/sear", "/search"));
446 EXPECT_FALSE(PathMatch("/", "/search"));
447 EXPECT_FALSE(PathMatch(std::string(), "/search"));
449 // Add examples with several levels of direcories in the restriction.
450 EXPECT_FALSE(PathMatch("/search/something", "search/s"));
451 EXPECT_FALSE(PathMatch("/search/", "/search/s"));
453 // Make sure adding characters to path will also fail.
454 EXPECT_FALSE(PathMatch("/searching", "/search/"));
455 EXPECT_FALSE(PathMatch("/searching", "/search"));
457 // Make sure we're case sensitive.
458 EXPECT_FALSE(PathMatch("/ABC", "/abc"));
459 EXPECT_FALSE(PathMatch("/abc", "/ABC"));
462 // The following are only applicable while we have a latency test in the code,
463 // and can be removed when that functionality is stripped.
464 TEST_F(SdchManagerTest
, LatencyTestControls
) {
465 GURL
url("http://www.google.com");
466 GURL
url2("http://www.google2.com");
468 // First make sure we default to false.
469 EXPECT_FALSE(sdch_manager()->AllowLatencyExperiment(url
));
470 EXPECT_FALSE(sdch_manager()->AllowLatencyExperiment(url2
));
472 // That we can set each to true.
473 sdch_manager()->SetAllowLatencyExperiment(url
, true);
474 EXPECT_TRUE(sdch_manager()->AllowLatencyExperiment(url
));
475 EXPECT_FALSE(sdch_manager()->AllowLatencyExperiment(url2
));
477 sdch_manager()->SetAllowLatencyExperiment(url2
, true);
478 EXPECT_TRUE(sdch_manager()->AllowLatencyExperiment(url
));
479 EXPECT_TRUE(sdch_manager()->AllowLatencyExperiment(url2
));
481 // And can reset them to false.
482 sdch_manager()->SetAllowLatencyExperiment(url
, false);
483 EXPECT_FALSE(sdch_manager()->AllowLatencyExperiment(url
));
484 EXPECT_TRUE(sdch_manager()->AllowLatencyExperiment(url2
));
486 sdch_manager()->SetAllowLatencyExperiment(url2
, false);
487 EXPECT_FALSE(sdch_manager()->AllowLatencyExperiment(url
));
488 EXPECT_FALSE(sdch_manager()->AllowLatencyExperiment(url2
));
491 TEST_F(SdchManagerTest
, CanUseMultipleManagers
) {
492 SdchManager second_manager
;
494 std::string
dictionary_domain_1("x.y.z.google.com");
495 std::string
dictionary_domain_2("x.y.z.chromium.org");
497 std::string
dictionary_text_1(NewSdchDictionary(dictionary_domain_1
));
498 std::string
dictionary_text_2(NewSdchDictionary(dictionary_domain_2
));
500 std::string tmp_hash
;
501 std::string server_hash_1
;
502 std::string server_hash_2
;
504 SdchManager::GenerateHash(dictionary_text_1
, &tmp_hash
, &server_hash_1
);
505 SdchManager::GenerateHash(dictionary_text_2
, &tmp_hash
, &server_hash_2
);
507 // Confirm that if you add directories to one manager, you
508 // can't get them from the other.
509 EXPECT_TRUE(AddSdchDictionary(dictionary_text_1
,
510 GURL("http://" + dictionary_domain_1
)));
511 scoped_ptr
<SdchManager::DictionarySet
> dict_set
;
513 SdchProblemCode problem_code
;
514 dict_set
= sdch_manager()->GetDictionarySetByHash(
515 GURL("http://" + dictionary_domain_1
+ "/random_url"),
516 server_hash_1
, &problem_code
);
517 EXPECT_TRUE(dict_set
);
518 EXPECT_TRUE(dict_set
->GetDictionary(server_hash_1
));
519 EXPECT_EQ(SDCH_OK
, problem_code
);
521 second_manager
.AddSdchDictionary(
522 dictionary_text_2
, GURL("http://" + dictionary_domain_2
), nullptr);
523 dict_set
= second_manager
.GetDictionarySetByHash(
524 GURL("http://" + dictionary_domain_2
+ "/random_url"),
525 server_hash_2
, &problem_code
);
526 EXPECT_TRUE(dict_set
);
527 EXPECT_TRUE(dict_set
->GetDictionary(server_hash_2
));
528 EXPECT_EQ(SDCH_OK
, problem_code
);
530 dict_set
= sdch_manager()->GetDictionarySetByHash(
531 GURL("http://" + dictionary_domain_2
+ "/random_url"),
532 server_hash_2
, &problem_code
);
533 EXPECT_FALSE(dict_set
);
534 EXPECT_EQ(SDCH_DICTIONARY_HASH_NOT_FOUND
, problem_code
);
536 dict_set
= second_manager
.GetDictionarySetByHash(
537 GURL("http://" + dictionary_domain_1
+ "/random_url"),
538 server_hash_1
, &problem_code
);
539 EXPECT_FALSE(dict_set
);
540 EXPECT_EQ(SDCH_DICTIONARY_HASH_NOT_FOUND
, problem_code
);
543 TEST_F(SdchManagerTest
, HttpsCorrectlySupported
) {
544 GURL
url("http://www.google.com");
545 GURL
secure_url("https://www.google.com");
547 bool expect_https_support
= true;
549 SdchProblemCode expected_code
=
550 expect_https_support
? SDCH_OK
: SDCH_SECURE_SCHEME_NOT_SUPPORTED
;
552 EXPECT_EQ(SDCH_OK
, sdch_manager()->IsInSupportedDomain(url
));
553 EXPECT_EQ(expected_code
, sdch_manager()->IsInSupportedDomain(secure_url
));
555 SdchManager::EnableSecureSchemeSupport(!expect_https_support
);
556 EXPECT_EQ(SDCH_OK
, sdch_manager()->IsInSupportedDomain(url
));
557 EXPECT_NE(expected_code
, sdch_manager()->IsInSupportedDomain(secure_url
));
560 TEST_F(SdchManagerTest
, ClearDictionaryData
) {
561 std::string
dictionary_domain("x.y.z.google.com");
562 GURL
blacklist_url("http://bad.chromium.org");
564 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
565 std::string tmp_hash
;
566 std::string server_hash
;
568 SdchManager::GenerateHash(dictionary_text
, &tmp_hash
, &server_hash
);
570 EXPECT_TRUE(AddSdchDictionary(dictionary_text
,
571 GURL("http://" + dictionary_domain
)));
573 scoped_ptr
<SdchManager::DictionarySet
> dict_set
;
575 SdchProblemCode problem_code
;
576 dict_set
= sdch_manager()->GetDictionarySetByHash(
577 GURL("http://" + dictionary_domain
+ "/random_url"),
578 server_hash
, &problem_code
);
579 EXPECT_TRUE(dict_set
);
580 EXPECT_TRUE(dict_set
->GetDictionary(server_hash
));
581 EXPECT_EQ(SDCH_OK
, problem_code
);
583 sdch_manager()->BlacklistDomain(GURL(blacklist_url
), SDCH_OK
);
584 EXPECT_EQ(SDCH_DOMAIN_BLACKLIST_INCLUDES_TARGET
,
585 sdch_manager()->IsInSupportedDomain(blacklist_url
));
587 sdch_manager()->ClearData();
589 dict_set
= sdch_manager()->GetDictionarySetByHash(
590 GURL("http://" + dictionary_domain
+ "/random_url"),
591 server_hash
, &problem_code
);
592 EXPECT_FALSE(dict_set
);
593 EXPECT_EQ(SDCH_DICTIONARY_HASH_NOT_FOUND
, problem_code
);
594 EXPECT_EQ(SDCH_OK
, sdch_manager()->IsInSupportedDomain(blacklist_url
));
597 TEST_F(SdchManagerTest
, GetDictionaryNotification
) {
598 GURL
test_request_gurl(GURL("http://www.example.com/data"));
599 GURL
test_dictionary_gurl(GURL("http://www.example.com/dict"));
600 MockSdchObserver observer
;
601 sdch_manager()->AddObserver(&observer
);
603 EXPECT_EQ(0, observer
.get_dictionary_notifications());
604 sdch_manager()->OnGetDictionary(test_request_gurl
, test_dictionary_gurl
);
605 EXPECT_EQ(1, observer
.get_dictionary_notifications());
606 EXPECT_EQ(test_request_gurl
, observer
.last_dictionary_request_url());
607 EXPECT_EQ(test_dictionary_gurl
, observer
.last_dictionary_url());
609 sdch_manager()->RemoveObserver(&observer
);
610 sdch_manager()->OnGetDictionary(test_request_gurl
, test_dictionary_gurl
);
611 EXPECT_EQ(1, observer
.get_dictionary_notifications());
612 EXPECT_EQ(test_request_gurl
, observer
.last_dictionary_request_url());
613 EXPECT_EQ(test_dictionary_gurl
, observer
.last_dictionary_url());
616 TEST_F(SdchManagerTest
, ExpirationCheckedProperly
) {
617 // Create an SDCH dictionary with an expiration time in the past.
618 std::string
dictionary_domain("x.y.z.google.com");
619 std::string
dictionary_text(base::StringPrintf(
620 "Domain: %s\nMax-age: 0\n\n", dictionary_domain
.c_str()));
621 dictionary_text
.append(
622 kTestVcdiffDictionary
, sizeof(kTestVcdiffDictionary
) - 1);
623 std::string client_hash
;
624 std::string server_hash
;
625 SdchManager::GenerateHash(dictionary_text
, &client_hash
, &server_hash
);
626 GURL
target_gurl("http://" + dictionary_domain
);
627 AddSdchDictionary(dictionary_text
, target_gurl
);
629 // It should be visible if looked up by hash whether expired or not.
630 scoped_ptr
<base::SimpleTestClock
> clock(new base::SimpleTestClock
);
631 clock
->SetNow(base::Time::Now());
632 clock
->Advance(base::TimeDelta::FromMinutes(5));
633 SdchProblemCode problem_code
;
634 scoped_ptr
<SdchManager::DictionarySet
> hash_set(
635 sdch_manager()->GetDictionarySetByHash(
636 target_gurl
, server_hash
, &problem_code
).Pass());
637 ASSERT_TRUE(hash_set
);
638 ASSERT_EQ(SDCH_OK
, problem_code
);
639 const_cast<SdchManager::Dictionary
*>(
640 hash_set
->GetDictionary(server_hash
))->SetClockForTesting(
643 // Make sure it's not visible for advertisement, but is visible
644 // if looked up by hash.
645 EXPECT_FALSE(sdch_manager()->GetDictionarySet(target_gurl
));
646 EXPECT_TRUE(sdch_manager()->GetDictionarySetByHash(
647 target_gurl
, server_hash
, &problem_code
));
648 EXPECT_EQ(SDCH_OK
, problem_code
);
651 TEST_F(SdchManagerTest
, SdchOnByDefault
) {
652 GURL
google_url("http://www.google.com");
653 scoped_ptr
<SdchManager
> sdch_manager(new SdchManager
);
655 EXPECT_EQ(SDCH_OK
, sdch_manager
->IsInSupportedDomain(google_url
));
656 SdchManager::EnableSdchSupport(false);
657 EXPECT_EQ(SDCH_DISABLED
, sdch_manager
->IsInSupportedDomain(google_url
));
660 // Confirm dispatch of notification.
661 TEST_F(SdchManagerTest
, SdchDictionaryUsed
) {
662 MockSdchObserver observer
;
663 sdch_manager()->AddObserver(&observer
);
665 EXPECT_EQ(0, observer
.dictionary_used_notifications());
666 sdch_manager()->OnDictionaryUsed("xyzzy");
667 EXPECT_EQ(1, observer
.dictionary_used_notifications());
668 EXPECT_EQ("xyzzy", observer
.last_server_hash());
670 std::string
dictionary_domain("x.y.z.google.com");
671 GURL
target_gurl("http://" + dictionary_domain
);
672 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
673 std::string client_hash
;
674 std::string server_hash
;
675 SdchManager::GenerateHash(dictionary_text
, &client_hash
, &server_hash
);
676 EXPECT_TRUE(AddSdchDictionary(dictionary_text
, target_gurl
));
677 EXPECT_EQ("xyzzy", observer
.last_server_hash());
678 EXPECT_EQ(1, observer
.dictionary_used_notifications());
680 EXPECT_TRUE(sdch_manager()->GetDictionarySet(target_gurl
));
681 EXPECT_EQ("xyzzy", observer
.last_server_hash());
682 EXPECT_EQ(1, observer
.dictionary_used_notifications());
684 sdch_manager()->RemoveObserver(&observer
);
685 EXPECT_EQ(1, observer
.dictionary_used_notifications());
686 EXPECT_EQ("xyzzy", observer
.last_server_hash());
687 sdch_manager()->OnDictionaryUsed("plugh");
688 EXPECT_EQ(1, observer
.dictionary_used_notifications());
689 EXPECT_EQ("xyzzy", observer
.last_server_hash());