From 0a60884751e554f218bc88a4948c9d0a0d736375 Mon Sep 17 00:00:00 2001 From: "marja@chromium.org" Date: Thu, 8 Sep 2011 10:55:19 +0000 Subject: Third-party appcache blocking. BUG=72586 TEST=AppCacheHostTest.SelectCacheAllowed, AppCacheHostTest.SelectCacheBlocked, AppCacheRequestHandlerTest.MainResource_Blocked Review URL: http://codereview.chromium.org/7720022 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@100131 0039d316-1c4b-4281-b951-d872f2087c98 --- chrome/browser/chrome_content_browser_client.cc | 4 +- chrome/browser/chrome_content_browser_client.h | 1 + .../renderer_host/offline_resource_handler.cc | 3 +- .../browser/appcache/chrome_appcache_service.cc | 11 ++- content/browser/appcache/chrome_appcache_service.h | 7 +- content/browser/content_browser_client.h | 1 + content/browser/mock_content_browser_client.cc | 3 +- content/browser/mock_content_browser_client.h | 1 + webkit/appcache/appcache_group.cc | 7 +- webkit/appcache/appcache_group.h | 3 - webkit/appcache/appcache_host.cc | 24 ++++- webkit/appcache/appcache_host.h | 8 +- webkit/appcache/appcache_host_unittest.cc | 89 +++++++++++++++++- webkit/appcache/appcache_policy.h | 20 ++-- webkit/appcache/appcache_request_handler.cc | 38 ++++---- webkit/appcache/appcache_request_handler.h | 5 +- .../appcache/appcache_request_handler_unittest.cc | 47 ++++++++++ webkit/appcache/appcache_service.cc | 24 +++-- webkit/appcache/appcache_service.h | 1 + webkit/appcache/appcache_storage.h | 3 +- webkit/appcache/appcache_storage_impl.cc | 22 +---- webkit/appcache/appcache_storage_impl.h | 2 +- webkit/appcache/appcache_storage_impl_unittest.cc | 91 +++--------------- webkit/appcache/appcache_update_job.cc | 44 +-------- webkit/appcache/appcache_update_job.h | 6 -- webkit/appcache/appcache_update_job_unittest.cc | 104 +-------------------- webkit/appcache/mock_appcache_policy.cc | 28 ++++++ webkit/appcache/mock_appcache_policy.h | 30 ++++++ webkit/appcache/mock_appcache_storage.cc | 8 +- webkit/appcache/mock_appcache_storage_unittest.cc | 3 +- webkit/appcache/view_appcache_internals_job.cc | 2 +- webkit/tools/test_shell/test_shell.gypi | 2 + 32 files changed, 316 insertions(+), 326 deletions(-) create mode 100644 webkit/appcache/mock_appcache_policy.cc create mode 100644 webkit/appcache/mock_appcache_policy.h diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 3e6639c9..d5b3579 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc @@ -385,13 +385,13 @@ SkBitmap* ChromeContentBrowserClient::GetDefaultFavicon() { bool ChromeContentBrowserClient::AllowAppCache( const GURL& manifest_url, + const GURL& first_party, const content::ResourceContext& context) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); ProfileIOData* io_data = reinterpret_cast(context.GetUserData(NULL)); - // FIXME(jochen): get the correct top-level origin. ContentSetting setting = io_data->GetHostContentSettingsMap()-> - GetCookieContentSetting(manifest_url, manifest_url, true); + GetCookieContentSetting(manifest_url, first_party, true); DCHECK(setting != CONTENT_SETTING_DEFAULT); return setting != CONTENT_SETTING_BLOCK; } diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index 239bb30..24948a4 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h @@ -38,6 +38,7 @@ class ChromeContentBrowserClient : public content::ContentBrowserClient { virtual std::string GetAcceptLangs(const TabContents* tab) OVERRIDE; virtual SkBitmap* GetDefaultFavicon() OVERRIDE; virtual bool AllowAppCache(const GURL& manifest_url, + const GURL& first_party, const content::ResourceContext& context) OVERRIDE; virtual bool AllowGetCookie(const GURL& url, const GURL& first_party, diff --git a/chrome/browser/renderer_host/offline_resource_handler.cc b/chrome/browser/renderer_host/offline_resource_handler.cc index 8c21549..1c1ed5d 100644 --- a/chrome/browser/renderer_host/offline_resource_handler.cc +++ b/chrome/browser/renderer_host/offline_resource_handler.cc @@ -112,7 +112,8 @@ bool OfflineResourceHandler::OnWillStart(int request_id, new net::CancelableCompletionCallback( this, &OfflineResourceHandler::OnCanHandleOfflineComplete); appcache_service_->CanHandleMainResourceOffline( - url, appcache_completion_callback_); + url, request_->first_party_for_cookies(), + appcache_completion_callback_); *defer = true; return true; diff --git a/content/browser/appcache/chrome_appcache_service.cc b/content/browser/appcache/chrome_appcache_service.cc index dc9b793..41936ef 100644 --- a/content/browser/appcache/chrome_appcache_service.cc +++ b/content/browser/appcache/chrome_appcache_service.cc @@ -49,18 +49,19 @@ void ChromeAppCacheService::InitializeOnIOThread( ChromeAppCacheService::~ChromeAppCacheService() { } -bool ChromeAppCacheService::CanLoadAppCache(const GURL& manifest_url) { +bool ChromeAppCacheService::CanLoadAppCache(const GURL& manifest_url, + const GURL& first_party) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); // We don't prompt for read access. return content::GetContentClient()->browser()->AllowAppCache( - manifest_url, *resource_context_); + manifest_url, first_party, *resource_context_); } -int ChromeAppCacheService::CanCreateAppCache( - const GURL& manifest_url, net::CompletionCallback* callback) { +bool ChromeAppCacheService::CanCreateAppCache( + const GURL& manifest_url, const GURL& first_party) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); return content::GetContentClient()->browser()->AllowAppCache( - manifest_url, *resource_context_) ? net::OK : net::ERR_ACCESS_DENIED; + manifest_url, first_party, *resource_context_); } void ChromeAppCacheService::Observe(int type, diff --git a/content/browser/appcache/chrome_appcache_service.h b/content/browser/appcache/chrome_appcache_service.h index 51829f9..3aff0cf 100644 --- a/content/browser/appcache/chrome_appcache_service.h +++ b/content/browser/appcache/chrome_appcache_service.h @@ -49,9 +49,10 @@ class ChromeAppCacheService virtual ~ChromeAppCacheService(); // AppCachePolicy overrides - virtual bool CanLoadAppCache(const GURL& manifest_url); - virtual int CanCreateAppCache(const GURL& manifest_url, - net::CompletionCallback* callback); + virtual bool CanLoadAppCache(const GURL& manifest_url, + const GURL& first_party); + virtual bool CanCreateAppCache(const GURL& manifest_url, + const GURL& first_party); // NotificationObserver override virtual void Observe(int type, diff --git a/content/browser/content_browser_client.h b/content/browser/content_browser_client.h index 32fa117..787273e 100644 --- a/content/browser/content_browser_client.h +++ b/content/browser/content_browser_client.h @@ -146,6 +146,7 @@ class ContentBrowserClient { // Allow the embedder to control if an AppCache can be used for the given url. // This is called on the IO thread. virtual bool AllowAppCache(const GURL& manifest_url, + const GURL& first_party, const content::ResourceContext& context) = 0; // Allow the embedder to control if the given cookie can be read. diff --git a/content/browser/mock_content_browser_client.cc b/content/browser/mock_content_browser_client.cc index 1ab31c9..51d770f 100644 --- a/content/browser/mock_content_browser_client.cc +++ b/content/browser/mock_content_browser_client.cc @@ -87,7 +87,8 @@ SkBitmap* MockContentBrowserClient::GetDefaultFavicon() { } bool MockContentBrowserClient::AllowAppCache( - const GURL& manifest_url, const content::ResourceContext& context) { + const GURL& manifest_url, const GURL& first_party, + const content::ResourceContext& context) { return true; } diff --git a/content/browser/mock_content_browser_client.h b/content/browser/mock_content_browser_client.h index 4320592..8af7faa 100644 --- a/content/browser/mock_content_browser_client.h +++ b/content/browser/mock_content_browser_client.h @@ -42,6 +42,7 @@ class MockContentBrowserClient : public ContentBrowserClient { virtual std::string GetAcceptLangs(const TabContents* tab) OVERRIDE; virtual SkBitmap* GetDefaultFavicon() OVERRIDE; virtual bool AllowAppCache(const GURL& manifest_url, + const GURL& first_party, const content::ResourceContext& context) OVERRIDE; virtual bool AllowGetCookie(const GURL& url, const GURL& first_party, diff --git a/webkit/appcache/appcache_group.cc b/webkit/appcache/appcache_group.cc index ddfb266..cdc6a70 100644 --- a/webkit/appcache/appcache_group.cc +++ b/webkit/appcache/appcache_group.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -264,9 +264,4 @@ void AppCacheGroup::SetUpdateStatus(UpdateStatus status) { } } -void AppCacheGroup::NotifyContentBlocked() { - FOR_EACH_OBSERVER( - UpdateObserver, observers_, OnContentBlocked(this)); -} - } // namespace appcache diff --git a/webkit/appcache/appcache_group.h b/webkit/appcache/appcache_group.h index 07dedb2..c762a53 100644 --- a/webkit/appcache/appcache_group.h +++ b/webkit/appcache/appcache_group.h @@ -30,9 +30,6 @@ class AppCacheGroup : public base::RefCounted { class UpdateObserver { public: - // Called if access to the appcache was blocked by a policy. - virtual void OnContentBlocked(AppCacheGroup* group) = 0; - // Called just after an appcache update has completed. virtual void OnUpdateComplete(AppCacheGroup* group) = 0; virtual ~UpdateObserver() {} diff --git a/webkit/appcache/appcache_host.cc b/webkit/appcache/appcache_host.cc index cb040ef..ddc9bd2 100644 --- a/webkit/appcache/appcache_host.cc +++ b/webkit/appcache/appcache_host.cc @@ -9,6 +9,7 @@ #include "base/stringprintf.h" #include "webkit/appcache/appcache.h" #include "webkit/appcache/appcache_backend_impl.h" +#include "webkit/appcache/appcache_policy.h" #include "webkit/appcache/appcache_request_handler.h" #include "webkit/quota/quota_manager.h" @@ -95,6 +96,19 @@ void AppCacheHost::SelectCache(const GURL& document_url, if (!manifest_url.is_empty() && (manifest_url.GetOrigin() == document_url.GetOrigin())) { + DCHECK(!first_party_url_.is_empty()); + AppCachePolicy* policy = service()->appcache_policy(); + if (policy && + !policy->CanCreateAppCache(manifest_url, first_party_url_)) { + FinishCacheSelection(NULL, NULL); + std::vector host_ids(1, host_id_); + frontend_->OnEventRaised(host_ids, CHECKING_EVENT); + frontend_->OnErrorEventRaised( + host_ids, "Cache creation was blocked by the content policy"); + frontend_->OnContentBlocked(host_id_, manifest_url); + return; + } + // Note: The client detects if the document was not loaded using HTTP GET // and invokes SelectCache without a manifest url, so that detection step // is also skipped here. See WebApplicationCacheHostImpl.cc @@ -267,8 +281,12 @@ AppCacheRequestHandler* AppCacheHost::CreateRequestHandler( return NULL; } - if (AppCacheRequestHandler::IsMainResourceType(resource_type)) + if (AppCacheRequestHandler::IsMainResourceType(resource_type)) { + // Store the first party origin so that it can be used later in SelectCache + // for checking whether the creation of the appcache is allowed. + first_party_url_ = request->first_party_for_cookies(); return new AppCacheRequestHandler(this, resource_type); + } if ((associated_cache() && associated_cache()->is_complete()) || is_selection_pending()) { @@ -421,10 +439,6 @@ void AppCacheHost::OnUpdateComplete(AppCacheGroup* group) { } } -void AppCacheHost::OnContentBlocked(AppCacheGroup* group) { - frontend_->OnContentBlocked(host_id_, group->manifest_url()); -} - void AppCacheHost::SetSwappableCache(AppCacheGroup* group) { if (!group) { swappable_cache_ = NULL; diff --git a/webkit/appcache/appcache_host.h b/webkit/appcache/appcache_host.h index 0f8ac47..b54524d 100644 --- a/webkit/appcache/appcache_host.h +++ b/webkit/appcache/appcache_host.h @@ -132,6 +132,8 @@ class AppCacheHost : public AppCacheStorage::Delegate, !pending_selected_manifest_url_.is_empty(); } + const GURL& first_party_url() const { return first_party_url_; } + private: Status GetStatus(); void LoadSelectedCache(int64 cache_id); @@ -150,7 +152,6 @@ class AppCacheHost : public AppCacheStorage::Delegate, void ObserveGroupBeingUpdated(AppCacheGroup* group); // AppCacheGroup::UpdateObserver methods. - virtual void OnContentBlocked(AppCacheGroup* group); virtual void OnUpdateComplete(AppCacheGroup* group); // Returns true if this host is for a dedicated worker context. @@ -245,6 +246,9 @@ class AppCacheHost : public AppCacheStorage::Delegate, // Used to inform the QuotaManager of what origins are currently in use. GURL origin_in_use_; + // First party url to be used in policy checks. + GURL first_party_url_; + friend class AppCacheRequestHandlerTest; friend class AppCacheUpdateJobTest; FRIEND_TEST_ALL_PREFIXES(AppCacheTest, CleanupUnusedCache); @@ -256,6 +260,8 @@ class AppCacheHost : public AppCacheStorage::Delegate, FRIEND_TEST_ALL_PREFIXES(AppCacheHostTest, FailedGroupLoad); FRIEND_TEST_ALL_PREFIXES(AppCacheHostTest, SetSwappableCache); FRIEND_TEST_ALL_PREFIXES(AppCacheHostTest, ForDedicatedWorker); + FRIEND_TEST_ALL_PREFIXES(AppCacheHostTest, SelectCacheAllowed); + FRIEND_TEST_ALL_PREFIXES(AppCacheHostTest, SelectCacheBlocked); FRIEND_TEST_ALL_PREFIXES(AppCacheGroupTest, QueueUpdate); DISALLOW_COPY_AND_ASSIGN(AppCacheHost); diff --git a/webkit/appcache/appcache_host_unittest.cc b/webkit/appcache/appcache_host_unittest.cc index 762ed9c..4621628 100644 --- a/webkit/appcache/appcache_host_unittest.cc +++ b/webkit/appcache/appcache_host_unittest.cc @@ -10,6 +10,7 @@ #include "webkit/appcache/appcache_backend_impl.h" #include "webkit/appcache/appcache_group.h" #include "webkit/appcache/appcache_host.h" +#include "webkit/appcache/mock_appcache_policy.h" #include "webkit/appcache/mock_appcache_service.h" #include "webkit/quota/quota_manager.h" @@ -32,7 +33,8 @@ class AppCacheHostTest : public testing::Test { : last_host_id_(-222), last_cache_id_(-222), last_status_(appcache::OBSOLETE), last_status_changed_(appcache::OBSOLETE), - last_event_id_(appcache::OBSOLETE_EVENT) { + last_event_id_(appcache::OBSOLETE_EVENT), + content_blocked_(false) { } virtual void OnCacheSelected( @@ -68,6 +70,7 @@ class AppCacheHostTest : public testing::Test { } virtual void OnContentBlocked(int host_id, const GURL& manifest_url) { + content_blocked_ = true; } int last_host_id_; @@ -75,6 +78,7 @@ class AppCacheHostTest : public testing::Test { appcache::Status last_status_; appcache::Status last_status_changed_; appcache::EventID last_event_id_; + bool content_blocked_; }; class MockQuotaManagerProxy : public quota::QuotaManagerProxy { @@ -432,5 +436,86 @@ TEST_F(AppCacheHostTest, ForDedicatedWorker) { EXPECT_EQ(NULL, worker_host->GetParentAppCacheHost()); } -} // namespace appcache +TEST_F(AppCacheHostTest, SelectCacheAllowed) { + scoped_refptr mock_quota_proxy( + new MockQuotaManagerProxy); + MockAppCachePolicy mock_appcache_policy; + mock_appcache_policy.can_create_return_value_ = true; + service_.set_quota_manager_proxy(mock_quota_proxy); + service_.set_appcache_policy(&mock_appcache_policy); + + // Reset our mock frontend + mock_frontend_.last_cache_id_ = -333; + mock_frontend_.last_host_id_ = -333; + mock_frontend_.last_status_ = OBSOLETE; + mock_frontend_.last_event_id_ = OBSOLETE_EVENT; + mock_frontend_.content_blocked_ = false; + + const GURL kDocAndOriginUrl(GURL("http://whatever/").GetOrigin()); + const GURL kManifestUrl(GURL("http://whatever/cache.manifest")); + { + AppCacheHost host(1, &mock_frontend_, &service_); + host.first_party_url_ = kDocAndOriginUrl; + host.SelectCache(kDocAndOriginUrl, kNoCacheId, kManifestUrl); + EXPECT_EQ(1, mock_quota_proxy->GetInUseCount(kDocAndOriginUrl)); + // MockAppCacheService::LoadOrCreateGroup is asynchronous, so we shouldn't + // have received an OnCacheSelected msg yet. + EXPECT_EQ(-333, mock_frontend_.last_host_id_); + EXPECT_EQ(-333, mock_frontend_.last_cache_id_); + EXPECT_EQ(OBSOLETE, mock_frontend_.last_status_); + // No error events either + EXPECT_EQ(OBSOLETE_EVENT, mock_frontend_.last_event_id_); + EXPECT_FALSE(mock_frontend_.content_blocked_); + + EXPECT_TRUE(host.is_selection_pending()); + } + EXPECT_EQ(0, mock_quota_proxy->GetInUseCount(kDocAndOriginUrl)); + service_.set_quota_manager_proxy(NULL); +} + +TEST_F(AppCacheHostTest, SelectCacheBlocked) { + scoped_refptr mock_quota_proxy( + new MockQuotaManagerProxy); + MockAppCachePolicy mock_appcache_policy; + mock_appcache_policy.can_create_return_value_ = false; + service_.set_quota_manager_proxy(mock_quota_proxy); + service_.set_appcache_policy(&mock_appcache_policy); + + // Reset our mock frontend + mock_frontend_.last_cache_id_ = -333; + mock_frontend_.last_host_id_ = -333; + mock_frontend_.last_status_ = OBSOLETE; + mock_frontend_.last_event_id_ = OBSOLETE_EVENT; + mock_frontend_.content_blocked_ = false; + + const GURL kDocAndOriginUrl(GURL("http://whatever/").GetOrigin()); + const GURL kManifestUrl(GURL("http://whatever/cache.manifest")); + { + AppCacheHost host(1, &mock_frontend_, &service_); + host.first_party_url_ = kDocAndOriginUrl; + host.SelectCache(kDocAndOriginUrl, kNoCacheId, kManifestUrl); + EXPECT_EQ(1, mock_quota_proxy->GetInUseCount(kDocAndOriginUrl)); + + // We should have received an OnCacheSelected msg + EXPECT_EQ(1, mock_frontend_.last_host_id_); + EXPECT_EQ(kNoCacheId, mock_frontend_.last_cache_id_); + EXPECT_EQ(UNCACHED, mock_frontend_.last_status_); + + // Also, an error event was raised + EXPECT_EQ(ERROR_EVENT, mock_frontend_.last_event_id_); + EXPECT_TRUE(mock_frontend_.content_blocked_); + + // Otherwise, see that it respond as if there is no cache selected. + EXPECT_EQ(1, host.host_id()); + EXPECT_EQ(&service_, host.service()); + EXPECT_EQ(&mock_frontend_, host.frontend()); + EXPECT_EQ(NULL, host.associated_cache()); + EXPECT_FALSE(host.is_selection_pending()); + EXPECT_TRUE(host.preferred_manifest_url().is_empty()); + } + EXPECT_EQ(0, mock_quota_proxy->GetInUseCount(kDocAndOriginUrl)); + service_.set_quota_manager_proxy(NULL); +} + +} // namespace appcache diff --git a/webkit/appcache/appcache_policy.h b/webkit/appcache/appcache_policy.h index 7d3e844..7ed8dc36 100644 --- a/webkit/appcache/appcache_policy.h +++ b/webkit/appcache/appcache_policy.h @@ -1,12 +1,10 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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 { @@ -18,16 +16,12 @@ class 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; + virtual bool CanLoadAppCache(const GURL& manifest_url, + const GURL& first_party) = 0; + + // Called prior to creating a new appcache. Returns true if allowed. + virtual bool CanCreateAppCache(const GURL& manifest_url, + const GURL& first_party) = 0; protected: ~AppCachePolicy() {} diff --git a/webkit/appcache/appcache_request_handler.cc b/webkit/appcache/appcache_request_handler.cc index 583df28..f4d74b1 100644 --- a/webkit/appcache/appcache_request_handler.cc +++ b/webkit/appcache/appcache_request_handler.cc @@ -7,6 +7,7 @@ #include "net/url_request/url_request.h" #include "net/url_request/url_request_job.h" #include "webkit/appcache/appcache.h" +#include "webkit/appcache/appcache_policy.h" #include "webkit/appcache/appcache_url_request_job.h" namespace appcache { @@ -217,8 +218,7 @@ void AppCacheRequestHandler::MaybeLoadMainResource(net::URLRequest* request) { void AppCacheRequestHandler::OnMainResponseFound( const GURL& url, const AppCacheEntry& entry, const GURL& fallback_url, const AppCacheEntry& fallback_entry, - int64 cache_id, const GURL& manifest_url, - bool was_blocked_by_policy) { + int64 cache_id, const GURL& manifest_url) { DCHECK(job_); DCHECK(host_); DCHECK(is_main_resource()); @@ -229,22 +229,28 @@ void AppCacheRequestHandler::OnMainResponseFound( if (!job_) return; - if (ResourceType::IsFrame(resource_type_)) { - if (was_blocked_by_policy) - host_->NotifyMainResourceBlocked(manifest_url); + AppCachePolicy* policy = host_->service()->appcache_policy(); + bool was_blocked_by_policy = !manifest_url.is_empty() && policy && + !policy->CanLoadAppCache(manifest_url, host_->first_party_url()); - if (cache_id != kNoCacheId) { - // AppCacheHost loads and holds a reference to the main resource cache - // for two reasons, firstly to preload the cache into the working set - // in advance of subresource loads happening, secondly to prevent the - // AppCache from falling out of the working set on frame navigations. - host_->LoadMainResourceCache(cache_id); - host_->set_preferred_manifest_url(manifest_url); - } - } else { - DCHECK(ResourceType::IsSharedWorker(resource_type_)); - if (was_blocked_by_policy) + if (was_blocked_by_policy) { + if (ResourceType::IsFrame(resource_type_)) { + host_->NotifyMainResourceBlocked(manifest_url); + } else { + DCHECK(ResourceType::IsSharedWorker(resource_type_)); host_->frontend()->OnContentBlocked(host_->host_id(), manifest_url); + } + DeliverNetworkResponse(); + return; + } + + if (ResourceType::IsFrame(resource_type_) && cache_id != kNoCacheId) { + // AppCacheHost loads and holds a reference to the main resource cache + // for two reasons, firstly to preload the cache into the working set + // in advance of subresource loads happening, secondly to prevent the + // AppCache from falling out of the working set on frame navigations. + host_->LoadMainResourceCache(cache_id); + host_->set_preferred_manifest_url(manifest_url); } // 6.11.1 Navigating across documents, steps 10 and 14. diff --git a/webkit/appcache/appcache_request_handler.h b/webkit/appcache/appcache_request_handler.h index b1cb331..c5abb5f 100644 --- a/webkit/appcache/appcache_request_handler.h +++ b/webkit/appcache/appcache_request_handler.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -76,8 +76,7 @@ class AppCacheRequestHandler : public net::URLRequest::UserData, virtual void OnMainResponseFound( const GURL& url, const AppCacheEntry& entry, const GURL& fallback_url, const AppCacheEntry& fallback_entry, - int64 cache_id, const GURL& mainfest_url, - bool was_blocked_by_policy); + int64 cache_id, const GURL& mainfest_url); // Sub-resource loading ------------------------------------- // Dedicated worker and all manner of sub-resources are handled here. diff --git a/webkit/appcache/appcache_request_handler_unittest.cc b/webkit/appcache/appcache_request_handler_unittest.cc index 4ea421a..60324fb0 100644 --- a/webkit/appcache/appcache_request_handler_unittest.cc +++ b/webkit/appcache/appcache_request_handler_unittest.cc @@ -18,6 +18,7 @@ #include "webkit/appcache/appcache_backend_impl.h" #include "webkit/appcache/appcache_request_handler.h" #include "webkit/appcache/appcache_url_request_job.h" +#include "webkit/appcache/mock_appcache_policy.h" #include "webkit/appcache/mock_appcache_service.h" namespace appcache { @@ -172,6 +173,8 @@ class AppCacheRequestHandlerTest : public testing::Test { orig_http_factory_ = net::URLRequest::Deprecated::RegisterProtocolFactory( "http", MockHttpJobFactory); mock_service_.reset(new MockAppCacheService); + mock_policy_.reset(new MockAppCachePolicy); + mock_service_->set_appcache_policy(mock_policy_.get()); mock_frontend_.reset(new MockFrontend); backend_impl_.reset(new AppCacheBackendImpl); backend_impl_->Initialize(mock_service_.get(), mock_frontend_.get(), @@ -193,6 +196,7 @@ class AppCacheRequestHandlerTest : public testing::Test { backend_impl_.reset(); mock_frontend_.reset(); mock_service_.reset(); + mock_policy_.reset(); host_ = NULL; } @@ -736,6 +740,44 @@ class AppCacheRequestHandlerTest : public testing::Test { TestFinished(); } + // MainResource_Blocked -------------------------------------------------- + + void MainResource_Blocked() { + PushNextTask(NewRunnableMethod( + this, &AppCacheRequestHandlerTest::Verify_MainResource_Blocked)); + + request_.reset(new MockURLRequest(GURL("http://blah/"))); + handler_.reset(host_->CreateRequestHandler(request_.get(), + ResourceType::MAIN_FRAME)); + EXPECT_TRUE(handler_.get()); + + mock_policy_->can_load_return_value_ = false; + mock_storage()->SimulateFindMainResource( + AppCacheEntry(AppCacheEntry::EXPLICIT, 1), + GURL(), AppCacheEntry(), + 1, GURL("http://blah/manifest/")); + + job_ = handler_->MaybeLoadResource(request_.get()); + EXPECT_TRUE(job_.get()); + EXPECT_TRUE(job_->is_waiting()); + + // We have to wait for completion of storage->FindResponseForMainRequest. + ScheduleNextTask(); + } + + void Verify_MainResource_Blocked() { + EXPECT_FALSE(job_->is_waiting()); + EXPECT_FALSE(job_->is_delivering_appcache_response()); + + EXPECT_EQ(0, handler_->found_cache_id_); + EXPECT_TRUE(handler_->found_manifest_url_.is_empty()); + EXPECT_TRUE(host_->preferred_manifest_url().is_empty()); + EXPECT_TRUE(host_->main_resource_blocked_); + EXPECT_TRUE(host_->blocked_manifest_url_ == GURL("http://blah/manifest/")); + + TestFinished(); + } + // Test case helpers -------------------------------------------------- AppCache* MakeNewCache() { @@ -760,6 +802,7 @@ class AppCacheRequestHandlerTest : public testing::Test { scoped_ptr mock_service_; scoped_ptr backend_impl_; scoped_ptr mock_frontend_; + scoped_ptr mock_policy_; AppCacheHost* host_; scoped_ptr request_; scoped_ptr handler_; @@ -844,6 +887,10 @@ TEST_F(AppCacheRequestHandlerTest, WorkerRequest) { RunTestOnIOThread(&AppCacheRequestHandlerTest::WorkerRequest); } +TEST_F(AppCacheRequestHandlerTest, MainResource_Blocked) { + RunTestOnIOThread(&AppCacheRequestHandlerTest::MainResource_Blocked); +} + } // namespace appcache // AppCacheRequestHandlerTest is expected to always live longer than the diff --git a/webkit/appcache/appcache_service.cc b/webkit/appcache/appcache_service.cc index eca61c5..73552c9 100644 --- a/webkit/appcache/appcache_service.cc +++ b/webkit/appcache/appcache_service.cc @@ -12,6 +12,7 @@ #include "webkit/appcache/appcache_backend_impl.h" #include "webkit/appcache/appcache_entry.h" #include "webkit/appcache/appcache_histograms.h" +#include "webkit/appcache/appcache_policy.h" #include "webkit/appcache/appcache_quota_client.h" #include "webkit/appcache/appcache_response.h" #include "webkit/appcache/appcache_storage_impl.h" @@ -77,11 +78,17 @@ class AppCacheService::CanHandleOfflineHelper : AsyncHelper { public: CanHandleOfflineHelper( AppCacheService* service, const GURL& url, - net::CompletionCallback* callback) - : AsyncHelper(service, callback), url_(url) { + const GURL& first_party, net::CompletionCallback* callback) + : AsyncHelper(service, callback), url_(url), first_party_(first_party) { } virtual void Start() { + 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); } @@ -90,20 +97,18 @@ class AppCacheService::CanHandleOfflineHelper : AsyncHelper { virtual void OnMainResponseFound( const GURL& url, const AppCacheEntry& entry, const GURL& fallback_url, const AppCacheEntry& fallback_entry, - int64 cache_id, const GURL& mainfest_url, - bool was_blocked_by_policy); + int64 cache_id, const GURL& mainfest_url); GURL url_; + GURL first_party_; DISALLOW_COPY_AND_ASSIGN(CanHandleOfflineHelper); }; void AppCacheService::CanHandleOfflineHelper::OnMainResponseFound( const GURL& url, const AppCacheEntry& entry, const GURL& fallback_url, const AppCacheEntry& fallback_entry, - int64 cache_id, const GURL& mainfest_url, - bool was_blocked_by_policy) { - bool can = !was_blocked_by_policy && - (entry.has_response_id() || fallback_entry.has_response_id()); + int64 cache_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; } @@ -438,9 +443,10 @@ void AppCacheService::Initialize(const FilePath& cache_directory, void AppCacheService::CanHandleMainResourceOffline( const GURL& url, + const GURL& first_party, net::CompletionCallback* callback) { CanHandleOfflineHelper* helper = - new CanHandleOfflineHelper(this, url, callback); + new CanHandleOfflineHelper(this, url, first_party, callback); helper->Start(); } diff --git a/webkit/appcache/appcache_service.h b/webkit/appcache/appcache_service.h index 27b507b..3858295 100644 --- a/webkit/appcache/appcache_service.h +++ b/webkit/appcache/appcache_service.h @@ -68,6 +68,7 @@ class AppCacheService { // Determines if a request for 'url' can be satisfied while offline. // This method always completes asynchronously. void CanHandleMainResourceOffline(const GURL& url, + const GURL& first_party, net::CompletionCallback* callback); // Populates 'collection' with info about all of the appcaches stored diff --git a/webkit/appcache/appcache_storage.h b/webkit/appcache/appcache_storage.h index 9ddb7c3..562bb16 100644 --- a/webkit/appcache/appcache_storage.h +++ b/webkit/appcache/appcache_storage.h @@ -65,8 +65,7 @@ class AppCacheStorage { virtual void OnMainResponseFound( const GURL& url, const AppCacheEntry& entry, const GURL& fallback_url, const AppCacheEntry& fallback_entry, - int64 cache_id, const GURL& mainfest_url, - bool was_blocked_by_policy) {} + int64 cache_id, const GURL& mainfest_url) {} }; explicit AppCacheStorage(AppCacheService* service); diff --git a/webkit/appcache/appcache_storage_impl.cc b/webkit/appcache/appcache_storage_impl.cc index 63c0554..fcba4e9 100644 --- a/webkit/appcache/appcache_storage_impl.cc +++ b/webkit/appcache/appcache_storage_impl.cc @@ -20,7 +20,6 @@ #include "webkit/appcache/appcache_entry.h" #include "webkit/appcache/appcache_group.h" #include "webkit/appcache/appcache_histograms.h" -#include "webkit/appcache/appcache_policy.h" #include "webkit/appcache/appcache_quota_client.h" #include "webkit/appcache/appcache_response.h" #include "webkit/appcache/appcache_service.h" @@ -950,7 +949,7 @@ FindMainResponseTask::FindFirstValidFallback( } void AppCacheStorageImpl::FindMainResponseTask::RunCompleted() { - storage_->CheckPolicyAndCallOnMainResponseFound( + storage_->CallOnMainResponseFound( &delegates_, url_, entry_, fallback_url_, fallback_entry_, cache_id_, manifest_url_); } @@ -1372,7 +1371,7 @@ void AppCacheStorageImpl::DeliverShortCircuitedFindMainResponse( scoped_refptr delegate_ref) { if (delegate_ref->delegate) { DelegateReferenceVector delegates(1, delegate_ref); - CheckPolicyAndCallOnMainResponseFound( + CallOnMainResponseFound( &delegates, url, found_entry, GURL(), AppCacheEntry(), cache.get() ? cache->cache_id() : kNoCacheId, @@ -1380,29 +1379,16 @@ void AppCacheStorageImpl::DeliverShortCircuitedFindMainResponse( } } -void AppCacheStorageImpl::CheckPolicyAndCallOnMainResponseFound( +void AppCacheStorageImpl::CallOnMainResponseFound( DelegateReferenceVector* delegates, const GURL& url, const AppCacheEntry& entry, const GURL& fallback_url, 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(), - GURL(), AppCacheEntry(), - kNoCacheId, manifest_url, true)); - return; - } - } - FOR_EACH_DELEGATE( (*delegates), OnMainResponseFound(url, entry, fallback_url, fallback_entry, - cache_id, manifest_url, false)); + cache_id, manifest_url)); } void AppCacheStorageImpl::FindResponseForSubRequest( diff --git a/webkit/appcache/appcache_storage_impl.h b/webkit/appcache/appcache_storage_impl.h index cd6bd87..0901dcd 100644 --- a/webkit/appcache/appcache_storage_impl.h +++ b/webkit/appcache/appcache_storage_impl.h @@ -112,7 +112,7 @@ class AppCacheStorageImpl : public AppCacheStorage { scoped_refptr newest_cache, scoped_refptr delegate_ref); - void CheckPolicyAndCallOnMainResponseFound( + void CallOnMainResponseFound( DelegateReferenceVector* delegates, const GURL& url, const AppCacheEntry& entry, const GURL& fallback_url, const AppCacheEntry& fallback_entry, diff --git a/webkit/appcache/appcache_storage_impl_unittest.cc b/webkit/appcache/appcache_storage_impl_unittest.cc index 0b914f7..1b2b5ff 100644 --- a/webkit/appcache/appcache_storage_impl_unittest.cc +++ b/webkit/appcache/appcache_storage_impl_unittest.cc @@ -13,7 +13,6 @@ #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/quota/quota_manager.h" @@ -88,8 +87,7 @@ class AppCacheStorageImplTest : public testing::Test { explicit MockStorageDelegate(AppCacheStorageImplTest* test) : loaded_cache_id_(0), stored_group_success_(false), would_exceed_quota_(false), obsoleted_success_(false), - found_cache_id_(kNoCacheId), found_blocked_by_policy_(false), - test_(test) { + found_cache_id_(kNoCacheId), test_(test) { } void OnCacheLoaded(AppCache* cache, int64 cache_id) { @@ -124,15 +122,13 @@ class AppCacheStorageImplTest : public testing::Test { void OnMainResponseFound(const GURL& url, const AppCacheEntry& entry, const GURL& fallback_url, const AppCacheEntry& fallback_entry, - int64 cache_id, const GURL& manifest_url, - bool was_blocked_by_policy) { + int64 cache_id, const GURL& manifest_url) { found_url_ = url; found_entry_ = entry; found_fallback_url_ = fallback_url; found_fallback_entry_ = fallback_entry; found_cache_id_ = cache_id; found_manifest_url_ = manifest_url; - found_blocked_by_policy_ = was_blocked_by_policy; test_->ScheduleNextTask(); } @@ -152,35 +148,6 @@ class AppCacheStorageImplTest : public testing::Test { AppCacheEntry found_fallback_entry_; int64 found_cache_id_; GURL found_manifest_url_; - bool found_blocked_by_policy_; - 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_; }; @@ -309,8 +276,7 @@ class AppCacheStorageImplTest : public testing::Test { // Test harness -------------------------------------------------- - AppCacheStorageImplTest() - : ALLOW_THIS_IN_INITIALIZER_LIST(policy_(this)) { + AppCacheStorageImplTest() { } template @@ -870,9 +836,7 @@ class AppCacheStorageImplTest : public testing::Test { void Verify_FindNoMainResponse() { EXPECT_EQ(kEntryUrl, delegate()->found_url_); - // If the request was blocked by a policy, the manifest url is still valid. - EXPECT_TRUE(delegate()->found_manifest_url_.is_empty() || - delegate()->found_blocked_by_policy_); + EXPECT_TRUE(delegate()->found_manifest_url_.is_empty()); EXPECT_EQ(kNoCacheId, delegate()->found_cache_id_); EXPECT_EQ(kNoResponseId, delegate()->found_entry_.response_id()); EXPECT_EQ(kNoResponseId, delegate()->found_fallback_entry_.response_id()); @@ -885,25 +849,17 @@ class AppCacheStorageImplTest : public testing::Test { // BasicFindMainResponse ------------------------------- void BasicFindMainResponseInDatabase() { - BasicFindMainResponse(true, false); + BasicFindMainResponse(true); } void BasicFindMainResponseInWorkingSet() { - BasicFindMainResponse(false, false); - } - - void BlockFindMainResponseWithPolicyCheck() { - BasicFindMainResponse(true, true); + BasicFindMainResponse(false); } - void BasicFindMainResponse(bool drop_from_working_set, - bool block_with_policy_check) { + void BasicFindMainResponse(bool drop_from_working_set) { PushNextTask(NewRunnableMethod( this, &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); @@ -929,19 +885,13 @@ class AppCacheStorageImplTest : public testing::Test { } void Verify_BasicFindMainResponse() { - 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_FALSE(delegate()->found_blocked_by_policy_); - 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(); - } + 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(); } // BasicFindMainFallbackResponse ------------------------------- @@ -1001,7 +951,6 @@ class AppCacheStorageImplTest : public testing::Test { void Verify_BasicFindMainFallbackResponse() { EXPECT_EQ(kFallbackTestUrl, delegate()->found_url_); EXPECT_EQ(kManifestUrl, delegate()->found_manifest_url_); - EXPECT_FALSE(delegate()->found_blocked_by_policy_); EXPECT_EQ(1, delegate()->found_cache_id_); EXPECT_FALSE(delegate()->found_entry_.has_response_id()); EXPECT_EQ(2, delegate()->found_fallback_entry_.response_id()); @@ -1076,7 +1025,6 @@ class AppCacheStorageImplTest : public testing::Test { void Verify_FindMainResponseWithMultipleHits() { EXPECT_EQ(kEntryUrl, delegate()->found_url_); EXPECT_EQ(kManifestUrl3, delegate()->found_manifest_url_); - EXPECT_FALSE(delegate()->found_blocked_by_policy_); EXPECT_EQ(3, delegate()->found_cache_id_); EXPECT_EQ(3, delegate()->found_entry_.response_id()); EXPECT_TRUE(delegate()->found_entry_.IsExplicit()); @@ -1093,7 +1041,6 @@ class AppCacheStorageImplTest : public testing::Test { void Verify_FindMainResponseWithMultipleHits2() { EXPECT_EQ(kEntryUrl, delegate()->found_url_); EXPECT_EQ(kManifestUrl, delegate()->found_manifest_url_); - EXPECT_FALSE(delegate()->found_blocked_by_policy_); EXPECT_EQ(1, delegate()->found_cache_id_); EXPECT_EQ(1, delegate()->found_entry_.response_id()); EXPECT_TRUE(delegate()->found_entry_.IsExplicit()); @@ -1110,7 +1057,6 @@ class AppCacheStorageImplTest : public testing::Test { void Verify_FindMainResponseWithMultipleHits3() { EXPECT_EQ(kEntryUrl, delegate()->found_url_); EXPECT_EQ(kManifestUrl2, delegate()->found_manifest_url_); - EXPECT_FALSE(delegate()->found_blocked_by_policy_); EXPECT_EQ(2, delegate()->found_cache_id_); EXPECT_EQ(2, delegate()->found_entry_.response_id()); EXPECT_TRUE(delegate()->found_entry_.IsExplicit()); @@ -1128,7 +1074,6 @@ class AppCacheStorageImplTest : public testing::Test { void Verify_FindMainResponseWithMultipleHits4() { EXPECT_EQ(kFallbackTestUrl, delegate()->found_url_); EXPECT_EQ(kManifestUrl3, delegate()->found_manifest_url_); - EXPECT_FALSE(delegate()->found_blocked_by_policy_); EXPECT_EQ(3, delegate()->found_cache_id_); EXPECT_FALSE(delegate()->found_entry_.has_response_id()); EXPECT_EQ(3 + kFallbackEntryIdOffset, @@ -1148,7 +1093,6 @@ class AppCacheStorageImplTest : public testing::Test { void Verify_FindMainResponseWithMultipleHits5() { EXPECT_EQ(kFallbackTestUrl, delegate()->found_url_); EXPECT_EQ(kManifestUrl2, delegate()->found_manifest_url_); - EXPECT_FALSE(delegate()->found_blocked_by_policy_); EXPECT_EQ(2, delegate()->found_cache_id_); EXPECT_FALSE(delegate()->found_entry_.has_response_id()); EXPECT_EQ(2 + kFallbackEntryIdOffset, @@ -1219,7 +1163,6 @@ class AppCacheStorageImplTest : public testing::Test { void Verify_ExclusionNotFound(GURL expected_url, int phase) { EXPECT_EQ(expected_url, delegate()->found_url_); EXPECT_TRUE(delegate()->found_manifest_url_.is_empty()); - EXPECT_FALSE(delegate()->found_blocked_by_policy_); EXPECT_EQ(kNoCacheId, delegate()->found_cache_id_); EXPECT_EQ(kNoResponseId, delegate()->found_entry_.response_id()); EXPECT_EQ(kNoResponseId, delegate()->found_fallback_entry_.response_id()); @@ -1309,7 +1252,6 @@ class AppCacheStorageImplTest : public testing::Test { scoped_ptr test_finished_event_; std::stack task_stack_; - MockAppCachePolicy policy_; scoped_ptr service_; scoped_ptr delegate_; scoped_refptr mock_quota_manager_proxy_; @@ -1382,11 +1324,6 @@ 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 edffe6d..0809336 100644 --- a/webkit/appcache/appcache_update_job.cc +++ b/webkit/appcache/appcache_update_job.cc @@ -14,7 +14,6 @@ #include "net/http/http_request_headers.h" #include "net/http/http_response_headers.h" #include "webkit/appcache/appcache_group.h" -#include "webkit/appcache/appcache_policy.h" namespace appcache { @@ -300,10 +299,7 @@ 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)), - ALLOW_THIS_IN_INITIALIZER_LIST(policy_callback_( - new net::CancelableCompletionCallback( - this, &AppCacheUpdateJob::OnPolicyCheckComplete))) { + this, &AppCacheUpdateJob::OnManifestDataReadComplete)) { DCHECK(group_); manifest_url_ = group_->manifest_url(); } @@ -320,8 +316,6 @@ AppCacheUpdateJob::~AppCacheUpdateJob() { if (group_) group_->SetUpdateStatus(AppCacheGroup::IDLE); - - policy_callback_->Cancel(); } void AppCacheUpdateJob::StartUpdate(AppCacheHost* host, @@ -383,39 +377,7 @@ void AppCacheUpdateJob::StartUpdate(AppCacheHost* host, is_new_pending_master_entry); } - 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; - } - - group_->NotifyContentBlocked(); - - const char* kErrorMessage = - "Cache creation was blocked by the content policy"; - MessageLoop::current()->PostTask(FROM_HERE, - method_factory_.NewRunnableMethod( - &AppCacheUpdateJob::HandleCacheFailure, - kErrorMessage)); + FetchManifest(true); } AppCacheResponseWriter* AppCacheUpdateJob::CreateResponseWriter() { @@ -1306,8 +1268,6 @@ 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 b85d73b..358ee3e 100644 --- a/webkit/appcache/appcache_update_job.h +++ b/webkit/appcache/appcache_update_job.h @@ -160,9 +160,6 @@ class AppCacheUpdateJob : public AppCacheStorage::Delegate, virtual void OnCacheSelectionComplete(AppCacheHost* host) {} // N/A virtual void OnDestructionImminent(AppCacheHost* host); - void CheckPolicy(); - void OnPolicyCheckComplete(int rv); - void HandleCacheFailure(const std::string& error_message); void FetchManifest(bool is_first_fetch); @@ -310,9 +307,6 @@ class AppCacheUpdateJob : public AppCacheStorage::Delegate, net::CompletionCallbackImpl manifest_data_write_callback_; net::CompletionCallbackImpl manifest_data_read_callback_; - scoped_refptr > - policy_callback_; - FRIEND_TEST_ALL_PREFIXES(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 d361ba5..c8a4a71 100644 --- a/webkit/appcache/appcache_update_job_unittest.cc +++ b/webkit/appcache/appcache_update_job_unittest.cc @@ -15,7 +15,6 @@ #include "net/url_request/url_request_test_util.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" @@ -551,40 +550,6 @@ class IOThread : public base::Thread { class AppCacheUpdateJobTest : public testing::Test, public AppCacheGroup::UpdateObserver { public: - class MockAppCachePolicy : public AppCachePolicy { - public: - MockAppCachePolicy() - : 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, NewRunnableMethod( - this, &MockAppCachePolicy::CompleteCanCreateAppCache)); - return net::ERR_IO_PENDING; - } - - void CompleteCanCreateAppCache() { - callback_->Run(can_create_return_value_); - } - - int can_create_return_value_; - bool return_immediately_; - GURL requested_manifest_url_; - net::CompletionCallback* callback_; - }; - - AppCacheUpdateJobTest() : do_checks_after_update_finished_(false), expect_group_obsolete_(false), @@ -644,52 +609,6 @@ 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()); @@ -1058,10 +977,6 @@ class AppCacheUpdateJobTest : public testing::Test, GURL manifest_url = MockHttpServer::GetMockUrl("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(), manifest_url, @@ -1072,7 +987,6 @@ class AppCacheUpdateJobTest : public testing::Test, MockFrontend* frontend = MakeMockFrontend(); AppCacheHost* host = MakeHost(1, frontend); update->StartUpdate(host, GURL()); - EXPECT_EQ(manifest_url, policy_.requested_manifest_url_);; // Set up checks for when update job finishes. do_checks_after_update_finished_ = true; @@ -1868,6 +1782,7 @@ class AppCacheUpdateJobTest : public testing::Test, MockFrontend* frontend = MakeMockFrontend(); AppCacheHost* host = MakeHost(1, frontend); + host->first_party_url_ = kManifestUrl; host->SelectCache(MockHttpServer::GetMockUrl("files/empty1"), kNoCacheId, kManifestUrl); @@ -2843,7 +2758,6 @@ class AppCacheUpdateJobTest : public testing::Test, MockFrontend* frontend = MakeMockFrontend(); AppCacheHost* host = MakeHost(1, frontend); update->StartUpdate(host, GURL()); - EXPECT_EQ(manifest_url, policy_.requested_manifest_url_); // Set up checks for when update job finishes. do_checks_after_update_finished_ = true; @@ -2872,7 +2786,6 @@ class AppCacheUpdateJobTest : public testing::Test, MockFrontend* frontend = MakeMockFrontend(); AppCacheHost* host = MakeHost(1, frontend); update->StartUpdate(host, GURL()); - EXPECT_EQ(manifest_url, policy_.requested_manifest_url_); // Set up checks for when update job finishes. do_checks_after_update_finished_ = true; @@ -2898,9 +2811,6 @@ class AppCacheUpdateJobTest : public testing::Test, UpdateFinished(); } - void OnContentBlocked(AppCacheGroup* group) { - } - void UpdateFinished() { // We unwind the stack prior to finishing up to let stack-based objects // get deleted. @@ -2928,7 +2838,6 @@ class AppCacheUpdateJobTest : public testing::Test, void MakeService() { service_.reset(new MockAppCacheService()); service_->set_request_context(io_thread_->request_context()); - service_->set_appcache_policy(&policy_); } AppCache* MakeCacheForGroup(int64 cache_id, int64 manifest_response_id) { @@ -3241,7 +3150,6 @@ class AppCacheUpdateJobTest : public testing::Test, scoped_refptr group_; scoped_refptr protect_newest_cache_; scoped_ptr event_; - MockAppCachePolicy policy_; scoped_ptr response_writer_; scoped_ptr > @@ -3335,14 +3243,6 @@ 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); } @@ -3550,5 +3450,3 @@ TEST_F(AppCacheUpdateJobTest, CrossOriginHttpsDenied) { // AppCacheUpdateJobTest is expected to always live longer than the // runnable methods. This lets us call NewRunnableMethod on its instances. DISABLE_RUNNABLE_METHOD_REFCOUNT(appcache::AppCacheUpdateJobTest); -DISABLE_RUNNABLE_METHOD_REFCOUNT( - appcache::AppCacheUpdateJobTest::MockAppCachePolicy); diff --git a/webkit/appcache/mock_appcache_policy.cc b/webkit/appcache/mock_appcache_policy.cc new file mode 100644 index 0000000..04ef3c3 --- /dev/null +++ b/webkit/appcache/mock_appcache_policy.cc @@ -0,0 +1,28 @@ +// Copyright (c) 2011 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/appcache/mock_appcache_policy.h" + +namespace appcache { + +MockAppCachePolicy::MockAppCachePolicy() + : can_load_return_value_(true), can_create_return_value_(true) { +} + +MockAppCachePolicy::~MockAppCachePolicy() { +} + +bool MockAppCachePolicy::CanLoadAppCache(const GURL& manifest_url, + const GURL& first_party) { + requested_manifest_url_ = manifest_url; + return can_load_return_value_; +} + +bool MockAppCachePolicy::CanCreateAppCache(const GURL& manifest_url, + const GURL& first_party) { + requested_manifest_url_ = manifest_url; + return can_create_return_value_; +} + +} // namespace appcache diff --git a/webkit/appcache/mock_appcache_policy.h b/webkit/appcache/mock_appcache_policy.h new file mode 100644 index 0000000..2fb962d --- /dev/null +++ b/webkit/appcache/mock_appcache_policy.h @@ -0,0 +1,30 @@ +// Copyright (c) 2011 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_MOCK_APPCACHE_POLICY_H_ +#define WEBKIT_APPCACHE_MOCK_APPCACHE_POLICY_H_ + +#include "googleurl/src/gurl.h" +#include "webkit/appcache/appcache_policy.h" + +namespace appcache { + +class MockAppCachePolicy : public AppCachePolicy { + public: + MockAppCachePolicy(); + virtual ~MockAppCachePolicy(); + + virtual bool CanLoadAppCache(const GURL& manifest_url, + const GURL& first_party); + virtual bool CanCreateAppCache(const GURL& manifest_url, + const GURL& first_party); + + bool can_load_return_value_; + bool can_create_return_value_; + GURL requested_manifest_url_; +}; + +} // namespace appcache + +#endif // WEBKIT_APPCACHE_MOCK_APPCACHE_POLICY_H_ diff --git a/webkit/appcache/mock_appcache_storage.cc b/webkit/appcache/mock_appcache_storage.cc index 58e8a7e..20ecf8d 100644 --- a/webkit/appcache/mock_appcache_storage.cc +++ b/webkit/appcache/mock_appcache_storage.cc @@ -248,7 +248,7 @@ void MockAppCacheStorage::ProcessFindResponseForMainRequest( delegate_ref->delegate->OnMainResponseFound( url, simulated_found_entry_, simulated_found_fallback_url_, simulated_found_fallback_entry_, - simulated_found_cache_id_, simulated_found_manifest_url_, false); + simulated_found_cache_id_, simulated_found_manifest_url_); } return; } @@ -348,7 +348,7 @@ void MockAppCacheStorage::ProcessFindResponseForMainRequest( if (found_candidate.entry.has_response_id()) { delegate_ref->delegate->OnMainResponseFound( url, found_candidate.entry, GURL(), AppCacheEntry(), - found_candidate.cache_id, found_candidate.manifest_url, false); + found_candidate.cache_id, found_candidate.manifest_url); return; } @@ -359,13 +359,13 @@ void MockAppCacheStorage::ProcessFindResponseForMainRequest( found_fallback_candidate.url, found_fallback_candidate.entry, found_fallback_candidate.cache_id, - found_fallback_candidate.manifest_url, false); + found_fallback_candidate.manifest_url); return; } // Didn't find anything. delegate_ref->delegate->OnMainResponseFound( - url, AppCacheEntry(), GURL(), AppCacheEntry(), kNoCacheId, GURL(), false); + url, AppCacheEntry(), GURL(), AppCacheEntry(), kNoCacheId, GURL()); } void MockAppCacheStorage::ProcessMakeGroupObsolete( diff --git a/webkit/appcache/mock_appcache_storage_unittest.cc b/webkit/appcache/mock_appcache_storage_unittest.cc index d04a896..ac03356 100644 --- a/webkit/appcache/mock_appcache_storage_unittest.cc +++ b/webkit/appcache/mock_appcache_storage_unittest.cc @@ -46,8 +46,7 @@ class MockAppCacheStorageTest : public testing::Test { void OnMainResponseFound(const GURL& url, const AppCacheEntry& entry, const GURL& fallback_url, const AppCacheEntry& fallback_entry, - int64 cache_id, const GURL& manifest_url, - bool was_blocked_by_policy) { + int64 cache_id, const GURL& manifest_url) { found_url_ = url; found_entry_ = entry; found_fallback_url_ = fallback_url; diff --git a/webkit/appcache/view_appcache_internals_job.cc b/webkit/appcache/view_appcache_internals_job.cc index f9a49ff..8e5f32a 100644 --- a/webkit/appcache/view_appcache_internals_job.cc +++ b/webkit/appcache/view_appcache_internals_job.cc @@ -112,7 +112,7 @@ void EmitAppCacheInfo(const GURL& base_url, EmitAnchor(info->manifest_url.spec(), info->manifest_url.spec(), out); out->append("
\n"); if (!service->appcache_policy()->CanLoadAppCache( - info->manifest_url)) { + info->manifest_url, info->manifest_url)) { out->append(kFormattedDisabledAppCacheMsg); } out->append("\n
\n"); diff --git a/webkit/tools/test_shell/test_shell.gypi b/webkit/tools/test_shell/test_shell.gypi index 7281d83..e241f44 100644 --- a/webkit/tools/test_shell/test_shell.gypi +++ b/webkit/tools/test_shell/test_shell.gypi @@ -378,6 +378,8 @@ '../../appcache/appcache_storage_impl_unittest.cc', '../../appcache/appcache_update_job_unittest.cc', '../../appcache/appcache_url_request_job_unittest.cc', + '../../appcache/mock_appcache_policy.h', + '../../appcache/mock_appcache_policy.cc', '../../appcache/mock_appcache_service.cc', '../../appcache/mock_appcache_service.h', '../../appcache/mock_appcache_storage.cc', -- cgit v1.1