Home | History | Annotate | Download | only in common
      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 // Patterns used in content setting rules.
      6 
      7 #ifndef CHROME_COMMON_CONTENT_SETTINGS_PATTERN_H_
      8 #define CHROME_COMMON_CONTENT_SETTINGS_PATTERN_H_
      9 
     10 #include <ostream>
     11 #include <string>
     12 
     13 #include "base/basictypes.h"
     14 #include "base/compiler_specific.h"
     15 #include "base/gtest_prod_util.h"
     16 
     17 class GURL;
     18 class Pickle;
     19 class PickleIterator;
     20 
     21 namespace content_settings {
     22 class PatternParser;
     23 }
     24 
     25 namespace IPC {
     26 class Message;
     27 }
     28 
     29 // A pattern used in content setting rules. See |IsValid| for a description of
     30 // possible patterns.
     31 class ContentSettingsPattern {
     32  public:
     33   // Each content settings pattern describes a set of origins. Patterns, and the
     34   // sets they describe, have specific relations. |Relation| describes the
     35   // relation of two patterns A and B. When pattern A is compared with pattern B
     36   // (A compare B) interesting relations are:
     37   // - IDENTITY:
     38   //   Pattern A and B are identical. The patterns are equal.
     39   //
     40   // - DISJOINT_ORDER_PRE:
     41   //   Pattern A and B have no intersection. A and B never match the origin of
     42   //   a URL at the same time. But pattern A has a higher precedence than
     43   //   pattern B when patterns are sorted.
     44   //
     45   // - DISJOINT_ORDER_POST:
     46   //   Pattern A and B have no intersection. A and B never match the origin of
     47   //   a URL at the same time. But pattern A has a lower precedence than
     48   //   pattern B when patterns are sorted.
     49   //
     50   // - SUCCESSOR:
     51   //   Pattern A and B have an intersection. But pattern B has a higher
     52   //   precedence than pattern A for URLs that are matched by both pattern.
     53   //
     54   // - PREDECESSOR:
     55   //   Pattern A and B have an intersection. But pattern A has a higher
     56   //   precedence than pattern B for URLs that are matched by both pattern.
     57   enum Relation {
     58     DISJOINT_ORDER_POST = -2,
     59     SUCCESSOR = -1,
     60     IDENTITY = 0,
     61     PREDECESSOR = 1,
     62     DISJOINT_ORDER_PRE = 2,
     63   };
     64 
     65   struct PatternParts {
     66     PatternParts();
     67     ~PatternParts();
     68 
     69     // Lowercase string of the URL scheme to match. This string is empty if the
     70     // |is_scheme_wildcard| flag is set.
     71     std::string scheme;
     72 
     73     // True if the scheme wildcard is set.
     74     bool is_scheme_wildcard;
     75 
     76     // Normalized string that is either of the following:
     77     // - IPv4 or IPv6
     78     // - hostname
     79     // - domain
     80     // - empty string if the |is_host_wildcard flag is set.
     81     std::string host;
     82 
     83     // True if the domain wildcard is set.
     84     bool has_domain_wildcard;
     85 
     86     // String with the port to match. This string is empty if the
     87     // |is_port_wildcard| flag is set.
     88     std::string port;
     89 
     90     // True if the port wildcard is set.
     91     bool is_port_wildcard;
     92 
     93     // TODO(markusheintz): Needed for legacy reasons. Remove. Path
     94     // specification. Only used for content settings pattern with a "file"
     95     // scheme part.
     96     std::string path;
     97 
     98     // True if the path wildcard is set.
     99     bool is_path_wildcard;
    100   };
    101 
    102   class BuilderInterface {
    103    public:
    104     virtual ~BuilderInterface() {}
    105 
    106     virtual BuilderInterface* WithPort(const std::string& port) = 0;
    107 
    108     virtual BuilderInterface* WithPortWildcard() = 0;
    109 
    110     virtual BuilderInterface* WithHost(const std::string& host) = 0;
    111 
    112     virtual BuilderInterface* WithDomainWildcard() = 0;
    113 
    114     virtual BuilderInterface* WithScheme(const std::string& scheme) = 0;
    115 
    116     virtual BuilderInterface* WithSchemeWildcard() = 0;
    117 
    118     virtual BuilderInterface* WithPath(const std::string& path) = 0;
    119 
    120     virtual BuilderInterface* WithPathWildcard() = 0;
    121 
    122     virtual BuilderInterface* Invalid() = 0;
    123 
    124     // Returns a content settings pattern according to the current configuration
    125     // of the builder.
    126     virtual ContentSettingsPattern Build() = 0;
    127   };
    128 
    129   static BuilderInterface* CreateBuilder(bool use_legacy_validate);
    130 
    131   // The version of the pattern format implemented.
    132   static const int kContentSettingsPatternVersion;
    133 
    134   // The format of a domain wildcard.
    135   static const char* kDomainWildcard;
    136 
    137   // The length of kDomainWildcard (without the trailing '\0').
    138   static const size_t kDomainWildcardLength;
    139 
    140   // Returns a wildcard content settings pattern that matches all possible valid
    141   // origins.
    142   static ContentSettingsPattern Wildcard();
    143 
    144   // Returns a pattern that matches the scheme and host of this URL, as well as
    145   // all subdomains and ports.
    146   static ContentSettingsPattern FromURL(const GURL& url);
    147 
    148   // Returns a pattern that matches exactly this URL.
    149   static ContentSettingsPattern FromURLNoWildcard(const GURL& url);
    150 
    151   // Returns a pattern that matches the given pattern specification.
    152   // Valid patterns specifications are:
    153   //   - [*.]domain.tld (matches domain.tld and all sub-domains)
    154   //   - host (matches an exact hostname)
    155   //   - scheme://host:port (supported schemes: http,https)
    156   //   - scheme://[*.]domain.tld:port (supported schemes: http,https)
    157   //   - file://path (The path has to be an absolute path and start with a '/')
    158   //   - a.b.c.d (matches an exact IPv4 ip)
    159   //   - [a:b:c:d:e:f:g:h] (matches an exact IPv6 ip)
    160   static ContentSettingsPattern FromString(const std::string& pattern_spec);
    161 
    162   static ContentSettingsPattern LegacyFromString(
    163       const std::string& pattern_spec);
    164 
    165   // Constructs an empty pattern. Empty patterns are invalid patterns. Invalid
    166   // patterns match nothing.
    167   ContentSettingsPattern();
    168 
    169   // Serializes the pattern to an IPC message or deserializes it.
    170   void WriteToMessage(IPC::Message* m) const;
    171   bool ReadFromMessage(const IPC::Message* m, PickleIterator* iter);
    172 
    173   // True if this is a valid pattern.
    174   bool IsValid() const { return is_valid_; }
    175 
    176   // True if |url| matches this pattern.
    177   bool Matches(const GURL& url) const;
    178 
    179   // True if this pattern matches all hosts (i.e. it has a host wildcard).
    180   bool MatchesAllHosts() const;
    181 
    182   // Returns a std::string representation of this pattern.
    183   const std::string ToString() const;
    184 
    185   // Compares the pattern with a given |other| pattern and returns the
    186   // |Relation| of the two patterns.
    187   Relation Compare(const ContentSettingsPattern& other) const;
    188 
    189   // Returns true if the pattern and the |other| pattern are identical.
    190   bool operator==(const ContentSettingsPattern& other) const;
    191 
    192   // Returns true if the pattern and the |other| pattern are not identical.
    193   bool operator!=(const ContentSettingsPattern& other) const;
    194 
    195   // Returns true if the pattern has a lower priority than the |other| pattern.
    196   bool operator<(const ContentSettingsPattern& other) const;
    197 
    198   // Returns true if the pattern has a higher priority than the |other| pattern.
    199   bool operator>(const ContentSettingsPattern& other) const;
    200 
    201  private:
    202   friend class content_settings::PatternParser;
    203   friend class Builder;
    204   FRIEND_TEST_ALL_PREFIXES(ContentSettingsPatternParserTest, SerializePatterns);
    205 
    206   class Builder : public BuilderInterface {
    207     public:
    208      explicit Builder(bool use_legacy_validate);
    209      virtual ~Builder();
    210 
    211      // Overrides BuilderInterface
    212      virtual BuilderInterface* WithPort(const std::string& port) OVERRIDE;
    213 
    214      virtual BuilderInterface* WithPortWildcard() OVERRIDE;
    215 
    216      virtual BuilderInterface* WithHost(const std::string& host) OVERRIDE;
    217 
    218      virtual BuilderInterface* WithDomainWildcard() OVERRIDE;
    219 
    220      virtual BuilderInterface* WithScheme(const std::string& scheme) OVERRIDE;
    221 
    222      virtual BuilderInterface* WithSchemeWildcard() OVERRIDE;
    223 
    224      virtual BuilderInterface* WithPath(const std::string& path) OVERRIDE;
    225 
    226      virtual BuilderInterface* WithPathWildcard() OVERRIDE;
    227 
    228      virtual BuilderInterface* Invalid() OVERRIDE;
    229 
    230      virtual ContentSettingsPattern Build() OVERRIDE;
    231 
    232     private:
    233      // Canonicalizes the pattern parts so that they are ASCII only, either
    234      // in original (if it was already ASCII) or punycode form. Returns true if
    235      // the canonicalization was successful.
    236      static bool Canonicalize(PatternParts* parts);
    237 
    238      // Returns true when the pattern |parts| represent a valid pattern.
    239      static bool Validate(const PatternParts& parts);
    240 
    241      static bool LegacyValidate(const PatternParts& parts);
    242 
    243      bool is_valid_;
    244 
    245      bool use_legacy_validate_;
    246 
    247      PatternParts parts_;
    248 
    249      DISALLOW_COPY_AND_ASSIGN(Builder);
    250   };
    251 
    252   static Relation CompareScheme(
    253       const ContentSettingsPattern::PatternParts& parts,
    254       const ContentSettingsPattern::PatternParts& other_parts);
    255 
    256   static Relation CompareHost(
    257       const ContentSettingsPattern::PatternParts& parts,
    258       const ContentSettingsPattern::PatternParts& other_parts);
    259 
    260   static Relation ComparePort(
    261       const ContentSettingsPattern::PatternParts& parts,
    262       const ContentSettingsPattern::PatternParts& other_parts);
    263 
    264   static bool Validate(const PatternParts& parts);
    265 
    266   ContentSettingsPattern(const PatternParts& parts, bool valid);
    267 
    268   PatternParts parts_;
    269 
    270   bool is_valid_;
    271 };
    272 
    273 // Stream operator so ContentSettingsPattern can be used in assertion
    274 // statements.
    275 inline std::ostream& operator<<(
    276     std::ostream& out, const ContentSettingsPattern& pattern) {
    277   return out << pattern.ToString();
    278 }
    279 
    280 #endif  // CHROME_COMMON_CONTENT_SETTINGS_PATTERN_H_
    281