Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / chrome / renderer / content_settings_observer.cc
blob1bfc461ea955394b4cb88e2cad4f782ae2fde5b4
1 // Copyright (c) 2012 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.
5 #include "chrome/renderer/content_settings_observer.h"
7 #include "base/command_line.h"
8 #include "base/metrics/histogram.h"
9 #include "chrome/common/chrome_switches.h"
10 #include "chrome/common/render_messages.h"
11 #include "chrome/common/url_constants.h"
12 #include "content/public/renderer/document_state.h"
13 #include "content/public/renderer/navigation_state.h"
14 #include "content/public/renderer/render_frame.h"
15 #include "content/public/renderer/render_view.h"
16 #include "extensions/common/constants.h"
17 #include "extensions/renderer/dispatcher.h"
18 #include "third_party/WebKit/public/platform/WebURL.h"
19 #include "third_party/WebKit/public/web/WebDataSource.h"
20 #include "third_party/WebKit/public/web/WebDocument.h"
21 #include "third_party/WebKit/public/web/WebFrame.h"
22 #include "third_party/WebKit/public/web/WebFrameClient.h"
23 #include "third_party/WebKit/public/web/WebSecurityOrigin.h"
24 #include "third_party/WebKit/public/web/WebView.h"
25 #include "webkit/child/weburlresponse_extradata_impl.h"
27 using blink::WebDataSource;
28 using blink::WebDocument;
29 using blink::WebFrame;
30 using blink::WebFrameClient;
31 using blink::WebSecurityOrigin;
32 using blink::WebString;
33 using blink::WebURL;
34 using blink::WebView;
35 using content::DocumentState;
36 using content::NavigationState;
37 using extensions::APIPermission;
39 namespace {
41 enum {
42 INSECURE_CONTENT_DISPLAY = 0,
43 INSECURE_CONTENT_DISPLAY_HOST_GOOGLE,
44 INSECURE_CONTENT_DISPLAY_HOST_WWW_GOOGLE,
45 INSECURE_CONTENT_DISPLAY_HTML,
46 INSECURE_CONTENT_RUN,
47 INSECURE_CONTENT_RUN_HOST_GOOGLE,
48 INSECURE_CONTENT_RUN_HOST_WWW_GOOGLE,
49 INSECURE_CONTENT_RUN_TARGET_YOUTUBE,
50 INSECURE_CONTENT_RUN_JS,
51 INSECURE_CONTENT_RUN_CSS,
52 INSECURE_CONTENT_RUN_SWF,
53 INSECURE_CONTENT_DISPLAY_HOST_YOUTUBE,
54 INSECURE_CONTENT_RUN_HOST_YOUTUBE,
55 INSECURE_CONTENT_RUN_HOST_GOOGLEUSERCONTENT,
56 INSECURE_CONTENT_DISPLAY_HOST_MAIL_GOOGLE,
57 INSECURE_CONTENT_RUN_HOST_MAIL_GOOGLE,
58 INSECURE_CONTENT_DISPLAY_HOST_PLUS_GOOGLE,
59 INSECURE_CONTENT_RUN_HOST_PLUS_GOOGLE,
60 INSECURE_CONTENT_DISPLAY_HOST_DOCS_GOOGLE,
61 INSECURE_CONTENT_RUN_HOST_DOCS_GOOGLE,
62 INSECURE_CONTENT_DISPLAY_HOST_SITES_GOOGLE,
63 INSECURE_CONTENT_RUN_HOST_SITES_GOOGLE,
64 INSECURE_CONTENT_DISPLAY_HOST_PICASAWEB_GOOGLE,
65 INSECURE_CONTENT_RUN_HOST_PICASAWEB_GOOGLE,
66 INSECURE_CONTENT_DISPLAY_HOST_GOOGLE_READER,
67 INSECURE_CONTENT_RUN_HOST_GOOGLE_READER,
68 INSECURE_CONTENT_DISPLAY_HOST_CODE_GOOGLE,
69 INSECURE_CONTENT_RUN_HOST_CODE_GOOGLE,
70 INSECURE_CONTENT_DISPLAY_HOST_GROUPS_GOOGLE,
71 INSECURE_CONTENT_RUN_HOST_GROUPS_GOOGLE,
72 INSECURE_CONTENT_DISPLAY_HOST_MAPS_GOOGLE,
73 INSECURE_CONTENT_RUN_HOST_MAPS_GOOGLE,
74 INSECURE_CONTENT_DISPLAY_HOST_GOOGLE_SUPPORT,
75 INSECURE_CONTENT_RUN_HOST_GOOGLE_SUPPORT,
76 INSECURE_CONTENT_DISPLAY_HOST_GOOGLE_INTL,
77 INSECURE_CONTENT_RUN_HOST_GOOGLE_INTL,
78 INSECURE_CONTENT_NUM_EVENTS
81 // Constants for UMA statistic collection.
82 static const char kWWWDotGoogleDotCom[] = "www.google.com";
83 static const char kMailDotGoogleDotCom[] = "mail.google.com";
84 static const char kPlusDotGoogleDotCom[] = "plus.google.com";
85 static const char kDocsDotGoogleDotCom[] = "docs.google.com";
86 static const char kSitesDotGoogleDotCom[] = "sites.google.com";
87 static const char kPicasawebDotGoogleDotCom[] = "picasaweb.google.com";
88 static const char kCodeDotGoogleDotCom[] = "code.google.com";
89 static const char kGroupsDotGoogleDotCom[] = "groups.google.com";
90 static const char kMapsDotGoogleDotCom[] = "maps.google.com";
91 static const char kWWWDotYoutubeDotCom[] = "www.youtube.com";
92 static const char kDotGoogleUserContentDotCom[] = ".googleusercontent.com";
93 static const char kGoogleReaderPathPrefix[] = "/reader/";
94 static const char kGoogleSupportPathPrefix[] = "/support/";
95 static const char kGoogleIntlPathPrefix[] = "/intl/";
96 static const char kDotJS[] = ".js";
97 static const char kDotCSS[] = ".css";
98 static const char kDotSWF[] = ".swf";
99 static const char kDotHTML[] = ".html";
101 // Constants for mixed-content blocking.
102 static const char kGoogleDotCom[] = "google.com";
104 static bool IsHostInDomain(const std::string& host, const std::string& domain) {
105 return (EndsWith(host, domain, false) &&
106 (host.length() == domain.length() ||
107 (host.length() > domain.length() &&
108 host[host.length() - domain.length() - 1] == '.')));
111 GURL GetOriginOrURL(const WebFrame* frame) {
112 WebString top_origin = frame->top()->document().securityOrigin().toString();
113 // The the |top_origin| is unique ("null") e.g., for file:// URLs. Use the
114 // document URL as the primary URL in those cases.
115 if (top_origin == "null")
116 return frame->top()->document().url();
117 return GURL(top_origin);
120 ContentSetting GetContentSettingFromRules(
121 const ContentSettingsForOneType& rules,
122 const WebFrame* frame,
123 const GURL& secondary_url) {
124 ContentSettingsForOneType::const_iterator it;
125 // If there is only one rule, it's the default rule and we don't need to match
126 // the patterns.
127 if (rules.size() == 1) {
128 DCHECK(rules[0].primary_pattern == ContentSettingsPattern::Wildcard());
129 DCHECK(rules[0].secondary_pattern == ContentSettingsPattern::Wildcard());
130 return rules[0].setting;
132 const GURL& primary_url = GetOriginOrURL(frame);
133 for (it = rules.begin(); it != rules.end(); ++it) {
134 if (it->primary_pattern.Matches(primary_url) &&
135 it->secondary_pattern.Matches(secondary_url)) {
136 return it->setting;
139 NOTREACHED();
140 return CONTENT_SETTING_DEFAULT;
143 } // namespace
145 ContentSettingsObserver::ContentSettingsObserver(
146 content::RenderFrame* render_frame,
147 extensions::Dispatcher* extension_dispatcher)
148 : content::RenderFrameObserver(render_frame),
149 content::RenderFrameObserverTracker<ContentSettingsObserver>(
150 render_frame),
151 extension_dispatcher_(extension_dispatcher),
152 allow_displaying_insecure_content_(false),
153 allow_running_insecure_content_(false),
154 content_setting_rules_(NULL),
155 is_interstitial_page_(false),
156 npapi_plugins_blocked_(false) {
157 ClearBlockedContentSettings();
158 render_frame->GetWebFrame()->setPermissionClient(this);
160 if (render_frame->GetRenderView()->GetMainRenderFrame() != render_frame) {
161 // Copy all the settings from the main render frame to avoid race conditions
162 // when initializing this data. See http://crbug.com/333308.
163 ContentSettingsObserver* parent = ContentSettingsObserver::Get(
164 render_frame->GetRenderView()->GetMainRenderFrame());
165 allow_displaying_insecure_content_ =
166 parent->allow_displaying_insecure_content_;
167 allow_running_insecure_content_ = parent->allow_running_insecure_content_;
168 temporarily_allowed_plugins_ = parent->temporarily_allowed_plugins_;
169 is_interstitial_page_ = parent->is_interstitial_page_;
170 npapi_plugins_blocked_ = parent->npapi_plugins_blocked_;
174 ContentSettingsObserver::~ContentSettingsObserver() {
177 void ContentSettingsObserver::SetContentSettingRules(
178 const RendererContentSettingRules* content_setting_rules) {
179 content_setting_rules_ = content_setting_rules;
182 bool ContentSettingsObserver::IsPluginTemporarilyAllowed(
183 const std::string& identifier) {
184 // If the empty string is in here, it means all plug-ins are allowed.
185 // TODO(bauerb): Remove this once we only pass in explicit identifiers.
186 return (temporarily_allowed_plugins_.find(identifier) !=
187 temporarily_allowed_plugins_.end()) ||
188 (temporarily_allowed_plugins_.find(std::string()) !=
189 temporarily_allowed_plugins_.end());
192 void ContentSettingsObserver::DidBlockContentType(
193 ContentSettingsType settings_type) {
194 if (!content_blocked_[settings_type]) {
195 content_blocked_[settings_type] = true;
196 Send(new ChromeViewHostMsg_ContentBlocked(routing_id(), settings_type));
200 bool ContentSettingsObserver::OnMessageReceived(const IPC::Message& message) {
201 bool handled = true;
202 IPC_BEGIN_MESSAGE_MAP(ContentSettingsObserver, message)
203 IPC_MESSAGE_HANDLER(ChromeViewMsg_SetAsInterstitial, OnSetAsInterstitial)
204 IPC_MESSAGE_HANDLER(ChromeViewMsg_NPAPINotSupported, OnNPAPINotSupported)
205 IPC_MESSAGE_HANDLER(ChromeViewMsg_SetAllowDisplayingInsecureContent,
206 OnSetAllowDisplayingInsecureContent)
207 IPC_MESSAGE_HANDLER(ChromeViewMsg_SetAllowRunningInsecureContent,
208 OnSetAllowRunningInsecureContent)
209 IPC_MESSAGE_HANDLER(ChromeViewMsg_ReloadFrame, OnReloadFrame);
210 IPC_MESSAGE_UNHANDLED(handled = false)
211 IPC_END_MESSAGE_MAP()
212 if (handled)
213 return true;
215 // Don't swallow LoadBlockedPlugins messages, as they're sent to every
216 // blocked plugin.
217 IPC_BEGIN_MESSAGE_MAP(ContentSettingsObserver, message)
218 IPC_MESSAGE_HANDLER(ChromeViewMsg_LoadBlockedPlugins, OnLoadBlockedPlugins)
219 IPC_END_MESSAGE_MAP()
221 return false;
224 void ContentSettingsObserver::DidCommitProvisionalLoad(bool is_new_navigation) {
225 WebFrame* frame = render_frame()->GetWebFrame();
226 if (frame->parent())
227 return; // Not a top-level navigation.
229 DocumentState* document_state = DocumentState::FromDataSource(
230 frame->dataSource());
231 NavigationState* navigation_state = document_state->navigation_state();
232 if (!navigation_state->was_within_same_page()) {
233 // Clear "block" flags for the new page. This needs to happen before any of
234 // |allowScript()|, |allowScriptFromSource()|, |allowImage()|, or
235 // |allowPlugins()| is called for the new page so that these functions can
236 // correctly detect that a piece of content flipped from "not blocked" to
237 // "blocked".
238 ClearBlockedContentSettings();
239 temporarily_allowed_plugins_.clear();
242 GURL url = frame->document().url();
243 // If we start failing this DCHECK, please makes sure we don't regress
244 // this bug: http://code.google.com/p/chromium/issues/detail?id=79304
245 DCHECK(frame->document().securityOrigin().toString() == "null" ||
246 !url.SchemeIs(content::kDataScheme));
249 bool ContentSettingsObserver::allowDatabase(const WebString& name,
250 const WebString& display_name,
251 unsigned long estimated_size) {
252 WebFrame* frame = render_frame()->GetWebFrame();
253 if (frame->document().securityOrigin().isUnique() ||
254 frame->top()->document().securityOrigin().isUnique())
255 return false;
257 bool result = false;
258 Send(new ChromeViewHostMsg_AllowDatabase(
259 routing_id(), GURL(frame->document().securityOrigin().toString()),
260 GURL(frame->top()->document().securityOrigin().toString()),
261 name, display_name, &result));
262 return result;
265 bool ContentSettingsObserver::allowFileSystem() {
266 WebFrame* frame = render_frame()->GetWebFrame();
267 if (frame->document().securityOrigin().isUnique() ||
268 frame->top()->document().securityOrigin().isUnique())
269 return false;
271 bool result = false;
272 Send(new ChromeViewHostMsg_AllowFileSystem(
273 routing_id(), GURL(frame->document().securityOrigin().toString()),
274 GURL(frame->top()->document().securityOrigin().toString()), &result));
275 return result;
278 bool ContentSettingsObserver::allowImage(bool enabled_per_settings,
279 const WebURL& image_url) {
280 bool allow = enabled_per_settings;
281 if (enabled_per_settings) {
282 if (is_interstitial_page_)
283 return true;
285 WebFrame* frame = render_frame()->GetWebFrame();
286 if (IsWhitelistedForContentSettings(frame))
287 return true;
289 if (content_setting_rules_) {
290 GURL secondary_url(image_url);
291 allow = GetContentSettingFromRules(
292 content_setting_rules_->image_rules,
293 frame, secondary_url) != CONTENT_SETTING_BLOCK;
296 if (!allow)
297 DidBlockContentType(CONTENT_SETTINGS_TYPE_IMAGES);
298 return allow;
301 bool ContentSettingsObserver::allowIndexedDB(const WebString& name,
302 const WebSecurityOrigin& origin) {
303 WebFrame* frame = render_frame()->GetWebFrame();
304 if (frame->document().securityOrigin().isUnique() ||
305 frame->top()->document().securityOrigin().isUnique())
306 return false;
308 bool result = false;
309 Send(new ChromeViewHostMsg_AllowIndexedDB(
310 routing_id(), GURL(frame->document().securityOrigin().toString()),
311 GURL(frame->top()->document().securityOrigin().toString()),
312 name, &result));
313 return result;
316 bool ContentSettingsObserver::allowPlugins(bool enabled_per_settings) {
317 return enabled_per_settings;
320 bool ContentSettingsObserver::allowScript(bool enabled_per_settings) {
321 if (!enabled_per_settings)
322 return false;
323 if (is_interstitial_page_)
324 return true;
326 WebFrame* frame = render_frame()->GetWebFrame();
327 std::map<WebFrame*, bool>::const_iterator it =
328 cached_script_permissions_.find(frame);
329 if (it != cached_script_permissions_.end())
330 return it->second;
332 // Evaluate the content setting rules before
333 // |IsWhitelistedForContentSettings|; if there is only the default rule
334 // allowing all scripts, it's quicker this way.
335 bool allow = true;
336 if (content_setting_rules_) {
337 ContentSetting setting = GetContentSettingFromRules(
338 content_setting_rules_->script_rules,
339 frame,
340 GURL(frame->document().securityOrigin().toString()));
341 allow = setting != CONTENT_SETTING_BLOCK;
343 allow = allow || IsWhitelistedForContentSettings(frame);
345 cached_script_permissions_[frame] = allow;
346 return allow;
349 bool ContentSettingsObserver::allowScriptFromSource(
350 bool enabled_per_settings,
351 const blink::WebURL& script_url) {
352 if (!enabled_per_settings)
353 return false;
354 if (is_interstitial_page_)
355 return true;
357 bool allow = true;
358 WebFrame* frame = render_frame()->GetWebFrame();
359 if (content_setting_rules_) {
360 ContentSetting setting = GetContentSettingFromRules(
361 content_setting_rules_->script_rules,
362 frame,
363 GURL(script_url));
364 allow = setting != CONTENT_SETTING_BLOCK;
366 return allow || IsWhitelistedForContentSettings(frame);
369 bool ContentSettingsObserver::allowStorage(bool local) {
370 WebFrame* frame = render_frame()->GetWebFrame();
371 if (frame->document().securityOrigin().isUnique() ||
372 frame->top()->document().securityOrigin().isUnique())
373 return false;
374 bool result = false;
376 StoragePermissionsKey key(
377 GURL(frame->document().securityOrigin().toString()), local);
378 std::map<StoragePermissionsKey, bool>::const_iterator permissions =
379 cached_storage_permissions_.find(key);
380 if (permissions != cached_storage_permissions_.end())
381 return permissions->second;
383 Send(new ChromeViewHostMsg_AllowDOMStorage(
384 routing_id(), GURL(frame->document().securityOrigin().toString()),
385 GURL(frame->top()->document().securityOrigin().toString()),
386 local, &result));
387 cached_storage_permissions_[key] = result;
388 return result;
391 bool ContentSettingsObserver::allowReadFromClipboard(bool default_value) {
392 bool allowed = false;
393 WebFrame* frame = render_frame()->GetWebFrame();
394 // TODO(dcheng): Should we consider a toURL() method on WebSecurityOrigin?
395 Send(new ChromeViewHostMsg_CanTriggerClipboardRead(
396 GURL(frame->document().securityOrigin().toString()), &allowed));
397 return allowed;
400 bool ContentSettingsObserver::allowWriteToClipboard(bool default_value) {
401 bool allowed = false;
402 WebFrame* frame = render_frame()->GetWebFrame();
403 Send(new ChromeViewHostMsg_CanTriggerClipboardWrite(
404 GURL(frame->document().securityOrigin().toString()), &allowed));
405 return allowed;
408 bool ContentSettingsObserver::allowWebComponents(bool default_value) {
409 if (default_value)
410 return true;
412 WebFrame* frame = render_frame()->GetWebFrame();
413 WebSecurityOrigin origin = frame->document().securityOrigin();
414 if (EqualsASCII(origin.protocol(), content::kChromeUIScheme))
415 return true;
417 if (const extensions::Extension* extension = GetExtension(origin)) {
418 if (extension->HasAPIPermission(APIPermission::kExperimental))
419 return true;
422 return false;
425 bool ContentSettingsObserver::allowMutationEvents(bool default_value) {
426 WebFrame* frame = render_frame()->GetWebFrame();
427 WebSecurityOrigin origin = frame->document().securityOrigin();
428 const extensions::Extension* extension = GetExtension(origin);
429 if (extension && extension->is_platform_app())
430 return false;
431 return default_value;
434 bool ContentSettingsObserver::allowPushState() {
435 WebFrame* frame = render_frame()->GetWebFrame();
436 WebSecurityOrigin origin = frame->document().securityOrigin();
437 const extensions::Extension* extension = GetExtension(origin);
438 return !extension || !extension->is_platform_app();
441 static void SendInsecureContentSignal(int signal) {
442 UMA_HISTOGRAM_ENUMERATION("SSL.InsecureContent", signal,
443 INSECURE_CONTENT_NUM_EVENTS);
446 bool ContentSettingsObserver::allowDisplayingInsecureContent(
447 bool allowed_per_settings,
448 const blink::WebSecurityOrigin& origin,
449 const blink::WebURL& resource_url) {
450 SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY);
452 std::string origin_host(origin.host().utf8());
453 WebFrame* frame = render_frame()->GetWebFrame();
454 GURL frame_gurl(frame->document().url());
455 if (IsHostInDomain(origin_host, kGoogleDotCom)) {
456 SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_GOOGLE);
457 if (StartsWithASCII(frame_gurl.path(), kGoogleSupportPathPrefix, false)) {
458 SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_GOOGLE_SUPPORT);
459 } else if (StartsWithASCII(frame_gurl.path(),
460 kGoogleIntlPathPrefix,
461 false)) {
462 SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_GOOGLE_INTL);
466 if (origin_host == kWWWDotGoogleDotCom) {
467 SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_WWW_GOOGLE);
468 if (StartsWithASCII(frame_gurl.path(), kGoogleReaderPathPrefix, false))
469 SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_GOOGLE_READER);
470 } else if (origin_host == kMailDotGoogleDotCom) {
471 SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_MAIL_GOOGLE);
472 } else if (origin_host == kPlusDotGoogleDotCom) {
473 SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_PLUS_GOOGLE);
474 } else if (origin_host == kDocsDotGoogleDotCom) {
475 SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_DOCS_GOOGLE);
476 } else if (origin_host == kSitesDotGoogleDotCom) {
477 SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_SITES_GOOGLE);
478 } else if (origin_host == kPicasawebDotGoogleDotCom) {
479 SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_PICASAWEB_GOOGLE);
480 } else if (origin_host == kCodeDotGoogleDotCom) {
481 SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_CODE_GOOGLE);
482 } else if (origin_host == kGroupsDotGoogleDotCom) {
483 SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_GROUPS_GOOGLE);
484 } else if (origin_host == kMapsDotGoogleDotCom) {
485 SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_MAPS_GOOGLE);
486 } else if (origin_host == kWWWDotYoutubeDotCom) {
487 SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_YOUTUBE);
490 GURL resource_gurl(resource_url);
491 if (EndsWith(resource_gurl.path(), kDotHTML, false))
492 SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HTML);
494 if (allowed_per_settings || allow_displaying_insecure_content_)
495 return true;
497 Send(new ChromeViewHostMsg_DidBlockDisplayingInsecureContent(routing_id()));
499 return false;
502 bool ContentSettingsObserver::allowRunningInsecureContent(
503 bool allowed_per_settings,
504 const blink::WebSecurityOrigin& origin,
505 const blink::WebURL& resource_url) {
506 std::string origin_host(origin.host().utf8());
507 WebFrame* frame = render_frame()->GetWebFrame();
508 GURL frame_gurl(frame->document().url());
509 DCHECK_EQ(frame_gurl.host(), origin_host);
511 bool is_google = IsHostInDomain(origin_host, kGoogleDotCom);
512 if (is_google) {
513 SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_GOOGLE);
514 if (StartsWithASCII(frame_gurl.path(), kGoogleSupportPathPrefix, false)) {
515 SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_GOOGLE_SUPPORT);
516 } else if (StartsWithASCII(frame_gurl.path(),
517 kGoogleIntlPathPrefix,
518 false)) {
519 SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_GOOGLE_INTL);
523 if (origin_host == kWWWDotGoogleDotCom) {
524 SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_WWW_GOOGLE);
525 if (StartsWithASCII(frame_gurl.path(), kGoogleReaderPathPrefix, false))
526 SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_GOOGLE_READER);
527 } else if (origin_host == kMailDotGoogleDotCom) {
528 SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_MAIL_GOOGLE);
529 } else if (origin_host == kPlusDotGoogleDotCom) {
530 SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_PLUS_GOOGLE);
531 } else if (origin_host == kDocsDotGoogleDotCom) {
532 SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_DOCS_GOOGLE);
533 } else if (origin_host == kSitesDotGoogleDotCom) {
534 SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_SITES_GOOGLE);
535 } else if (origin_host == kPicasawebDotGoogleDotCom) {
536 SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_PICASAWEB_GOOGLE);
537 } else if (origin_host == kCodeDotGoogleDotCom) {
538 SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_CODE_GOOGLE);
539 } else if (origin_host == kGroupsDotGoogleDotCom) {
540 SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_GROUPS_GOOGLE);
541 } else if (origin_host == kMapsDotGoogleDotCom) {
542 SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_MAPS_GOOGLE);
543 } else if (origin_host == kWWWDotYoutubeDotCom) {
544 SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_YOUTUBE);
545 } else if (EndsWith(origin_host, kDotGoogleUserContentDotCom, false)) {
546 SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_GOOGLEUSERCONTENT);
549 GURL resource_gurl(resource_url);
550 if (resource_gurl.host() == kWWWDotYoutubeDotCom)
551 SendInsecureContentSignal(INSECURE_CONTENT_RUN_TARGET_YOUTUBE);
553 if (EndsWith(resource_gurl.path(), kDotJS, false))
554 SendInsecureContentSignal(INSECURE_CONTENT_RUN_JS);
555 else if (EndsWith(resource_gurl.path(), kDotCSS, false))
556 SendInsecureContentSignal(INSECURE_CONTENT_RUN_CSS);
557 else if (EndsWith(resource_gurl.path(), kDotSWF, false))
558 SendInsecureContentSignal(INSECURE_CONTENT_RUN_SWF);
560 if (!allow_running_insecure_content_ && !allowed_per_settings) {
561 DidBlockContentType(CONTENT_SETTINGS_TYPE_MIXEDSCRIPT);
562 return false;
565 return true;
568 void ContentSettingsObserver::didNotAllowPlugins() {
569 DidBlockContentType(CONTENT_SETTINGS_TYPE_PLUGINS);
572 void ContentSettingsObserver::didNotAllowScript() {
573 DidBlockContentType(CONTENT_SETTINGS_TYPE_JAVASCRIPT);
576 bool ContentSettingsObserver::AreNPAPIPluginsBlocked() const {
577 return npapi_plugins_blocked_;
580 void ContentSettingsObserver::OnLoadBlockedPlugins(
581 const std::string& identifier) {
582 temporarily_allowed_plugins_.insert(identifier);
585 void ContentSettingsObserver::OnSetAsInterstitial() {
586 is_interstitial_page_ = true;
589 void ContentSettingsObserver::OnNPAPINotSupported() {
590 npapi_plugins_blocked_ = true;
593 void ContentSettingsObserver::OnSetAllowDisplayingInsecureContent(bool allow) {
594 allow_displaying_insecure_content_ = allow;
597 void ContentSettingsObserver::OnSetAllowRunningInsecureContent(bool allow) {
598 allow_running_insecure_content_ = allow;
599 OnSetAllowDisplayingInsecureContent(allow);
602 void ContentSettingsObserver::OnReloadFrame() {
603 DCHECK(!render_frame()->GetWebFrame()->parent()) <<
604 "Should only be called on the main frame";
605 render_frame()->GetWebFrame()->reload();
608 void ContentSettingsObserver::ClearBlockedContentSettings() {
609 for (size_t i = 0; i < arraysize(content_blocked_); ++i)
610 content_blocked_[i] = false;
611 cached_storage_permissions_.clear();
612 cached_script_permissions_.clear();
615 const extensions::Extension* ContentSettingsObserver::GetExtension(
616 const WebSecurityOrigin& origin) const {
617 if (!EqualsASCII(origin.protocol(), extensions::kExtensionScheme))
618 return NULL;
620 const std::string extension_id = origin.host().utf8().data();
621 if (!extension_dispatcher_->IsExtensionActive(extension_id))
622 return NULL;
624 return extension_dispatcher_->extensions()->GetByID(extension_id);
627 bool ContentSettingsObserver::IsWhitelistedForContentSettings(WebFrame* frame) {
628 // Whitelist Instant processes.
629 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kInstantProcess))
630 return true;
632 // Whitelist ftp directory listings, as they require JavaScript to function
633 // properly.
634 webkit_glue::WebURLResponseExtraDataImpl* extra_data =
635 static_cast<webkit_glue::WebURLResponseExtraDataImpl*>(
636 frame->dataSource()->response().extraData());
637 if (extra_data && extra_data->is_ftp_directory_listing())
638 return true;
639 return IsWhitelistedForContentSettings(frame->document().securityOrigin(),
640 frame->document().url());
643 bool ContentSettingsObserver::IsWhitelistedForContentSettings(
644 const WebSecurityOrigin& origin,
645 const GURL& document_url) {
646 if (document_url == GURL(content::kUnreachableWebDataURL))
647 return true;
649 if (origin.isUnique())
650 return false; // Uninitialized document?
652 if (EqualsASCII(origin.protocol(), content::kChromeUIScheme))
653 return true; // Browser UI elements should still work.
655 if (EqualsASCII(origin.protocol(), content::kChromeDevToolsScheme))
656 return true; // DevTools UI elements should still work.
658 if (EqualsASCII(origin.protocol(), extensions::kExtensionScheme))
659 return true;
661 // TODO(creis, fsamuel): Remove this once the concept of swapped out
662 // RenderFrames goes away.
663 if (document_url == GURL(content::kSwappedOutURL))
664 return true;
666 // If the scheme is file:, an empty file name indicates a directory listing,
667 // which requires JavaScript to function properly.
668 if (EqualsASCII(origin.protocol(), content::kFileScheme)) {
669 return document_url.SchemeIs(content::kFileScheme) &&
670 document_url.ExtractFileName().empty();
673 return false;