summaryrefslogtreecommitdiffstats
path: root/webkit/appcache
diff options
context:
space:
mode:
authormichaeln@chromium.org <michaeln@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-17 22:20:36 +0000
committermichaeln@chromium.org <michaeln@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-17 22:20:36 +0000
commitea776d0208899b770ea386b994216ef476197a46 (patch)
treecb614ced5bd6e764e01f244813d07b0a48870a0a /webkit/appcache
parenta3d3a7cf3b81cc8d00490bb7bfd92b57f0146d9c (diff)
downloadchromium_src-ea776d0208899b770ea386b994216ef476197a46.zip
chromium_src-ea776d0208899b770ea386b994216ef476197a46.tar.gz
chromium_src-ea776d0208899b770ea386b994216ef476197a46.tar.bz2
Introduce an AppCachePolicy interface that allows the containing browser to determine appcache permissions. The policy can allow or deny loading existing manifests or the creation of new manifests. The policy check for creating new manifests can be async to allow for a user prompt.
BUG=none TEST=new unit tests added Review URL: http://codereview.chromium.org/565042 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@39280 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/appcache')
-rw-r--r--webkit/appcache/appcache_policy.h38
-rw-r--r--webkit/appcache/appcache_service.cc2
-rw-r--r--webkit/appcache/appcache_service.h11
-rw-r--r--webkit/appcache/appcache_storage_impl.cc35
-rw-r--r--webkit/appcache/appcache_storage_impl.h5
-rw-r--r--webkit/appcache/appcache_storage_impl_unittest.cc72
-rw-r--r--webkit/appcache/appcache_update_job.cc51
-rw-r--r--webkit/appcache/appcache_update_job.h9
-rw-r--r--webkit/appcache/appcache_update_job_unittest.cc105
9 files changed, 307 insertions, 21 deletions
diff --git a/webkit/appcache/appcache_policy.h b/webkit/appcache/appcache_policy.h
new file mode 100644
index 0000000..7d3e844
--- /dev/null
+++ b/webkit/appcache/appcache_policy.h
@@ -0,0 +1,38 @@
+// Copyright (c) 2010 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.
+
+#ifndef WEBKIT_APPCACHE_APPCACHE_POLICY_H_
+#define WEBKIT_APPCACHE_APPCACHE_POLICY_H_
+
+#include "net/base/completion_callback.h"
+
+class GURL;
+
+namespace appcache {
+
+class AppCachePolicy {
+ public:
+ AppCachePolicy() {}
+
+ // Called prior to loading a main resource from the appache.
+ // Returns true if allowed. This is expected to return immediately
+ // without any user prompt.
+ virtual bool CanLoadAppCache(const GURL& manifest_url) = 0;
+
+ // Called prior to creating a new appcache.
+ // Returns net::OK if allowed, net::ERR_ACCESS_DENIED if not allowed.
+ // May also return net::ERR_IO_PENDING to indicate
+ // that the completion callback will be notified (asynchronously and on
+ // the current thread) of the final result. Note: The completion callback
+ // must remain valid until notified.
+ virtual int CanCreateAppCache(const GURL& manifest_url,
+ net::CompletionCallback* callback) = 0;
+
+ protected:
+ ~AppCachePolicy() {}
+};
+
+} // namespace appcache
+
+#endif // WEBKIT_APPCACHE_APPCACHE_POLICY_H_
diff --git a/webkit/appcache/appcache_service.cc b/webkit/appcache/appcache_service.cc
index f0c8784..65cc457 100644
--- a/webkit/appcache/appcache_service.cc
+++ b/webkit/appcache/appcache_service.cc
@@ -11,7 +11,7 @@
namespace appcache {
AppCacheService::AppCacheService()
- : request_context_(NULL) {
+ : appcache_policy_(NULL), request_context_(NULL) {
}
AppCacheService::~AppCacheService() {
diff --git a/webkit/appcache/appcache_service.h b/webkit/appcache/appcache_service.h
index 986e620..70a0953 100644
--- a/webkit/appcache/appcache_service.h
+++ b/webkit/appcache/appcache_service.h
@@ -15,6 +15,7 @@ class URLRequestContext;
namespace appcache {
class AppCacheBackendImpl;
+class AppCachePolicy;
// Class that manages the application cache service. Sends notifications
// to many frontends. One instance per user-profile. Each instance has
@@ -40,6 +41,14 @@ class AppCacheService {
request_context_ = context;
}
+ // The appcache policy, may be null, in which case access is always allowed.
+ // The service does NOT assume ownership of the policy, it is the callers
+ // responsibility to ensure that the pointer remains valid while set.
+ AppCachePolicy* appcache_policy() const { return appcache_policy_; }
+ void set_appcache_policy(AppCachePolicy* policy) {
+ appcache_policy_ = policy;
+ }
+
// Track which processes are using this appcache service.
void RegisterBackend(AppCacheBackendImpl* backend_impl);
void UnregisterBackend(AppCacheBackendImpl* backend_impl);
@@ -51,6 +60,8 @@ class AppCacheService {
AppCacheStorage* storage() const { return storage_.get(); }
protected:
+ AppCachePolicy* appcache_policy_;
+
// Deals with persistence.
scoped_ptr<AppCacheStorage> storage_;
diff --git a/webkit/appcache/appcache_storage_impl.cc b/webkit/appcache/appcache_storage_impl.cc
index ed893c1..0d908aa 100644
--- a/webkit/appcache/appcache_storage_impl.cc
+++ b/webkit/appcache/appcache_storage_impl.cc
@@ -12,11 +12,14 @@
#include "base/stl_util-inl.h"
#include "base/string_util.h"
#include "net/base/cache_type.h"
+#include "net/base/net_errors.h"
#include "webkit/appcache/appcache.h"
#include "webkit/appcache/appcache_database.h"
#include "webkit/appcache/appcache_entry.h"
#include "webkit/appcache/appcache_group.h"
+#include "webkit/appcache/appcache_policy.h"
#include "webkit/appcache/appcache_response.h"
+#include "webkit/appcache/appcache_service.h"
#include "webkit/appcache/appcache_thread.h"
namespace appcache {
@@ -562,9 +565,8 @@ void AppCacheStorageImpl::FindMainResponseTask::Run() {
}
void AppCacheStorageImpl::FindMainResponseTask::RunCompleted() {
- FOR_EACH_DELEGATE(delegates_,
- OnMainResponseFound(url_, entry_, fallback_entry_,
- cache_id_, manifest_url_));
+ storage_->CheckPolicyAndCallOnMainResponseFound(
+ &delegates_, url_, entry_, fallback_entry_, cache_id_, manifest_url_);
}
// MarkEntryAsForeignTask -------
@@ -902,13 +904,36 @@ void AppCacheStorageImpl::DeliverShortCircuitedFindMainResponse(
scoped_refptr<AppCacheGroup> group, scoped_refptr<AppCache> cache,
scoped_refptr<DelegateReference> delegate_ref) {
if (delegate_ref->delegate) {
- delegate_ref->delegate->OnMainResponseFound(
- url, found_entry, AppCacheEntry(),
+ DelegateReferenceVector delegates(1, delegate_ref);
+ CheckPolicyAndCallOnMainResponseFound(
+ &delegates, url, found_entry, AppCacheEntry(),
cache.get() ? cache->cache_id() : kNoCacheId,
group.get() ? group->manifest_url() : GURL());
}
}
+void AppCacheStorageImpl::CheckPolicyAndCallOnMainResponseFound(
+ DelegateReferenceVector* delegates, const GURL& url,
+ const AppCacheEntry& entry, const AppCacheEntry& fallback_entry,
+ int64 cache_id, const GURL& manifest_url) {
+ if (!manifest_url.is_empty()) {
+ // Check the policy prior to returning a main resource from the appcache.
+ AppCachePolicy* policy = service()->appcache_policy();
+ if (policy && !policy->CanLoadAppCache(manifest_url)) {
+ FOR_EACH_DELEGATE(
+ (*delegates),
+ OnMainResponseFound(url, AppCacheEntry(), AppCacheEntry(),
+ kNoCacheId, GURL()));
+ return;
+ }
+ }
+
+ FOR_EACH_DELEGATE(
+ (*delegates),
+ OnMainResponseFound(url, entry, fallback_entry,
+ cache_id, manifest_url));
+}
+
void AppCacheStorageImpl::FindResponseForSubRequest(
AppCache* cache, const GURL& url,
AppCacheEntry* found_entry, AppCacheEntry* found_fallback_entry,
diff --git a/webkit/appcache/appcache_storage_impl.h b/webkit/appcache/appcache_storage_impl.h
index 96fc876..93391e9 100644
--- a/webkit/appcache/appcache_storage_impl.h
+++ b/webkit/appcache/appcache_storage_impl.h
@@ -97,6 +97,11 @@ class AppCacheStorageImpl : public AppCacheStorage {
scoped_refptr<AppCacheGroup> group, scoped_refptr<AppCache> newest_cache,
scoped_refptr<DelegateReference> delegate_ref);
+ void CheckPolicyAndCallOnMainResponseFound(
+ DelegateReferenceVector* delegates, const GURL& url,
+ const AppCacheEntry& entry, const AppCacheEntry& fallback_entry,
+ int64 cache_id, const GURL& manifest_url);
+
disk_cache::Backend* disk_cache();
// The directory in which we place files in the file system.
diff --git a/webkit/appcache/appcache_storage_impl_unittest.cc b/webkit/appcache/appcache_storage_impl_unittest.cc
index 9e207f8..ad6a8310 100644
--- a/webkit/appcache/appcache_storage_impl_unittest.cc
+++ b/webkit/appcache/appcache_storage_impl_unittest.cc
@@ -7,11 +7,13 @@
#include "base/message_loop.h"
#include "base/thread.h"
#include "base/waitable_event.h"
+#include "net/base/net_errors.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webkit/appcache/appcache.h"
#include "webkit/appcache/appcache_database.h"
#include "webkit/appcache/appcache_entry.h"
#include "webkit/appcache/appcache_group.h"
+#include "webkit/appcache/appcache_policy.h"
#include "webkit/appcache/appcache_service.h"
#include "webkit/appcache/appcache_storage_impl.h"
#include "webkit/tools/test_shell/simple_appcache_system.h"
@@ -130,6 +132,34 @@ class AppCacheStorageImplTest : public testing::Test {
AppCacheStorageImplTest* test_;
};
+ class MockAppCachePolicy : public AppCachePolicy {
+ public:
+ explicit MockAppCachePolicy(AppCacheStorageImplTest* test)
+ : can_load_return_value_(true), can_create_return_value_(0),
+ callback_(NULL), test_(test) {
+ }
+
+ virtual bool CanLoadAppCache(const GURL& manifest_url) {
+ requested_manifest_url_ = manifest_url;
+ return can_load_return_value_;
+ }
+
+ virtual int CanCreateAppCache(const GURL& manifest_url,
+ net::CompletionCallback* callback) {
+ requested_manifest_url_ = manifest_url;
+ callback_ = callback;
+ if (can_create_return_value_ == net::ERR_IO_PENDING)
+ test_->ScheduleNextTask();
+ return can_create_return_value_;
+ }
+
+ bool can_load_return_value_;
+ int can_create_return_value_;
+ GURL requested_manifest_url_;
+ net::CompletionCallback* callback_;
+ AppCacheStorageImplTest* test_;
+ };
+
// Helper class run a test on our io_thread. The io_thread
// is spun up once and reused for all tests.
template <class Method>
@@ -182,7 +212,8 @@ class AppCacheStorageImplTest : public testing::Test {
// Test harness --------------------------------------------------
AppCacheStorageImplTest()
- : ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
+ : ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)),
+ ALLOW_THIS_IN_INITIALIZER_LIST(policy_(this)) {
}
template <class Method>
@@ -664,17 +695,25 @@ class AppCacheStorageImplTest : public testing::Test {
// BasicFindMainResponse -------------------------------
void BasicFindMainResponseInDatabase() {
- BasicFindMainResponse(true);
+ BasicFindMainResponse(true, false);
}
void BasicFindMainResponseInWorkingSet() {
- BasicFindMainResponse(false);
+ BasicFindMainResponse(false, false);
+ }
+
+ void BlockFindMainResponseWithPolicyCheck() {
+ BasicFindMainResponse(true, true);
}
- void BasicFindMainResponse(bool drop_from_working_set) {
+ void BasicFindMainResponse(bool drop_from_working_set,
+ bool block_with_policy_check) {
PushNextTask(method_factory_.NewRunnableMethod(
&AppCacheStorageImplTest::Verify_BasicFindMainResponse));
+ policy_.can_load_return_value_ = !block_with_policy_check;
+ service()->set_appcache_policy(&policy_);
+
// Setup some preconditions. Create a complete cache with an entry
// in storage.
MakeCacheAndGroup(kManifestUrl, 1, 1, true);
@@ -700,13 +739,18 @@ class AppCacheStorageImplTest : public testing::Test {
}
void Verify_BasicFindMainResponse() {
- EXPECT_EQ(kEntryUrl, delegate()->found_url_);
- EXPECT_EQ(kManifestUrl, delegate()->found_manifest_url_);
- EXPECT_EQ(1, delegate()->found_cache_id_);
- EXPECT_EQ(1, delegate()->found_entry_.response_id());
- EXPECT_TRUE(delegate()->found_entry_.IsExplicit());
- EXPECT_FALSE(delegate()->found_fallback_entry_.has_response_id());
- TestFinished();
+ EXPECT_EQ(kManifestUrl, policy_.requested_manifest_url_);
+ if (policy_.can_load_return_value_) {
+ EXPECT_EQ(kEntryUrl, delegate()->found_url_);
+ EXPECT_EQ(kManifestUrl, delegate()->found_manifest_url_);
+ EXPECT_EQ(1, delegate()->found_cache_id_);
+ EXPECT_EQ(1, delegate()->found_entry_.response_id());
+ EXPECT_TRUE(delegate()->found_entry_.IsExplicit());
+ EXPECT_FALSE(delegate()->found_fallback_entry_.has_response_id());
+ TestFinished();
+ } else {
+ Verify_FindNoMainResponse();
+ }
}
// BasicFindMainFallbackResponse -------------------------------
@@ -914,6 +958,7 @@ class AppCacheStorageImplTest : public testing::Test {
ScopedRunnableMethodFactory<AppCacheStorageImplTest> method_factory_;
scoped_ptr<base::WaitableEvent> test_finished_event_;
std::stack<Task*> task_stack_;
+ MockAppCachePolicy policy_;
scoped_ptr<AppCacheService> service_;
scoped_ptr<MockStorageDelegate> delegate_;
scoped_refptr<AppCacheGroup> group_;
@@ -981,6 +1026,11 @@ TEST_F(AppCacheStorageImplTest, BasicFindMainResponseInWorkingSet) {
&AppCacheStorageImplTest::BasicFindMainResponseInWorkingSet);
}
+TEST_F(AppCacheStorageImplTest, BlockFindMainResponseWithPolicyCheck) {
+ RunTestOnIOThread(
+ &AppCacheStorageImplTest::BlockFindMainResponseWithPolicyCheck);
+}
+
TEST_F(AppCacheStorageImplTest, BasicFindMainFallbackResponseInDatabase) {
RunTestOnIOThread(
&AppCacheStorageImplTest::BasicFindMainFallbackResponseInDatabase);
diff --git a/webkit/appcache/appcache_update_job.cc b/webkit/appcache/appcache_update_job.cc
index dcf77b0..a022ed3 100644
--- a/webkit/appcache/appcache_update_job.cc
+++ b/webkit/appcache/appcache_update_job.cc
@@ -9,7 +9,9 @@
#include "base/string_util.h"
#include "net/base/io_buffer.h"
#include "net/base/load_flags.h"
+#include "net/base/net_errors.h"
#include "webkit/appcache/appcache_group.h"
+#include "webkit/appcache/appcache_policy.h"
#include "webkit/appcache/appcache_response.h"
namespace appcache {
@@ -113,7 +115,10 @@ AppCacheUpdateJob::AppCacheUpdateJob(AppCacheService* service,
ALLOW_THIS_IN_INITIALIZER_LIST(manifest_data_write_callback_(
this, &AppCacheUpdateJob::OnManifestDataWriteComplete)),
ALLOW_THIS_IN_INITIALIZER_LIST(manifest_data_read_callback_(
- this, &AppCacheUpdateJob::OnManifestDataReadComplete)) {
+ this, &AppCacheUpdateJob::OnManifestDataReadComplete)),
+ ALLOW_THIS_IN_INITIALIZER_LIST(policy_callback_(
+ new net::CancelableCompletionCallback<AppCacheUpdateJob>(
+ this, &AppCacheUpdateJob::OnPolicyCheckComplete))) {
DCHECK(group_);
manifest_url_ = group_->manifest_url();
}
@@ -130,6 +135,8 @@ AppCacheUpdateJob::~AppCacheUpdateJob() {
if (group_)
group_->SetUpdateStatus(AppCacheGroup::IDLE);
+
+ policy_callback_->Cancel();
}
void AppCacheUpdateJob::StartUpdate(AppCacheHost* host,
@@ -191,7 +198,45 @@ void AppCacheUpdateJob::StartUpdate(AppCacheHost* host,
is_new_pending_master_entry);
}
- FetchManifest(true);
+ if (update_type_ == CACHE_ATTEMPT)
+ CheckPolicy();
+ else
+ FetchManifest(true);
+}
+
+void AppCacheUpdateJob::CheckPolicy() {
+ int rv = net::OK;
+ policy_callback_->AddRef(); // Balanced in OnPolicyCheckComplete.
+ AppCachePolicy* policy = service_->appcache_policy();
+ if (policy) {
+ rv = policy->CanCreateAppCache(manifest_url_, policy_callback_);
+ if (rv == net::ERR_IO_PENDING)
+ return;
+ }
+ OnPolicyCheckComplete(rv);
+}
+
+void AppCacheUpdateJob::OnPolicyCheckComplete(int rv) {
+ policy_callback_->Release(); // Balanced in CheckPolicy.
+ if (rv == net::OK) {
+ FetchManifest(true);
+ return;
+ }
+
+ MessageLoop::current()->PostTask(FROM_HERE,
+ method_factory_.NewRunnableMethod(
+ &AppCacheUpdateJob::HandleCacheFailure));
+}
+
+void AppCacheUpdateJob::HandleCacheFailure() {
+ // TODO(michaeln): For now this is only invoked from one point
+ // of failure. Overtime, attempt the migrate the various places
+ // where we can detect a failure condition to use this same
+ // method to enter the cache_failure state.
+ internal_state_ = CACHE_FAILURE;
+ CancelAllUrlFetches();
+ CancelAllMasterEntryFetches();
+ MaybeCompleteUpdate();
}
void AppCacheUpdateJob::FetchManifest(bool is_first_fetch) {
@@ -1227,6 +1272,8 @@ void AppCacheUpdateJob::Cancel() {
manifest_response_writer_.reset();
service_->storage()->CancelDelegateCallbacks(this);
+
+ policy_callback_->Cancel();
}
void AppCacheUpdateJob::ClearPendingMasterEntries() {
diff --git a/webkit/appcache/appcache_update_job.h b/webkit/appcache/appcache_update_job.h
index 2580ff8..c50f202 100644
--- a/webkit/appcache/appcache_update_job.h
+++ b/webkit/appcache/appcache_update_job.h
@@ -14,6 +14,7 @@
#include "base/ref_counted.h"
#include "base/task.h"
#include "googleurl/src/gurl.h"
+#include "net/base/completion_callback.h"
#include "net/url_request/url_request.h"
#include "testing/gtest/include/gtest/gtest_prod.h"
#include "webkit/appcache/appcache.h"
@@ -99,6 +100,11 @@ class AppCacheUpdateJob : public URLRequest::Delegate,
void OnCacheSelectionComplete(AppCacheHost* host) {} // N/A
void OnDestructionImminent(AppCacheHost* host);
+ void CheckPolicy();
+ void OnPolicyCheckComplete(int rv);
+
+ void HandleCacheFailure();
+
void FetchManifest(bool is_first_fetch);
// Add extra HTTP headers to the request based on the response info and
@@ -260,6 +266,9 @@ class AppCacheUpdateJob : public URLRequest::Delegate,
net::CompletionCallbackImpl<AppCacheUpdateJob> manifest_data_write_callback_;
net::CompletionCallbackImpl<AppCacheUpdateJob> manifest_data_read_callback_;
+ scoped_refptr<net::CancelableCompletionCallback<AppCacheUpdateJob> >
+ policy_callback_;
+
FRIEND_TEST(AppCacheGroupTest, QueueUpdate);
DISALLOW_COPY_AND_ASSIGN(AppCacheUpdateJob);
};
diff --git a/webkit/appcache/appcache_update_job_unittest.cc b/webkit/appcache/appcache_update_job_unittest.cc
index d41e486..42efbff 100644
--- a/webkit/appcache/appcache_update_job_unittest.cc
+++ b/webkit/appcache/appcache_update_job_unittest.cc
@@ -7,10 +7,12 @@
#include "base/stl_util-inl.h"
#include "base/thread.h"
#include "base/waitable_event.h"
+#include "net/base/net_errors.h"
#include "net/url_request/url_request_test_job.h"
#include "net/url_request/url_request_unittest.h"
#include "webkit/appcache/appcache_group.h"
#include "webkit/appcache/appcache_host.h"
+#include "webkit/appcache/appcache_policy.h"
#include "webkit/appcache/appcache_response.h"
#include "webkit/appcache/appcache_update_job.h"
#include "webkit/appcache/mock_appcache_service.h"
@@ -276,6 +278,43 @@ bool HttpHeadersRequestTestJob::already_checked_ = false;
class AppCacheUpdateJobTest : public testing::Test,
public AppCacheGroup::UpdateObserver {
public:
+ class MockAppCachePolicy : public AppCachePolicy {
+ public:
+ MockAppCachePolicy()
+ : ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)),
+ can_create_return_value_(net::OK), return_immediately_(true),
+ callback_(NULL) {
+ }
+
+ virtual bool CanLoadAppCache(const GURL& manifest_url) {
+ return true;
+ }
+
+ virtual int CanCreateAppCache(const GURL& manifest_url,
+ net::CompletionCallback* callback) {
+ requested_manifest_url_ = manifest_url;
+ callback_ = callback;
+ if (return_immediately_)
+ return can_create_return_value_;
+
+ MessageLoop::current()->PostTask(FROM_HERE,
+ method_factory_.NewRunnableMethod(
+ &MockAppCachePolicy::CompleteCanCreateAppCache));
+ return net::ERR_IO_PENDING;
+ }
+
+ void CompleteCanCreateAppCache() {
+ callback_->Run(can_create_return_value_);
+ }
+
+ ScopedRunnableMethodFactory<MockAppCachePolicy> method_factory_;
+ int can_create_return_value_;
+ bool return_immediately_;
+ GURL requested_manifest_url_;
+ net::CompletionCallback* callback_;
+ };
+
+
AppCacheUpdateJobTest()
: ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)),
do_checks_after_update_finished_(false),
@@ -355,6 +394,52 @@ class AppCacheUpdateJobTest : public testing::Test,
UpdateFinished();
}
+ void ImmediatelyBlockCacheAttemptTest() {
+ BlockCacheAttemptTest(true);
+ }
+
+ void DelayedBlockCacheAttemptTest() {
+ BlockCacheAttemptTest(false);
+ }
+
+ void BlockCacheAttemptTest(bool immediately) {
+ ASSERT_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type());
+
+ GURL manifest_url = GURL("http://failme");
+
+ // Setup to block the cache attempt immediately.
+ policy_.return_immediately_ = immediately;
+ policy_.can_create_return_value_ = net::ERR_ACCESS_DENIED;
+
+ MakeService();
+ group_ = new AppCacheGroup(service_.get(), manifest_url,
+ service_->storage()->NewGroupId());
+
+ AppCacheUpdateJob* update = new AppCacheUpdateJob(service_.get(), group_);
+ group_->update_job_ = update;
+
+ MockFrontend mock_frontend;
+ AppCacheHost host(1, &mock_frontend, service_.get());
+
+ update->StartUpdate(&host, GURL());
+ EXPECT_EQ(manifest_url, policy_.requested_manifest_url_);
+
+ // Verify state.
+ EXPECT_EQ(AppCacheUpdateJob::CACHE_ATTEMPT, update->update_type_);
+ EXPECT_EQ(AppCacheUpdateJob::FETCH_MANIFEST, update->internal_state_);
+ EXPECT_EQ(AppCacheGroup::CHECKING, group_->update_status());
+
+ // Verify notifications.
+ MockFrontend::RaisedEvents& events = mock_frontend.raised_events_;
+ size_t expected = 1;
+ EXPECT_EQ(expected, events.size());
+ EXPECT_EQ(1U, events[0].first.size());
+ EXPECT_EQ(host.host_id(), events[0].first[0]);
+ EXPECT_EQ(CHECKING_EVENT, events[0].second);
+
+ WaitForUpdateToFinish();
+ }
+
void StartUpgradeAttemptTest() {
ASSERT_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type());
@@ -727,9 +812,15 @@ class AppCacheUpdateJobTest : public testing::Test,
void BasicCacheAttemptSuccessTest() {
ASSERT_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type());
+ GURL manifest_url = http_server_->TestServerPage("files/manifest1");
+
+ // We also test the async AppCachePolicy return path in this test case.
+ policy_.return_immediately_ = false;
+ policy_.can_create_return_value_ = net::OK;
+
MakeService();
group_ = new AppCacheGroup(
- service_.get(), http_server_->TestServerPage("files/manifest1"),
+ service_.get(), manifest_url,
service_->storage()->NewGroupId());
AppCacheUpdateJob* update = new AppCacheUpdateJob(service_.get(), group_);
group_->update_job_ = update;
@@ -737,7 +828,7 @@ class AppCacheUpdateJobTest : public testing::Test,
MockFrontend* frontend = MakeMockFrontend();
AppCacheHost* host = MakeHost(1, frontend);
update->StartUpdate(host, GURL());
- EXPECT_TRUE(update->manifest_url_request_ != NULL);
+ EXPECT_EQ(manifest_url, policy_.requested_manifest_url_);;
// Set up checks for when update job finishes.
do_checks_after_update_finished_ = true;
@@ -2485,6 +2576,7 @@ class AppCacheUpdateJobTest : public testing::Test,
void MakeService() {
service_.reset(new MockAppCacheService());
service_->set_request_context(request_context_);
+ service_->set_appcache_policy(&policy_);
}
AppCache* MakeCacheForGroup(int64 cache_id, int64 manifest_response_id) {
@@ -2777,6 +2869,7 @@ class AppCacheUpdateJobTest : public testing::Test,
scoped_refptr<AppCacheGroup> group_;
scoped_refptr<AppCache> protect_newest_cache_;
scoped_ptr<base::WaitableEvent> event_;
+ MockAppCachePolicy policy_;
scoped_ptr<AppCacheResponseWriter> response_writer_;
scoped_ptr<net::CompletionCallbackImpl<AppCacheUpdateJobTest> >
@@ -2873,6 +2966,14 @@ TEST_F(AppCacheUpdateJobTest, StartCacheAttempt) {
RunTestOnIOThread(&AppCacheUpdateJobTest::StartCacheAttemptTest);
}
+TEST_F(AppCacheUpdateJobTest, ImmediatelyBlockCacheAttemptTest) {
+ RunTestOnIOThread(&AppCacheUpdateJobTest::ImmediatelyBlockCacheAttemptTest);
+}
+
+TEST_F(AppCacheUpdateJobTest, DelayedBlockCacheAttemptTest) {
+ RunTestOnIOThread(&AppCacheUpdateJobTest::DelayedBlockCacheAttemptTest);
+}
+
TEST_F(AppCacheUpdateJobTest, StartUpgradeAttempt) {
RunTestOnIOThread(&AppCacheUpdateJobTest::StartUpgradeAttemptTest);
}