1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Use of this source code is governed by a BSD-style license that can be 321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// found in the LICENSE file. 421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/content_settings/content_settings_pattern.h" 621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "base/string_util.h" 8dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/common/url_constants.h" 921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "net/base/net_util.h" 1021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "googleurl/src/gurl.h" 1121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "googleurl/src/url_canon.h" 1221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 13dc0f95d653279beabeb9817299e2902918ba123eKristian Monsennamespace { 14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 15dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool IsValidHostlessPattern(const std::string& pattern) { 16dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::string file_scheme_plus_separator(chrome::kFileScheme); 17dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen file_scheme_plus_separator += chrome::kStandardSchemeSeparator; 18dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 19dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return StartsWithASCII(pattern, file_scheme_plus_separator, false); 20dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 22dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} // namespace 23dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 2421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// The version of the pattern format implemented. Version 1 includes the 2521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// following patterns: 2621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// - [*.]domain.tld (matches domain.tld and all sub-domains) 2721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// - host (matches an exact hostname) 2821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// - a.b.c.d (matches an exact IPv4 ip) 2921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// - [a:b:c:d:e:f:g:h] (matches an exact IPv6 ip) 3021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// - file:///tmp/test.html (a complete URL without a host) 3121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Version 2 adds a resource identifier for plugins. 3221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// TODO(jochen): update once this feature is no longer behind a flag. 3321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenconst int ContentSettingsPattern::kContentSettingsPatternVersion = 1; 3421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenconst char* ContentSettingsPattern::kDomainWildcard = "[*.]"; 3521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenconst size_t ContentSettingsPattern::kDomainWildcardLength = 4; 3621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 3721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// static 3821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenContentSettingsPattern ContentSettingsPattern::FromURL( 3921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const GURL& url) { 40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // TODO(markusheintz): Add scheme wildcard; 4121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return ContentSettingsPattern(!url.has_host() || url.HostIsIPAddress() ? 4221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net::GetHostOrSpecFromURL(url) : 4321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen std::string(kDomainWildcard) + url.host()); 4421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 4521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 4621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// static 4721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenContentSettingsPattern ContentSettingsPattern::FromURLNoWildcard( 4821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const GURL& url) { 49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return ContentSettingsPattern(net::GetHostOrSpecFromURL(url), url.scheme()); 5021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 5121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 5221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool ContentSettingsPattern::IsValid() const { 5321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (pattern_.empty()) 5421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return false; 5521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 56dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (IsValidHostlessPattern(pattern_)) 57dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return true; 58dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 5921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const std::string host(pattern_.length() > kDomainWildcardLength && 6021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen StartsWithASCII(pattern_, kDomainWildcard, false) ? 6121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen pattern_.substr(kDomainWildcardLength) : 6221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen pattern_); 6321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen url_canon::CanonHostInfo host_info; 6421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return host.find('*') == std::string::npos && 6521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen !net::CanonicalizeHost(host, &host_info).empty(); 6621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 6721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 6821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool ContentSettingsPattern::Matches(const GURL& url) const { 6921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (!IsValid()) 7021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return false; 7121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 7221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const std::string host(net::GetHostOrSpecFromURL(url)); 7321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (pattern_.length() < kDomainWildcardLength || 7421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen !StartsWithASCII(pattern_, kDomainWildcard, false)) 7521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return pattern_ == host; 7621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 7721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const size_t match = 7821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen host.rfind(pattern_.substr(kDomainWildcardLength)); 7921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 8021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return (match != std::string::npos) && 8121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen (match == 0 || host[match - 1] == '.') && 8221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen (match + pattern_.length() - kDomainWildcardLength == host.length()); 8321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 8421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 8521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenstd::string ContentSettingsPattern::CanonicalizePattern() const { 86dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!IsValid()) 8721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return ""; 88dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 89dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (IsValidHostlessPattern(pattern_)) 90dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return GURL(pattern_).spec(); 9121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 9221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen bool starts_with_wildcard = pattern_.length() > kDomainWildcardLength && 9321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen StartsWithASCII(pattern_, kDomainWildcard, false); 9421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 9521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const std::string host(starts_with_wildcard ? 9621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen pattern_.substr(kDomainWildcardLength) : pattern_); 9721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 9821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen std::string canonicalized_pattern = 9921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen starts_with_wildcard ? kDomainWildcard : ""; 10021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 10121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen url_canon::CanonHostInfo host_info; 10221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen canonicalized_pattern += net::CanonicalizeHost(host, &host_info); 10321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 10421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return canonicalized_pattern; 10521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 106