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