| // Copyright 2015 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. |
| |
| #include "net/base/stale_while_revalidate_experiment_domains.h" |
| |
| #include <stddef.h> |
| |
| #include "base/logging.h" |
| #include "net/base/lookup_string_in_fixed_set.h" |
| |
| namespace net { |
| |
| namespace { |
| |
| #include "net/base/stale_while_revalidate_experiment_domains-inc.cc" |
| |
| // The maximum number of dots in any domain in the list. This is used to ignore |
| // parts of the host name that are irrelevant, and so must be correct. |
| const int kMaxDots = 2; |
| |
| // The minimum number of dots in a host necessary for it to be considered a |
| // match. |
| const int kMinDots = 1; |
| |
| bool LookupTail(const base::StringPiece& host, size_t pos) { |
| DCHECK_LT(pos, host.size()); |
| return LookupStringInFixedSet(kDafsa, sizeof(kDafsa), host.data() + pos, |
| host.size() - pos) == 0; |
| } |
| |
| bool LookupTrimmedHost(const base::StringPiece& trimmed) { |
| // |trimmed| contains at least one non-dot. The maximum number of dots we want |
| // to look for is kMaxInterestingDots; any dots before that will not affect |
| // the outcome of the match. |
| const int kMaxInterestingDots = kMaxDots + 1; |
| |
| // Scan |trimmed| from the right for up to kMaxInterestingDots dots, checking |
| // for a domain match at each position. |
| int found_dots = 0; |
| size_t pos = base::StringPiece::npos; |
| while (found_dots < kMaxInterestingDots) { |
| pos = trimmed.find_last_of('.', pos); |
| if (pos == base::StringPiece::npos) |
| break; |
| ++found_dots; |
| if (found_dots > kMinDots && LookupTail(trimmed, pos + 1)) |
| return true; |
| if (pos == 0) |
| return false; |
| --pos; |
| } |
| |
| if (found_dots >= kMinDots && found_dots <= kMaxDots) { |
| // We might have an exact match. |
| return LookupTail(trimmed, 0); |
| } |
| |
| return false; |
| } |
| |
| } // namespace |
| |
| bool IsHostInStaleWhileRevalidateExperimentDomain( |
| const base::StringPiece& host) { |
| // Ignore trailing dots. |
| size_t last_interesting_pos = host.find_last_not_of('.'); |
| if (last_interesting_pos == base::StringPiece::npos) |
| return false; |
| |
| return LookupTrimmedHost(host.substr(0, last_interesting_pos + 1)); |
| } |
| |
| } // namespace net |