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