// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef NET_PROXY_PROXY_BYPASS_RULES_H_
#define NET_PROXY_PROXY_BYPASS_RULES_H_
#pragma once

#include <string>
#include <vector>

#include "googleurl/src/gurl.h"
#include "net/base/net_export.h"

namespace net {

// ProxyBypassRules describes the set of URLs that should bypass the proxy
// settings, as a list of rules. A URL is said to match the bypass rules
// if it matches any one of these rules.
class NET_EXPORT ProxyBypassRules {
 public:
  // Interface for an individual proxy bypass rule.
  class NET_EXPORT Rule {
   public:
    Rule();
    virtual ~Rule();

    // Returns true if |url| matches the rule.
    virtual bool Matches(const GURL& url) const = 0;

    // Returns a string representation of this rule. This is used both for
    // visualizing the rules, and also to test equality of a rules list.
    virtual std::string ToString() const = 0;

    // Creates a copy of this rule. (Caller is responsible for deleting it)
    virtual Rule* Clone() const = 0;

    bool Equals(const Rule& rule) const;

   private:
    DISALLOW_COPY_AND_ASSIGN(Rule);
  };

  typedef std::vector<const Rule*> RuleList;

  // Note: This class supports copy constructor and assignment.
  ProxyBypassRules();
  ProxyBypassRules(const ProxyBypassRules& rhs);
  ~ProxyBypassRules();
  ProxyBypassRules& operator=(const ProxyBypassRules& rhs);

  // Returns the current list of rules. The rules list contains pointers
  // which are owned by this class, callers should NOT keep references
  // or delete them.
  const RuleList& rules() const { return rules_; }

  // Returns true if |url| matches any of the proxy bypass rules.
  bool Matches(const GURL& url) const;

  // Returns true if |*this| is equal to |other|; in other words, whether they
  // describe the same set of rules.
  bool Equals(const ProxyBypassRules& other) const;

  // Initializes the list of rules by parsing the string |raw|. |raw| is a
  // comma separated list of rules. See AddRuleFromString() to see the list
  // of supported formats.
  void ParseFromString(const std::string& raw);

  // This is a variant of ParseFromString, which interprets hostname patterns
  // as suffix tests rather than hostname tests (so "google.com" would actually
  // match "*google.com"). This is only currently used for the linux no_proxy
  // evironment variable. It is less flexible, since with the suffix matching
  // format you can't match an individual host.
  // NOTE: Use ParseFromString() unless you truly need this behavior.
  void ParseFromStringUsingSuffixMatching(const std::string& raw);

  // Adds a rule that matches a URL when all of the following are true:
  //  (a) The URL's scheme matches |optional_scheme|, if
  //      |!optional_scheme.empty()|
  //  (b) The URL's hostname matches |hostname_pattern|.
  //  (c) The URL's (effective) port number matches |optional_port| if
  //      |optional_port != -1|
  // Returns true if the rule was successfully added.
  bool AddRuleForHostname(const std::string& optional_scheme,
                          const std::string& hostname_pattern,
                          int optional_port);

  // Adds a rule that bypasses all "local" hostnames.
  // This matches IE's interpretation of the
  // "Bypass proxy server for local addresses" settings checkbox. Fully
  // qualified domain names or IP addresses are considered non-local,
  // regardless of what they map to (except for the loopback addresses).
  void AddRuleToBypassLocal();

  // Adds a rule given by the string |raw|. The format of |raw| can be any of
  // the following:
  //
  // (1) [ URL_SCHEME "://" ] HOSTNAME_PATTERN [ ":" <port> ]
  //
  //   Match all hostnames that match the pattern HOSTNAME_PATTERN.
  //
  //   Examples:
  //     "foobar.com", "*foobar.com", "*.foobar.com", "*foobar.com:99",
  //     "https://x.*.y.com:99"
  //
  // (2) "." HOSTNAME_SUFFIX_PATTERN [ ":" PORT ]
  //
  //   Match a particular domain suffix.
  //
  //   Examples:
  //     ".google.com", ".com", "http://.google.com"
  //
  // (3) [ SCHEME "://" ] IP_LITERAL [ ":" PORT ]
  //
  //   Match URLs which are IP address literals.
  //
  //   Conceptually this is the similar to (1), but with special cases
  //   to handle IP literal canonicalization. For example matching
  //   on "[0:0:0::1]" would be the same as matching on "[::1]" since
  //   the IPv6 canonicalization is done internally.
  //
  //   Examples:
  //     "127.0.1", "[0:0::1]", "[::1]", "http://[::1]:99"
  //
  // (4)  IP_LITERAL "/" PREFIX_LENGHT_IN_BITS
  //
  //   Match any URL that is to an IP literal that falls between the
  //   given range. IP range is specified using CIDR notation.
  //
  //   Examples:
  //     "192.168.1.1/16", "fefe:13::abc/33".
  //
  // (5)  "<local>"
  //
  //   Match local addresses. The meaning of "<local>" is whether the
  //   host matches one of: "127.0.0.1", "::1", "localhost".
  //
  // See the unit-tests for more examples.
  //
  // Returns true if the rule was successfully added.
  //
  // TODO(eroman): support IPv6 literals without brackets.
  //
  bool AddRuleFromString(const std::string& raw);

  // This is a variant of AddFromString, which interprets hostname patterns as
  // suffix tests rather than hostname tests (so "google.com" would actually
  // match "*google.com"). This is used for KDE which interprets every rule as
  // a suffix test. It is less flexible, since with the suffix matching format
  // you can't match an individual host.
  //
  // Returns true if the rule was successfully added.
  //
  // NOTE: Use AddRuleFromString() unless you truly need this behavior.
  bool AddRuleFromStringUsingSuffixMatching(const std::string& raw);

  // Converts the rules to string representation. Inverse operation to
  // ParseFromString().
  std::string ToString() const;

  // Removes all the rules.
  void Clear();

  // Sets |*this| to |other|.
  void AssignFrom(const ProxyBypassRules& other);

 private:
  // The following are variants of ParseFromString() and AddRuleFromString(),
  // which additionally prefix hostname patterns with a wildcard if
  // |use_hostname_suffix_matching| was true.
  void ParseFromStringInternal(const std::string& raw,
                               bool use_hostname_suffix_matching);
  bool AddRuleFromStringInternal(const std::string& raw,
                                 bool use_hostname_suffix_matching);
  bool AddRuleFromStringInternalWithLogging(const std::string& raw,
                                            bool use_hostname_suffix_matching);

  RuleList rules_;
};

}  // namespace net

#endif  // NET_PROXY_PROXY_BYPASS_RULES_H_
