Index: webkit/browser/appcache/appcache_service_impl.cc |
diff --git a/webkit/browser/appcache/appcache_service_impl.cc b/webkit/browser/appcache/appcache_service_impl.cc |
deleted file mode 100644 |
index 3091a5cb5fabc4d2dad69303e06668de25cb2e2c..0000000000000000000000000000000000000000 |
--- a/webkit/browser/appcache/appcache_service_impl.cc |
+++ /dev/null |
@@ -1,578 +0,0 @@ |
-// Copyright 2014 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "webkit/browser/appcache/appcache_service_impl.h" |
- |
-#include <functional> |
- |
-#include "base/bind.h" |
-#include "base/bind_helpers.h" |
-#include "base/logging.h" |
-#include "base/message_loop/message_loop.h" |
-#include "base/stl_util.h" |
-#include "net/base/completion_callback.h" |
-#include "net/base/io_buffer.h" |
-#include "webkit/browser/appcache/appcache.h" |
-#include "webkit/browser/appcache/appcache_backend_impl.h" |
-#include "webkit/browser/appcache/appcache_entry.h" |
-#include "webkit/browser/appcache/appcache_executable_handler.h" |
-#include "webkit/browser/appcache/appcache_histograms.h" |
-#include "webkit/browser/appcache/appcache_policy.h" |
-#include "webkit/browser/appcache/appcache_quota_client.h" |
-#include "webkit/browser/appcache/appcache_response.h" |
-#include "webkit/browser/appcache/appcache_service_impl.h" |
-#include "webkit/browser/appcache/appcache_storage_impl.h" |
-#include "webkit/browser/quota/special_storage_policy.h" |
- |
-namespace appcache { |
- |
-namespace { |
- |
-void DeferredCallback(const net::CompletionCallback& callback, int rv) { |
- callback.Run(rv); |
-} |
- |
-} // namespace |
- |
-AppCacheInfoCollection::AppCacheInfoCollection() {} |
- |
-AppCacheInfoCollection::~AppCacheInfoCollection() {} |
- |
-// AsyncHelper ------- |
- |
-class AppCacheServiceImpl::AsyncHelper |
- : public AppCacheStorage::Delegate { |
- public: |
- AsyncHelper(AppCacheServiceImpl* service, |
- const net::CompletionCallback& callback) |
- : service_(service), callback_(callback) { |
- service_->pending_helpers_.insert(this); |
- } |
- |
- virtual ~AsyncHelper() { |
- if (service_) |
- service_->pending_helpers_.erase(this); |
- } |
- |
- virtual void Start() = 0; |
- virtual void Cancel(); |
- |
- protected: |
- void CallCallback(int rv) { |
- if (!callback_.is_null()) { |
- // Defer to guarantee async completion. |
- base::MessageLoop::current()->PostTask( |
- FROM_HERE, base::Bind(&DeferredCallback, callback_, rv)); |
- } |
- callback_.Reset(); |
- } |
- |
- AppCacheServiceImpl* service_; |
- net::CompletionCallback callback_; |
-}; |
- |
-void AppCacheServiceImpl::AsyncHelper::Cancel() { |
- if (!callback_.is_null()) { |
- callback_.Run(net::ERR_ABORTED); |
- callback_.Reset(); |
- } |
- service_->storage()->CancelDelegateCallbacks(this); |
- service_ = NULL; |
-} |
- |
-// CanHandleOfflineHelper ------- |
- |
-class AppCacheServiceImpl::CanHandleOfflineHelper : AsyncHelper { |
- public: |
- CanHandleOfflineHelper( |
- AppCacheServiceImpl* service, const GURL& url, |
- const GURL& first_party, const net::CompletionCallback& callback) |
- : AsyncHelper(service, callback), |
- url_(url), |
- first_party_(first_party) { |
- } |
- |
- virtual void Start() OVERRIDE { |
- AppCachePolicy* policy = service_->appcache_policy(); |
- if (policy && !policy->CanLoadAppCache(url_, first_party_)) { |
- CallCallback(net::ERR_FAILED); |
- delete this; |
- return; |
- } |
- |
- service_->storage()->FindResponseForMainRequest(url_, GURL(), this); |
- } |
- |
- private: |
- // AppCacheStorage::Delegate implementation. |
- virtual void OnMainResponseFound( |
- const GURL& url, const AppCacheEntry& entry, |
- const GURL& fallback_url, const AppCacheEntry& fallback_entry, |
- int64 cache_id, int64 group_id, const GURL& mainfest_url) OVERRIDE; |
- |
- GURL url_; |
- GURL first_party_; |
- |
- DISALLOW_COPY_AND_ASSIGN(CanHandleOfflineHelper); |
-}; |
- |
-void AppCacheServiceImpl::CanHandleOfflineHelper::OnMainResponseFound( |
- const GURL& url, const AppCacheEntry& entry, |
- const GURL& fallback_url, const AppCacheEntry& fallback_entry, |
- int64 cache_id, int64 group_id, const GURL& manifest_url) { |
- bool can = (entry.has_response_id() || fallback_entry.has_response_id()); |
- CallCallback(can ? net::OK : net::ERR_FAILED); |
- delete this; |
-} |
- |
-// DeleteHelper ------- |
- |
-class AppCacheServiceImpl::DeleteHelper : public AsyncHelper { |
- public: |
- DeleteHelper( |
- AppCacheServiceImpl* service, const GURL& manifest_url, |
- const net::CompletionCallback& callback) |
- : AsyncHelper(service, callback), manifest_url_(manifest_url) { |
- } |
- |
- virtual void Start() OVERRIDE { |
- service_->storage()->LoadOrCreateGroup(manifest_url_, this); |
- } |
- |
- private: |
- // AppCacheStorage::Delegate implementation. |
- virtual void OnGroupLoaded( |
- appcache::AppCacheGroup* group, const GURL& manifest_url) OVERRIDE; |
- virtual void OnGroupMadeObsolete(appcache::AppCacheGroup* group, |
- bool success, |
- int response_code) OVERRIDE; |
- |
- GURL manifest_url_; |
- DISALLOW_COPY_AND_ASSIGN(DeleteHelper); |
-}; |
- |
-void AppCacheServiceImpl::DeleteHelper::OnGroupLoaded( |
- appcache::AppCacheGroup* group, const GURL& manifest_url) { |
- if (group) { |
- group->set_being_deleted(true); |
- group->CancelUpdate(); |
- service_->storage()->MakeGroupObsolete(group, this, 0); |
- } else { |
- CallCallback(net::ERR_FAILED); |
- delete this; |
- } |
-} |
- |
-void AppCacheServiceImpl::DeleteHelper::OnGroupMadeObsolete( |
- appcache::AppCacheGroup* group, |
- bool success, |
- int response_code) { |
- CallCallback(success ? net::OK : net::ERR_FAILED); |
- delete this; |
-} |
- |
-// DeleteOriginHelper ------- |
- |
-class AppCacheServiceImpl::DeleteOriginHelper : public AsyncHelper { |
- public: |
- DeleteOriginHelper( |
- AppCacheServiceImpl* service, const GURL& origin, |
- const net::CompletionCallback& callback) |
- : AsyncHelper(service, callback), origin_(origin), |
- num_caches_to_delete_(0), successes_(0), failures_(0) { |
- } |
- |
- virtual void Start() OVERRIDE { |
- // We start by listing all caches, continues in OnAllInfo(). |
- service_->storage()->GetAllInfo(this); |
- } |
- |
- private: |
- // AppCacheStorage::Delegate implementation. |
- virtual void OnAllInfo(AppCacheInfoCollection* collection) OVERRIDE; |
- virtual void OnGroupLoaded( |
- appcache::AppCacheGroup* group, const GURL& manifest_url) OVERRIDE; |
- virtual void OnGroupMadeObsolete(appcache::AppCacheGroup* group, |
- bool success, |
- int response_code) OVERRIDE; |
- |
- void CacheCompleted(bool success); |
- |
- GURL origin_; |
- int num_caches_to_delete_; |
- int successes_; |
- int failures_; |
- |
- DISALLOW_COPY_AND_ASSIGN(DeleteOriginHelper); |
-}; |
- |
-void AppCacheServiceImpl::DeleteOriginHelper::OnAllInfo( |
- AppCacheInfoCollection* collection) { |
- if (!collection) { |
- // Failed to get a listing. |
- CallCallback(net::ERR_FAILED); |
- delete this; |
- return; |
- } |
- |
- std::map<GURL, AppCacheInfoVector>::iterator found = |
- collection->infos_by_origin.find(origin_); |
- if (found == collection->infos_by_origin.end() || found->second.empty()) { |
- // No caches for this origin. |
- CallCallback(net::OK); |
- delete this; |
- return; |
- } |
- |
- // We have some caches to delete. |
- const AppCacheInfoVector& caches_to_delete = found->second; |
- successes_ = 0; |
- failures_ = 0; |
- num_caches_to_delete_ = static_cast<int>(caches_to_delete.size()); |
- for (AppCacheInfoVector::const_iterator iter = caches_to_delete.begin(); |
- iter != caches_to_delete.end(); ++iter) { |
- service_->storage()->LoadOrCreateGroup(iter->manifest_url, this); |
- } |
-} |
- |
-void AppCacheServiceImpl::DeleteOriginHelper::OnGroupLoaded( |
- appcache::AppCacheGroup* group, const GURL& manifest_url) { |
- if (group) { |
- group->set_being_deleted(true); |
- group->CancelUpdate(); |
- service_->storage()->MakeGroupObsolete(group, this, 0); |
- } else { |
- CacheCompleted(false); |
- } |
-} |
- |
-void AppCacheServiceImpl::DeleteOriginHelper::OnGroupMadeObsolete( |
- appcache::AppCacheGroup* group, |
- bool success, |
- int response_code) { |
- CacheCompleted(success); |
-} |
- |
-void AppCacheServiceImpl::DeleteOriginHelper::CacheCompleted(bool success) { |
- if (success) |
- ++successes_; |
- else |
- ++failures_; |
- if ((successes_ + failures_) < num_caches_to_delete_) |
- return; |
- |
- CallCallback(!failures_ ? net::OK : net::ERR_FAILED); |
- delete this; |
-} |
- |
- |
-// GetInfoHelper ------- |
- |
-class AppCacheServiceImpl::GetInfoHelper : AsyncHelper { |
- public: |
- GetInfoHelper( |
- AppCacheServiceImpl* service, AppCacheInfoCollection* collection, |
- const net::CompletionCallback& callback) |
- : AsyncHelper(service, callback), collection_(collection) { |
- } |
- |
- virtual void Start() OVERRIDE { |
- service_->storage()->GetAllInfo(this); |
- } |
- |
- private: |
- // AppCacheStorage::Delegate implementation. |
- virtual void OnAllInfo(AppCacheInfoCollection* collection) OVERRIDE; |
- |
- scoped_refptr<AppCacheInfoCollection> collection_; |
- |
- DISALLOW_COPY_AND_ASSIGN(GetInfoHelper); |
-}; |
- |
-void AppCacheServiceImpl::GetInfoHelper::OnAllInfo( |
- AppCacheInfoCollection* collection) { |
- if (collection) |
- collection->infos_by_origin.swap(collection_->infos_by_origin); |
- CallCallback(collection ? net::OK : net::ERR_FAILED); |
- delete this; |
-} |
- |
-// CheckResponseHelper ------- |
- |
-class AppCacheServiceImpl::CheckResponseHelper : AsyncHelper { |
- public: |
- CheckResponseHelper( |
- AppCacheServiceImpl* service, const GURL& manifest_url, int64 cache_id, |
- int64 response_id) |
- : AsyncHelper(service, net::CompletionCallback()), |
- manifest_url_(manifest_url), |
- cache_id_(cache_id), |
- response_id_(response_id), |
- kIOBufferSize(32 * 1024), |
- expected_total_size_(0), |
- amount_headers_read_(0), |
- amount_data_read_(0) { |
- } |
- |
- virtual void Start() OVERRIDE { |
- service_->storage()->LoadOrCreateGroup(manifest_url_, this); |
- } |
- |
- virtual void Cancel() OVERRIDE { |
- AppCacheHistograms::CountCheckResponseResult( |
- AppCacheHistograms::CHECK_CANCELED); |
- response_reader_.reset(); |
- AsyncHelper::Cancel(); |
- } |
- |
- private: |
- virtual void OnGroupLoaded(AppCacheGroup* group, |
- const GURL& manifest_url) OVERRIDE; |
- void OnReadInfoComplete(int result); |
- void OnReadDataComplete(int result); |
- |
- // Inputs describing what to check. |
- GURL manifest_url_; |
- int64 cache_id_; |
- int64 response_id_; |
- |
- // Internals used to perform the checks. |
- const int kIOBufferSize; |
- scoped_refptr<AppCache> cache_; |
- scoped_ptr<AppCacheResponseReader> response_reader_; |
- scoped_refptr<HttpResponseInfoIOBuffer> info_buffer_; |
- scoped_refptr<net::IOBuffer> data_buffer_; |
- int64 expected_total_size_; |
- int amount_headers_read_; |
- int amount_data_read_; |
- DISALLOW_COPY_AND_ASSIGN(CheckResponseHelper); |
-}; |
- |
-void AppCacheServiceImpl::CheckResponseHelper::OnGroupLoaded( |
- AppCacheGroup* group, const GURL& manifest_url) { |
- DCHECK_EQ(manifest_url_, manifest_url); |
- if (!group || !group->newest_complete_cache() || group->is_being_deleted() || |
- group->is_obsolete()) { |
- AppCacheHistograms::CountCheckResponseResult( |
- AppCacheHistograms::MANIFEST_OUT_OF_DATE); |
- delete this; |
- return; |
- } |
- |
- cache_ = group->newest_complete_cache(); |
- const AppCacheEntry* entry = cache_->GetEntryWithResponseId(response_id_); |
- if (!entry) { |
- if (cache_->cache_id() == cache_id_) { |
- AppCacheHistograms::CountCheckResponseResult( |
- AppCacheHistograms::ENTRY_NOT_FOUND); |
- service_->DeleteAppCacheGroup(manifest_url_, net::CompletionCallback()); |
- } else { |
- AppCacheHistograms::CountCheckResponseResult( |
- AppCacheHistograms::RESPONSE_OUT_OF_DATE); |
- } |
- delete this; |
- return; |
- } |
- |
- // Verify that we can read the response info and data. |
- expected_total_size_ = entry->response_size(); |
- response_reader_.reset(service_->storage()->CreateResponseReader( |
- manifest_url_, group->group_id(), response_id_)); |
- info_buffer_ = new HttpResponseInfoIOBuffer(); |
- response_reader_->ReadInfo( |
- info_buffer_.get(), |
- base::Bind(&CheckResponseHelper::OnReadInfoComplete, |
- base::Unretained(this))); |
-} |
- |
-void AppCacheServiceImpl::CheckResponseHelper::OnReadInfoComplete(int result) { |
- if (result < 0) { |
- AppCacheHistograms::CountCheckResponseResult( |
- AppCacheHistograms::READ_HEADERS_ERROR); |
- service_->DeleteAppCacheGroup(manifest_url_, net::CompletionCallback()); |
- delete this; |
- return; |
- } |
- amount_headers_read_ = result; |
- |
- // Start reading the data. |
- data_buffer_ = new net::IOBuffer(kIOBufferSize); |
- response_reader_->ReadData( |
- data_buffer_.get(), |
- kIOBufferSize, |
- base::Bind(&CheckResponseHelper::OnReadDataComplete, |
- base::Unretained(this))); |
-} |
- |
-void AppCacheServiceImpl::CheckResponseHelper::OnReadDataComplete(int result) { |
- if (result > 0) { |
- // Keep reading until we've read thru everything or failed to read. |
- amount_data_read_ += result; |
- response_reader_->ReadData( |
- data_buffer_.get(), |
- kIOBufferSize, |
- base::Bind(&CheckResponseHelper::OnReadDataComplete, |
- base::Unretained(this))); |
- return; |
- } |
- |
- AppCacheHistograms::CheckResponseResultType check_result; |
- if (result < 0) |
- check_result = AppCacheHistograms::READ_DATA_ERROR; |
- else if (info_buffer_->response_data_size != amount_data_read_ || |
- expected_total_size_ != amount_data_read_ + amount_headers_read_) |
- check_result = AppCacheHistograms::UNEXPECTED_DATA_SIZE; |
- else |
- check_result = AppCacheHistograms::RESPONSE_OK; |
- AppCacheHistograms::CountCheckResponseResult(check_result); |
- |
- if (check_result != AppCacheHistograms::RESPONSE_OK) |
- service_->DeleteAppCacheGroup(manifest_url_, net::CompletionCallback()); |
- delete this; |
-} |
- |
-// AppCacheStorageReference ------ |
- |
-AppCacheStorageReference::AppCacheStorageReference( |
- scoped_ptr<AppCacheStorage> storage) |
- : storage_(storage.Pass()) {} |
-AppCacheStorageReference::~AppCacheStorageReference() {} |
- |
-// AppCacheServiceImpl ------- |
- |
-AppCacheServiceImpl::AppCacheServiceImpl(quota::QuotaManagerProxy* |
- quota_manager_proxy) |
- : appcache_policy_(NULL), quota_client_(NULL), handler_factory_(NULL), |
- quota_manager_proxy_(quota_manager_proxy), |
- request_context_(NULL), |
- force_keep_session_state_(false) { |
- if (quota_manager_proxy_.get()) { |
- quota_client_ = new AppCacheQuotaClient(this); |
- quota_manager_proxy_->RegisterClient(quota_client_); |
- } |
-} |
- |
-AppCacheServiceImpl::~AppCacheServiceImpl() { |
- DCHECK(backends_.empty()); |
- std::for_each(pending_helpers_.begin(), |
- pending_helpers_.end(), |
- std::mem_fun(&AsyncHelper::Cancel)); |
- STLDeleteElements(&pending_helpers_); |
- if (quota_client_) |
- quota_client_->NotifyAppCacheDestroyed(); |
- |
- // Destroy storage_ first; ~AppCacheStorageImpl accesses other data members |
- // (special_storage_policy_). |
- storage_.reset(); |
-} |
- |
-void AppCacheServiceImpl::Initialize(const base::FilePath& cache_directory, |
- base::MessageLoopProxy* db_thread, |
- base::MessageLoopProxy* cache_thread) { |
- DCHECK(!storage_.get()); |
- cache_directory_ = cache_directory; |
- db_thread_ = db_thread; |
- cache_thread_ = cache_thread; |
- AppCacheStorageImpl* storage = new AppCacheStorageImpl(this); |
- storage->Initialize(cache_directory, db_thread, cache_thread); |
- storage_.reset(storage); |
-} |
- |
-void AppCacheServiceImpl::ScheduleReinitialize() { |
- if (reinit_timer_.IsRunning()) |
- return; |
- |
- // Reinitialization only happens when corruption has been noticed. |
- // We don't want to thrash the disk but we also don't want to |
- // leave the appcache disabled for an indefinite period of time. Some |
- // users never shutdown the browser. |
- |
- const base::TimeDelta kZeroDelta; |
- const base::TimeDelta kOneHour(base::TimeDelta::FromHours(1)); |
- const base::TimeDelta k30Seconds(base::TimeDelta::FromSeconds(30)); |
- |
- // If the system managed to stay up for long enough, reset the |
- // delay so a new failure won't incur a long wait to get going again. |
- base::TimeDelta up_time = base::Time::Now() - last_reinit_time_; |
- if (next_reinit_delay_ != kZeroDelta && up_time > kOneHour) |
- next_reinit_delay_ = kZeroDelta; |
- |
- reinit_timer_.Start(FROM_HERE, next_reinit_delay_, |
- this, &AppCacheServiceImpl::Reinitialize); |
- |
- // Adjust the delay for next time. |
- base::TimeDelta increment = std::max(k30Seconds, next_reinit_delay_); |
- next_reinit_delay_ = std::min(next_reinit_delay_ + increment, kOneHour); |
-} |
- |
-void AppCacheServiceImpl::Reinitialize() { |
- AppCacheHistograms::CountReinitAttempt(!last_reinit_time_.is_null()); |
- last_reinit_time_ = base::Time::Now(); |
- |
- // Inform observers of about this and give them a chance to |
- // defer deletion of the old storage object. |
- scoped_refptr<AppCacheStorageReference> |
- old_storage_ref(new AppCacheStorageReference(storage_.Pass())); |
- FOR_EACH_OBSERVER(Observer, observers_, |
- OnServiceReinitialized(old_storage_ref.get())); |
- |
- Initialize(cache_directory_, db_thread_, cache_thread_); |
-} |
- |
-void AppCacheServiceImpl::CanHandleMainResourceOffline( |
- const GURL& url, |
- const GURL& first_party, |
- const net::CompletionCallback& callback) { |
- CanHandleOfflineHelper* helper = |
- new CanHandleOfflineHelper(this, url, first_party, callback); |
- helper->Start(); |
-} |
- |
-void AppCacheServiceImpl::GetAllAppCacheInfo( |
- AppCacheInfoCollection* collection, |
- const net::CompletionCallback& callback) { |
- DCHECK(collection); |
- GetInfoHelper* helper = new GetInfoHelper(this, collection, callback); |
- helper->Start(); |
-} |
- |
-void AppCacheServiceImpl::DeleteAppCacheGroup( |
- const GURL& manifest_url, |
- const net::CompletionCallback& callback) { |
- DeleteHelper* helper = new DeleteHelper(this, manifest_url, callback); |
- helper->Start(); |
-} |
- |
-void AppCacheServiceImpl::DeleteAppCachesForOrigin( |
- const GURL& origin, const net::CompletionCallback& callback) { |
- DeleteOriginHelper* helper = new DeleteOriginHelper(this, origin, callback); |
- helper->Start(); |
-} |
- |
-void AppCacheServiceImpl::CheckAppCacheResponse(const GURL& manifest_url, |
- int64 cache_id, |
- int64 response_id) { |
- CheckResponseHelper* helper = new CheckResponseHelper( |
- this, manifest_url, cache_id, response_id); |
- helper->Start(); |
-} |
- |
-void AppCacheServiceImpl::set_special_storage_policy( |
- quota::SpecialStoragePolicy* policy) { |
- special_storage_policy_ = policy; |
-} |
- |
-void AppCacheServiceImpl::RegisterBackend( |
- AppCacheBackendImpl* backend_impl) { |
- DCHECK(backends_.find(backend_impl->process_id()) == backends_.end()); |
- backends_.insert( |
- BackendMap::value_type(backend_impl->process_id(), backend_impl)); |
-} |
- |
-void AppCacheServiceImpl::UnregisterBackend( |
- AppCacheBackendImpl* backend_impl) { |
- backends_.erase(backend_impl->process_id()); |
-} |
- |
-} // namespace appcache |