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_; |
} |