Commit 2b8a914a authored by ttuttle@chromium.org's avatar ttuttle@chromium.org

Domain Reliability: Add wildcard domain support.

Add support for configs with domains *.foo.bar.  Given a domain foo.bar, it
will first look for a config with domain foo.bar, then *.foo.bar, then *.bar.

BUG=396139

Review URL: https://codereview.chromium.org/404363003

Cr-Commit-Position: refs/heads/master@{#288428}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@288428 0039d316-1c4b-4281-b951-d872f2087c98
parent 9c765638
......@@ -176,7 +176,7 @@ TEST_F(DomainReliabilityContextTest, ReportUpload) {
time_.Advance(max_delay());
EXPECT_TRUE(upload_pending());
EXPECT_EQ(kExpectedReport, upload_report());
EXPECT_EQ(GURL("https://example/upload"), upload_url());
EXPECT_EQ(GURL("https://exampleuploader/upload"), upload_url());
CallUploadCallback(true);
EXPECT_TRUE(CheckNoBeacons());
......
......@@ -196,13 +196,14 @@ void DomainReliabilityMonitor::OnRequestLegComplete(
response_code = request.response_info.headers->response_code();
else
response_code = -1;
ContextMap::iterator context_it;
std::string beacon_status;
int error_code = net::OK;
if (request.status.status() == net::URLRequestStatus::FAILED)
error_code = request.status.error();
DomainReliabilityContext* context = GetContextForHost(request.url.host());
// Ignore requests where:
// 1. There is no context for the request host.
// 2. The request did not access the network.
......@@ -211,7 +212,7 @@ void DomainReliabilityMonitor::OnRequestLegComplete(
// 4. The request was itself a Domain Reliability upload (to avoid loops).
// 5. There is no defined beacon status for the error or HTTP response code
// (to avoid leaking network-local errors).
if ((context_it = contexts_.find(request.url.host())) == contexts_.end() ||
if (!context ||
!request.AccessedNetwork() ||
(request.load_flags & net::LOAD_DO_NOT_SEND_COOKIES) ||
request.is_upload ||
......@@ -233,7 +234,36 @@ void DomainReliabilityMonitor::OnRequestLegComplete(
beacon.http_response_code = response_code;
beacon.start_time = request.load_timing_info.request_start;
beacon.elapsed = time_->NowTicks() - beacon.start_time;
context_it->second->OnBeacon(request.url, beacon);
context->OnBeacon(request.url, beacon);
}
// TODO(ttuttle): Keep a separate wildcard_contexts_ map to avoid having to
// prepend '*.' to domains.
DomainReliabilityContext* DomainReliabilityMonitor::GetContextForHost(
const std::string& host) const {
ContextMap::const_iterator context_it;
context_it = contexts_.find(host);
if (context_it != contexts_.end())
return context_it->second;
std::string host_with_asterisk = "*." + host;
context_it = contexts_.find(host_with_asterisk);
if (context_it != contexts_.end())
return context_it->second;
size_t dot_pos = host.find('.');
if (dot_pos == std::string::npos)
return NULL;
// TODO(ttuttle): Make sure parent is not in PSL before using.
std::string parent_with_asterisk = "*." + host.substr(dot_pos + 1);
context_it = contexts_.find(parent_with_asterisk);
if (context_it != contexts_.end())
return context_it->second;
return NULL;
}
base::WeakPtr<DomainReliabilityMonitor>
......
......@@ -112,6 +112,8 @@ class DOMAIN_RELIABILITY_EXPORT DomainReliabilityMonitor {
void ClearContexts();
void OnRequestLegComplete(const RequestInfo& info);
DomainReliabilityContext* GetContextForHost(const std::string& host) const;
base::WeakPtr<DomainReliabilityMonitor> MakeWeakPtr();
scoped_ptr<base::ThreadChecker> thread_checker_;
......
......@@ -87,13 +87,27 @@ class DomainReliabilityMonitorTest : public testing::Test {
bool CheckRequestCounts(size_t index,
uint32 expected_successful,
uint32 expected_failed) {
return CheckRequestCounts(context_,
index,
expected_successful,
expected_failed);
}
bool CheckRequestCounts(DomainReliabilityContext* context,
size_t index,
uint32 expected_successful,
uint32 expected_failed) {
uint32 successful, failed;
context_->GetRequestCountsForTesting(index, &successful, &failed);
context->GetRequestCountsForTesting(index, &successful, &failed);
EXPECT_EQ(expected_successful, successful);
EXPECT_EQ(expected_failed, failed);
return expected_successful == successful && expected_failed == failed;
}
DomainReliabilityContext* CreateAndAddContext(const std::string& domain) {
return monitor_.AddContextForTesting(MakeTestConfigWithDomain(domain));
}
scoped_refptr<base::TestSimpleTaskRunner> network_task_runner_;
scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
MockTime* time_;
......@@ -301,6 +315,70 @@ TEST_F(DomainReliabilityMonitorTest, IgnoreSuccessError) {
EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex, 1u, 0u));
}
TEST_F(DomainReliabilityMonitorTest, WildcardMatchesSelf) {
DomainReliabilityContext* context = CreateAndAddContext("*.wildcard");
RequestInfo request = MakeRequestInfo();
request.url = GURL("http://wildcard/always_report");
OnRequestLegComplete(request);
EXPECT_TRUE(CheckRequestCounts(context, kAlwaysReportIndex, 1u, 0u));
}
TEST_F(DomainReliabilityMonitorTest, WildcardMatchesSubdomain) {
DomainReliabilityContext* context = CreateAndAddContext("*.wildcard");
RequestInfo request = MakeRequestInfo();
request.url = GURL("http://test.wildcard/always_report");
OnRequestLegComplete(request);
EXPECT_TRUE(CheckRequestCounts(context, kAlwaysReportIndex, 1u, 0u));
}
TEST_F(DomainReliabilityMonitorTest, WildcardDoesntMatchSubsubdomain) {
DomainReliabilityContext* context = CreateAndAddContext("*.wildcard");
RequestInfo request = MakeRequestInfo();
request.url = GURL("http://test.test.wildcard/always_report");
OnRequestLegComplete(request);
EXPECT_TRUE(CheckRequestCounts(context, kAlwaysReportIndex, 0u, 0u));
}
TEST_F(DomainReliabilityMonitorTest, WildcardPrefersSelfToSelfWildcard) {
DomainReliabilityContext* context1 = CreateAndAddContext("wildcard");
DomainReliabilityContext* context2 = CreateAndAddContext("*.wildcard");
RequestInfo request = MakeRequestInfo();
request.url = GURL("http://wildcard/always_report");
OnRequestLegComplete(request);
EXPECT_TRUE(CheckRequestCounts(context1, kAlwaysReportIndex, 1u, 0u));
EXPECT_TRUE(CheckRequestCounts(context2, kAlwaysReportIndex, 0u, 0u));
}
TEST_F(DomainReliabilityMonitorTest, WildcardPrefersSelfToParentWildcard) {
DomainReliabilityContext* context1 = CreateAndAddContext("test.wildcard");
DomainReliabilityContext* context2 = CreateAndAddContext("*.wildcard");
RequestInfo request = MakeRequestInfo();
request.url = GURL("http://test.wildcard/always_report");
OnRequestLegComplete(request);
EXPECT_TRUE(CheckRequestCounts(context1, kAlwaysReportIndex, 1u, 0u));
EXPECT_TRUE(CheckRequestCounts(context2, kAlwaysReportIndex, 0u, 0u));
}
TEST_F(DomainReliabilityMonitorTest,
WildcardPrefersSelfWildcardToParentWildcard) {
DomainReliabilityContext* context1 = CreateAndAddContext("*.test.wildcard");
DomainReliabilityContext* context2 = CreateAndAddContext("*.wildcard");
RequestInfo request = MakeRequestInfo();
request.url = GURL("http://test.wildcard/always_report");
OnRequestLegComplete(request);
EXPECT_TRUE(CheckRequestCounts(context1, kAlwaysReportIndex, 1u, 0u));
EXPECT_TRUE(CheckRequestCounts(context2, kAlwaysReportIndex, 0u, 0u));
}
} // namespace
} // namespace domain_reliability
......@@ -154,13 +154,18 @@ DomainReliabilityScheduler::Params MakeTestSchedulerParams() {
}
scoped_ptr<const DomainReliabilityConfig> MakeTestConfig() {
return MakeTestConfigWithDomain("example");
}
scoped_ptr<const DomainReliabilityConfig> MakeTestConfigWithDomain(
const std::string& domain) {
DomainReliabilityConfig* config = new DomainReliabilityConfig();
DomainReliabilityConfig::Resource* resource;
resource = new DomainReliabilityConfig::Resource();
resource->name = "always_report";
resource->url_patterns.push_back(
new std::string("http://example/always_report"));
new std::string("http://*/always_report"));
resource->success_sample_rate = 1.0;
resource->failure_sample_rate = 1.0;
config->resources.push_back(resource);
......@@ -168,19 +173,19 @@ scoped_ptr<const DomainReliabilityConfig> MakeTestConfig() {
resource = new DomainReliabilityConfig::Resource();
resource->name = "never_report";
resource->url_patterns.push_back(
new std::string("http://example/never_report"));
new std::string("http://*/never_report"));
resource->success_sample_rate = 0.0;
resource->failure_sample_rate = 0.0;
config->resources.push_back(resource);
DomainReliabilityConfig::Collector* collector;
collector = new DomainReliabilityConfig::Collector();
collector->upload_url = GURL("https://example/upload");
collector->upload_url = GURL("https://exampleuploader/upload");
config->collectors.push_back(collector);
config->version = "1";
config->valid_until = 1234567890.0;
config->domain = "example";
config->domain = domain;
DCHECK(config->IsValid());
......
......@@ -115,6 +115,8 @@ class MockTime : public MockableTime {
};
scoped_ptr<const DomainReliabilityConfig> MakeTestConfig();
scoped_ptr<const DomainReliabilityConfig> MakeTestConfigWithDomain(
const std::string& domain);
DomainReliabilityScheduler::Params MakeTestSchedulerParams();
} // namespace domain_reliability
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment