content_settings_utils.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
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.
4
5#include "chrome/browser/content_settings/content_settings_utils.h"
6
7#include <vector>
8
9#include "base/command_line.h"
10#include "base/logging.h"
11#include "base/memory/scoped_ptr.h"
12#include "base/memory/scoped_vector.h"
13#include "base/string_split.h"
14#include "base/values.h"
15#include "chrome/browser/content_settings/content_settings_provider.h"
16#include "chrome/browser/content_settings/content_settings_rule.h"
17#include "chrome/browser/content_settings/host_content_settings_map.h"
18#include "chrome/common/chrome_switches.h"
19#include "chrome/common/content_settings_pattern.h"
20#include "googleurl/src/gurl.h"
21
22namespace {
23
24// The names of the ContentSettingsType values, for use with dictionary prefs.
25const char* kTypeNames[] = {
26  "cookies",
27  "images",
28  "javascript",
29  "plugins",
30  "popups",
31  "geolocation",
32  "notifications",
33  "intents",
34  "auto-select-certificate",
35  "fullscreen",
36  "mouselock",
37  "mixed-script",
38  "media-stream",
39  "register-protocol-handler",
40  "ppapi-broker",
41};
42COMPILE_ASSERT(arraysize(kTypeNames) == CONTENT_SETTINGS_NUM_TYPES,
43               type_names_incorrect_size);
44
45const char kPatternSeparator[] = ",";
46
47}  // namespace
48
49namespace content_settings {
50
51std::string GetTypeName(ContentSettingsType type) {
52  return std::string(kTypeNames[type]);
53}
54
55std::string CreatePatternString(
56    const ContentSettingsPattern& item_pattern,
57    const ContentSettingsPattern& top_level_frame_pattern) {
58  return item_pattern.ToString()
59         + std::string(kPatternSeparator)
60         + top_level_frame_pattern.ToString();
61}
62
63PatternPair ParsePatternString(const std::string& pattern_str) {
64  std::vector<std::string> pattern_str_list;
65  base::SplitString(pattern_str, kPatternSeparator[0], &pattern_str_list);
66
67  // If the |pattern_str| is an empty string then the |pattern_string_list|
68  // contains a single empty string. In this case the empty string will be
69  // removed to signal an invalid |pattern_str|. Invalid pattern strings are
70  // handle by the "if"-statment below. So the order of the if statements here
71  // must be preserved.
72  if (pattern_str_list.size() == 1) {
73    if (pattern_str_list[0].empty()) {
74      pattern_str_list.pop_back();
75    } else {
76      pattern_str_list.push_back("*");
77    }
78  }
79
80  if (pattern_str_list.size() > 2 ||
81      pattern_str_list.size() == 0) {
82    return PatternPair(ContentSettingsPattern(),
83                       ContentSettingsPattern());
84  }
85
86  PatternPair pattern_pair;
87  pattern_pair.first =
88      ContentSettingsPattern::FromString(pattern_str_list[0]);
89  pattern_pair.second =
90      ContentSettingsPattern::FromString(pattern_str_list[1]);
91  return pattern_pair;
92}
93
94ContentSetting ValueToContentSetting(const base::Value* value) {
95  ContentSetting setting = CONTENT_SETTING_DEFAULT;
96  bool valid = ParseContentSettingValue(value, &setting);
97  DCHECK(valid);
98  return setting;
99}
100
101bool ParseContentSettingValue(const base::Value* value,
102                              ContentSetting* setting) {
103  if (!value) {
104    *setting = CONTENT_SETTING_DEFAULT;
105    return true;
106  }
107  int int_value = -1;
108  if (!value->GetAsInteger(&int_value))
109    return false;
110  *setting = IntToContentSetting(int_value);
111  return *setting != CONTENT_SETTING_DEFAULT;
112}
113
114base::Value* GetContentSettingValueAndPatterns(
115    const ProviderInterface* provider,
116    const GURL& primary_url,
117    const GURL& secondary_url,
118    ContentSettingsType content_type,
119    const std::string& resource_identifier,
120    bool include_incognito,
121    ContentSettingsPattern* primary_pattern,
122    ContentSettingsPattern* secondary_pattern) {
123  if (include_incognito) {
124    // Check incognito-only specific settings. It's essential that the
125    // |RuleIterator| gets out of scope before we get a rule iterator for the
126    // normal mode.
127    scoped_ptr<RuleIterator> incognito_rule_iterator(
128        provider->GetRuleIterator(content_type, resource_identifier, true));
129    base::Value* value = GetContentSettingValueAndPatterns(
130        incognito_rule_iterator.get(), primary_url, secondary_url,
131        primary_pattern, secondary_pattern);
132    if (value)
133      return value;
134  }
135  // No settings from the incognito; use the normal mode.
136  scoped_ptr<RuleIterator> rule_iterator(
137      provider->GetRuleIterator(content_type, resource_identifier, false));
138  return GetContentSettingValueAndPatterns(
139      rule_iterator.get(), primary_url, secondary_url,
140      primary_pattern, secondary_pattern);
141}
142
143base::Value* GetContentSettingValueAndPatterns(
144    RuleIterator* rule_iterator,
145    const GURL& primary_url,
146    const GURL& secondary_url,
147    ContentSettingsPattern* primary_pattern,
148    ContentSettingsPattern* secondary_pattern) {
149  while (rule_iterator->HasNext()) {
150    const Rule& rule = rule_iterator->Next();
151    if (rule.primary_pattern.Matches(primary_url) &&
152        rule.secondary_pattern.Matches(secondary_url)) {
153      if (primary_pattern)
154        *primary_pattern = rule.primary_pattern;
155      if (secondary_pattern)
156        *secondary_pattern = rule.secondary_pattern;
157      return rule.value.get()->DeepCopy();
158    }
159  }
160  return NULL;
161}
162
163base::Value* GetContentSettingValue(const ProviderInterface* provider,
164                                    const GURL& primary_url,
165                                    const GURL& secondary_url,
166                                    ContentSettingsType content_type,
167                                    const std::string& resource_identifier,
168                                    bool include_incognito) {
169  return GetContentSettingValueAndPatterns(provider, primary_url, secondary_url,
170                               content_type, resource_identifier,
171                               include_incognito, NULL, NULL);
172}
173
174ContentSetting GetContentSetting(const ProviderInterface* provider,
175                                 const GURL& primary_url,
176                                 const GURL& secondary_url,
177                                 ContentSettingsType content_type,
178                                 const std::string& resource_identifier,
179                                 bool include_incognito) {
180  scoped_ptr<base::Value> value(
181      GetContentSettingValue(provider, primary_url, secondary_url,
182                             content_type, resource_identifier,
183                             include_incognito));
184  return ValueToContentSetting(value.get());
185}
186
187void GetRendererContentSettingRules(const HostContentSettingsMap* map,
188                                    RendererContentSettingRules* rules) {
189  map->GetSettingsForOneType(CONTENT_SETTINGS_TYPE_IMAGES, "",
190                             &(rules->image_rules));
191  map->GetSettingsForOneType(CONTENT_SETTINGS_TYPE_JAVASCRIPT, "",
192                             &(rules->script_rules));
193}
194
195}  // namespace content_settings
196