Home | History | Annotate | Download | only in content_settings
      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/extensions/api/content_settings/content_settings_helpers.h"
      6 
      7 #include "base/basictypes.h"
      8 #include "base/logging.h"
      9 #include "base/memory/scoped_ptr.h"
     10 #include "content/public/common/url_constants.h"
     11 #include "extensions/common/url_pattern.h"
     12 
     13 namespace {
     14 
     15 const char kNoPathWildcardsError[] =
     16     "Path wildcards in file URL patterns are not allowed.";
     17 const char kNoPathsError[] = "Specific paths are not allowed.";
     18 const char kInvalidPatternError[] = "The pattern \"*\" is invalid.";
     19 
     20 const char* const kContentSettingsTypeNames[] = {
     21   "cookies",
     22   "images",
     23   "javascript",
     24   "plugins",
     25   "popups",
     26   "location",
     27   "notifications",
     28 };
     29 COMPILE_ASSERT(arraysize(kContentSettingsTypeNames) <=
     30                CONTENT_SETTINGS_NUM_TYPES,
     31                content_settings_type_names_size_invalid);
     32 
     33 const char* const kContentSettingNames[] = {
     34   "default",
     35   "allow",
     36   "block",
     37   "ask",
     38   "session_only",
     39 };
     40 COMPILE_ASSERT(arraysize(kContentSettingNames) <=
     41                CONTENT_SETTING_NUM_SETTINGS,
     42                content_setting_names_size_invalid);
     43 
     44 // TODO(bauerb): Move this someplace where it can be reused.
     45 std::string GetDefaultPort(const std::string& scheme) {
     46   if (scheme == content::kHttpScheme)
     47     return "80";
     48   if (scheme == content::kHttpsScheme)
     49     return "443";
     50   NOTREACHED();
     51   return std::string();
     52 }
     53 
     54 }  // namespace
     55 
     56 namespace extensions {
     57 namespace content_settings_helpers {
     58 
     59 ContentSettingsPattern ParseExtensionPattern(const std::string& pattern_str,
     60                                              std::string* error) {
     61   const int kAllowedSchemes =
     62       URLPattern::SCHEME_HTTP | URLPattern::SCHEME_HTTPS |
     63       URLPattern::SCHEME_FILE;
     64   URLPattern url_pattern(kAllowedSchemes);
     65   URLPattern::ParseResult result = url_pattern.Parse(pattern_str);
     66   if (result != URLPattern::PARSE_SUCCESS) {
     67     *error = URLPattern::GetParseResultString(result);
     68     return ContentSettingsPattern();
     69   } else {
     70     scoped_ptr<ContentSettingsPattern::BuilderInterface> builder(
     71         ContentSettingsPattern::CreateBuilder(false));
     72     builder->WithHost(url_pattern.host());
     73     if (url_pattern.match_subdomains())
     74       builder->WithDomainWildcard();
     75 
     76     std::string scheme = url_pattern.scheme();
     77     if (scheme == "*")
     78       builder->WithSchemeWildcard();
     79     else
     80       builder->WithScheme(scheme);
     81 
     82     std::string port = url_pattern.port();
     83     if (port.empty() && scheme != "file") {
     84       if (scheme == "*")
     85         port = "*";
     86       else
     87         port = GetDefaultPort(scheme);
     88     }
     89     if (port == "*")
     90       builder->WithPortWildcard();
     91     else
     92       builder->WithPort(port);
     93 
     94     std::string path = url_pattern.path();
     95     if (scheme == "file") {
     96       // For file URLs we allow only exact path matches.
     97       if (path.find_first_of("*?") != std::string::npos) {
     98         *error = kNoPathWildcardsError;
     99         return ContentSettingsPattern();
    100       } else {
    101         builder->WithPath(path);
    102       }
    103     } else if (path != "/*") {
    104       // For other URLs we allow only paths which match everything.
    105       *error = kNoPathsError;
    106       return ContentSettingsPattern();
    107     }
    108 
    109     ContentSettingsPattern pattern = builder->Build();
    110     if (!pattern.IsValid())
    111       *error = kInvalidPatternError;
    112     return pattern;
    113   }
    114 }
    115 
    116 ContentSettingsType StringToContentSettingsType(
    117     const std::string& content_type) {
    118   for (size_t type = 0; type < arraysize(kContentSettingsTypeNames); ++type) {
    119     if (content_type == kContentSettingsTypeNames[type])
    120       return static_cast<ContentSettingsType>(type);
    121   }
    122   return CONTENT_SETTINGS_TYPE_DEFAULT;
    123 }
    124 
    125 const char* ContentSettingsTypeToString(ContentSettingsType type) {
    126   size_t index = static_cast<size_t>(type);
    127   DCHECK_LT(index, arraysize(kContentSettingsTypeNames));
    128   return kContentSettingsTypeNames[index];
    129 }
    130 
    131 bool StringToContentSetting(const std::string& setting_str,
    132                             ContentSetting* setting) {
    133   for (size_t type = 0; type < arraysize(kContentSettingNames); ++type) {
    134     if (setting_str == kContentSettingNames[type]) {
    135       *setting = static_cast<ContentSetting>(type);
    136       return true;
    137     }
    138   }
    139   return false;
    140 }
    141 
    142 const char* ContentSettingToString(ContentSetting setting) {
    143   size_t index = static_cast<size_t>(setting);
    144   DCHECK_LT(index, arraysize(kContentSettingNames));
    145   return kContentSettingNames[index];
    146 }
    147 
    148 }  // namespace content_settings_helpers
    149 }  // namespace extensions
    150