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 "net/base/sdch_manager.h"
12 #include "testing/gtest/include/gtest/gtest.h"
16 //------------------------------------------------------------------------------
17 // Provide sample data and compression results with a sample VCDIFF dictionary.
18 // Note an SDCH dictionary has extra meta-data before the VCDIFF dictionary.
19 static const char kTestVcdiffDictionary
[] = "DictionaryFor"
20 "SdchCompression1SdchCompression2SdchCompression3SdchCompression\n";
22 //------------------------------------------------------------------------------
24 class SdchManagerTest
: public testing::Test
{
27 : sdch_manager_(new SdchManager
) {
30 scoped_ptr
<SdchManager
> sdch_manager_
; // A singleton database.
33 //------------------------------------------------------------------------------
34 static std::string
NewSdchDictionary(const std::string
& domain
) {
35 std::string dictionary
;
36 if (!domain
.empty()) {
37 dictionary
.append("Domain: ");
38 dictionary
.append(domain
);
39 dictionary
.append("\n");
41 dictionary
.append("\n");
42 dictionary
.append(kTestVcdiffDictionary
, sizeof(kTestVcdiffDictionary
) - 1);
46 TEST_F(SdchManagerTest
, DomainSupported
) {
47 GURL
google_url("http://www.google.com");
49 net::SdchManager::EnableSdchSupport(false);
50 EXPECT_FALSE(SdchManager::Global()->IsInSupportedDomain(google_url
));
51 net::SdchManager::EnableSdchSupport(true);
52 EXPECT_TRUE(SdchManager::Global()->IsInSupportedDomain(google_url
));
55 TEST_F(SdchManagerTest
, DomainBlacklisting
) {
56 GURL
test_url("http://www.test.com");
57 GURL
google_url("http://www.google.com");
59 SdchManager::BlacklistDomain(test_url
);
60 EXPECT_FALSE(SdchManager::Global()->IsInSupportedDomain(test_url
));
61 EXPECT_TRUE(SdchManager::Global()->IsInSupportedDomain(google_url
));
63 SdchManager::BlacklistDomain(google_url
);
64 EXPECT_FALSE(SdchManager::Global()->IsInSupportedDomain(google_url
));
67 TEST_F(SdchManagerTest
, DomainBlacklistingCaseSensitivity
) {
68 GURL
test_url("http://www.TesT.com");
69 GURL
test2_url("http://www.tEst.com");
71 EXPECT_TRUE(SdchManager::Global()->IsInSupportedDomain(test_url
));
72 EXPECT_TRUE(SdchManager::Global()->IsInSupportedDomain(test2_url
));
73 SdchManager::BlacklistDomain(test_url
);
74 EXPECT_FALSE(SdchManager::Global()->IsInSupportedDomain(test2_url
));
77 TEST_F(SdchManagerTest
, BlacklistingReset
) {
78 GURL
gurl("http://mytest.DoMain.com");
79 std::string
domain(gurl
.host());
81 SdchManager::ClearBlacklistings();
82 EXPECT_EQ(SdchManager::BlackListDomainCount(domain
), 0);
83 EXPECT_EQ(SdchManager::BlacklistDomainExponential(domain
), 0);
84 EXPECT_TRUE(SdchManager::Global()->IsInSupportedDomain(gurl
));
87 TEST_F(SdchManagerTest
, BlacklistingSingleBlacklist
) {
88 GURL
gurl("http://mytest.DoMain.com");
89 std::string
domain(gurl
.host());
90 SdchManager::ClearBlacklistings();
92 SdchManager::Global()->BlacklistDomain(gurl
);
93 EXPECT_EQ(SdchManager::BlackListDomainCount(domain
), 1);
94 EXPECT_EQ(SdchManager::BlacklistDomainExponential(domain
), 1);
96 // Check that any domain lookup reduces the blacklist counter.
97 EXPECT_FALSE(SdchManager::Global()->IsInSupportedDomain(gurl
));
98 EXPECT_EQ(SdchManager::BlackListDomainCount(domain
), 0);
99 EXPECT_TRUE(SdchManager::Global()->IsInSupportedDomain(gurl
));
102 TEST_F(SdchManagerTest
, BlacklistingExponential
) {
103 GURL
gurl("http://mytest.DoMain.com");
104 std::string
domain(gurl
.host());
105 SdchManager::ClearBlacklistings();
108 for (int i
= 1; i
< 100; ++i
) {
109 SdchManager::Global()->BlacklistDomain(gurl
);
110 EXPECT_EQ(SdchManager::BlacklistDomainExponential(domain
), exponential
);
112 EXPECT_EQ(SdchManager::BlackListDomainCount(domain
), exponential
);
113 EXPECT_FALSE(SdchManager::Global()->IsInSupportedDomain(gurl
));
114 EXPECT_EQ(SdchManager::BlackListDomainCount(domain
), exponential
- 1);
116 // Simulate a large number of domain checks (which eventually remove the
118 SdchManager::ClearDomainBlacklisting(domain
);
119 EXPECT_EQ(SdchManager::BlackListDomainCount(domain
), 0);
120 EXPECT_TRUE(SdchManager::Global()->IsInSupportedDomain(gurl
));
122 // Predict what exponential backoff will be.
123 exponential
= 1 + 2 * exponential
;
125 exponential
= INT_MAX
; // We don't wrap.
129 TEST_F(SdchManagerTest
, CanSetExactMatchDictionary
) {
130 std::string
dictionary_domain("x.y.z.google.com");
131 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
133 // Perfect match should work.
134 EXPECT_TRUE(sdch_manager_
->AddSdchDictionary(dictionary_text
,
135 GURL("http://" + dictionary_domain
)));
138 TEST_F(SdchManagerTest
, CanAdvertiseDictionaryOverHTTP
) {
139 std::string
dictionary_domain("x.y.z.google.com");
140 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
142 EXPECT_TRUE(sdch_manager_
->AddSdchDictionary(dictionary_text
,
143 GURL("http://" + dictionary_domain
)));
145 std::string dictionary_list
;
146 // HTTP target URL can advertise dictionary.
147 sdch_manager_
->GetAvailDictionaryList(
148 GURL("http://" + dictionary_domain
+ "/test"),
150 EXPECT_FALSE(dictionary_list
.empty());
153 TEST_F(SdchManagerTest
, CanNotAdvertiseDictionaryOverHTTPS
) {
154 std::string
dictionary_domain("x.y.z.google.com");
155 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
157 EXPECT_TRUE(sdch_manager_
->AddSdchDictionary(dictionary_text
,
158 GURL("http://" + dictionary_domain
)));
160 std::string dictionary_list
;
161 // HTTPS target URL should NOT advertise dictionary.
162 sdch_manager_
->GetAvailDictionaryList(
163 GURL("https://" + dictionary_domain
+ "/test"),
165 EXPECT_TRUE(dictionary_list
.empty());
168 TEST_F(SdchManagerTest
, CanUseHTTPSDictionaryOverHTTPSIfEnabled
) {
169 std::string
dictionary_domain("x.y.z.google.com");
170 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
172 EXPECT_TRUE(sdch_manager_
->AddSdchDictionary(dictionary_text
,
173 GURL("https://" + dictionary_domain
)));
175 GURL
target_url("https://" + dictionary_domain
+ "/test");
176 std::string dictionary_list
;
177 // HTTPS target URL should advertise dictionary if secure scheme support is
179 sdch_manager_
->EnableSecureSchemeSupport(true);
180 sdch_manager_
->GetAvailDictionaryList(target_url
, &dictionary_list
);
181 EXPECT_FALSE(dictionary_list
.empty());
183 // Dictionary should be available.
184 SdchManager::Dictionary
* dictionary
= NULL
;
185 std::string client_hash
;
186 std::string server_hash
;
187 sdch_manager_
->GenerateHash(dictionary_text
, &client_hash
, &server_hash
);
188 sdch_manager_
->GetVcdiffDictionary(server_hash
, target_url
, &dictionary
);
189 EXPECT_TRUE(dictionary
!= NULL
);
192 TEST_F(SdchManagerTest
, CanNotUseHTTPDictionaryOverHTTPS
) {
193 std::string
dictionary_domain("x.y.z.google.com");
194 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
196 EXPECT_TRUE(sdch_manager_
->AddSdchDictionary(dictionary_text
,
197 GURL("http://" + dictionary_domain
)));
199 GURL
target_url("https://" + dictionary_domain
+ "/test");
200 std::string dictionary_list
;
201 // HTTPS target URL should not advertise dictionary acquired over HTTP even if
202 // secure scheme support is enabled.
203 sdch_manager_
->EnableSecureSchemeSupport(true);
204 sdch_manager_
->GetAvailDictionaryList(target_url
, &dictionary_list
);
205 EXPECT_TRUE(dictionary_list
.empty());
207 SdchManager::Dictionary
* dictionary
= NULL
;
208 std::string client_hash
;
209 std::string server_hash
;
210 sdch_manager_
->GenerateHash(dictionary_text
, &client_hash
, &server_hash
);
211 sdch_manager_
->GetVcdiffDictionary(server_hash
, target_url
, &dictionary
);
212 EXPECT_TRUE(dictionary
== NULL
);
215 TEST_F(SdchManagerTest
, FailToSetDomainMismatchDictionary
) {
216 std::string
dictionary_domain("x.y.z.google.com");
217 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
219 // Fail the "domain match" requirement.
220 EXPECT_FALSE(sdch_manager_
->AddSdchDictionary(dictionary_text
,
221 GURL("http://y.z.google.com")));
224 TEST_F(SdchManagerTest
, FailToSetDotHostPrefixDomainDictionary
) {
225 std::string
dictionary_domain("x.y.z.google.com");
226 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
228 // Fail the HD with D being the domain and H having a dot requirement.
229 EXPECT_FALSE(sdch_manager_
->AddSdchDictionary(dictionary_text
,
230 GURL("http://w.x.y.z.google.com")));
233 TEST_F(SdchManagerTest
, FailToSetRepeatPrefixWithDotDictionary
) {
234 // Make sure that a prefix that matches the domain postfix won't confuse
235 // the validation checks.
236 std::string
dictionary_domain("www.google.com");
237 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
239 // Fail the HD with D being the domain and H having a dot requirement.
240 EXPECT_FALSE(sdch_manager_
->AddSdchDictionary(dictionary_text
,
241 GURL("http://www.google.com.www.google.com")));
244 TEST_F(SdchManagerTest
, CanSetLeadingDotDomainDictionary
) {
245 // Make sure that a prefix that matches the domain postfix won't confuse
246 // the validation checks.
247 std::string
dictionary_domain(".google.com");
248 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
250 // Verify that a leading dot in the domain is acceptable, as long as the host
251 // name does not contain any dots preceding the matched domain name.
252 EXPECT_TRUE(sdch_manager_
->AddSdchDictionary(dictionary_text
,
253 GURL("http://www.google.com")));
256 // Make sure the order of the tests is not helping us or confusing things.
257 // See test CanSetExactMatchDictionary above for first try.
258 TEST_F(SdchManagerTest
, CanStillSetExactMatchDictionary
) {
259 std::string
dictionary_domain("x.y.z.google.com");
260 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
262 // Perfect match should *STILL* work.
263 EXPECT_TRUE(sdch_manager_
->AddSdchDictionary(dictionary_text
,
264 GURL("http://" + dictionary_domain
)));
267 // Make sure the DOS protection precludes the addition of too many dictionaries.
268 TEST_F(SdchManagerTest
, TooManyDictionaries
) {
269 std::string
dictionary_domain(".google.com");
270 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
273 while (count
<= SdchManager::kMaxDictionaryCount
+ 1) {
274 if (!sdch_manager_
->AddSdchDictionary(dictionary_text
,
275 GURL("http://www.google.com")))
278 dictionary_text
+= " "; // Create dictionary with different SHA signature.
281 EXPECT_EQ(SdchManager::kMaxDictionaryCount
, count
);
284 TEST_F(SdchManagerTest
, DictionaryNotTooLarge
) {
285 std::string
dictionary_domain(".google.com");
286 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
288 dictionary_text
.append(
289 SdchManager::kMaxDictionarySize
- dictionary_text
.size(), ' ');
290 EXPECT_TRUE(sdch_manager_
->AddSdchDictionary(dictionary_text
,
291 GURL("http://" + dictionary_domain
)));
294 TEST_F(SdchManagerTest
, DictionaryTooLarge
) {
295 std::string
dictionary_domain(".google.com");
296 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
298 dictionary_text
.append(
299 SdchManager::kMaxDictionarySize
+ 1 - dictionary_text
.size(), ' ');
300 EXPECT_FALSE(sdch_manager_
->AddSdchDictionary(dictionary_text
,
301 GURL("http://" + dictionary_domain
)));
304 TEST_F(SdchManagerTest
, PathMatch
) {
305 bool (*PathMatch
)(const std::string
& path
, const std::string
& restriction
) =
306 SdchManager::Dictionary::PathMatch
;
307 // Perfect match is supported.
308 EXPECT_TRUE(PathMatch("/search", "/search"));
309 EXPECT_TRUE(PathMatch("/search/", "/search/"));
311 // Prefix only works if last character of restriction is a slash, or first
312 // character in path after a match is a slash. Validate each case separately.
314 // Rely on the slash in the path (not at the end of the restriction).
315 EXPECT_TRUE(PathMatch("/search/something", "/search"));
316 EXPECT_TRUE(PathMatch("/search/s", "/search"));
317 EXPECT_TRUE(PathMatch("/search/other", "/search"));
318 EXPECT_TRUE(PathMatch("/search/something", "/search"));
320 // Rely on the slash at the end of the restriction.
321 EXPECT_TRUE(PathMatch("/search/something", "/search/"));
322 EXPECT_TRUE(PathMatch("/search/s", "/search/"));
323 EXPECT_TRUE(PathMatch("/search/other", "/search/"));
324 EXPECT_TRUE(PathMatch("/search/something", "/search/"));
326 // Make sure less that sufficient prefix match is false.
327 EXPECT_FALSE(PathMatch("/sear", "/search"));
328 EXPECT_FALSE(PathMatch("/", "/search"));
329 EXPECT_FALSE(PathMatch(std::string(), "/search"));
331 // Add examples with several levels of direcories in the restriction.
332 EXPECT_FALSE(PathMatch("/search/something", "search/s"));
333 EXPECT_FALSE(PathMatch("/search/", "/search/s"));
335 // Make sure adding characters to path will also fail.
336 EXPECT_FALSE(PathMatch("/searching", "/search/"));
337 EXPECT_FALSE(PathMatch("/searching", "/search"));
339 // Make sure we're case sensitive.
340 EXPECT_FALSE(PathMatch("/ABC", "/abc"));
341 EXPECT_FALSE(PathMatch("/abc", "/ABC"));
344 // The following are only applicable while we have a latency test in the code,
345 // and can be removed when that functionality is stripped.
346 TEST_F(SdchManagerTest
, LatencyTestControls
) {
347 GURL
url("http://www.google.com");
348 GURL
url2("http://www.google2.com");
350 // First make sure we default to false.
351 EXPECT_FALSE(sdch_manager_
->AllowLatencyExperiment(url
));
352 EXPECT_FALSE(sdch_manager_
->AllowLatencyExperiment(url2
));
354 // That we can set each to true.
355 sdch_manager_
->SetAllowLatencyExperiment(url
, true);
356 EXPECT_TRUE(sdch_manager_
->AllowLatencyExperiment(url
));
357 EXPECT_FALSE(sdch_manager_
->AllowLatencyExperiment(url2
));
359 sdch_manager_
->SetAllowLatencyExperiment(url2
, true);
360 EXPECT_TRUE(sdch_manager_
->AllowLatencyExperiment(url
));
361 EXPECT_TRUE(sdch_manager_
->AllowLatencyExperiment(url2
));
363 // And can reset them to false.
364 sdch_manager_
->SetAllowLatencyExperiment(url
, false);
365 EXPECT_FALSE(sdch_manager_
->AllowLatencyExperiment(url
));
366 EXPECT_TRUE(sdch_manager_
->AllowLatencyExperiment(url2
));
368 sdch_manager_
->SetAllowLatencyExperiment(url2
, false);
369 EXPECT_FALSE(sdch_manager_
->AllowLatencyExperiment(url
));
370 EXPECT_FALSE(sdch_manager_
->AllowLatencyExperiment(url2
));