OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "chrome/renderer/content_settings_observer.h" |
| 6 |
| 7 #include "chrome/common/render_messages.h" |
| 8 #include "chrome/common/url_constants.h" |
| 9 #include "content/renderer/render_view.h" |
| 10 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDataSource.h" |
| 11 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" |
| 12 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrameClient.h" |
| 13 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h" |
| 14 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLRequest.h" |
| 15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" |
| 16 |
| 17 using WebKit::WebDataSource; |
| 18 using WebKit::WebFrame; |
| 19 using WebKit::WebFrameClient; |
| 20 using WebKit::WebSecurityOrigin; |
| 21 using WebKit::WebURLRequest; |
| 22 using WebKit::WebView; |
| 23 |
| 24 namespace { |
| 25 |
| 26 // True if |frame| contains content that is white-listed for content settings. |
| 27 static bool IsWhitelistedForContentSettings(WebFrame* frame) { |
| 28 WebSecurityOrigin origin = frame->securityOrigin(); |
| 29 if (origin.isEmpty()) |
| 30 return false; // Uninitialized document? |
| 31 |
| 32 if (EqualsASCII(origin.protocol(), chrome::kChromeUIScheme)) |
| 33 return true; // Browser UI elements should still work. |
| 34 |
| 35 // If the scheme is ftp: or file:, an empty file name indicates a directory |
| 36 // listing, which requires JavaScript to function properly. |
| 37 GURL frame_url = frame->url(); |
| 38 const char* kDirProtocols[] = { "ftp", "file" }; |
| 39 for (size_t i = 0; i < arraysize(kDirProtocols); ++i) { |
| 40 if (EqualsASCII(origin.protocol(), kDirProtocols[i])) { |
| 41 return frame_url.SchemeIs(kDirProtocols[i]) && |
| 42 frame_url.ExtractFileName().empty(); |
| 43 } |
| 44 } |
| 45 |
| 46 return false; |
| 47 } |
| 48 |
| 49 } // namespace |
| 50 |
| 51 ContentSettingsObserver::ContentSettingsObserver(RenderView* render_view) |
| 52 : RenderViewObserver(render_view), |
| 53 RenderViewObserverTracker<ContentSettingsObserver>(render_view) { |
| 54 ClearBlockedContentSettings(); |
| 55 } |
| 56 |
| 57 ContentSettingsObserver::~ContentSettingsObserver() { |
| 58 } |
| 59 |
| 60 |
| 61 void ContentSettingsObserver::SetContentSettings( |
| 62 const ContentSettings& settings) { |
| 63 current_content_settings_ = settings; |
| 64 } |
| 65 |
| 66 ContentSetting ContentSettingsObserver::GetContentSetting( |
| 67 ContentSettingsType type) { |
| 68 return current_content_settings_.settings[type]; |
| 69 } |
| 70 |
| 71 void ContentSettingsObserver::DidBlockContentType( |
| 72 ContentSettingsType settings_type, |
| 73 const std::string& resource_identifier) { |
| 74 if (!content_blocked_[settings_type]) { |
| 75 content_blocked_[settings_type] = true; |
| 76 Send(new ViewHostMsg_ContentBlocked(routing_id(), settings_type, |
| 77 resource_identifier)); |
| 78 } |
| 79 } |
| 80 |
| 81 bool ContentSettingsObserver::OnMessageReceived(const IPC::Message& message) { |
| 82 bool handled = true; |
| 83 IPC_BEGIN_MESSAGE_MAP(ContentSettingsObserver, message) |
| 84 IPC_MESSAGE_HANDLER(ViewMsg_SetContentSettingsForLoadingURL, |
| 85 OnSetContentSettingsForLoadingURL) |
| 86 IPC_MESSAGE_UNHANDLED(handled = false) |
| 87 IPC_END_MESSAGE_MAP() |
| 88 return handled; |
| 89 } |
| 90 |
| 91 void ContentSettingsObserver::DidCommitProvisionalLoad( |
| 92 WebFrame* frame, bool is_new_navigation) { |
| 93 if (frame->parent()) |
| 94 return; // Not a top-level navigation. |
| 95 |
| 96 WebDataSource* ds = frame->dataSource(); |
| 97 const WebURLRequest& request = ds->request(); |
| 98 |
| 99 // Clear "block" flags for the new page. This needs to happen before any of |
| 100 // allowScripts(), allowImages(), allowPlugins() is called for the new page |
| 101 // so that these functions can correctly detect that a piece of content |
| 102 // flipped from "not blocked" to "blocked". |
| 103 ClearBlockedContentSettings(); |
| 104 |
| 105 // Set content settings. Default them from the parent window if one exists. |
| 106 // This makes sure about:blank windows work as expected. |
| 107 HostContentSettings::iterator host_content_settings = |
| 108 host_content_settings_.find(GURL(request.url())); |
| 109 if (host_content_settings != host_content_settings_.end()) { |
| 110 SetContentSettings(host_content_settings->second); |
| 111 |
| 112 // These content settings were merely recorded transiently for this load. |
| 113 // We can erase them now. If at some point we reload this page, the |
| 114 // browser will send us new, up-to-date content settings. |
| 115 host_content_settings_.erase(host_content_settings); |
| 116 } else if (frame->opener()) { |
| 117 // The opener's view is not guaranteed to be non-null (it could be |
| 118 // detached from its page but not yet destructed). |
| 119 if (WebView* opener_view = frame->opener()->view()) { |
| 120 RenderView* opener = RenderView::FromWebView(opener_view); |
| 121 ContentSettingsObserver* observer = ContentSettingsObserver::Get(opener); |
| 122 SetContentSettings(observer->current_content_settings_); |
| 123 } |
| 124 } |
| 125 } |
| 126 |
| 127 bool ContentSettingsObserver::AllowImages(WebFrame* frame, |
| 128 bool enabled_per_settings) { |
| 129 if (enabled_per_settings && |
| 130 AllowContentType(CONTENT_SETTINGS_TYPE_IMAGES)) { |
| 131 return true; |
| 132 } |
| 133 |
| 134 if (IsWhitelistedForContentSettings(frame)) |
| 135 return true; |
| 136 |
| 137 DidBlockContentType(CONTENT_SETTINGS_TYPE_IMAGES, std::string()); |
| 138 return false; // Other protocols fall through here. |
| 139 } |
| 140 |
| 141 bool ContentSettingsObserver::AllowPlugins(WebFrame* frame, |
| 142 bool enabled_per_settings) { |
| 143 return render_view()->WebFrameClient::allowPlugins( |
| 144 frame, enabled_per_settings); |
| 145 } |
| 146 |
| 147 bool ContentSettingsObserver::AllowScript(WebFrame* frame, |
| 148 bool enabled_per_settings) { |
| 149 if (enabled_per_settings && |
| 150 AllowContentType(CONTENT_SETTINGS_TYPE_JAVASCRIPT)) { |
| 151 return true; |
| 152 } |
| 153 |
| 154 if (IsWhitelistedForContentSettings(frame)) |
| 155 return true; |
| 156 |
| 157 return false; // Other protocols fall through here. |
| 158 } |
| 159 |
| 160 void ContentSettingsObserver::DidNotAllowPlugins(WebFrame* frame) { |
| 161 DidBlockContentType(CONTENT_SETTINGS_TYPE_PLUGINS, std::string()); |
| 162 } |
| 163 |
| 164 void ContentSettingsObserver::DidNotAllowScript(WebFrame* frame) { |
| 165 DidBlockContentType(CONTENT_SETTINGS_TYPE_JAVASCRIPT, std::string()); |
| 166 } |
| 167 |
| 168 void ContentSettingsObserver::OnSetContentSettingsForLoadingURL( |
| 169 const GURL& url, |
| 170 const ContentSettings& content_settings) { |
| 171 host_content_settings_[url] = content_settings; |
| 172 } |
| 173 |
| 174 bool ContentSettingsObserver::AllowContentType( |
| 175 ContentSettingsType settings_type) { |
| 176 // CONTENT_SETTING_ASK is only valid for cookies. |
| 177 return current_content_settings_.settings[settings_type] != |
| 178 CONTENT_SETTING_BLOCK; |
| 179 } |
| 180 |
| 181 void ContentSettingsObserver::ClearBlockedContentSettings() { |
| 182 for (size_t i = 0; i < arraysize(content_blocked_); ++i) |
| 183 content_blocked_[i] = false; |
| 184 } |
OLD | NEW |