1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // Make sure stdint.h includes SIZE_MAX. (See C89, p259, footnote 221.)
6 #ifndef __STDC_LIMIT_MACROS
7 #define __STDC_LIMIT_MACROS 1
10 #include "components/domain_reliability/config.h"
14 #include "base/json/json_reader.h"
15 #include "base/json/json_value_converter.h"
16 #include "base/profiler/scoped_tracker.h"
17 #include "base/rand_util.h"
18 #include "base/strings/string_util.h"
22 bool ConvertURL(const base::StringPiece
& string_piece
, GURL
* url
) {
23 *url
= GURL(string_piece
.as_string());
24 return url
->is_valid();
27 bool IsValidSampleRate(double p
) { return p
>= 0.0 && p
<= 1.0; }
31 namespace domain_reliability
{
34 const size_t DomainReliabilityConfig::kInvalidResourceIndex
= SIZE_MAX
;
36 DomainReliabilityConfig::Resource::Resource() {
38 DomainReliabilityConfig::Resource::~Resource() {}
40 bool DomainReliabilityConfig::Resource::MatchesUrl(const GURL
& url
) const {
41 const std::string
& spec
= url
.spec();
43 for (const auto& url_pattern
: url_patterns
) {
44 if (MatchPattern(spec
, *url_pattern
))
51 bool DomainReliabilityConfig::Resource::DecideIfShouldReportRequest(
53 double sample_rate
= success
? success_sample_rate
: failure_sample_rate
;
54 DCHECK(IsValidSampleRate(sample_rate
));
55 return base::RandDouble() < sample_rate
;
59 void DomainReliabilityConfig::Resource::RegisterJSONConverter(
60 base::JSONValueConverter
<DomainReliabilityConfig::Resource
>* converter
) {
61 converter
->RegisterStringField("resource_name", &Resource::name
);
62 converter
->RegisterRepeatedString("url_patterns", &Resource::url_patterns
);
63 converter
->RegisterDoubleField("success_sample_rate",
64 &Resource::success_sample_rate
);
65 converter
->RegisterDoubleField("failure_sample_rate",
66 &Resource::failure_sample_rate
);
69 bool DomainReliabilityConfig::Resource::IsValid() const {
70 return !name
.empty() && !url_patterns
.empty() &&
71 IsValidSampleRate(success_sample_rate
) &&
72 IsValidSampleRate(failure_sample_rate
);
75 DomainReliabilityConfig::Collector::Collector() {}
76 DomainReliabilityConfig::Collector::~Collector() {}
79 void DomainReliabilityConfig::Collector::RegisterJSONConverter(
80 base::JSONValueConverter
<DomainReliabilityConfig::Collector
>* converter
) {
81 converter
->RegisterCustomField
<GURL
>("upload_url", &Collector::upload_url
,
85 bool DomainReliabilityConfig::Collector::IsValid() const {
86 return upload_url
.is_valid();
89 DomainReliabilityConfig::DomainReliabilityConfig() : valid_until(0.0) {}
90 DomainReliabilityConfig::~DomainReliabilityConfig() {}
93 scoped_ptr
<const DomainReliabilityConfig
> DomainReliabilityConfig::FromJSON(
94 const base::StringPiece
& json
) {
95 // TODO(vadimt): Remove ScopedTracker below once crbug.com/436671 is fixed.
96 tracked_objects::ScopedTracker
tracking_profile(
97 FROM_HERE_WITH_EXPLICIT_FUNCTION(
98 "436671 DomainReliabilityConfig::FromJSON"));
99 scoped_ptr
<base::Value
> value(base::JSONReader::Read(json
));
100 base::JSONValueConverter
<DomainReliabilityConfig
> converter
;
101 scoped_ptr
<DomainReliabilityConfig
> config(new DomainReliabilityConfig());
103 // If we can parse and convert the JSON into a valid config, return that.
104 if (value
&& converter
.Convert(*value
, config
.get()) && config
->IsValid())
105 return config
.Pass();
106 return scoped_ptr
<const DomainReliabilityConfig
>();
109 bool DomainReliabilityConfig::IsValid() const {
110 if (valid_until
== 0.0 || domain
.empty() ||
111 resources
.empty() || collectors
.empty()) {
115 for (auto& resource
: resources
) {
116 if (!resource
->IsValid())
120 for (auto& collector
: collectors
) {
121 if (!collector
->IsValid())
128 bool DomainReliabilityConfig::IsExpired(base::Time now
) const {
129 DCHECK_NE(0.0, valid_until
);
130 base::Time valid_until_time
= base::Time::FromDoubleT(valid_until
);
131 return now
> valid_until_time
;
134 size_t DomainReliabilityConfig::GetResourceIndexForUrl(const GURL
& url
) const {
135 // Removes username, password, and fragment.
136 GURL sanitized_url
= url
.GetAsReferrer();
138 for (size_t i
= 0; i
< resources
.size(); ++i
) {
139 if (resources
[i
]->MatchesUrl(sanitized_url
))
143 return kInvalidResourceIndex
;
147 void DomainReliabilityConfig::RegisterJSONConverter(
148 base::JSONValueConverter
<DomainReliabilityConfig
>* converter
) {
149 converter
->RegisterStringField("config_version",
150 &DomainReliabilityConfig::version
);
151 converter
->RegisterDoubleField("config_valid_until",
152 &DomainReliabilityConfig::valid_until
);
153 converter
->RegisterStringField("monitored_domain",
154 &DomainReliabilityConfig::domain
);
155 converter
->RegisterRepeatedMessage("monitored_resources",
156 &DomainReliabilityConfig::resources
);
157 converter
->RegisterRepeatedMessage("collectors",
158 &DomainReliabilityConfig::collectors
);
161 } // namespace domain_reliability