Index: chrome/renderer/content_settings_observer.cc |
diff --git a/chrome/renderer/content_settings_observer.cc b/chrome/renderer/content_settings_observer.cc |
index 24b0db39c33c0003016f48f1a924639a9df7302a..a9c3fd9647cb23b7bd54deb940cd07a770407e68 100644 |
--- a/chrome/renderer/content_settings_observer.cc |
+++ b/chrome/renderer/content_settings_observer.cc |
@@ -59,14 +59,32 @@ GURL GetOriginOrURL(const WebFrame* frame) { |
return GURL(top_origin); |
} |
+ContentSetting GetContentSettingFromRules( |
+ const ContentSettingsForOneType& rules, |
+ const GURL& primary_url, |
+ const GURL& secondary_url) { |
+ ContentSettingsForOneType::const_iterator it; |
+ // If there is only one rule, it's the default rule and we don't need to match |
+ // the patterns. |
+ if (rules.size() == 1) |
+ return rules[0].setting; |
Bernhard Bauer
2011/11/11 13:00:53
Can we have a DCHECK here that this rule applies?
marja
2011/11/11 14:25:10
Done. (Checked that it's a wildcard-wildcard rule.
|
+ for (it = rules.begin(); it != rules.end(); ++it) { |
+ if (it->primary_pattern.Matches(primary_url) && |
+ it->secondary_pattern.Matches(secondary_url)) { |
+ return it->setting; |
+ } |
+ } |
+ NOTREACHED(); |
+ return CONTENT_SETTING_DEFAULT; |
+} |
+ |
} // namespace |
ContentSettingsObserver::ContentSettingsObserver( |
content::RenderView* render_view) |
: content::RenderViewObserver(render_view), |
content::RenderViewObserverTracker<ContentSettingsObserver>(render_view), |
- default_content_settings_(NULL), |
- image_setting_rules_(NULL), |
+ content_setting_rules_(NULL), |
plugins_temporarily_allowed_(false) { |
ClearBlockedContentSettings(); |
} |
@@ -74,26 +92,9 @@ ContentSettingsObserver::ContentSettingsObserver( |
ContentSettingsObserver::~ContentSettingsObserver() { |
} |
-void ContentSettingsObserver::SetContentSettings( |
- const ContentSettings& settings) { |
- current_content_settings_ = settings; |
-} |
- |
-void ContentSettingsObserver::SetDefaultContentSettings( |
- const ContentSettings* settings) { |
- default_content_settings_ = settings; |
-} |
- |
-void ContentSettingsObserver::SetImageSettingRules( |
- const ContentSettingsForOneType* image_setting_rules) { |
- image_setting_rules_ = image_setting_rules; |
-} |
- |
-ContentSetting ContentSettingsObserver::GetContentSetting( |
- ContentSettingsType type) { |
- // Don't call this for plug-ins. |
- DCHECK_NE(CONTENT_SETTINGS_TYPE_PLUGINS, type); |
- return current_content_settings_.settings[type]; |
+void ContentSettingsObserver::SetContentSettingRules( |
+ const RendererContentSettingRules* content_setting_rules) { |
+ content_setting_rules_ = content_setting_rules; |
} |
void ContentSettingsObserver::DidBlockContentType( |
@@ -117,8 +118,6 @@ bool ContentSettingsObserver::OnMessageReceived(const IPC::Message& message) { |
// blocked plugin. |
IPC_MESSAGE_HANDLER_GENERIC(ChromeViewMsg_LoadBlockedPlugins, |
OnLoadBlockedPlugins(); handled = false) |
- IPC_MESSAGE_HANDLER(ChromeViewMsg_SetContentSettingsForLoadingURL, |
- OnSetContentSettingsForLoadingURL) |
IPC_MESSAGE_UNHANDLED(handled = false) |
IPC_END_MESSAGE_MAP() |
return handled; |
@@ -132,54 +131,19 @@ void ContentSettingsObserver::DidCommitProvisionalLoad( |
NavigationState* state = NavigationState::FromDataSource(frame->dataSource()); |
if (!state->was_within_same_page()) { |
// Clear "block" flags for the new page. This needs to happen before any of |
- // allowScripts(), allowImage(), allowPlugins() is called for the new page |
- // so that these functions can correctly detect that a piece of content |
- // flipped from "not blocked" to "blocked". |
+ // |AllowScript()|, |AllowScriptFromSource()|, |AllowImage()|, or |
+ // |AllowPlugins()| is called for the new page so that these functions can |
+ // correctly detect that a piece of content flipped from "not blocked" to |
+ // "blocked". |
ClearBlockedContentSettings(); |
plugins_temporarily_allowed_ = false; |
} |
GURL url = frame->document().url(); |
- |
- if (frame->document().securityOrigin().toString() == "null" && |
- !url.SchemeIs(chrome::kFileScheme)) { |
- // The Frame has a unique security origin. Instead of granting the frame |
- // privileges based on it's URL, we fall back to the default content |
- // settings. |
- |
- // We exempt file URLs here because we sandbox them by default, but folks |
- // might reasonably want to supply non-default content settings for various |
- // file URLs. |
- if (default_content_settings_) |
- SetContentSettings(*default_content_settings_); |
- return; |
- } |
- |
// If we start failing this DCHECK, please makes sure we don't regress |
// this bug: http://code.google.com/p/chromium/issues/detail?id=79304 |
- DCHECK(!url.SchemeIs(chrome::kDataScheme)); |
- |
- // Set content settings. Default them from the parent window if one exists. |
- // This makes sure about:blank windows work as expected. |
- HostContentSettings::iterator host_content_settings = |
- host_content_settings_.find(url); |
- if (host_content_settings != host_content_settings_.end()) { |
- SetContentSettings(host_content_settings->second); |
- |
- // These content settings were merely recorded transiently for this load. |
- // We can erase them now. If at some point we reload this page, the |
- // browser will send us new, up-to-date content settings. |
- host_content_settings_.erase(host_content_settings); |
- } else if (frame->opener()) { |
- // The opener's view is not guaranteed to be non-null (it could be |
- // detached from its page but not yet destructed). |
- if (WebView* opener_view = frame->opener()->view()) { |
- content::RenderView* opener = |
- content::RenderView::FromWebView(opener_view); |
- ContentSettingsObserver* observer = ContentSettingsObserver::Get(opener); |
- SetContentSettings(observer->current_content_settings_); |
- } |
- } |
+ DCHECK(frame->document().securityOrigin().toString() == "null" || |
+ !url.SchemeIs(chrome::kDataScheme)); |
} |
bool ContentSettingsObserver::AllowDatabase(WebFrame* frame, |
@@ -217,19 +181,12 @@ bool ContentSettingsObserver::AllowImage(WebFrame* frame, |
return true; |
bool allow = enabled_per_settings; |
- const GURL& primary_url = GetOriginOrURL(frame); |
- GURL secondary_url(image_url); |
- if (image_setting_rules_ && |
- enabled_per_settings) { |
- ContentSettingsForOneType::const_iterator it; |
- for (it = image_setting_rules_->begin(); |
- it != image_setting_rules_->end(); ++it) { |
- if (it->primary_pattern.Matches(primary_url) && |
- it->secondary_pattern.Matches(secondary_url)) { |
- allow = (it->setting != CONTENT_SETTING_BLOCK); |
- break; |
- } |
- } |
+ if (content_setting_rules_ && enabled_per_settings) { |
+ const GURL& primary_url = GetOriginOrURL(frame); |
+ GURL secondary_url(image_url); |
+ allow = GetContentSettingFromRules( |
+ content_setting_rules_->image_rules, |
+ primary_url, secondary_url) != CONTENT_SETTING_BLOCK; |
} |
if (!allow) |
@@ -259,15 +216,65 @@ bool ContentSettingsObserver::AllowPlugins(WebFrame* frame, |
bool ContentSettingsObserver::AllowScript(WebFrame* frame, |
bool enabled_per_settings) { |
- if (enabled_per_settings && |
- AllowContentType(CONTENT_SETTINGS_TYPE_JAVASCRIPT)) { |
- return true; |
+ if (!enabled_per_settings) |
+ return false; |
+ |
+ // Evaluate the content setting rules before |
+ // |IsWhitelistedForContentSettings|; if there is only the default rule |
+ // allowing all scripts, it's quicker this way. |
+ bool allow = true; |
+ if (content_setting_rules_) { |
+ // If there is only one rule, it's the default rule and we don't need to |
+ // construct the GURLs or match the patterns. |
+ const ContentSettingsForOneType& rules = |
+ content_setting_rules_->script_rules; |
+ if (rules.size() == 1) { |
Bernhard Bauer
2011/11/11 13:00:53
Can you use |GetContentSettingFromRules| here?
marja
2011/11/11 14:25:10
Done. (Seems to not kill the perf if I modify the
|
+ allow = rules[0].setting != CONTENT_SETTING_BLOCK; |
+ } else { |
+ const GURL& primary_url = GetOriginOrURL(frame); |
+ GURL secondary_url(frame->document().securityOrigin().toString()); |
+ ContentSettingsForOneType::const_iterator it; |
+ for (it = rules.begin(); it != rules.end(); ++it) { |
+ if (it->primary_pattern.Matches(primary_url) && |
+ it->secondary_pattern.Matches(secondary_url)) { |
+ allow = it->setting != CONTENT_SETTING_BLOCK; |
+ break; |
+ } |
+ } |
+ } |
} |
+ return allow || IsWhitelistedForContentSettings(frame); |
+} |
- if (IsWhitelistedForContentSettings(frame)) |
- return true; |
- |
- return false; // Other protocols fall through here. |
+bool ContentSettingsObserver::AllowScriptFromSource( |
+ WebFrame* frame, |
+ bool enabled_per_settings, |
+ const WebKit::WebURL& script_url) { |
+ if (!enabled_per_settings) |
+ return false; |
+ |
+ bool allow = true; |
+ if (content_setting_rules_) { |
+ // If there is only one rule, it's the default rule and we don't need to |
+ // construct the GURLs or match the patterns. |
+ const ContentSettingsForOneType& rules = |
+ content_setting_rules_->script_rules; |
+ if (rules.size() == 1) { |
+ allow = rules[0].setting != CONTENT_SETTING_BLOCK; |
+ } else { |
+ const GURL& primary_url = GetOriginOrURL(frame); |
+ GURL secondary_url(script_url); |
+ ContentSettingsForOneType::const_iterator it; |
+ for (it = rules.begin(); it != rules.end(); ++it) { |
+ if (it->primary_pattern.Matches(primary_url) && |
+ it->secondary_pattern.Matches(secondary_url)) { |
+ allow = it->setting != CONTENT_SETTING_BLOCK; |
+ break; |
+ } |
+ } |
+ } |
+ } |
+ return allow || IsWhitelistedForContentSettings(frame); |
} |
bool ContentSettingsObserver::AllowStorage(WebFrame* frame, bool local) { |
@@ -300,23 +307,10 @@ void ContentSettingsObserver::DidNotAllowScript(WebFrame* frame) { |
DidBlockContentType(CONTENT_SETTINGS_TYPE_JAVASCRIPT, std::string()); |
} |
-void ContentSettingsObserver::OnSetContentSettingsForLoadingURL( |
- const GURL& url, |
- const ContentSettings& content_settings) { |
- host_content_settings_[url] = content_settings; |
-} |
- |
void ContentSettingsObserver::OnLoadBlockedPlugins() { |
plugins_temporarily_allowed_ = true; |
} |
-bool ContentSettingsObserver::AllowContentType( |
- ContentSettingsType settings_type) { |
- // CONTENT_SETTING_ASK is only valid for cookies. |
- return current_content_settings_.settings[settings_type] != |
- CONTENT_SETTING_BLOCK; |
-} |
- |
void ContentSettingsObserver::ClearBlockedContentSettings() { |
for (size_t i = 0; i < arraysize(content_blocked_); ++i) |
content_blocked_[i] = false; |