OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/field_trial.h" | 5 #include "base/field_trial.h" |
6 #include "base/histogram.h" | 6 #include "base/histogram.h" |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/sha2.h" | 8 #include "base/sha2.h" |
9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
10 #include "net/base/base64.h" | 10 #include "net/base/base64.h" |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 std::string client_hash; | 115 std::string client_hash; |
116 std::string server_hash; | 116 std::string server_hash; |
117 GenerateHash(dictionary_text, &client_hash, &server_hash); | 117 GenerateHash(dictionary_text, &client_hash, &server_hash); |
118 if (dictionaries_.find(server_hash) != dictionaries_.end()) { | 118 if (dictionaries_.find(server_hash) != dictionaries_.end()) { |
119 SdchErrorRecovery(DICTIONARY_ALREADY_LOADED); | 119 SdchErrorRecovery(DICTIONARY_ALREADY_LOADED); |
120 return false; // Already loaded. | 120 return false; // Already loaded. |
121 } | 121 } |
122 | 122 |
123 std::string domain, path; | 123 std::string domain, path; |
124 std::set<int> ports; | 124 std::set<int> ports; |
125 Time expiration; | 125 Time expiration(Time::Now() + TimeDelta::FromDays(30)); |
126 | 126 |
127 size_t header_end = dictionary_text.find("\n\n"); | 127 size_t header_end = dictionary_text.find("\n\n"); |
128 if (std::string::npos == header_end) { | 128 if (std::string::npos == header_end) { |
129 SdchErrorRecovery(DICTIONARY_HAS_NO_HEADER); | 129 SdchErrorRecovery(DICTIONARY_HAS_NO_HEADER); |
130 return false; // Missing header. | 130 return false; // Missing header. |
131 } | 131 } |
132 size_t line_start = 0; // Start of line being parsed. | 132 size_t line_start = 0; // Start of line being parsed. |
133 while (1) { | 133 while (1) { |
134 size_t line_end = dictionary_text.find('\n', line_start); | 134 size_t line_end = dictionary_text.find('\n', line_start); |
135 DCHECK(std::string::npos != line_end); | 135 DCHECK(std::string::npos != line_end); |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
293 if (net::RegistryControlledDomainService::GetDomainAndRegistry(domain).size() | 293 if (net::RegistryControlledDomainService::GetDomainAndRegistry(domain).size() |
294 == 0) { | 294 == 0) { |
295 SdchErrorRecovery(DICTIONARY_SPECIFIES_TOP_LEVEL_DOMAIN); | 295 SdchErrorRecovery(DICTIONARY_SPECIFIES_TOP_LEVEL_DOMAIN); |
296 return false; // domain was a TLD. | 296 return false; // domain was a TLD. |
297 } | 297 } |
298 if (!Dictionary::DomainMatch(dictionary_url, domain)) { | 298 if (!Dictionary::DomainMatch(dictionary_url, domain)) { |
299 SdchErrorRecovery(DICTIONARY_DOMAIN_NOT_MATCHING_SOURCE_URL); | 299 SdchErrorRecovery(DICTIONARY_DOMAIN_NOT_MATCHING_SOURCE_URL); |
300 return false; | 300 return false; |
301 } | 301 } |
302 | 302 |
303 // TODO(jar): Enforce item 4 above. | 303 std::string referrer_url_host = dictionary_url.host(); |
| 304 size_t postfix_domain_index = referrer_url_host.rfind(domain); |
| 305 // See if it is indeed a postfix, or just an internal string. |
| 306 if (referrer_url_host.size() == postfix_domain_index + domain.size()) { |
| 307 // It is a postfix... so check to see if there's a dot in the prefix. |
| 308 size_t end_of_host_index = referrer_url_host.find_first_of('.'); |
| 309 if (referrer_url_host.npos != end_of_host_index && |
| 310 end_of_host_index < postfix_domain_index) |
| 311 return false; |
| 312 } |
304 | 313 |
305 if (!ports.empty() | 314 if (!ports.empty() |
306 && 0 == ports.count(dictionary_url.EffectiveIntPort())) { | 315 && 0 == ports.count(dictionary_url.EffectiveIntPort())) { |
307 SdchErrorRecovery(DICTIONARY_PORT_NOT_MATCHING_SOURCE_URL); | 316 SdchErrorRecovery(DICTIONARY_PORT_NOT_MATCHING_SOURCE_URL); |
308 return false; | 317 return false; |
309 } | 318 } |
310 return true; | 319 return true; |
311 } | 320 } |
312 | 321 |
313 // static | 322 // static |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
358 4. The request is not an HTTPS request. | 367 4. The request is not an HTTPS request. |
359 */ | 368 */ |
360 if (!DomainMatch(target_url, domain_)) | 369 if (!DomainMatch(target_url, domain_)) |
361 return false; | 370 return false; |
362 if (!ports_.empty() && 0 == ports_.count(target_url.EffectiveIntPort())) | 371 if (!ports_.empty() && 0 == ports_.count(target_url.EffectiveIntPort())) |
363 return false; | 372 return false; |
364 if (path_.size() && !PathMatch(target_url.path(), path_)) | 373 if (path_.size() && !PathMatch(target_url.path(), path_)) |
365 return false; | 374 return false; |
366 if (target_url.SchemeIsSecure()) | 375 if (target_url.SchemeIsSecure()) |
367 return false; | 376 return false; |
| 377 if (Time::Now() > expiration_) |
| 378 return false; |
368 return true; | 379 return true; |
369 } | 380 } |
370 | 381 |
371 bool SdchManager::Dictionary::PathMatch(const std::string& path, | 382 bool SdchManager::Dictionary::PathMatch(const std::string& path, |
372 const std::string& restriction) { | 383 const std::string& restriction) { |
373 /* Must be either: | 384 /* Must be either: |
374 1. P2 is equal to P1 | 385 1. P2 is equal to P1 |
375 2. P2 is a prefix of P1 and either the final character in P2 is "/" or the | 386 2. P2 is a prefix of P1 and either the final character in P2 is "/" or the |
376 character following P2 in P1 is "/". | 387 character following P2 in P1 is "/". |
377 */ | 388 */ |
378 if (path == restriction) | 389 if (path == restriction) |
379 return true; | 390 return true; |
380 size_t prefix_length = restriction.size(); | 391 size_t prefix_length = restriction.size(); |
381 if (prefix_length > path.size()) | 392 if (prefix_length > path.size()) |
382 return false; // Can't be a prefix. | 393 return false; // Can't be a prefix. |
383 if (0 != restriction.compare(0, prefix_length, path)) | 394 if (0 != restriction.compare(0, prefix_length, path)) |
384 return false; | 395 return false; |
385 return restriction[prefix_length - 1] == '/' || path[prefix_length] == '/'; | 396 return restriction[prefix_length - 1] == '/' || path[prefix_length] == '/'; |
386 } | 397 } |
387 | 398 |
388 // static | 399 // static |
389 bool SdchManager::Dictionary::DomainMatch(const GURL& gurl, | 400 bool SdchManager::Dictionary::DomainMatch(const GURL& gurl, |
390 const std::string& restriction) { | 401 const std::string& restriction) { |
391 // TODO(jar): This is not precisely a domain match definition. | 402 // TODO(jar): This is not precisely a domain match definition. |
392 return gurl.DomainIs(restriction.data(), restriction.size()); | 403 return gurl.DomainIs(restriction.data(), restriction.size()); |
393 } | 404 } |
OLD | NEW |