Chromium Code Reviews| Index: net/base/sdch_dictionary.cc |
| diff --git a/net/base/sdch_dictionary.cc b/net/base/sdch_dictionary.cc |
| index b8faf552390601da1e31dfe13d229ab60cded96e..cea20405669ea06990d4ada669c6949af3e84480 100644 |
| --- a/net/base/sdch_dictionary.cc |
| +++ b/net/base/sdch_dictionary.cc |
| @@ -4,20 +4,12 @@ |
| #include "net/base/sdch_dictionary.h" |
| +#include "base/strings/string_util.h" |
| #include "base/time/clock.h" |
| #include "base/time/default_clock.h" |
| #include "base/values.h" |
| #include "net/base/registry_controlled_domains/registry_controlled_domain.h" |
| -namespace { |
| - |
| -bool DomainMatch(const GURL& gurl, const std::string& restriction) { |
| - // TODO(jar): This is not precisely a domain match definition. |
| - return gurl.DomainIs(restriction); |
| -} |
| - |
| -} // namespace |
| - |
| namespace net { |
| SdchDictionary::SdchDictionary(const std::string& dictionary_text, |
| @@ -157,6 +149,71 @@ bool SdchDictionary::PathMatch(const std::string& path, |
| return restriction[prefix_length - 1] == '/' || path[prefix_length] == '/'; |
| } |
| +// static |
| +bool SdchDictionary::DomainMatch(const GURL& gurl, |
| + const std::string& restriction) { |
| + /* RFC 2965: |
|
Mike West
2016/04/14 07:32:49
1. This RFC has been updated by https://tools.ietf
|
| + * Host A's name domain-matches host B's if |
| + * * their host name strings string-compare equal; or |
| + * * A is a HDN string and has the form NB, where N is a non-empty |
| + * name string, B has the form .B', and B' is a HDN string. (So, |
| + * x.y.com domain-matches .Y.com but not Y.com.) |
| + * |
| + * In our case |gurl| is B, |restriction| is "A". |
| + */ |
| + if (!gurl.is_valid() || restriction.empty()) |
| + return false; |
| + |
| + // Avoid useless string allocation by using GURL::host() |
| + base::StringPiece host(gurl.possibly_invalid_spec().data() + |
| + gurl.parsed_for_possibly_invalid_spec().host.begin, |
| + gurl.parsed_for_possibly_invalid_spec().host.len); |
| + if (host.empty()) |
| + return false; |
| + |
| + base::StringPiece domain(restriction); |
| + |
| + // Ignore trailing '.'s |
| + if (*host.rbegin() == '.') |
| + host.remove_suffix(1); |
| + |
| + if (*domain.rbegin() == '.') |
| + domain.remove_suffix(1); |
| + |
| + // Skip leading '.' in domain and remember it for future use |
| + bool has_leading_dot = domain[0] == '.'; |
| + if (has_leading_dot) { |
| + domain.remove_prefix(1); |
| + } |
| + |
| + if (host.length() < domain.length()) |
| + return false; |
| + |
| + // Advance host to be same length as domain. |
| + auto distance = host.length() - domain.length(); |
| + if (distance > 0) { |
| + // Make sure there aren't extra characters in host before the compared part; |
| + // if the host name is longer than the input domain name, then the character |
| + // immediately before the compared part should be a dot. For example, |
| + // www.google.com has domain "google.com", but www.iamnotgoogle.com does |
| + // not. |
| + if (host[distance - 1] != '.') |
| + return false; |
| + |
| + host.remove_prefix(distance); |
| + } |
| + |
| + if (!base::LowerCaseEqualsASCII(host, domain)) |
| + return false; |
| + |
| + // If we compared only part of host with domain check that domain starts with |
| + // '.' |
| + if (distance > 0) |
| + return has_leading_dot; |
| + |
| + return true; |
| +} |
| + |
| bool SdchDictionary::Expired() const { |
| return base::Time::Now() > expiration_; |
| } |