Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
| 11 #include "base/strings/string_util.h" | 11 #include "base/strings/string_util.h" |
| 12 #include "crypto/sha2.h" | 12 #include "crypto/sha2.h" |
| 13 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" | 13 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" |
| 14 #include "net/base/sdch_observer.h" | |
| 14 #include "net/url_request/url_request_http_job.h" | 15 #include "net/url_request/url_request_http_job.h" |
| 15 | 16 |
| 16 namespace { | 17 namespace { |
| 17 | 18 |
| 18 void StripTrailingDot(GURL* gurl) { | 19 void StripTrailingDot(GURL* gurl) { |
| 19 std::string host(gurl->host()); | 20 std::string host(gurl->host()); |
| 20 | 21 |
| 21 if (host.empty()) | 22 if (host.empty()) |
| 22 return; | 23 return; |
| 23 | 24 |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 234 } | 235 } |
| 235 | 236 |
| 236 // static | 237 // static |
| 237 bool SdchManager::Dictionary::DomainMatch(const GURL& gurl, | 238 bool SdchManager::Dictionary::DomainMatch(const GURL& gurl, |
| 238 const std::string& restriction) { | 239 const std::string& restriction) { |
| 239 // TODO(jar): This is not precisely a domain match definition. | 240 // TODO(jar): This is not precisely a domain match definition. |
| 240 return gurl.DomainIs(restriction.data(), restriction.size()); | 241 return gurl.DomainIs(restriction.data(), restriction.size()); |
| 241 } | 242 } |
| 242 | 243 |
| 243 //------------------------------------------------------------------------------ | 244 //------------------------------------------------------------------------------ |
| 244 SdchManager::SdchManager() | 245 SdchManager::SdchManager() { |
| 245 : fetches_count_for_testing_(0) { | |
| 246 DCHECK(CalledOnValidThread()); | 246 DCHECK(CalledOnValidThread()); |
| 247 } | 247 } |
| 248 | 248 |
| 249 SdchManager::~SdchManager() { | 249 SdchManager::~SdchManager() { |
| 250 DCHECK(CalledOnValidThread()); | 250 DCHECK(CalledOnValidThread()); |
| 251 while (!dictionaries_.empty()) { | 251 while (!dictionaries_.empty()) { |
| 252 DictionaryMap::iterator it = dictionaries_.begin(); | 252 DictionaryMap::iterator it = dictionaries_.begin(); |
| 253 dictionaries_.erase(it->first); | 253 dictionaries_.erase(it->first); |
| 254 } | 254 } |
| 255 } | 255 } |
| 256 | 256 |
| 257 void SdchManager::ClearData() { | 257 void SdchManager::ClearData() { |
| 258 blacklisted_domains_.clear(); | 258 blacklisted_domains_.clear(); |
| 259 allow_latency_experiment_.clear(); | 259 allow_latency_experiment_.clear(); |
| 260 if (fetcher_.get()) | |
| 261 fetcher_->Cancel(); | |
| 262 | 260 |
| 263 // Note that this may result in not having dictionaries we've advertised | 261 // Note that this may result in not having dictionaries we've advertised |
| 264 // for incoming responses. The window is relatively small (as ClearData() | 262 // for incoming responses. The window is relatively small (as ClearData() |
| 265 // is not expected to be called frequently), so we rely on meta-refresh | 263 // is not expected to be called frequently), so we rely on meta-refresh |
| 266 // to handle this case. | 264 // to handle this case. |
| 267 dictionaries_.clear(); | 265 dictionaries_.clear(); |
| 266 | |
| 267 FOR_EACH_OBSERVER(SdchObserver, observers_, OnClearDictionaries(this)); | |
| 268 } | 268 } |
| 269 | 269 |
| 270 // static | 270 // static |
| 271 void SdchManager::SdchErrorRecovery(ProblemCodes problem) { | 271 void SdchManager::SdchErrorRecovery(ProblemCodes problem) { |
| 272 UMA_HISTOGRAM_ENUMERATION("Sdch3.ProblemCodes_4", problem, MAX_PROBLEM_CODE); | 272 UMA_HISTOGRAM_ENUMERATION("Sdch3.ProblemCodes_4", problem, MAX_PROBLEM_CODE); |
| 273 } | 273 } |
| 274 | 274 |
| 275 void SdchManager::set_sdch_fetcher(scoped_ptr<SdchFetcher> fetcher) { | |
| 276 DCHECK(CalledOnValidThread()); | |
| 277 fetcher_ = fetcher.Pass(); | |
| 278 } | |
| 279 | |
| 280 // static | 275 // static |
| 281 void SdchManager::EnableSdchSupport(bool enabled) { | 276 void SdchManager::EnableSdchSupport(bool enabled) { |
| 282 g_sdch_enabled_ = enabled; | 277 g_sdch_enabled_ = enabled; |
| 283 } | 278 } |
| 284 | 279 |
| 285 // static | 280 // static |
| 286 void SdchManager::EnableSecureSchemeSupport(bool enabled) { | 281 void SdchManager::EnableSecureSchemeSupport(bool enabled) { |
| 287 g_secure_scheme_supported_ = enabled; | 282 g_secure_scheme_supported_ = enabled; |
| 288 } | 283 } |
| 289 | 284 |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 370 if (count > 0) { | 365 if (count > 0) { |
| 371 it->second.count = count; | 366 it->second.count = count; |
| 372 } else { | 367 } else { |
| 373 it->second.count = 0; | 368 it->second.count = 0; |
| 374 it->second.reason = MIN_PROBLEM_CODE; | 369 it->second.reason = MIN_PROBLEM_CODE; |
| 375 } | 370 } |
| 376 | 371 |
| 377 return false; | 372 return false; |
| 378 } | 373 } |
| 379 | 374 |
| 380 void SdchManager::FetchDictionary(const GURL& request_url, | 375 void SdchManager::OnGetDictionary(const GURL& request_url, |
| 381 const GURL& dictionary_url) { | 376 const GURL& dictionary_url) { |
| 382 DCHECK(CalledOnValidThread()); | 377 if (!CanFetchDictionary(request_url, dictionary_url)) |
| 383 if (CanFetchDictionary(request_url, dictionary_url) && fetcher_.get()) { | 378 return; |
| 384 ++fetches_count_for_testing_; | 379 |
| 385 fetcher_->Schedule(dictionary_url); | 380 FOR_EACH_OBSERVER(SdchObserver, observers_, |
| 386 } | 381 OnGetDictionary(this, request_url, dictionary_url)); |
| 387 } | 382 } |
| 388 | 383 |
| 389 bool SdchManager::CanFetchDictionary(const GURL& referring_url, | 384 bool SdchManager::CanFetchDictionary(const GURL& referring_url, |
| 390 const GURL& dictionary_url) const { | 385 const GURL& dictionary_url) const { |
| 391 DCHECK(CalledOnValidThread()); | 386 DCHECK(CalledOnValidThread()); |
| 392 /* The user agent may retrieve a dictionary from the dictionary URL if all of | 387 /* The user agent may retrieve a dictionary from the dictionary URL if all of |
| 393 the following are true: | 388 the following are true: |
| 394 1 The dictionary URL host name matches the referrer URL host name and | 389 1 The dictionary URL host name matches the referrer URL host name and |
| 395 scheme. | 390 scheme. |
| 396 2 The dictionary URL host name domain matches the parent domain of the | 391 2 The dictionary URL host name domain matches the parent domain of the |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 492 allow_latency_experiment_.insert(url.host()); | 487 allow_latency_experiment_.insert(url.host()); |
| 493 return; | 488 return; |
| 494 } | 489 } |
| 495 ExperimentSet::iterator it = allow_latency_experiment_.find(url.host()); | 490 ExperimentSet::iterator it = allow_latency_experiment_.find(url.host()); |
| 496 if (allow_latency_experiment_.end() == it) | 491 if (allow_latency_experiment_.end() == it) |
| 497 return; // It was already erased, or never allowed. | 492 return; // It was already erased, or never allowed. |
| 498 SdchErrorRecovery(LATENCY_TEST_DISALLOWED); | 493 SdchErrorRecovery(LATENCY_TEST_DISALLOWED); |
| 499 allow_latency_experiment_.erase(it); | 494 allow_latency_experiment_.erase(it); |
| 500 } | 495 } |
| 501 | 496 |
| 497 void SdchManager::AddObserver(SdchObserver* observer) { | |
| 498 observers_.AddObserver(observer); | |
| 499 observer->AddRef(); | |
| 500 } | |
| 501 | |
| 502 void SdchManager::RemoveObserver(SdchObserver* observer) { | |
| 503 observers_.RemoveObserver(observer); | |
| 504 observer->RemoveRef(); | |
|
Ryan Sleevi
2014/10/20 22:42:04
This sort of manual ref-counting strikes me as all
Randy Smith (Not in Mondays)
2014/10/21 19:05:36
First, I want to call out that the Add/RemoveRef()
Ryan Sleevi
2014/10/21 23:09:29
I have a different judgement. I dislike re-inventi
Randy Smith (Not in Mondays)
2014/10/23 20:57:07
Done.
(I tried to do an RAII pattern where Sdch
| |
| 505 } | |
| 506 | |
| 502 void SdchManager::AddSdchDictionary(const std::string& dictionary_text, | 507 void SdchManager::AddSdchDictionary(const std::string& dictionary_text, |
| 503 const GURL& dictionary_url) { | 508 const GURL& dictionary_url) { |
| 504 DCHECK(CalledOnValidThread()); | 509 DCHECK(CalledOnValidThread()); |
| 505 std::string client_hash; | 510 std::string client_hash; |
| 506 std::string server_hash; | 511 std::string server_hash; |
| 507 GenerateHash(dictionary_text, &client_hash, &server_hash); | 512 GenerateHash(dictionary_text, &client_hash, &server_hash); |
| 508 if (dictionaries_.find(server_hash) != dictionaries_.end()) { | 513 if (dictionaries_.find(server_hash) != dictionaries_.end()) { |
| 509 SdchErrorRecovery(DICTIONARY_ALREADY_LOADED); | 514 SdchErrorRecovery(DICTIONARY_ALREADY_LOADED); |
| 510 return; // Already loaded. | 515 return; // Already loaded. |
| 511 } | 516 } |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 609 void SdchManager::UrlSafeBase64Encode(const std::string& input, | 614 void SdchManager::UrlSafeBase64Encode(const std::string& input, |
| 610 std::string* output) { | 615 std::string* output) { |
| 611 // Since this is only done during a dictionary load, and hashes are only 8 | 616 // Since this is only done during a dictionary load, and hashes are only 8 |
| 612 // characters, we just do the simple fixup, rather than rewriting the encoder. | 617 // characters, we just do the simple fixup, rather than rewriting the encoder. |
| 613 base::Base64Encode(input, output); | 618 base::Base64Encode(input, output); |
| 614 std::replace(output->begin(), output->end(), '+', '-'); | 619 std::replace(output->begin(), output->end(), '+', '-'); |
| 615 std::replace(output->begin(), output->end(), '/', '_'); | 620 std::replace(output->begin(), output->end(), '/', '_'); |
| 616 } | 621 } |
| 617 | 622 |
| 618 } // namespace net | 623 } // namespace net |
| OLD | NEW |