Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / components / data_reduction_proxy / core / common / data_reduction_proxy_event_store.cc
blob4bc17d0f9fd7a63b252993c43d3918992881b109
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"
7 #include <vector>
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"
17 namespace {
19 const size_t kMaxEventsToStore = 100;
21 struct StringToConstant {
22 const char* name;
23 const int constant;
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))
53 return std::string();
55 values.push_back(value_string);
58 return base::JoinString(values, ";");
61 } // namespace
63 namespace data_reduction_proxy {
65 // static
66 void DataReductionProxyEventStore::AddConstants(
67 base::DictionaryValue* constants_dict) {
68 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
69 for (size_t i = 0;
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);
79 ++i) {
80 dict->SetInteger(kDataReductionProxyBypassActionTypeTable[i].name,
81 kDataReductionProxyBypassActionTypeTable[i].constant);
84 constants_dict->Set("dataReductionProxyBypassActionType", dict.Pass());
87 DataReductionProxyEventStore::DataReductionProxyEventStore()
88 : enabled_(false),
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_) {
110 case CHECK_PENDING:
111 data_reduction_proxy_values->SetString("probe", "Pending");
112 break;
113 case CHECK_SUCCESS:
114 data_reduction_proxy_values->SetString("probe", "Success");
115 break;
116 case CHECK_FAILED:
117 data_reduction_proxy_values->SetString("probe", "Failed");
118 break;
119 case CHECK_UNKNOWN:
120 break;
121 default:
122 NOTREACHED();
123 break;
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();
149 delete head;
152 stored_events_.push_back(event.release());
155 void DataReductionProxyEventStore::AddEnabledEvent(
156 scoped_ptr<base::Value> event,
157 bool enabled) {
158 DCHECK(thread_checker_.CalledOnValidThread());
159 enabled_ = enabled;
160 if (enabled)
161 current_configuration_.reset(event->DeepCopy());
162 else
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", &params_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", &params_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", &params_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;
241 int int_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)) {
255 GURL 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());
262 std::string json;
263 base::JSONWriter::Write(*last_bypass.get(), &json);
264 return json;
267 } // namespace data_reduction_proxy