1 // Copyright (c) 2011 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.
4
5 #include "chrome/browser/chromeos/proxy_cros_settings_provider.h"
6
7 #include "base/command_line.h"
8 #include "base/string_util.h"
9 #include "chrome/browser/browser_process.h"
10 #include "chrome/browser/ui/browser_list.h"
11 #include "chrome/common/chrome_switches.h"
12
13 namespace chromeos {
14
15 static const char kProxyPacUrl[] = "cros.session.proxy.pacurl";
16 static const char kProxySingleHttp[] = "cros.session.proxy.singlehttp";
17 static const char kProxySingleHttpPort[] = "cros.session.proxy.singlehttpport";
18 static const char kProxyHttpUrl[] = "cros.session.proxy.httpurl";
19 static const char kProxyHttpPort[] = "cros.session.proxy.httpport";
20 static const char kProxyHttpsUrl[] = "cros.session.proxy.httpsurl";
21 static const char kProxyHttpsPort[] = "cros.session.proxy.httpsport";
22 static const char kProxyType[] = "cros.session.proxy.type";
23 static const char kProxySingle[] = "cros.session.proxy.single";
24 static const char kProxyFtpUrl[] = "cros.session.proxy.ftpurl";
25 static const char kProxyFtpPort[] = "cros.session.proxy.ftpport";
26 static const char kProxySocks[] = "cros.session.proxy.socks";
27 static const char kProxySocksPort[] = "cros.session.proxy.socksport";
28 static const char kProxyIgnoreList[] = "cros.session.proxy.ignorelist";
29
30 //------------------ ProxyCrosSettingsProvider: public methods -----------------
31
ProxyCrosSettingsProvider()32 ProxyCrosSettingsProvider::ProxyCrosSettingsProvider() { }
33
DoSet(const std::string & path,Value * in_value)34 void ProxyCrosSettingsProvider::DoSet(const std::string& path,
35 Value* in_value) {
36 if (!in_value) {
37 return;
38 }
39
40 chromeos::ProxyConfigServiceImpl* config_service = GetConfigService();
41 // Don't persist settings to device for guest session.
42 config_service->UISetPersistToDevice(
43 !CommandLine::ForCurrentProcess()->HasSwitch(switches::kGuestSession));
44 // Retrieve proxy config.
45 chromeos::ProxyConfigServiceImpl::ProxyConfig config;
46 config_service->UIGetProxyConfig(&config);
47
48 if (path == kProxyPacUrl) {
49 std::string val;
50 if (in_value->GetAsString(&val)) {
51 GURL url(val);
52 config_service->UISetProxyConfigToPACScript(url);
53 }
54 } else if (path == kProxySingleHttp) {
55 std::string val;
56 if (in_value->GetAsString(&val)) {
57 config_service->UISetProxyConfigToSingleProxy(CreateProxyServerFromHost(
58 val, config.single_proxy, net::ProxyServer::SCHEME_HTTP));
59 }
60 } else if (path == kProxySingleHttpPort) {
61 int val;
62 if (in_value->GetAsInteger(&val)) {
63 config_service->UISetProxyConfigToSingleProxy(CreateProxyServerFromPort(
64 val, config.single_proxy, net::ProxyServer::SCHEME_HTTP));
65 }
66 } else if (path == kProxyHttpUrl) {
67 std::string val;
68 if (in_value->GetAsString(&val)) {
69 config_service->UISetProxyConfigToProxyPerScheme("http",
70 CreateProxyServerFromHost(
71 val, config.http_proxy, net::ProxyServer::SCHEME_HTTP));
72 }
73 } else if (path == kProxyHttpPort) {
74 int val;
75 if (in_value->GetAsInteger(&val)) {
76 config_service->UISetProxyConfigToProxyPerScheme("http",
77 CreateProxyServerFromPort(
78 val, config.http_proxy, net::ProxyServer::SCHEME_HTTP));
79 }
80 } else if (path == kProxyHttpsUrl) {
81 std::string val;
82 if (in_value->GetAsString(&val)) {
83 config_service->UISetProxyConfigToProxyPerScheme("https",
84 CreateProxyServerFromHost(
85 val, config.https_proxy, net::ProxyServer::SCHEME_HTTP));
86 }
87 } else if (path == kProxyHttpsPort) {
88 int val;
89 if (in_value->GetAsInteger(&val)) {
90 config_service->UISetProxyConfigToProxyPerScheme("https",
91 CreateProxyServerFromPort(
92 val, config.https_proxy, net::ProxyServer::SCHEME_HTTP));
93 }
94 } else if (path == kProxyType) {
95 int val;
96 if (in_value->GetAsInteger(&val)) {
97 if (val == 3) {
98 if (config.automatic_proxy.pac_url.is_valid())
99 config_service->UISetProxyConfigToPACScript(
100 config.automatic_proxy.pac_url);
101 else
102 config_service->UISetProxyConfigToAutoDetect();
103 } else if (val == 2) {
104 if (config.single_proxy.server.is_valid()) {
105 config_service->UISetProxyConfigToSingleProxy(
106 config.single_proxy.server);
107 } else {
108 bool set_config = false;
109 if (config.http_proxy.server.is_valid()) {
110 config_service->UISetProxyConfigToProxyPerScheme("http",
111 config.http_proxy.server);
112 set_config = true;
113 }
114 if (config.https_proxy.server.is_valid()) {
115 config_service->UISetProxyConfigToProxyPerScheme("https",
116 config.https_proxy.server);
117 set_config = true;
118 }
119 if (config.ftp_proxy.server.is_valid()) {
120 config_service->UISetProxyConfigToProxyPerScheme("ftp",
121 config.ftp_proxy.server);
122 set_config = true;
123 }
124 if (config.socks_proxy.server.is_valid()) {
125 config_service->UISetProxyConfigToProxyPerScheme("socks",
126 config.socks_proxy.server);
127 set_config = true;
128 }
129 if (!set_config) {
130 config_service->UISetProxyConfigToProxyPerScheme("http",
131 net::ProxyServer());
132 }
133 }
134 } else {
135 config_service->UISetProxyConfigToDirect();
136 }
137 }
138 } else if (path == kProxySingle) {
139 bool val;
140 if (in_value->GetAsBoolean(&val)) {
141 if (val)
142 config_service->UISetProxyConfigToSingleProxy(
143 config.single_proxy.server);
144 else
145 config_service->UISetProxyConfigToProxyPerScheme("http",
146 config.http_proxy.server);
147 }
148 } else if (path == kProxyFtpUrl) {
149 std::string val;
150 if (in_value->GetAsString(&val)) {
151 config_service->UISetProxyConfigToProxyPerScheme("ftp",
152 CreateProxyServerFromHost(
153 val, config.ftp_proxy, net::ProxyServer::SCHEME_HTTP));
154 }
155 } else if (path == kProxyFtpPort) {
156 int val;
157 if (in_value->GetAsInteger(&val)) {
158 config_service->UISetProxyConfigToProxyPerScheme("ftp",
159 CreateProxyServerFromPort(
160 val, config.ftp_proxy, net::ProxyServer::SCHEME_HTTP));
161 }
162 } else if (path == kProxySocks) {
163 std::string val;
164 if (in_value->GetAsString(&val)) {
165 config_service->UISetProxyConfigToProxyPerScheme("socks",
166 CreateProxyServerFromHost(val, config.socks_proxy,
167 StartsWithASCII(val, "socks5://", false) ?
168 net::ProxyServer::SCHEME_SOCKS5 :
169 net::ProxyServer::SCHEME_SOCKS4));
170 }
171 } else if (path == kProxySocksPort) {
172 int val;
173 if (in_value->GetAsInteger(&val)) {
174 std::string host = config.socks_proxy.server.host_port_pair().host();
175 config_service->UISetProxyConfigToProxyPerScheme("socks",
176 CreateProxyServerFromPort(val, config.socks_proxy,
177 StartsWithASCII(host, "socks5://", false) ?
178 net::ProxyServer::SCHEME_SOCKS5 :
179 net::ProxyServer::SCHEME_SOCKS4));
180 }
181 } else if (path == kProxyIgnoreList) {
182 net::ProxyBypassRules bypass_rules;
183 if (in_value->GetType() == Value::TYPE_LIST) {
184 const ListValue* list_value = static_cast<const ListValue*>(in_value);
185 for (size_t x = 0; x < list_value->GetSize(); x++) {
186 std::string val;
187 if (list_value->GetString(x, &val)) {
188 bypass_rules.AddRuleFromString(val);
189 }
190 }
191 config_service->UISetProxyConfigBypassRules(bypass_rules);
192 }
193 }
194 }
195
Get(const std::string & path,Value ** out_value) const196 bool ProxyCrosSettingsProvider::Get(const std::string& path,
197 Value** out_value) const {
198 bool found = false;
199 bool managed = false;
200 Value* data;
201 chromeos::ProxyConfigServiceImpl* config_service = GetConfigService();
202 chromeos::ProxyConfigServiceImpl::ProxyConfig config;
203 config_service->UIGetProxyConfig(&config);
204
205 if (path == kProxyPacUrl) {
206 if (config.automatic_proxy.pac_url.is_valid()) {
207 data = Value::CreateStringValue(config.automatic_proxy.pac_url.spec());
208 found = true;
209 }
210 } else if (path == kProxySingleHttp) {
211 found = (data = CreateServerHostValue(config.single_proxy));
212 } else if (path == kProxySingleHttpPort) {
213 found = (data = CreateServerPortValue(config.single_proxy));
214 } else if (path == kProxyHttpUrl) {
215 found = (data = CreateServerHostValue(config.http_proxy));
216 } else if (path == kProxyHttpsUrl) {
217 found = (data = CreateServerHostValue(config.https_proxy));
218 } else if (path == kProxyType) {
219 if (config.mode ==
220 chromeos::ProxyConfigServiceImpl::ProxyConfig::MODE_AUTO_DETECT ||
221 config.mode ==
222 chromeos::ProxyConfigServiceImpl::ProxyConfig::MODE_PAC_SCRIPT) {
223 data = Value::CreateIntegerValue(3);
224 } else if (config.mode ==
225 chromeos::ProxyConfigServiceImpl::ProxyConfig::MODE_SINGLE_PROXY ||
226 config.mode ==
227 chromeos::ProxyConfigServiceImpl::ProxyConfig::MODE_PROXY_PER_SCHEME) {
228 data = Value::CreateIntegerValue(2);
229 } else {
230 data = Value::CreateIntegerValue(1);
231 }
232 found = true;
233 } else if (path == kProxySingle) {
234 data = Value::CreateBooleanValue(config.mode ==
235 chromeos::ProxyConfigServiceImpl::ProxyConfig::MODE_SINGLE_PROXY);
236 found = true;
237 } else if (path == kProxyFtpUrl) {
238 found = (data = CreateServerHostValue(config.ftp_proxy));
239 } else if (path == kProxySocks) {
240 found = (data = CreateServerHostValue(config.socks_proxy));
241 } else if (path == kProxyHttpPort) {
242 found = (data = CreateServerPortValue(config.http_proxy));
243 } else if (path == kProxyHttpsPort) {
244 found = (data = CreateServerPortValue(config.https_proxy));
245 } else if (path == kProxyFtpPort) {
246 found = (data = CreateServerPortValue(config.ftp_proxy));
247 } else if (path == kProxySocksPort) {
248 found = (data = CreateServerPortValue(config.socks_proxy));
249 } else if (path == kProxyIgnoreList) {
250 ListValue* list = new ListValue();
251 net::ProxyBypassRules::RuleList bypass_rules = config.bypass_rules.rules();
252 for (size_t x = 0; x < bypass_rules.size(); x++) {
253 list->Append(Value::CreateStringValue(bypass_rules[x]->ToString()));
254 }
255 *out_value = list;
256 return true;
257 }
258 if (found) {
259 DictionaryValue* dict = new DictionaryValue;
260 dict->Set("value", data);
261 dict->SetBoolean("managed", managed);
262 *out_value = dict;
263 return true;
264 } else {
265 *out_value = NULL;
266 return false;
267 }
268 }
269
HandlesSetting(const std::string & path)270 bool ProxyCrosSettingsProvider::HandlesSetting(const std::string& path) {
271 return ::StartsWithASCII(path, "cros.session.proxy", true);
272 }
273
274 //----------------- ProxyCrosSettingsProvider: private methods -----------------
275
276 chromeos::ProxyConfigServiceImpl*
GetConfigService() const277 ProxyCrosSettingsProvider::GetConfigService() const {
278 return g_browser_process->chromeos_proxy_config_service_impl();
279 }
280
CreateProxyServerFromHost(const std::string & host,const ProxyConfigServiceImpl::ProxyConfig::ManualProxy & proxy,net::ProxyServer::Scheme scheme) const281 net::ProxyServer ProxyCrosSettingsProvider::CreateProxyServerFromHost(
282 const std::string& host,
283 const ProxyConfigServiceImpl::ProxyConfig::ManualProxy& proxy,
284 net::ProxyServer::Scheme scheme) const {
285 uint16 port = 0;
286 if (proxy.server.is_valid())
287 port = proxy.server.host_port_pair().port();
288 if (host.length() == 0 && port == 0)
289 return net::ProxyServer();
290 if (port == 0)
291 port = net::ProxyServer::GetDefaultPortForScheme(scheme);
292 net::HostPortPair host_port_pair(host, port);
293 return net::ProxyServer(scheme, host_port_pair);
294 }
295
CreateProxyServerFromPort(uint16 port,const ProxyConfigServiceImpl::ProxyConfig::ManualProxy & proxy,net::ProxyServer::Scheme scheme) const296 net::ProxyServer ProxyCrosSettingsProvider::CreateProxyServerFromPort(
297 uint16 port,
298 const ProxyConfigServiceImpl::ProxyConfig::ManualProxy& proxy,
299 net::ProxyServer::Scheme scheme) const {
300 std::string host;
301 if (proxy.server.is_valid())
302 host = proxy.server.host_port_pair().host();
303 if (host.length() == 0 && port == 0)
304 return net::ProxyServer();
305 net::HostPortPair host_port_pair(host, port);
306 return net::ProxyServer(scheme, host_port_pair);
307 }
308
CreateServerHostValue(const ProxyConfigServiceImpl::ProxyConfig::ManualProxy & proxy) const309 Value* ProxyCrosSettingsProvider::CreateServerHostValue(
310 const ProxyConfigServiceImpl::ProxyConfig::ManualProxy& proxy) const {
311 return proxy.server.is_valid() ?
312 Value::CreateStringValue(proxy.server.host_port_pair().host()) :
313 NULL;
314 }
315
CreateServerPortValue(const ProxyConfigServiceImpl::ProxyConfig::ManualProxy & proxy) const316 Value* ProxyCrosSettingsProvider::CreateServerPortValue(
317 const ProxyConfigServiceImpl::ProxyConfig::ManualProxy& proxy) const {
318 return proxy.server.is_valid() ?
319 Value::CreateIntegerValue(proxy.server.host_port_pair().port()) :
320 NULL;
321 }
322
323 } // namespace chromeos
324