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/pattern.h"
19 #include "base/strings/string_util.h"
23 bool ConvertURL(const base::StringPiece
& string_piece
, GURL
* url
) {
24 *url
= GURL(string_piece
.as_string());
25 return url
->is_valid();
28 bool IsValidSampleRate(double p
) { return p
>= 0.0 && p
<= 1.0; }
32 namespace domain_reliability
{
35 const size_t DomainReliabilityConfig::kInvalidResourceIndex
= SIZE_MAX
;
37 DomainReliabilityConfig::Resource::Resource() {
39 DomainReliabilityConfig::Resource::~Resource() {}
41 bool DomainReliabilityConfig::Resource::MatchesUrl(const GURL
& url
) const {
42 const std::string
& spec
= url
.spec();
44 for (const auto& url_pattern
: url_patterns
) {
45 if (base::MatchPattern(spec
, *url_pattern
))
52 bool DomainReliabilityConfig::Resource::DecideIfShouldReportRequest(
54 double sample_rate
= success
? success_sample_rate
: failure_sample_rate
;
55 DCHECK(IsValidSampleRate(sample_rate
));
56 return base::RandDouble() < sample_rate
;
60 void DomainReliabilityConfig::Resource::RegisterJSONConverter(
61 base::JSONValueConverter
<DomainReliabilityConfig::Resource
>* converter
) {
62 converter
->RegisterStringField("resource_name", &Resource::name
);
63 converter
->RegisterRepeatedString("url_patterns", &Resource::url_patterns
);
64 converter
->RegisterDoubleField("success_sample_rate",
65 &Resource::success_sample_rate
);
66 converter
->RegisterDoubleField("failure_sample_rate",
67 &Resource::failure_sample_rate
);
70 bool DomainReliabilityConfig::Resource::IsValid() const {
71 return !name
.empty() && !url_patterns
.empty() &&
72 IsValidSampleRate(success_sample_rate
) &&
73 IsValidSampleRate(failure_sample_rate
);
76 DomainReliabilityConfig::Collector::Collector() {}
77 DomainReliabilityConfig::Collector::~Collector() {}
80 void DomainReliabilityConfig::Collector::RegisterJSONConverter(
81 base::JSONValueConverter
<DomainReliabilityConfig::Collector
>* converter
) {
82 converter
->RegisterCustomField
<GURL
>("upload_url", &Collector::upload_url
,
86 bool DomainReliabilityConfig::Collector::IsValid() const {
87 return upload_url
.is_valid();
90 DomainReliabilityConfig::DomainReliabilityConfig() : valid_until(0.0) {}
91 DomainReliabilityConfig::~DomainReliabilityConfig() {}
94 scoped_ptr
<const DomainReliabilityConfig
> DomainReliabilityConfig::FromJSON(
95 const base::StringPiece
& json
) {
96 // TODO(vadimt): Remove ScopedTracker below once crbug.com/436671 is fixed.
97 tracked_objects::ScopedTracker
tracking_profile(
98 FROM_HERE_WITH_EXPLICIT_FUNCTION(
99 "436671 DomainReliabilityConfig::FromJSON"));
100 scoped_ptr
<base::Value
> value
= base::JSONReader::Read(json
);
101 base::JSONValueConverter
<DomainReliabilityConfig
> converter
;
102 scoped_ptr
<DomainReliabilityConfig
> config(new DomainReliabilityConfig());
104 // If we can parse and convert the JSON into a valid config, return that.
105 if (value
&& converter
.Convert(*value
, config
.get()) && config
->IsValid())
106 return config
.Pass();
107 return scoped_ptr
<const DomainReliabilityConfig
>();
110 bool DomainReliabilityConfig::IsValid() const {
111 if (valid_until
== 0.0 || domain
.empty() ||
112 resources
.empty() || collectors
.empty()) {
116 for (auto& resource
: resources
) {
117 if (!resource
->IsValid())
121 for (auto& collector
: collectors
) {
122 if (!collector
->IsValid())
129 bool DomainReliabilityConfig::IsExpired(base::Time now
) const {
130 DCHECK_NE(0.0, valid_until
);
131 base::Time valid_until_time
= base::Time::FromDoubleT(valid_until
);
132 return now
> valid_until_time
;
135 size_t DomainReliabilityConfig::GetResourceIndexForUrl(const GURL
& url
) const {
136 // Removes username, password, and fragment.
137 GURL sanitized_url
= url
.GetAsReferrer();
139 for (size_t i
= 0; i
< resources
.size(); ++i
) {
140 if (resources
[i
]->MatchesUrl(sanitized_url
))
144 return kInvalidResourceIndex
;
148 void DomainReliabilityConfig::RegisterJSONConverter(
149 base::JSONValueConverter
<DomainReliabilityConfig
>* converter
) {
150 converter
->RegisterStringField("config_version",
151 &DomainReliabilityConfig::version
);
152 converter
->RegisterDoubleField("config_valid_until",
153 &DomainReliabilityConfig::valid_until
);
154 converter
->RegisterStringField("monitored_domain",
155 &DomainReliabilityConfig::domain
);
156 converter
->RegisterRepeatedMessage("monitored_resources",
157 &DomainReliabilityConfig::resources
);
158 converter
->RegisterRepeatedMessage("collectors",
159 &DomainReliabilityConfig::collectors
);
162 } // namespace domain_reliability