Chromium Code Reviews| 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; |