| 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 |