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 32 ProxyCrosSettingsProvider::ProxyCrosSettingsProvider() { } 33 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 196 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 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* 277 ProxyCrosSettingsProvider::GetConfigService() const { 278 return g_browser_process->chromeos_proxy_config_service_impl(); 279 } 280 281 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 296 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 309 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 316 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