// Copyright 2014 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. // Make sure stdint.h includes SIZE_MAX. (See C89, p259, footnote 221.) #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include "components/domain_reliability/config.h" #include #include "base/json/json_reader.h" #include "base/json/json_value_converter.h" #include "base/profiler/scoped_tracker.h" #include "base/rand_util.h" #include "base/strings/pattern.h" #include "base/strings/string_util.h" namespace { bool ConvertURL(const base::StringPiece& string_piece, GURL* url) { *url = GURL(string_piece.as_string()); return url->is_valid(); } bool IsValidSampleRate(double p) { return p >= 0.0 && p <= 1.0; } } // namespace namespace domain_reliability { // static const size_t DomainReliabilityConfig::kInvalidResourceIndex = SIZE_MAX; DomainReliabilityConfig::Resource::Resource() { } DomainReliabilityConfig::Resource::~Resource() {} bool DomainReliabilityConfig::Resource::MatchesUrl(const GURL& url) const { const std::string& spec = url.spec(); for (const auto& url_pattern : url_patterns) { if (base::MatchPattern(spec, *url_pattern)) return true; } return false; } bool DomainReliabilityConfig::Resource::DecideIfShouldReportRequest( bool success) const { double sample_rate = success ? success_sample_rate : failure_sample_rate; DCHECK(IsValidSampleRate(sample_rate)); return base::RandDouble() < sample_rate; } // static void DomainReliabilityConfig::Resource::RegisterJSONConverter( base::JSONValueConverter* converter) { converter->RegisterStringField("resource_name", &Resource::name); converter->RegisterRepeatedString("url_patterns", &Resource::url_patterns); converter->RegisterDoubleField("success_sample_rate", &Resource::success_sample_rate); converter->RegisterDoubleField("failure_sample_rate", &Resource::failure_sample_rate); } bool DomainReliabilityConfig::Resource::IsValid() const { return !name.empty() && !url_patterns.empty() && IsValidSampleRate(success_sample_rate) && IsValidSampleRate(failure_sample_rate); } DomainReliabilityConfig::Collector::Collector() {} DomainReliabilityConfig::Collector::~Collector() {} // static void DomainReliabilityConfig::Collector::RegisterJSONConverter( base::JSONValueConverter* converter) { converter->RegisterCustomField("upload_url", &Collector::upload_url, &ConvertURL); } bool DomainReliabilityConfig::Collector::IsValid() const { return upload_url.is_valid(); } DomainReliabilityConfig::DomainReliabilityConfig() {} DomainReliabilityConfig::~DomainReliabilityConfig() {} // static scoped_ptr DomainReliabilityConfig::FromJSON( const base::StringPiece& json) { scoped_ptr value = base::JSONReader::Read(json); base::JSONValueConverter converter; scoped_ptr config(new DomainReliabilityConfig()); // If we can parse and convert the JSON into a valid config, return that. if (value && converter.Convert(*value, config.get()) && config->IsValid()) return config.Pass(); return scoped_ptr(); } bool DomainReliabilityConfig::IsValid() const { if (domain.empty() || resources.empty() || collectors.empty()) return false; for (auto& resource : resources) { if (!resource->IsValid()) return false; } for (auto& collector : collectors) { if (!collector->IsValid()) return false; } return true; } size_t DomainReliabilityConfig::GetResourceIndexForUrl(const GURL& url) const { // Removes username, password, and fragment. GURL sanitized_url = url.GetAsReferrer(); for (size_t i = 0; i < resources.size(); ++i) { if (resources[i]->MatchesUrl(sanitized_url)) return i; } return kInvalidResourceIndex; } // static void DomainReliabilityConfig::RegisterJSONConverter( base::JSONValueConverter* converter) { converter->RegisterStringField("config_version", &DomainReliabilityConfig::version); converter->RegisterStringField("monitored_domain", &DomainReliabilityConfig::domain); converter->RegisterRepeatedMessage("monitored_resources", &DomainReliabilityConfig::resources); converter->RegisterRepeatedMessage("collectors", &DomainReliabilityConfig::collectors); } } // namespace domain_reliability