blob: 1e295b15eacd8b97d4c1996ff4c0b8e73278ec43 [file] [log] [blame]
// 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