| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 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 "net/base/sdch_manager.h" | 5 #include "net/base/sdch_manager.h" |
| 6 | 6 |
| 7 #include "base/base64.h" | 7 #include "base/base64.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
| 10 #include "base/string_number_conversions.h" | 10 #include "base/string_number_conversions.h" |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 199 // static | 199 // static |
| 200 bool SdchManager::Dictionary::DomainMatch(const GURL& gurl, | 200 bool SdchManager::Dictionary::DomainMatch(const GURL& gurl, |
| 201 const std::string& restriction) { | 201 const std::string& restriction) { |
| 202 // TODO(jar): This is not precisely a domain match definition. | 202 // TODO(jar): This is not precisely a domain match definition. |
| 203 return gurl.DomainIs(restriction.data(), restriction.size()); | 203 return gurl.DomainIs(restriction.data(), restriction.size()); |
| 204 } | 204 } |
| 205 | 205 |
| 206 //------------------------------------------------------------------------------ | 206 //------------------------------------------------------------------------------ |
| 207 SdchManager::SdchManager() { | 207 SdchManager::SdchManager() { |
| 208 DCHECK(!global_); | 208 DCHECK(!global_); |
| 209 DCHECK(CalledOnValidThread()); |
| 209 global_ = this; | 210 global_ = this; |
| 210 } | 211 } |
| 211 | 212 |
| 212 SdchManager::~SdchManager() { | 213 SdchManager::~SdchManager() { |
| 213 DCHECK_EQ(this, global_); | 214 DCHECK_EQ(this, global_); |
| 215 DCHECK(CalledOnValidThread()); |
| 214 while (!dictionaries_.empty()) { | 216 while (!dictionaries_.empty()) { |
| 215 DictionaryMap::iterator it = dictionaries_.begin(); | 217 DictionaryMap::iterator it = dictionaries_.begin(); |
| 216 it->second->Release(); | 218 it->second->Release(); |
| 217 dictionaries_.erase(it->first); | 219 dictionaries_.erase(it->first); |
| 218 } | 220 } |
| 219 global_ = NULL; | 221 global_ = NULL; |
| 220 } | 222 } |
| 221 | 223 |
| 222 // static | 224 // static |
| 223 void SdchManager::Shutdown() { | 225 void SdchManager::Shutdown() { |
| 224 EnableSdchSupport(false); | 226 EnableSdchSupport(false); |
| 225 if (!global_ ) | 227 if (!global_ ) |
| 226 return; | 228 return; |
| 227 global_->fetcher_.reset(NULL); | 229 global_->set_sdch_fetcher(NULL); |
| 228 } | 230 } |
| 229 | 231 |
| 230 // static | 232 // static |
| 231 SdchManager* SdchManager::Global() { | 233 SdchManager* SdchManager::Global() { |
| 232 return global_; | 234 return global_; |
| 233 } | 235 } |
| 234 | 236 |
| 235 // static | 237 // static |
| 236 void SdchManager::SdchErrorRecovery(ProblemCodes problem) { | 238 void SdchManager::SdchErrorRecovery(ProblemCodes problem) { |
| 237 UMA_HISTOGRAM_ENUMERATION("Sdch3.ProblemCodes_4", problem, MAX_PROBLEM_CODE); | 239 UMA_HISTOGRAM_ENUMERATION("Sdch3.ProblemCodes_4", problem, MAX_PROBLEM_CODE); |
| 238 } | 240 } |
| 239 | 241 |
| 242 void SdchManager::set_sdch_fetcher(SdchFetcher* fetcher) { |
| 243 DCHECK(CalledOnValidThread()); |
| 244 fetcher_.reset(fetcher); |
| 245 } |
| 246 |
| 240 // static | 247 // static |
| 241 void SdchManager::EnableSdchSupport(bool enabled) { | 248 void SdchManager::EnableSdchSupport(bool enabled) { |
| 242 g_sdch_enabled_ = enabled; | 249 g_sdch_enabled_ = enabled; |
| 243 } | 250 } |
| 244 | 251 |
| 245 // static | 252 // static |
| 246 void SdchManager::BlacklistDomain(const GURL& url) { | 253 void SdchManager::BlacklistDomain(const GURL& url) { |
| 247 if (!global_ ) | 254 if (!global_ ) |
| 248 return; | 255 return; |
| 249 global_->SetAllowLatencyExperiment(url, false); | 256 global_->SetAllowLatencyExperiment(url, false); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 | 301 |
| 295 // static | 302 // static |
| 296 int SdchManager::BlacklistDomainExponential(const std::string& domain) { | 303 int SdchManager::BlacklistDomainExponential(const std::string& domain) { |
| 297 if (Global()->exponential_blacklist_count.end() == | 304 if (Global()->exponential_blacklist_count.end() == |
| 298 Global()->exponential_blacklist_count.find(domain)) | 305 Global()->exponential_blacklist_count.find(domain)) |
| 299 return 0; | 306 return 0; |
| 300 return Global()->exponential_blacklist_count[StringToLowerASCII(domain)]; | 307 return Global()->exponential_blacklist_count[StringToLowerASCII(domain)]; |
| 301 } | 308 } |
| 302 | 309 |
| 303 bool SdchManager::IsInSupportedDomain(const GURL& url) { | 310 bool SdchManager::IsInSupportedDomain(const GURL& url) { |
| 311 DCHECK(CalledOnValidThread()); |
| 304 if (!g_sdch_enabled_ ) | 312 if (!g_sdch_enabled_ ) |
| 305 return false; | 313 return false; |
| 306 | 314 |
| 307 if (blacklisted_domains_.empty()) | 315 if (blacklisted_domains_.empty()) |
| 308 return true; | 316 return true; |
| 309 | 317 |
| 310 std::string domain(StringToLowerASCII(url.host())); | 318 std::string domain(StringToLowerASCII(url.host())); |
| 311 DomainCounter::iterator it = blacklisted_domains_.find(domain); | 319 DomainCounter::iterator it = blacklisted_domains_.find(domain); |
| 312 if (blacklisted_domains_.end() == it) | 320 if (blacklisted_domains_.end() == it) |
| 313 return true; | 321 return true; |
| 314 | 322 |
| 315 int count = it->second - 1; | 323 int count = it->second - 1; |
| 316 if (count > 0) | 324 if (count > 0) |
| 317 blacklisted_domains_[domain] = count; | 325 blacklisted_domains_[domain] = count; |
| 318 else | 326 else |
| 319 blacklisted_domains_.erase(domain); | 327 blacklisted_domains_.erase(domain); |
| 320 SdchErrorRecovery(DOMAIN_BLACKLIST_INCLUDES_TARGET); | 328 SdchErrorRecovery(DOMAIN_BLACKLIST_INCLUDES_TARGET); |
| 321 return false; | 329 return false; |
| 322 } | 330 } |
| 323 | 331 |
| 324 void SdchManager::FetchDictionary(const GURL& request_url, | 332 void SdchManager::FetchDictionary(const GURL& request_url, |
| 325 const GURL& dictionary_url) { | 333 const GURL& dictionary_url) { |
| 334 DCHECK(CalledOnValidThread()); |
| 326 if (SdchManager::Global()->CanFetchDictionary(request_url, dictionary_url) && | 335 if (SdchManager::Global()->CanFetchDictionary(request_url, dictionary_url) && |
| 327 fetcher_.get()) | 336 fetcher_.get()) |
| 328 fetcher_->Schedule(dictionary_url); | 337 fetcher_->Schedule(dictionary_url); |
| 329 } | 338 } |
| 330 | 339 |
| 331 bool SdchManager::CanFetchDictionary(const GURL& referring_url, | 340 bool SdchManager::CanFetchDictionary(const GURL& referring_url, |
| 332 const GURL& dictionary_url) const { | 341 const GURL& dictionary_url) const { |
| 342 DCHECK(CalledOnValidThread()); |
| 333 /* The user agent may retrieve a dictionary from the dictionary URL if all of | 343 /* The user agent may retrieve a dictionary from the dictionary URL if all of |
| 334 the following are true: | 344 the following are true: |
| 335 1 The dictionary URL host name matches the referrer URL host name | 345 1 The dictionary URL host name matches the referrer URL host name |
| 336 2 The dictionary URL host name domain matches the parent domain of the | 346 2 The dictionary URL host name domain matches the parent domain of the |
| 337 referrer URL host name | 347 referrer URL host name |
| 338 3 The parent domain of the referrer URL host name is not a top level | 348 3 The parent domain of the referrer URL host name is not a top level |
| 339 domain | 349 domain |
| 340 4 The dictionary URL is not an HTTPS URL. | 350 4 The dictionary URL is not an HTTPS URL. |
| 341 */ | 351 */ |
| 342 // Item (1) above implies item (2). Spec should be updated. | 352 // Item (1) above implies item (2). Spec should be updated. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 355 if (!referring_url.SchemeIs("http")) { | 365 if (!referring_url.SchemeIs("http")) { |
| 356 SdchErrorRecovery(DICTIONARY_SELECTED_FROM_NON_HTTP); | 366 SdchErrorRecovery(DICTIONARY_SELECTED_FROM_NON_HTTP); |
| 357 return false; | 367 return false; |
| 358 } | 368 } |
| 359 | 369 |
| 360 return true; | 370 return true; |
| 361 } | 371 } |
| 362 | 372 |
| 363 bool SdchManager::AddSdchDictionary(const std::string& dictionary_text, | 373 bool SdchManager::AddSdchDictionary(const std::string& dictionary_text, |
| 364 const GURL& dictionary_url) { | 374 const GURL& dictionary_url) { |
| 375 DCHECK(CalledOnValidThread()); |
| 365 std::string client_hash; | 376 std::string client_hash; |
| 366 std::string server_hash; | 377 std::string server_hash; |
| 367 GenerateHash(dictionary_text, &client_hash, &server_hash); | 378 GenerateHash(dictionary_text, &client_hash, &server_hash); |
| 368 if (dictionaries_.find(server_hash) != dictionaries_.end()) { | 379 if (dictionaries_.find(server_hash) != dictionaries_.end()) { |
| 369 SdchErrorRecovery(DICTIONARY_ALREADY_LOADED); | 380 SdchErrorRecovery(DICTIONARY_ALREADY_LOADED); |
| 370 return false; // Already loaded. | 381 return false; // Already loaded. |
| 371 } | 382 } |
| 372 | 383 |
| 373 std::string domain, path; | 384 std::string domain, path; |
| 374 std::set<int> ports; | 385 std::set<int> ports; |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 453 Dictionary* dictionary = | 464 Dictionary* dictionary = |
| 454 new Dictionary(dictionary_text, header_end + 2, client_hash, | 465 new Dictionary(dictionary_text, header_end + 2, client_hash, |
| 455 dictionary_url, domain, path, expiration, ports); | 466 dictionary_url, domain, path, expiration, ports); |
| 456 dictionary->AddRef(); | 467 dictionary->AddRef(); |
| 457 dictionaries_[server_hash] = dictionary; | 468 dictionaries_[server_hash] = dictionary; |
| 458 return true; | 469 return true; |
| 459 } | 470 } |
| 460 | 471 |
| 461 void SdchManager::GetVcdiffDictionary(const std::string& server_hash, | 472 void SdchManager::GetVcdiffDictionary(const std::string& server_hash, |
| 462 const GURL& referring_url, Dictionary** dictionary) { | 473 const GURL& referring_url, Dictionary** dictionary) { |
| 474 DCHECK(CalledOnValidThread()); |
| 463 *dictionary = NULL; | 475 *dictionary = NULL; |
| 464 DictionaryMap::iterator it = dictionaries_.find(server_hash); | 476 DictionaryMap::iterator it = dictionaries_.find(server_hash); |
| 465 if (it == dictionaries_.end()) { | 477 if (it == dictionaries_.end()) { |
| 466 return; | 478 return; |
| 467 } | 479 } |
| 468 Dictionary* matching_dictionary = it->second; | 480 Dictionary* matching_dictionary = it->second; |
| 469 if (!matching_dictionary->CanUse(referring_url)) | 481 if (!matching_dictionary->CanUse(referring_url)) |
| 470 return; | 482 return; |
| 471 *dictionary = matching_dictionary; | 483 *dictionary = matching_dictionary; |
| 472 } | 484 } |
| 473 | 485 |
| 474 // TODO(jar): If we have evictions from the dictionaries_, then we need to | 486 // TODO(jar): If we have evictions from the dictionaries_, then we need to |
| 475 // change this interface to return a list of reference counted Dictionary | 487 // change this interface to return a list of reference counted Dictionary |
| 476 // instances that can be used if/when a server specifies one. | 488 // instances that can be used if/when a server specifies one. |
| 477 void SdchManager::GetAvailDictionaryList(const GURL& target_url, | 489 void SdchManager::GetAvailDictionaryList(const GURL& target_url, |
| 478 std::string* list) { | 490 std::string* list) { |
| 491 DCHECK(CalledOnValidThread()); |
| 479 int count = 0; | 492 int count = 0; |
| 480 for (DictionaryMap::iterator it = dictionaries_.begin(); | 493 for (DictionaryMap::iterator it = dictionaries_.begin(); |
| 481 it != dictionaries_.end(); ++it) { | 494 it != dictionaries_.end(); ++it) { |
| 482 if (!it->second->CanAdvertise(target_url)) | 495 if (!it->second->CanAdvertise(target_url)) |
| 483 continue; | 496 continue; |
| 484 ++count; | 497 ++count; |
| 485 if (!list->empty()) | 498 if (!list->empty()) |
| 486 list->append(","); | 499 list->append(","); |
| 487 list->append(it->second->client_hash()); | 500 list->append(it->second->client_hash()); |
| 488 } | 501 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 503 UrlSafeBase64Encode(second_48_bits, server_hash); | 516 UrlSafeBase64Encode(second_48_bits, server_hash); |
| 504 | 517 |
| 505 DCHECK_EQ(server_hash->length(), 8u); | 518 DCHECK_EQ(server_hash->length(), 8u); |
| 506 DCHECK_EQ(client_hash->length(), 8u); | 519 DCHECK_EQ(client_hash->length(), 8u); |
| 507 } | 520 } |
| 508 | 521 |
| 509 //------------------------------------------------------------------------------ | 522 //------------------------------------------------------------------------------ |
| 510 // Methods for supporting latency experiments. | 523 // Methods for supporting latency experiments. |
| 511 | 524 |
| 512 bool SdchManager::AllowLatencyExperiment(const GURL& url) const { | 525 bool SdchManager::AllowLatencyExperiment(const GURL& url) const { |
| 526 DCHECK(CalledOnValidThread()); |
| 513 return allow_latency_experiment_.end() != | 527 return allow_latency_experiment_.end() != |
| 514 allow_latency_experiment_.find(url.host()); | 528 allow_latency_experiment_.find(url.host()); |
| 515 } | 529 } |
| 516 | 530 |
| 517 void SdchManager::SetAllowLatencyExperiment(const GURL& url, bool enable) { | 531 void SdchManager::SetAllowLatencyExperiment(const GURL& url, bool enable) { |
| 532 DCHECK(CalledOnValidThread()); |
| 518 if (enable) { | 533 if (enable) { |
| 519 allow_latency_experiment_.insert(url.host()); | 534 allow_latency_experiment_.insert(url.host()); |
| 520 return; | 535 return; |
| 521 } | 536 } |
| 522 ExperimentSet::iterator it = allow_latency_experiment_.find(url.host()); | 537 ExperimentSet::iterator it = allow_latency_experiment_.find(url.host()); |
| 523 if (allow_latency_experiment_.end() == it) | 538 if (allow_latency_experiment_.end() == it) |
| 524 return; // It was already erased, or never allowed. | 539 return; // It was already erased, or never allowed. |
| 525 SdchErrorRecovery(LATENCY_TEST_DISALLOWED); | 540 SdchErrorRecovery(LATENCY_TEST_DISALLOWED); |
| 526 allow_latency_experiment_.erase(it); | 541 allow_latency_experiment_.erase(it); |
| 527 } | 542 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 540 case '/': | 555 case '/': |
| 541 (*output)[i] = '_'; | 556 (*output)[i] = '_'; |
| 542 continue; | 557 continue; |
| 543 default: | 558 default: |
| 544 continue; | 559 continue; |
| 545 } | 560 } |
| 546 } | 561 } |
| 547 } | 562 } |
| 548 | 563 |
| 549 } // namespace net | 564 } // namespace net |
| OLD | NEW |