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 |