summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbattre@chromium.org <battre@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-29 16:54:31 +0000
committerbattre@chromium.org <battre@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-29 16:54:31 +0000
commite81d4d7c8966f4650ea8041f8d0bad4fe72b4f54 (patch)
tree46394d04d84e59b9caf598a7138350c3400762c9
parent965b6b2599050aab93cc398630d10ce30f3b4248 (diff)
downloadchromium_src-e81d4d7c8966f4650ea8041f8d0bad4fe72b4f54.zip
chromium_src-e81d4d7c8966f4650ea8041f8d0bad4fe72b4f54.tar.gz
chromium_src-e81d4d7c8966f4650ea8041f8d0bad4fe72b4f54.tar.bz2
Allow webRequest API extensions to clear the in-memory cache of WebKit.
If the behavior of a webRequest API extension changes (i.e. different URLs are blocked) this effect was not visible instantly due to WebKit's in-memory cache. This CL introduces a means to clear the cache. BUG=94284 TEST=no Review URL: http://codereview.chromium.org/7835031 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@103289 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/extensions/extension_function_dispatcher.cc1
-rw-r--r--chrome/browser/extensions/extension_webrequest_api.cc6
-rw-r--r--chrome/browser/extensions/extension_webrequest_api.h7
-rw-r--r--chrome/browser/renderer_host/web_cache_manager.cc17
-rw-r--r--chrome/browser/renderer_host/web_cache_manager.h17
-rw-r--r--chrome/common/extensions/api/extension_api.json8
-rw-r--r--chrome/common/extensions/docs/experimental.webRequest.html133
-rw-r--r--chrome/common/extensions/docs/samples.json1
-rw-r--r--chrome/common/render_messages.h3
-rw-r--r--chrome/renderer/chrome_content_renderer_client.cc3
-rw-r--r--chrome/renderer/chrome_render_process_observer.cc18
-rw-r--r--chrome/renderer/chrome_render_process_observer.h10
-rw-r--r--chrome/renderer/chrome_render_view_observer.cc9
-rw-r--r--chrome/renderer/chrome_render_view_observer.h7
14 files changed, 226 insertions, 14 deletions
diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc
index 619d841..9d7b435 100644
--- a/chrome/browser/extensions/extension_function_dispatcher.cc
+++ b/chrome/browser/extensions/extension_function_dispatcher.cc
@@ -361,6 +361,7 @@ void FactoryRegistry::ResetFunctions() {
// WebRequest.
RegisterFunction<WebRequestAddEventListener>();
RegisterFunction<WebRequestEventHandled>();
+ RegisterFunction<WebRequestHandlerBehaviorChanged>();
// Preferences.
RegisterFunction<GetPreferenceFunction>();
diff --git a/chrome/browser/extensions/extension_webrequest_api.cc b/chrome/browser/extensions/extension_webrequest_api.cc
index cf13a52..1e80edd 100644
--- a/chrome/browser/extensions/extension_webrequest_api.cc
+++ b/chrome/browser/extensions/extension_webrequest_api.cc
@@ -20,6 +20,7 @@
#include "chrome/browser/extensions/extension_webrequest_time_tracker.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_host/chrome_render_message_filter.h"
+#include "chrome/browser/renderer_host/web_cache_manager.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_error_utils.h"
#include "chrome/common/extensions/url_pattern.h"
@@ -1498,3 +1499,8 @@ bool WebRequestEventHandled::RunImpl() {
return true;
}
+
+bool WebRequestHandlerBehaviorChanged::RunImpl() {
+ WebCacheManager::GetInstance()->ClearCacheOnNavigation();
+ return true;
+}
diff --git a/chrome/browser/extensions/extension_webrequest_api.h b/chrome/browser/extensions/extension_webrequest_api.h
index f44d5b7..8a131c0 100644
--- a/chrome/browser/extensions/extension_webrequest_api.h
+++ b/chrome/browser/extensions/extension_webrequest_api.h
@@ -370,4 +370,11 @@ class WebRequestEventHandled : public SyncIOThreadExtensionFunction {
DECLARE_EXTENSION_FUNCTION_NAME("experimental.webRequest.eventHandled");
};
+class WebRequestHandlerBehaviorChanged : public AsyncExtensionFunction {
+ public:
+ virtual bool RunImpl();
+ DECLARE_EXTENSION_FUNCTION_NAME(
+ "experimental.webRequest.handlerBehaviorChanged");
+};
+
#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_WEBREQUEST_API_H_
diff --git a/chrome/browser/renderer_host/web_cache_manager.cc b/chrome/browser/renderer_host/web_cache_manager.cc
index 5a3a0ff..8ee268d 100644
--- a/chrome/browser/renderer_host/web_cache_manager.cc
+++ b/chrome/browser/renderer_host/web_cache_manager.cc
@@ -146,8 +146,15 @@ void WebCacheManager::SetGlobalSizeLimit(size_t bytes) {
void WebCacheManager::ClearCache() {
// Tell each renderer process to clear the cache.
- ClearRendederCache(active_renderers_);
- ClearRendederCache(inactive_renderers_);
+ ClearRendederCache(active_renderers_, INSTANTLY);
+ ClearRendederCache(inactive_renderers_, INSTANTLY);
+}
+
+void WebCacheManager::ClearCacheOnNavigation() {
+ // Tell each renderer process to clear the cache when a tab is reloaded or
+ // the user navigates to a new website.
+ ClearRendederCache(active_renderers_, ON_NAVIGATION);
+ ClearRendederCache(inactive_renderers_, ON_NAVIGATION);
}
void WebCacheManager::Observe(int type,
@@ -321,12 +328,14 @@ void WebCacheManager::EnactStrategy(const AllocationStrategy& strategy) {
}
}
-void WebCacheManager::ClearRendederCache(const std::set<int>& renderers) {
+void WebCacheManager::ClearRendederCache(
+ const std::set<int>& renderers,
+ WebCacheManager::ClearCacheOccasion occasion) {
std::set<int>::const_iterator iter = renderers.begin();
for (; iter != renderers.end(); ++iter) {
RenderProcessHost* host = RenderProcessHost::FromID(*iter);
if (host)
- host->Send(new ChromeViewMsg_ClearCache());
+ host->Send(new ChromeViewMsg_ClearCache(occasion == ON_NAVIGATION));
}
}
diff --git a/chrome/browser/renderer_host/web_cache_manager.h b/chrome/browser/renderer_host/web_cache_manager.h
index 02c6958..0006572 100644
--- a/chrome/browser/renderer_host/web_cache_manager.h
+++ b/chrome/browser/renderer_host/web_cache_manager.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 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.
@@ -70,6 +70,10 @@ class WebCacheManager : public NotificationObserver {
// Clears all in-memory caches.
void ClearCache();
+ // Clears all in-memory caches when a tab is reloaded or the user navigates
+ // to a different website.
+ void ClearCacheOnNavigation();
+
// NotificationObserver implementation:
virtual void Observe(int type,
const NotificationSource& source,
@@ -179,8 +183,17 @@ class WebCacheManager : public NotificationObserver {
// allocations according to |strategy|.
void EnactStrategy(const AllocationStrategy& strategy);
+ enum ClearCacheOccasion {
+ // Instructs to clear the cache instantly.
+ INSTANTLY,
+ // Instructs to clear the cache when a navigation takes place (this
+ // includes reloading a tab).
+ ON_NAVIGATION
+ };
+
// Inform all |renderers| to clear their cache.
- void ClearRendederCache(const std::set<int>& renderers);
+ void ClearRendederCache(const std::set<int>& renderers,
+ ClearCacheOccasion occation);
// Check to see if any active renderers have fallen inactive.
void FindInactiveRenderers();
diff --git a/chrome/common/extensions/api/extension_api.json b/chrome/common/extensions/api/extension_api.json
index 4f4077a..a0e91fe8 100644
--- a/chrome/common/extensions/api/extension_api.json
+++ b/chrome/common/extensions/api/extension_api.json
@@ -5704,6 +5704,14 @@
"name": "response"
}
]
+ },
+ {
+ "name": "handlerBehaviorChanged",
+ "type": "function",
+ "description": "Needs to be called when the behavior of the webRequest handlers has changed to prevent incorrect handling due to caching. This function call is expensive. Don't call it often.",
+ "parameters": [
+ {"type": "function", "name": "callback", "optional": true, "parameters": []}
+ ]
}
],
"events": [
diff --git a/chrome/common/extensions/docs/experimental.webRequest.html b/chrome/common/extensions/docs/experimental.webRequest.html
index 6b0847e..7b1f2cd 100644
--- a/chrome/common/extensions/docs/experimental.webRequest.html
+++ b/chrome/common/extensions/docs/experimental.webRequest.html
@@ -319,6 +319,8 @@
<a href="#method-anchor">methodName</a>
</li><li style="display: none; ">
<a href="#method-anchor">methodName</a>
+ </li><li>
+ <a href="#method-handlerBehaviorChanged">handlerBehaviorChanged</a>
</li>
</ol>
</li>
@@ -806,6 +808,137 @@ chrome.windows.onRemoved.addListener(
</p>
</div> <!-- /description -->
+ </div><div class="apiItem">
+ <a name="method-handlerBehaviorChanged"></a> <!-- method-anchor -->
+ <h4>handlerBehaviorChanged</h4>
+
+ <div class="summary"><span style="display: none; ">void</span>
+ <!-- Note: intentionally longer 80 columns -->
+ <span>chrome.experimental.webRequest.handlerBehaviorChanged</span>(<span class="optional"><span style="display: none; ">, </span><span>function</span>
+ <var><span>callback</span></var></span>)</div>
+
+ <div class="description">
+ <p class="todo" style="display: none; ">Undocumented.</p>
+ <p>Needs to be called when the behavior of the webRequest handlers has changed to prevent incorrect handling due to caching. This function call is expensive. Don't call it often.</p>
+
+ <!-- PARAMETERS -->
+ <h4>Parameters</h4>
+ <dl>
+ <div>
+ <div>
+ <dt>
+ <var>callback</var>
+ <em>
+
+ <!-- TYPE -->
+ <div style="display:inline">
+ (
+ <span class="optional">optional</span>
+ <span class="enum" style="display: none; ">enumerated</span>
+ <span id="typeTemplate">
+ <span style="display: none; ">
+ <a> Type</a>
+ </span>
+ <span>
+ <span style="display: none; ">
+ array of <span><span></span></span>
+ </span>
+ <span>function</span>
+ <span style="display: none; "></span>
+ </span>
+ </span>
+ )
+ </div>
+
+ </em>
+ </dt>
+ <dd class="todo">
+ Undocumented.
+ </dd>
+ <dd style="display: none; ">
+ Description of this parameter from the json schema.
+ </dd>
+ <dd style="display: none; ">
+ This parameter was added in version
+ <b><span></span></b>.
+ You must omit this parameter in earlier versions,
+ and you may omit it in any version. If you require this
+ parameter, the manifest key
+ <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a>
+ can ensure that your extension won't be run in an earlier browser version.
+ </dd>
+
+ <!-- OBJECT PROPERTIES -->
+ <dd style="display: none; ">
+ <dl>
+ <div>
+ <div>
+ </div>
+ </div>
+ </dl>
+ </dd>
+
+ <!-- OBJECT METHODS -->
+ <dd style="display: none; ">
+ <div></div>
+ </dd>
+
+ <!-- OBJECT EVENT FIELDS -->
+ <dd style="display: none; ">
+ <div></div>
+ </dd>
+
+ <!-- FUNCTION PARAMETERS -->
+ <dd style="display: none; ">
+ <div></div>
+ </dd>
+
+ </div>
+ </div>
+ </dl>
+
+ <!-- RETURNS -->
+ <h4 style="display: none; ">Returns</h4>
+ <dl>
+ <div style="display: none; ">
+ <div>
+ </div>
+ </div>
+ </dl>
+
+ <!-- CALLBACK -->
+ <div>
+ <div>
+ <h4>Callback function</h4>
+ <p style="display: none; ">
+ The callback <em>parameter</em> should specify a function
+ that looks like this:
+ </p>
+ <p>
+ If you specify the <em>callback</em> parameter, it should
+ specify a function that looks like this:
+ </p>
+
+ <!-- Note: intentionally longer 80 columns -->
+ <pre>function(<span></span>) <span class="subdued">{...}</span>;</pre>
+ <dl>
+ <div style="display: none; ">
+ <div>
+ </div>
+ </div>
+ </dl>
+ </div>
+ </div>
+
+ <!-- MIN_VERSION -->
+ <p style="display: none; ">
+ This function was added in version <b><span></span></b>.
+ If you require this function, the manifest key
+ <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a>
+ can ensure that your extension won't be run in an earlier browser version.
+ </p>
+ </div> <!-- /description -->
+
</div> <!-- /apiItem -->
</div> <!-- /apiGroup -->
diff --git a/chrome/common/extensions/docs/samples.json b/chrome/common/extensions/docs/samples.json
index 66f22ed..5614d6d 100644
--- a/chrome/common/extensions/docs/samples.json
+++ b/chrome/common/extensions/docs/samples.json
@@ -89,6 +89,7 @@
"chrome.experimental.webNavigation.onReferenceFragmentUpdated": "experimental.webNavigation.html#event-onReferenceFragmentUpdated",
"chrome.experimental.webRequest.addEventListener": "experimental.webRequest.html#method-addEventListener",
"chrome.experimental.webRequest.eventHandled": "experimental.webRequest.html#method-eventHandled",
+ "chrome.experimental.webRequest.handlerBehaviorChanged": "experimental.webRequest.html#method-handlerBehaviorChanged",
"chrome.experimental.webRequest.onAuthRequired": "experimental.webRequest.html#event-onAuthRequired",
"chrome.experimental.webRequest.onBeforeRedirect": "experimental.webRequest.html#event-onBeforeRedirect",
"chrome.experimental.webRequest.onBeforeRequest": "experimental.webRequest.html#event-onBeforeRequest",
diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h
index 7d92fa2..84d1cff 100644
--- a/chrome/common/render_messages.h
+++ b/chrome/common/render_messages.h
@@ -138,7 +138,8 @@ IPC_MESSAGE_CONTROL3(ChromeViewMsg_SetCacheCapacities,
size_t /* capacity */)
// Tells the renderer to clear the cache.
-IPC_MESSAGE_CONTROL0(ChromeViewMsg_ClearCache)
+IPC_MESSAGE_CONTROL1(ChromeViewMsg_ClearCache,
+ bool /* on_navigation */)
// Tells the renderer to dump as much memory as it can, perhaps because we
// have memory pressure or the renderer is (or will be) paged out. This
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc
index 91841cf..88d41cf 100644
--- a/chrome/renderer/chrome_content_renderer_client.cc
+++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -243,7 +243,8 @@ void ChromeContentRendererClient::RenderViewCreated(RenderView* render_view) {
TranslateHelper* translate = new TranslateHelper(render_view, autofill_agent);
new ChromeRenderViewObserver(
- render_view, content_settings, extension_dispatcher_.get(), translate);
+ render_view, content_settings, chrome_observer_.get(),
+ extension_dispatcher_.get(), translate);
// Used only for testing/automation.
if (CommandLine::ForCurrentProcess()->HasSwitch(
diff --git a/chrome/renderer/chrome_render_process_observer.cc b/chrome/renderer/chrome_render_process_observer.cc
index 93d1fa8..ad41476 100644
--- a/chrome/renderer/chrome_render_process_observer.cc
+++ b/chrome/renderer/chrome_render_process_observer.cc
@@ -196,7 +196,8 @@ bool ChromeRenderProcessObserver::is_incognito_process_ = false;
ChromeRenderProcessObserver::ChromeRenderProcessObserver(
chrome::ChromeContentRendererClient* client)
- : client_(client) {
+ : client_(client),
+ clear_cache_pending_(false) {
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
if (command_line.HasSwitch(switches::kEnableWatchdog)) {
// TODO(JAR): Need to implement renderer IO msgloop watchdog.
@@ -314,8 +315,12 @@ void ChromeRenderProcessObserver::OnSetCacheCapacities(size_t min_dead_capacity,
min_dead_capacity, max_dead_capacity, capacity);
}
-void ChromeRenderProcessObserver::OnClearCache() {
- WebCache::clear();
+void ChromeRenderProcessObserver::OnClearCache(bool on_navigation) {
+ if (on_navigation) {
+ clear_cache_pending_ = true;
+ } else {
+ WebCache::clear();
+ }
}
void ChromeRenderProcessObserver::OnGetCacheResourceStats() {
@@ -409,3 +414,10 @@ void ChromeRenderProcessObserver::OnPurgeMemory() {
if (client_)
client_->OnPurgeMemory();
}
+
+void ChromeRenderProcessObserver::ExecutePendingClearCache() {
+ if (clear_cache_pending_) {
+ clear_cache_pending_ = false;
+ WebCache::clear();
+ }
+}
diff --git a/chrome/renderer/chrome_render_process_observer.h b/chrome/renderer/chrome_render_process_observer.h
index 80bf18ef..615b6c3 100644
--- a/chrome/renderer/chrome_render_process_observer.h
+++ b/chrome/renderer/chrome_render_process_observer.h
@@ -33,6 +33,10 @@ class ChromeRenderProcessObserver : public RenderProcessObserver {
static bool is_incognito_process() { return is_incognito_process_; }
+ // Needs to be called by RenderViews in case of navigations to execute
+ // any 'clear cache' commands that were delayed until the next navigation.
+ void ExecutePendingClearCache();
+
private:
// RenderProcessObserver implementation.
virtual bool OnControlMessageReceived(const IPC::Message& message) OVERRIDE;
@@ -45,7 +49,9 @@ class ChromeRenderProcessObserver : public RenderProcessObserver {
void OnSetCacheCapacities(size_t min_dead_capacity,
size_t max_dead_capacity,
size_t capacity);
- void OnClearCache();
+ // If |on_navigation| is true, the clearing is delayed until the next
+ // navigation event.
+ void OnClearCache(bool on_navigation);
void OnGetCacheResourceStats();
void OnSetFieldTrialGroup(const std::string& fiel_trial_name,
const std::string& group_name);
@@ -58,6 +64,8 @@ class ChromeRenderProcessObserver : public RenderProcessObserver {
static bool is_incognito_process_;
scoped_ptr<ResourceDispatcherDelegate> resource_delegate_;
chrome::ChromeContentRendererClient* client_;
+ // If true, the web cache shall be cleared before the next navigation event.
+ bool clear_cache_pending_;
DISALLOW_COPY_AND_ASSIGN(ChromeRenderProcessObserver);
};
diff --git a/chrome/renderer/chrome_render_view_observer.cc b/chrome/renderer/chrome_render_view_observer.cc
index b913137..f4648fbc 100644
--- a/chrome/renderer/chrome_render_view_observer.cc
+++ b/chrome/renderer/chrome_render_view_observer.cc
@@ -16,6 +16,7 @@
#include "chrome/common/url_constants.h"
#include "chrome/renderer/about_handler.h"
#include "chrome/renderer/automation/dom_automation_controller.h"
+#include "chrome/renderer/chrome_render_process_observer.h"
#include "chrome/renderer/content_settings_observer.h"
#include "chrome/renderer/extensions/extension_dispatcher.h"
#include "chrome/renderer/external_host_bindings.h"
@@ -198,11 +199,13 @@ GURL StripRef(const GURL& url) {
ChromeRenderViewObserver::ChromeRenderViewObserver(
RenderView* render_view,
ContentSettingsObserver* content_settings,
+ ChromeRenderProcessObserver* chrome_render_process_observer,
ExtensionDispatcher* extension_dispatcher,
TranslateHelper* translate_helper)
: RenderViewObserver(render_view),
- content_settings_(content_settings),
+ chrome_render_process_observer_(chrome_render_process_observer),
extension_dispatcher_(extension_dispatcher),
+ content_settings_(content_settings),
translate_helper_(translate_helper),
phishing_classifier_(NULL),
last_indexed_page_id_(-1),
@@ -336,6 +339,10 @@ void ChromeRenderViewObserver::OnSetAllowRunningInsecureContent(bool allow) {
}
void ChromeRenderViewObserver::Navigate(const GURL& url) {
+ // Execute cache clear operations that were postponed until a navigation
+ // event (including tab reload).
+ if (chrome_render_process_observer_)
+ chrome_render_process_observer_->ExecutePendingClearCache();
AboutHandler::MaybeHandle(url);
}
diff --git a/chrome/renderer/chrome_render_view_observer.h b/chrome/renderer/chrome_render_view_observer.h
index fa2946a..cf1497e 100644
--- a/chrome/renderer/chrome_render_view_observer.h
+++ b/chrome/renderer/chrome_render_view_observer.h
@@ -16,6 +16,7 @@
#include "googleurl/src/gurl.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebPermissionClient.h"
+class ChromeRenderProcessObserver;
class ContentSettingsObserver;
class DomAutomationController;
class ExtensionDispatcher;
@@ -43,6 +44,7 @@ class ChromeRenderViewObserver : public RenderViewObserver,
ChromeRenderViewObserver(
RenderView* render_view,
ContentSettingsObserver* content_settings,
+ ChromeRenderProcessObserver* chrome_render_process_observer,
ExtensionDispatcher* extension_dispatcher,
TranslateHelper* translate_helper);
virtual ~ChromeRenderViewObserver();
@@ -171,9 +173,12 @@ class ChromeRenderViewObserver : public RenderViewObserver,
// Save the JavaScript to preload if a ViewMsg_WebUIJavaScript is received.
scoped_ptr<WebUIJavaScript> webui_javascript_;
+ // Owned by ChromeContentRendererClient and outlive us.
+ ChromeRenderProcessObserver* chrome_render_process_observer_;
+ ExtensionDispatcher* extension_dispatcher_;
+
// Have the same lifetime as us.
ContentSettingsObserver* content_settings_;
- ExtensionDispatcher* extension_dispatcher_;
TranslateHelper* translate_helper_;
safe_browsing::PhishingClassifierDelegate* phishing_classifier_;