conditional_cache_deletion_helper.cc 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. // Copyright 2018 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "services/network/conditional_cache_deletion_helper.h"
  5. #include "base/bind.h"
  6. #include "base/callback.h"
  7. #include "base/location.h"
  8. #include "base/task/single_thread_task_runner.h"
  9. #include "base/threading/thread_task_runner_handle.h"
  10. #include "net/http/http_cache.h"
  11. #include "net/http/http_util.h"
  12. namespace {
  13. bool EntryPredicateFromURLsAndTime(
  14. const base::RepeatingCallback<bool(const GURL&)>& url_matcher,
  15. const base::Time& begin_time,
  16. const base::Time& end_time,
  17. const disk_cache::Entry* entry) {
  18. std::string entry_key(entry->GetKey());
  19. std::string url_string(
  20. net::HttpCache::GetResourceURLFromHttpCacheKey(entry_key));
  21. return (entry->GetLastUsed() >= begin_time &&
  22. entry->GetLastUsed() < end_time && url_matcher.Run(GURL(url_string)));
  23. }
  24. } // namespace
  25. namespace network {
  26. // static
  27. std::unique_ptr<ConditionalCacheDeletionHelper>
  28. ConditionalCacheDeletionHelper::CreateAndStart(
  29. disk_cache::Backend* cache,
  30. const base::RepeatingCallback<bool(const GURL&)>& url_matcher,
  31. const base::Time& begin_time,
  32. const base::Time& end_time,
  33. base::OnceClosure completion_callback) {
  34. std::unique_ptr<ConditionalCacheDeletionHelper> deletion_helper(
  35. new ConditionalCacheDeletionHelper(
  36. base::BindRepeating(
  37. &EntryPredicateFromURLsAndTime, url_matcher,
  38. begin_time.is_null() ? base::Time() : begin_time,
  39. end_time.is_null() ? base::Time::Max() : end_time),
  40. std::move(completion_callback), cache->CreateIterator()));
  41. // Any status other than OK (since no entry), IO_PENDING, or FAILED would
  42. // work here.
  43. deletion_helper->IterateOverEntries(
  44. disk_cache::EntryResult::MakeError(net::ERR_CACHE_OPEN_FAILURE));
  45. return deletion_helper;
  46. }
  47. ConditionalCacheDeletionHelper::ConditionalCacheDeletionHelper(
  48. const base::RepeatingCallback<bool(const disk_cache::Entry*)>& condition,
  49. base::OnceClosure completion_callback,
  50. std::unique_ptr<disk_cache::Backend::Iterator> iterator)
  51. : condition_(condition),
  52. completion_callback_(std::move(completion_callback)),
  53. iterator_(std::move(iterator)) {}
  54. ConditionalCacheDeletionHelper::~ConditionalCacheDeletionHelper() = default;
  55. void ConditionalCacheDeletionHelper::IterateOverEntries(
  56. disk_cache::EntryResult result) {
  57. while (result.net_error() != net::ERR_IO_PENDING) {
  58. // If the entry obtained in the previous iteration matches the condition,
  59. // mark it for deletion. The iterator is already one step forward, so it
  60. // won't be invalidated. Always close the previous entry so it does not
  61. // leak.
  62. if (previous_entry_) {
  63. if (condition_.Run(previous_entry_.get())) {
  64. previous_entry_->Doom();
  65. }
  66. previous_entry_->Close();
  67. }
  68. if (result.net_error() == net::ERR_FAILED) {
  69. // The iteration finished successfully or we can no longer iterate
  70. // (e.g. the cache was destroyed). We cannot distinguish between the two,
  71. // but we know that there is nothing more that we can do.
  72. base::ThreadTaskRunnerHandle::Get()->PostTask(
  73. FROM_HERE,
  74. base::BindOnce(&ConditionalCacheDeletionHelper::NotifyCompletion,
  75. weak_factory_.GetWeakPtr()));
  76. return;
  77. }
  78. previous_entry_ = result.ReleaseEntry();
  79. result = iterator_->OpenNextEntry(
  80. base::BindOnce(&ConditionalCacheDeletionHelper::IterateOverEntries,
  81. weak_factory_.GetWeakPtr()));
  82. }
  83. }
  84. void ConditionalCacheDeletionHelper::NotifyCompletion() {
  85. std::move(completion_callback_).Run();
  86. }
  87. } // namespace network