Home | History | Annotate | Download | only in content_settings
      1 // Copyright (c) 2011 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_pattern.h"
      6 
      7 #include "base/string_util.h"
      8 #include "chrome/common/url_constants.h"
      9 #include "net/base/net_util.h"
     10 #include "googleurl/src/gurl.h"
     11 #include "googleurl/src/url_canon.h"
     12 
     13 namespace {
     14 
     15 bool IsValidHostlessPattern(const std::string& pattern) {
     16   std::string file_scheme_plus_separator(chrome::kFileScheme);
     17   file_scheme_plus_separator += chrome::kStandardSchemeSeparator;
     18 
     19   return StartsWithASCII(pattern, file_scheme_plus_separator, false);
     20 }
     21 
     22 }  // namespace
     23 
     24 // The version of the pattern format implemented. Version 1 includes the
     25 // following patterns:
     26 //   - [*.]domain.tld (matches domain.tld and all sub-domains)
     27 //   - host (matches an exact hostname)
     28 //   - a.b.c.d (matches an exact IPv4 ip)
     29 //   - [a:b:c:d:e:f:g:h] (matches an exact IPv6 ip)
     30 //   - file:///tmp/test.html (a complete URL without a host)
     31 // Version 2 adds a resource identifier for plugins.
     32 // TODO(jochen): update once this feature is no longer behind a flag.
     33 const int ContentSettingsPattern::kContentSettingsPatternVersion = 1;
     34 const char* ContentSettingsPattern::kDomainWildcard = "[*.]";
     35 const size_t ContentSettingsPattern::kDomainWildcardLength = 4;
     36 
     37 // static
     38 ContentSettingsPattern ContentSettingsPattern::FromURL(
     39     const GURL& url) {
     40   // TODO(markusheintz): Add scheme wildcard;
     41   return ContentSettingsPattern(!url.has_host() || url.HostIsIPAddress() ?
     42       net::GetHostOrSpecFromURL(url) :
     43       std::string(kDomainWildcard) + url.host());
     44 }
     45 
     46 // static
     47 ContentSettingsPattern ContentSettingsPattern::FromURLNoWildcard(
     48     const GURL& url) {
     49   return ContentSettingsPattern(net::GetHostOrSpecFromURL(url), url.scheme());
     50 }
     51 
     52 bool ContentSettingsPattern::IsValid() const {
     53   if (pattern_.empty())
     54     return false;
     55 
     56   if (IsValidHostlessPattern(pattern_))
     57     return true;
     58 
     59   const std::string host(pattern_.length() > kDomainWildcardLength &&
     60                          StartsWithASCII(pattern_, kDomainWildcard, false) ?
     61                          pattern_.substr(kDomainWildcardLength) :
     62                          pattern_);
     63   url_canon::CanonHostInfo host_info;
     64   return host.find('*') == std::string::npos &&
     65          !net::CanonicalizeHost(host, &host_info).empty();
     66 }
     67 
     68 bool ContentSettingsPattern::Matches(const GURL& url) const {
     69   if (!IsValid())
     70     return false;
     71 
     72   const std::string host(net::GetHostOrSpecFromURL(url));
     73   if (pattern_.length() < kDomainWildcardLength ||
     74       !StartsWithASCII(pattern_, kDomainWildcard, false))
     75     return pattern_ == host;
     76 
     77   const size_t match =
     78       host.rfind(pattern_.substr(kDomainWildcardLength));
     79 
     80   return (match != std::string::npos) &&
     81          (match == 0 || host[match - 1] == '.') &&
     82          (match + pattern_.length() - kDomainWildcardLength == host.length());
     83 }
     84 
     85 std::string ContentSettingsPattern::CanonicalizePattern() const {
     86   if (!IsValid())
     87     return "";
     88 
     89   if (IsValidHostlessPattern(pattern_))
     90     return GURL(pattern_).spec();
     91 
     92   bool starts_with_wildcard = pattern_.length() > kDomainWildcardLength &&
     93       StartsWithASCII(pattern_, kDomainWildcard, false);
     94 
     95   const std::string host(starts_with_wildcard ?
     96       pattern_.substr(kDomainWildcardLength) : pattern_);
     97 
     98   std::string canonicalized_pattern =
     99       starts_with_wildcard ? kDomainWildcard : "";
    100 
    101   url_canon::CanonHostInfo host_info;
    102   canonicalized_pattern += net::CanonicalizeHost(host, &host_info);
    103 
    104   return canonicalized_pattern;
    105 }
    106