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 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.h"
9 #include "base/basictypes.h"
10 #include "base/json/json_writer.h"
11 #include "base/stl_util.h"
12 #include "base/strings/string_util.h"
13 #include "base/time/time.h"
14 #include "base/values.h"
15 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_storage_delegate.h"
19 const size_t kMaxEventsToStore
= 100;
21 struct StringToConstant
{
26 // Creates an associative array of the enum name to enum value for
27 // DataReductionProxyBypassType. Ensures that the same enum space is used
28 // without having to keep an enum map in sync.
29 const StringToConstant kDataReductionProxyBypassEventTypeTable
[] = {
30 #define BYPASS_EVENT_TYPE(label, value) { \
31 # label, data_reduction_proxy::BYPASS_EVENT_TYPE_ ## label },
32 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_bypass_type_list.h"
33 #undef BYPASS_EVENT_TYPE
36 // Creates an associate array of the enum name to enum value for
37 // DataReductionProxyBypassAction. Ensures that the same enum space is used
38 // without having to keep an enum map in sync.
39 const StringToConstant kDataReductionProxyBypassActionTypeTable
[] = {
40 #define BYPASS_ACTION_TYPE(label, value) \
41 { #label, data_reduction_proxy::BYPASS_ACTION_TYPE_##label } \
43 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_bypass_action_list.h"
44 #undef BYPASS_ACTION_TYPE
47 std::string
JoinListValueStrings(base::ListValue
* list_value
) {
48 std::vector
<std::string
> values
;
49 for (auto it
= list_value
->begin(); it
!= list_value
->end(); ++it
) {
50 std::string value_string
;
51 base::Value
* value
= *it
;
52 if (!value
->GetAsString(&value_string
))
55 values
.push_back(value_string
);
58 return base::JoinString(values
, ";");
63 namespace data_reduction_proxy
{
66 void DataReductionProxyEventStore::AddConstants(
67 base::DictionaryValue
* constants_dict
) {
68 scoped_ptr
<base::DictionaryValue
> dict(new base::DictionaryValue());
70 i
< arraysize(kDataReductionProxyBypassEventTypeTable
); ++i
) {
71 dict
->SetInteger(kDataReductionProxyBypassEventTypeTable
[i
].name
,
72 kDataReductionProxyBypassEventTypeTable
[i
].constant
);
75 constants_dict
->Set("dataReductionProxyBypassEventType", dict
.Pass());
77 dict
.reset(new base::DictionaryValue());
78 for (size_t i
= 0; i
< arraysize(kDataReductionProxyBypassActionTypeTable
);
80 dict
->SetInteger(kDataReductionProxyBypassActionTypeTable
[i
].name
,
81 kDataReductionProxyBypassActionTypeTable
[i
].constant
);
84 constants_dict
->Set("dataReductionProxyBypassActionType", dict
.Pass());
87 DataReductionProxyEventStore::DataReductionProxyEventStore()
89 secure_proxy_check_state_(CHECK_UNKNOWN
),
90 expiration_ticks_(0) {
93 DataReductionProxyEventStore::~DataReductionProxyEventStore() {
94 STLDeleteElements(&stored_events_
);
97 base::Value
* DataReductionProxyEventStore::GetSummaryValue() const {
98 DCHECK(thread_checker_
.CalledOnValidThread());
99 scoped_ptr
<base::DictionaryValue
> data_reduction_proxy_values(
100 new base::DictionaryValue());
101 data_reduction_proxy_values
->SetBoolean("enabled", enabled_
);
103 base::Value
* current_configuration
= current_configuration_
.get();
104 if (current_configuration
!= nullptr) {
105 data_reduction_proxy_values
->Set("proxy_config",
106 current_configuration
->DeepCopy());
109 switch (secure_proxy_check_state_
) {
111 data_reduction_proxy_values
->SetString("probe", "Pending");
114 data_reduction_proxy_values
->SetString("probe", "Success");
117 data_reduction_proxy_values
->SetString("probe", "Failed");
126 base::Value
* last_bypass_event
= last_bypass_event_
.get();
127 if (last_bypass_event
!= nullptr) {
128 int current_time_ticks_ms
=
129 (base::TimeTicks::Now() - base::TimeTicks()).InMilliseconds();
130 if (expiration_ticks_
> current_time_ticks_ms
) {
131 data_reduction_proxy_values
->Set("last_bypass",
132 last_bypass_event
->DeepCopy());
136 base::ListValue
* eventsList
= new base::ListValue();
137 for (size_t i
= 0; i
< stored_events_
.size(); ++i
)
138 eventsList
->Append(stored_events_
[i
]->DeepCopy());
140 data_reduction_proxy_values
->Set("events", eventsList
);
142 return data_reduction_proxy_values
.release();
145 void DataReductionProxyEventStore::AddEvent(scoped_ptr
<base::Value
> event
) {
146 if (stored_events_
.size() == kMaxEventsToStore
) {
147 base::Value
* head
= stored_events_
.front();
148 stored_events_
.pop_front();
152 stored_events_
.push_back(event
.release());
155 void DataReductionProxyEventStore::AddEnabledEvent(
156 scoped_ptr
<base::Value
> event
,
158 DCHECK(thread_checker_
.CalledOnValidThread());
161 current_configuration_
.reset(event
->DeepCopy());
163 current_configuration_
.reset();
164 AddEvent(event
.Pass());
167 void DataReductionProxyEventStore::AddEventAndSecureProxyCheckState(
168 scoped_ptr
<base::Value
> event
,
169 SecureProxyCheckState state
) {
170 DCHECK(thread_checker_
.CalledOnValidThread());
171 secure_proxy_check_state_
= state
;
172 AddEvent(event
.Pass());
175 void DataReductionProxyEventStore::AddAndSetLastBypassEvent(
176 scoped_ptr
<base::Value
> event
,
177 int64 expiration_ticks
) {
178 DCHECK(thread_checker_
.CalledOnValidThread());
179 last_bypass_event_
.reset(event
->DeepCopy());
180 expiration_ticks_
= expiration_ticks
;
181 AddEvent(event
.Pass());
184 std::string
DataReductionProxyEventStore::GetHttpProxyList() const {
185 DCHECK(thread_checker_
.CalledOnValidThread());
186 if (!enabled_
|| !current_configuration_
)
187 return std::string();
189 base::DictionaryValue
* config_dict
;
190 if (!current_configuration_
->GetAsDictionary(&config_dict
))
191 return std::string();
193 base::DictionaryValue
* params_dict
;
194 if (!config_dict
->GetDictionary("params", ¶ms_dict
))
195 return std::string();
197 base::ListValue
* proxy_list
;
198 if (!params_dict
->GetList("http_proxy_list", &proxy_list
))
199 return std::string();
201 return JoinListValueStrings(proxy_list
);
204 std::string
DataReductionProxyEventStore::GetHttpsProxyList() const {
205 DCHECK(thread_checker_
.CalledOnValidThread());
206 if (!enabled_
|| !current_configuration_
)
207 return std::string();
209 base::DictionaryValue
* config_dict
;
210 if (!current_configuration_
->GetAsDictionary(&config_dict
))
211 return std::string();
213 base::DictionaryValue
* params_dict
;
214 if (!config_dict
->GetDictionary("params", ¶ms_dict
))
215 return std::string();
217 base::ListValue
* proxy_list
;
218 if (!params_dict
->GetList("https_proxy_list", &proxy_list
))
219 return std::string();
221 return JoinListValueStrings(proxy_list
);
224 std::string
DataReductionProxyEventStore::SanitizedLastBypassEvent() const {
225 DCHECK(thread_checker_
.CalledOnValidThread());
226 if (!enabled_
|| !last_bypass_event_
)
227 return std::string();
229 base::DictionaryValue
* bypass_dict
;
230 base::DictionaryValue
* params_dict
;
231 if (!last_bypass_event_
->GetAsDictionary(&bypass_dict
))
232 return std::string();
234 if (!bypass_dict
->GetDictionary("params", ¶ms_dict
))
235 return std::string();
237 // Explicitly add parameters to prevent automatic adding of new parameters.
238 scoped_ptr
<base::DictionaryValue
> last_bypass(new base::DictionaryValue());
240 std::string str_value
;
242 if (bypass_dict
->GetString("time", &str_value
))
243 last_bypass
->SetString("bypass_time", str_value
);
245 if (params_dict
->GetInteger("bypass_type", &int_value
))
246 last_bypass
->SetInteger("bypass_type", int_value
);
248 if (params_dict
->GetInteger("bypass_action_type", &int_value
))
249 last_bypass
->SetInteger("bypass_action", int_value
);
251 if (params_dict
->GetString("bypass_duration_seconds", &str_value
))
252 last_bypass
->SetString("bypass_seconds", str_value
);
254 if (params_dict
->GetString("url", &str_value
)) {
256 GURL::Replacements replacements
;
257 replacements
.ClearQuery();
258 GURL clean_url
= url
.ReplaceComponents(replacements
);
259 last_bypass
->SetString("url", clean_url
.spec());
263 base::JSONWriter::Write(*last_bypass
.get(), &json
);
267 } // namespace data_reduction_proxy