| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/proxy/proxy_config_service_linux.h" | 5 #include "net/proxy/proxy_config_service_linux.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <fcntl.h> | 8 #include <fcntl.h> |
| 9 #if defined(USE_GCONF) | 9 #if defined(USE_GCONF) |
| 10 #include <gconf/gconf-client.h> | 10 #include <gconf/gconf-client.h> |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 47 | 47 |
| 48 namespace net { | 48 namespace net { |
| 49 | 49 |
| 50 namespace { | 50 namespace { |
| 51 | 51 |
| 52 // Given a proxy hostname from a setting, returns that hostname with | 52 // Given a proxy hostname from a setting, returns that hostname with |
| 53 // an appropriate proxy server scheme prefix. | 53 // an appropriate proxy server scheme prefix. |
| 54 // scheme indicates the desired proxy scheme: usually http, with | 54 // scheme indicates the desired proxy scheme: usually http, with |
| 55 // socks 4 or 5 as special cases. | 55 // socks 4 or 5 as special cases. |
| 56 // TODO(arindam): Remove URI string manipulation by using MapUrlSchemeToProxy. | 56 // TODO(arindam): Remove URI string manipulation by using MapUrlSchemeToProxy. |
| 57 std::string FixupProxyHostScheme(ProxyServer::Scheme scheme, | 57 std::string FixupProxyHostScheme(ProxyServer::Scheme scheme, std::string host) { |
| 58 std::string host) { | |
| 59 if (scheme == ProxyServer::SCHEME_SOCKS5 && | 58 if (scheme == ProxyServer::SCHEME_SOCKS5 && |
| 60 StartsWithASCII(host, "socks4://", false)) { | 59 StartsWithASCII(host, "socks4://", false)) { |
| 61 // We default to socks 5, but if the user specifically set it to | 60 // We default to socks 5, but if the user specifically set it to |
| 62 // socks4://, then use that. | 61 // socks4://, then use that. |
| 63 scheme = ProxyServer::SCHEME_SOCKS4; | 62 scheme = ProxyServer::SCHEME_SOCKS4; |
| 64 } | 63 } |
| 65 // Strip the scheme if any. | 64 // Strip the scheme if any. |
| 66 std::string::size_type colon = host.find("://"); | 65 std::string::size_type colon = host.find("://"); |
| 67 if (colon != std::string::npos) | 66 if (colon != std::string::npos) |
| 68 host = host.substr(colon + 3); | 67 host = host.substr(colon + 3); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 89 host.resize(host.length() - 1); | 88 host.resize(host.length() - 1); |
| 90 return host; | 89 return host; |
| 91 } | 90 } |
| 92 | 91 |
| 93 } // namespace | 92 } // namespace |
| 94 | 93 |
| 95 ProxyConfigServiceLinux::Delegate::~Delegate() { | 94 ProxyConfigServiceLinux::Delegate::~Delegate() { |
| 96 } | 95 } |
| 97 | 96 |
| 98 bool ProxyConfigServiceLinux::Delegate::GetProxyFromEnvVarForScheme( | 97 bool ProxyConfigServiceLinux::Delegate::GetProxyFromEnvVarForScheme( |
| 99 const char* variable, ProxyServer::Scheme scheme, | 98 const char* variable, |
| 99 ProxyServer::Scheme scheme, |
| 100 ProxyServer* result_server) { | 100 ProxyServer* result_server) { |
| 101 std::string env_value; | 101 std::string env_value; |
| 102 if (env_var_getter_->GetVar(variable, &env_value)) { | 102 if (env_var_getter_->GetVar(variable, &env_value)) { |
| 103 if (!env_value.empty()) { | 103 if (!env_value.empty()) { |
| 104 env_value = FixupProxyHostScheme(scheme, env_value); | 104 env_value = FixupProxyHostScheme(scheme, env_value); |
| 105 ProxyServer proxy_server = | 105 ProxyServer proxy_server = |
| 106 ProxyServer::FromURI(env_value, ProxyServer::SCHEME_HTTP); | 106 ProxyServer::FromURI(env_value, ProxyServer::SCHEME_HTTP); |
| 107 if (proxy_server.is_valid() && !proxy_server.is_direct()) { | 107 if (proxy_server.is_valid() && !proxy_server.is_direct()) { |
| 108 *result_server = proxy_server; | 108 *result_server = proxy_server; |
| 109 return true; | 109 return true; |
| 110 } else { | 110 } else { |
| 111 LOG(ERROR) << "Failed to parse environment variable " << variable; | 111 LOG(ERROR) << "Failed to parse environment variable " << variable; |
| 112 } | 112 } |
| 113 } | 113 } |
| 114 } | 114 } |
| 115 return false; | 115 return false; |
| 116 } | 116 } |
| 117 | 117 |
| 118 bool ProxyConfigServiceLinux::Delegate::GetProxyFromEnvVar( | 118 bool ProxyConfigServiceLinux::Delegate::GetProxyFromEnvVar( |
| 119 const char* variable, ProxyServer* result_server) { | 119 const char* variable, |
| 120 return GetProxyFromEnvVarForScheme(variable, ProxyServer::SCHEME_HTTP, | 120 ProxyServer* result_server) { |
| 121 result_server); | 121 return GetProxyFromEnvVarForScheme( |
| 122 variable, ProxyServer::SCHEME_HTTP, result_server); |
| 122 } | 123 } |
| 123 | 124 |
| 124 bool ProxyConfigServiceLinux::Delegate::GetConfigFromEnv(ProxyConfig* config) { | 125 bool ProxyConfigServiceLinux::Delegate::GetConfigFromEnv(ProxyConfig* config) { |
| 125 // Check for automatic configuration first, in | 126 // Check for automatic configuration first, in |
| 126 // "auto_proxy". Possibly only the "environment_proxy" firefox | 127 // "auto_proxy". Possibly only the "environment_proxy" firefox |
| 127 // extension has ever used this, but it still sounds like a good | 128 // extension has ever used this, but it still sounds like a good |
| 128 // idea. | 129 // idea. |
| 129 std::string auto_proxy; | 130 std::string auto_proxy; |
| 130 if (env_var_getter_->GetVar("auto_proxy", &auto_proxy)) { | 131 if (env_var_getter_->GetVar("auto_proxy", &auto_proxy)) { |
| 131 if (auto_proxy.empty()) { | 132 if (auto_proxy.empty()) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 146 bool have_http = GetProxyFromEnvVar("http_proxy", &proxy_server); | 147 bool have_http = GetProxyFromEnvVar("http_proxy", &proxy_server); |
| 147 if (have_http) | 148 if (have_http) |
| 148 config->proxy_rules().proxies_for_http.SetSingleProxyServer(proxy_server); | 149 config->proxy_rules().proxies_for_http.SetSingleProxyServer(proxy_server); |
| 149 // It would be tempting to let http_proxy apply for all protocols | 150 // It would be tempting to let http_proxy apply for all protocols |
| 150 // if https_proxy and ftp_proxy are not defined. Googling turns up | 151 // if https_proxy and ftp_proxy are not defined. Googling turns up |
| 151 // several documents that mention only http_proxy. But then the | 152 // several documents that mention only http_proxy. But then the |
| 152 // user really might not want to proxy https. And it doesn't seem | 153 // user really might not want to proxy https. And it doesn't seem |
| 153 // like other apps do this. So we will refrain. | 154 // like other apps do this. So we will refrain. |
| 154 bool have_https = GetProxyFromEnvVar("https_proxy", &proxy_server); | 155 bool have_https = GetProxyFromEnvVar("https_proxy", &proxy_server); |
| 155 if (have_https) | 156 if (have_https) |
| 156 config->proxy_rules().proxies_for_https. | 157 config->proxy_rules().proxies_for_https.SetSingleProxyServer( |
| 157 SetSingleProxyServer(proxy_server); | 158 proxy_server); |
| 158 bool have_ftp = GetProxyFromEnvVar("ftp_proxy", &proxy_server); | 159 bool have_ftp = GetProxyFromEnvVar("ftp_proxy", &proxy_server); |
| 159 if (have_ftp) | 160 if (have_ftp) |
| 160 config->proxy_rules().proxies_for_ftp.SetSingleProxyServer(proxy_server); | 161 config->proxy_rules().proxies_for_ftp.SetSingleProxyServer(proxy_server); |
| 161 if (have_http || have_https || have_ftp) { | 162 if (have_http || have_https || have_ftp) { |
| 162 // mustn't change type unless some rules are actually set. | 163 // mustn't change type unless some rules are actually set. |
| 163 config->proxy_rules().type = | 164 config->proxy_rules().type = |
| 164 ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME; | 165 ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME; |
| 165 } | 166 } |
| 166 } | 167 } |
| 167 if (config->proxy_rules().empty()) { | 168 if (config->proxy_rules().empty()) { |
| 168 // If the above were not defined, try for socks. | 169 // If the above were not defined, try for socks. |
| 169 // For environment variables, we default to version 5, per the gnome | 170 // For environment variables, we default to version 5, per the gnome |
| 170 // documentation: http://library.gnome.org/devel/gnet/stable/gnet-socks.html | 171 // documentation: http://library.gnome.org/devel/gnet/stable/gnet-socks.html |
| 171 ProxyServer::Scheme scheme = ProxyServer::SCHEME_SOCKS5; | 172 ProxyServer::Scheme scheme = ProxyServer::SCHEME_SOCKS5; |
| 172 std::string env_version; | 173 std::string env_version; |
| 173 if (env_var_getter_->GetVar("SOCKS_VERSION", &env_version) | 174 if (env_var_getter_->GetVar("SOCKS_VERSION", &env_version) && |
| 174 && env_version == "4") | 175 env_version == "4") |
| 175 scheme = ProxyServer::SCHEME_SOCKS4; | 176 scheme = ProxyServer::SCHEME_SOCKS4; |
| 176 if (GetProxyFromEnvVarForScheme("SOCKS_SERVER", scheme, &proxy_server)) { | 177 if (GetProxyFromEnvVarForScheme("SOCKS_SERVER", scheme, &proxy_server)) { |
| 177 config->proxy_rules().type = ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY; | 178 config->proxy_rules().type = ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY; |
| 178 config->proxy_rules().single_proxies.SetSingleProxyServer(proxy_server); | 179 config->proxy_rules().single_proxies.SetSingleProxyServer(proxy_server); |
| 179 } | 180 } |
| 180 } | 181 } |
| 181 // Look for the proxy bypass list. | 182 // Look for the proxy bypass list. |
| 182 std::string no_proxy; | 183 std::string no_proxy; |
| 183 env_var_getter_->GetVar("no_proxy", &no_proxy); | 184 env_var_getter_->GetVar("no_proxy", &no_proxy); |
| 184 if (config->proxy_rules().empty()) { | 185 if (config->proxy_rules().empty()) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 197 | 198 |
| 198 namespace { | 199 namespace { |
| 199 | 200 |
| 200 const int kDebounceTimeoutMilliseconds = 250; | 201 const int kDebounceTimeoutMilliseconds = 250; |
| 201 | 202 |
| 202 #if defined(USE_GCONF) | 203 #if defined(USE_GCONF) |
| 203 // This setting getter uses gconf, as used in GNOME 2 and some GNOME 3 desktops. | 204 // This setting getter uses gconf, as used in GNOME 2 and some GNOME 3 desktops. |
| 204 class SettingGetterImplGConf : public ProxyConfigServiceLinux::SettingGetter { | 205 class SettingGetterImplGConf : public ProxyConfigServiceLinux::SettingGetter { |
| 205 public: | 206 public: |
| 206 SettingGetterImplGConf() | 207 SettingGetterImplGConf() |
| 207 : client_(NULL), system_proxy_id_(0), system_http_proxy_id_(0), | 208 : client_(NULL), |
| 208 notify_delegate_(NULL) { | 209 system_proxy_id_(0), |
| 209 } | 210 system_http_proxy_id_(0), |
| 211 notify_delegate_(NULL) {} |
| 210 | 212 |
| 211 virtual ~SettingGetterImplGConf() { | 213 virtual ~SettingGetterImplGConf() { |
| 212 // client_ should have been released before now, from | 214 // client_ should have been released before now, from |
| 213 // Delegate::OnDestroy(), while running on the UI thread. However | 215 // Delegate::OnDestroy(), while running on the UI thread. However |
| 214 // on exiting the process, it may happen that Delegate::OnDestroy() | 216 // on exiting the process, it may happen that Delegate::OnDestroy() |
| 215 // task is left pending on the glib loop after the loop was quit, | 217 // task is left pending on the glib loop after the loop was quit, |
| 216 // and pending tasks may then be deleted without being run. | 218 // and pending tasks may then be deleted without being run. |
| 217 if (client_) { | 219 if (client_) { |
| 218 // gconf client was not cleaned up. | 220 // gconf client was not cleaned up. |
| 219 if (task_runner_->BelongsToCurrentThread()) { | 221 if (task_runner_->BelongsToCurrentThread()) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 246 LOG(ERROR) << "Unable to create a gconf client"; | 248 LOG(ERROR) << "Unable to create a gconf client"; |
| 247 task_runner_ = NULL; | 249 task_runner_ = NULL; |
| 248 return false; | 250 return false; |
| 249 } | 251 } |
| 250 GError* error = NULL; | 252 GError* error = NULL; |
| 251 bool added_system_proxy = false; | 253 bool added_system_proxy = false; |
| 252 // We need to add the directories for which we'll be asking | 254 // We need to add the directories for which we'll be asking |
| 253 // for notifications, and we might as well ask to preload them. | 255 // for notifications, and we might as well ask to preload them. |
| 254 // These need to be removed again in ShutDown(); we are careful | 256 // These need to be removed again in ShutDown(); we are careful |
| 255 // here to only leave client_ non-NULL if both have been added. | 257 // here to only leave client_ non-NULL if both have been added. |
| 256 gconf_client_add_dir(client_, "/system/proxy", | 258 gconf_client_add_dir( |
| 257 GCONF_CLIENT_PRELOAD_ONELEVEL, &error); | 259 client_, "/system/proxy", GCONF_CLIENT_PRELOAD_ONELEVEL, &error); |
| 258 if (error == NULL) { | 260 if (error == NULL) { |
| 259 added_system_proxy = true; | 261 added_system_proxy = true; |
| 260 gconf_client_add_dir(client_, "/system/http_proxy", | 262 gconf_client_add_dir( |
| 261 GCONF_CLIENT_PRELOAD_ONELEVEL, &error); | 263 client_, "/system/http_proxy", GCONF_CLIENT_PRELOAD_ONELEVEL, &error); |
| 262 } | 264 } |
| 263 if (error != NULL) { | 265 if (error != NULL) { |
| 264 LOG(ERROR) << "Error requesting gconf directory: " << error->message; | 266 LOG(ERROR) << "Error requesting gconf directory: " << error->message; |
| 265 g_error_free(error); | 267 g_error_free(error); |
| 266 if (added_system_proxy) | 268 if (added_system_proxy) |
| 267 gconf_client_remove_dir(client_, "/system/proxy", NULL); | 269 gconf_client_remove_dir(client_, "/system/proxy", NULL); |
| 268 g_object_unref(client_); | 270 g_object_unref(client_); |
| 269 client_ = NULL; | 271 client_ = NULL; |
| 270 task_runner_ = NULL; | 272 task_runner_ = NULL; |
| 271 return false; | 273 return false; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 292 | 294 |
| 293 virtual bool SetUpNotifications( | 295 virtual bool SetUpNotifications( |
| 294 ProxyConfigServiceLinux::Delegate* delegate) OVERRIDE { | 296 ProxyConfigServiceLinux::Delegate* delegate) OVERRIDE { |
| 295 DCHECK(client_); | 297 DCHECK(client_); |
| 296 DCHECK(task_runner_->BelongsToCurrentThread()); | 298 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 297 GError* error = NULL; | 299 GError* error = NULL; |
| 298 notify_delegate_ = delegate; | 300 notify_delegate_ = delegate; |
| 299 // We have to keep track of the IDs returned by gconf_client_notify_add() so | 301 // We have to keep track of the IDs returned by gconf_client_notify_add() so |
| 300 // that we can remove them in ShutDown(). (Otherwise, notifications will be | 302 // that we can remove them in ShutDown(). (Otherwise, notifications will be |
| 301 // delivered to this object after it is deleted, which is bad, m'kay?) | 303 // delivered to this object after it is deleted, which is bad, m'kay?) |
| 302 system_proxy_id_ = gconf_client_notify_add( | 304 system_proxy_id_ = gconf_client_notify_add(client_, |
| 303 client_, "/system/proxy", | 305 "/system/proxy", |
| 304 OnGConfChangeNotification, this, | 306 OnGConfChangeNotification, |
| 305 NULL, &error); | 307 this, |
| 308 NULL, |
| 309 &error); |
| 306 if (error == NULL) { | 310 if (error == NULL) { |
| 307 system_http_proxy_id_ = gconf_client_notify_add( | 311 system_http_proxy_id_ = gconf_client_notify_add(client_, |
| 308 client_, "/system/http_proxy", | 312 "/system/http_proxy", |
| 309 OnGConfChangeNotification, this, | 313 OnGConfChangeNotification, |
| 310 NULL, &error); | 314 this, |
| 315 NULL, |
| 316 &error); |
| 311 } | 317 } |
| 312 if (error != NULL) { | 318 if (error != NULL) { |
| 313 LOG(ERROR) << "Error requesting gconf notifications: " << error->message; | 319 LOG(ERROR) << "Error requesting gconf notifications: " << error->message; |
| 314 g_error_free(error); | 320 g_error_free(error); |
| 315 ShutDown(); | 321 ShutDown(); |
| 316 return false; | 322 return false; |
| 317 } | 323 } |
| 318 // Simulate a change to avoid possibly losing updates before this point. | 324 // Simulate a change to avoid possibly losing updates before this point. |
| 319 OnChangeNotification(); | 325 OnChangeNotification(); |
| 320 return true; | 326 return true; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 376 return GetStringListByPath("/system/http_proxy/ignore_hosts", result); | 382 return GetStringListByPath("/system/http_proxy/ignore_hosts", result); |
| 377 } | 383 } |
| 378 return false; // Placate compiler. | 384 return false; // Placate compiler. |
| 379 } | 385 } |
| 380 | 386 |
| 381 virtual bool BypassListIsReversed() OVERRIDE { | 387 virtual bool BypassListIsReversed() OVERRIDE { |
| 382 // This is a KDE-specific setting. | 388 // This is a KDE-specific setting. |
| 383 return false; | 389 return false; |
| 384 } | 390 } |
| 385 | 391 |
| 386 virtual bool MatchHostsUsingSuffixMatching() OVERRIDE { | 392 virtual bool MatchHostsUsingSuffixMatching() OVERRIDE { return false; } |
| 387 return false; | |
| 388 } | |
| 389 | 393 |
| 390 private: | 394 private: |
| 391 bool GetStringByPath(const char* key, std::string* result) { | 395 bool GetStringByPath(const char* key, std::string* result) { |
| 392 DCHECK(client_); | 396 DCHECK(client_); |
| 393 DCHECK(task_runner_->BelongsToCurrentThread()); | 397 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 394 GError* error = NULL; | 398 GError* error = NULL; |
| 395 gchar* value = gconf_client_get_string(client_, key, &error); | 399 gchar* value = gconf_client_get_string(client_, key, &error); |
| 396 if (HandleGError(error, key)) | 400 if (HandleGError(error, key)) |
| 397 return false; | 401 return false; |
| 398 if (!value) | 402 if (!value) |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 433 return false; | 437 return false; |
| 434 // We don't bother to distinguish an unset value because callers | 438 // We don't bother to distinguish an unset value because callers |
| 435 // don't care. 0 is returned if unset. | 439 // don't care. 0 is returned if unset. |
| 436 *result = value; | 440 *result = value; |
| 437 return true; | 441 return true; |
| 438 } | 442 } |
| 439 bool GetStringListByPath(const char* key, std::vector<std::string>* result) { | 443 bool GetStringListByPath(const char* key, std::vector<std::string>* result) { |
| 440 DCHECK(client_); | 444 DCHECK(client_); |
| 441 DCHECK(task_runner_->BelongsToCurrentThread()); | 445 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 442 GError* error = NULL; | 446 GError* error = NULL; |
| 443 GSList* list = gconf_client_get_list(client_, key, | 447 GSList* list = |
| 444 GCONF_VALUE_STRING, &error); | 448 gconf_client_get_list(client_, key, GCONF_VALUE_STRING, &error); |
| 445 if (HandleGError(error, key)) | 449 if (HandleGError(error, key)) |
| 446 return false; | 450 return false; |
| 447 if (!list) | 451 if (!list) |
| 448 return false; | 452 return false; |
| 449 for (GSList *it = list; it; it = it->next) { | 453 for (GSList* it = list; it; it = it->next) { |
| 450 result->push_back(static_cast<char*>(it->data)); | 454 result->push_back(static_cast<char*>(it->data)); |
| 451 g_free(it->data); | 455 g_free(it->data); |
| 452 } | 456 } |
| 453 g_slist_free(list); | 457 g_slist_free(list); |
| 454 return true; | 458 return true; |
| 455 } | 459 } |
| 456 | 460 |
| 457 // Logs and frees a glib error. Returns false if there was no error | 461 // Logs and frees a glib error. Returns false if there was no error |
| 458 // (error is NULL). | 462 // (error is NULL). |
| 459 bool HandleGError(GError* error, const char* key) { | 463 bool HandleGError(GError* error, const char* key) { |
| 460 if (error != NULL) { | 464 if (error != NULL) { |
| 461 LOG(ERROR) << "Error getting gconf value for " << key | 465 LOG(ERROR) << "Error getting gconf value for " << key << ": " |
| 462 << ": " << error->message; | 466 << error->message; |
| 463 g_error_free(error); | 467 g_error_free(error); |
| 464 return true; | 468 return true; |
| 465 } | 469 } |
| 466 return false; | 470 return false; |
| 467 } | 471 } |
| 468 | 472 |
| 469 // This is the callback from the debounce timer. | 473 // This is the callback from the debounce timer. |
| 470 void OnDebouncedNotification() { | 474 void OnDebouncedNotification() { |
| 471 DCHECK(task_runner_->BelongsToCurrentThread()); | 475 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 472 CHECK(notify_delegate_); | 476 CHECK(notify_delegate_); |
| 473 // Forward to a method on the proxy config service delegate object. | 477 // Forward to a method on the proxy config service delegate object. |
| 474 notify_delegate_->OnCheckProxyConfigSettings(); | 478 notify_delegate_->OnCheckProxyConfigSettings(); |
| 475 } | 479 } |
| 476 | 480 |
| 477 void OnChangeNotification() { | 481 void OnChangeNotification() { |
| 478 // We don't use Reset() because the timer may not yet be running. | 482 // We don't use Reset() because the timer may not yet be running. |
| 479 // (In that case Stop() is a no-op.) | 483 // (In that case Stop() is a no-op.) |
| 480 debounce_timer_.Stop(); | 484 debounce_timer_.Stop(); |
| 481 debounce_timer_.Start(FROM_HERE, | 485 debounce_timer_.Start( |
| 486 FROM_HERE, |
| 482 base::TimeDelta::FromMilliseconds(kDebounceTimeoutMilliseconds), | 487 base::TimeDelta::FromMilliseconds(kDebounceTimeoutMilliseconds), |
| 483 this, &SettingGetterImplGConf::OnDebouncedNotification); | 488 this, |
| 489 &SettingGetterImplGConf::OnDebouncedNotification); |
| 484 } | 490 } |
| 485 | 491 |
| 486 // gconf notification callback, dispatched on the default glib main loop. | 492 // gconf notification callback, dispatched on the default glib main loop. |
| 487 static void OnGConfChangeNotification(GConfClient* client, guint cnxn_id, | 493 static void OnGConfChangeNotification(GConfClient* client, |
| 488 GConfEntry* entry, gpointer user_data) { | 494 guint cnxn_id, |
| 495 GConfEntry* entry, |
| 496 gpointer user_data) { |
| 489 VLOG(1) << "gconf change notification for key " | 497 VLOG(1) << "gconf change notification for key " |
| 490 << gconf_entry_get_key(entry); | 498 << gconf_entry_get_key(entry); |
| 491 // We don't track which key has changed, just that something did change. | 499 // We don't track which key has changed, just that something did change. |
| 492 SettingGetterImplGConf* setting_getter = | 500 SettingGetterImplGConf* setting_getter = |
| 493 reinterpret_cast<SettingGetterImplGConf*>(user_data); | 501 reinterpret_cast<SettingGetterImplGConf*>(user_data); |
| 494 setting_getter->OnChangeNotification(); | 502 setting_getter->OnChangeNotification(); |
| 495 } | 503 } |
| 496 | 504 |
| 497 GConfClient* client_; | 505 GConfClient* client_; |
| 498 // These ids are the values returned from gconf_client_notify_add(), which we | 506 // These ids are the values returned from gconf_client_notify_add(), which we |
| (...skipping 11 matching lines...) Expand all Loading... |
| 510 | 518 |
| 511 DISALLOW_COPY_AND_ASSIGN(SettingGetterImplGConf); | 519 DISALLOW_COPY_AND_ASSIGN(SettingGetterImplGConf); |
| 512 }; | 520 }; |
| 513 #endif // defined(USE_GCONF) | 521 #endif // defined(USE_GCONF) |
| 514 | 522 |
| 515 #if defined(USE_GIO) | 523 #if defined(USE_GIO) |
| 516 // This setting getter uses gsettings, as used in most GNOME 3 desktops. | 524 // This setting getter uses gsettings, as used in most GNOME 3 desktops. |
| 517 class SettingGetterImplGSettings | 525 class SettingGetterImplGSettings |
| 518 : public ProxyConfigServiceLinux::SettingGetter { | 526 : public ProxyConfigServiceLinux::SettingGetter { |
| 519 public: | 527 public: |
| 520 SettingGetterImplGSettings() : | 528 SettingGetterImplGSettings() |
| 521 client_(NULL), | 529 : client_(NULL), |
| 522 http_client_(NULL), | 530 http_client_(NULL), |
| 523 https_client_(NULL), | 531 https_client_(NULL), |
| 524 ftp_client_(NULL), | 532 ftp_client_(NULL), |
| 525 socks_client_(NULL), | 533 socks_client_(NULL), |
| 526 notify_delegate_(NULL) { | 534 notify_delegate_(NULL) {} |
| 527 } | |
| 528 | 535 |
| 529 virtual ~SettingGetterImplGSettings() { | 536 virtual ~SettingGetterImplGSettings() { |
| 530 // client_ should have been released before now, from | 537 // client_ should have been released before now, from |
| 531 // Delegate::OnDestroy(), while running on the UI thread. However | 538 // Delegate::OnDestroy(), while running on the UI thread. However |
| 532 // on exiting the process, it may happen that | 539 // on exiting the process, it may happen that |
| 533 // Delegate::OnDestroy() task is left pending on the glib loop | 540 // Delegate::OnDestroy() task is left pending on the glib loop |
| 534 // after the loop was quit, and pending tasks may then be deleted | 541 // after the loop was quit, and pending tasks may then be deleted |
| 535 // without being run. | 542 // without being run. |
| 536 if (client_) { | 543 if (client_) { |
| 537 // gconf client was not cleaned up. | 544 // gconf client was not cleaned up. |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 600 } | 607 } |
| 601 | 608 |
| 602 virtual bool SetUpNotifications( | 609 virtual bool SetUpNotifications( |
| 603 ProxyConfigServiceLinux::Delegate* delegate) OVERRIDE { | 610 ProxyConfigServiceLinux::Delegate* delegate) OVERRIDE { |
| 604 DCHECK(client_); | 611 DCHECK(client_); |
| 605 DCHECK(task_runner_->BelongsToCurrentThread()); | 612 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 606 notify_delegate_ = delegate; | 613 notify_delegate_ = delegate; |
| 607 // We could watch for the change-event signal instead of changed, but | 614 // We could watch for the change-event signal instead of changed, but |
| 608 // since we have to watch more than one object, we'd still have to | 615 // since we have to watch more than one object, we'd still have to |
| 609 // debounce change notifications. This is conceptually simpler. | 616 // debounce change notifications. This is conceptually simpler. |
| 610 g_signal_connect(G_OBJECT(client_), "changed", | 617 g_signal_connect(G_OBJECT(client_), |
| 611 G_CALLBACK(OnGSettingsChangeNotification), this); | 618 "changed", |
| 612 g_signal_connect(G_OBJECT(http_client_), "changed", | 619 G_CALLBACK(OnGSettingsChangeNotification), |
| 613 G_CALLBACK(OnGSettingsChangeNotification), this); | 620 this); |
| 614 g_signal_connect(G_OBJECT(https_client_), "changed", | 621 g_signal_connect(G_OBJECT(http_client_), |
| 615 G_CALLBACK(OnGSettingsChangeNotification), this); | 622 "changed", |
| 616 g_signal_connect(G_OBJECT(ftp_client_), "changed", | 623 G_CALLBACK(OnGSettingsChangeNotification), |
| 617 G_CALLBACK(OnGSettingsChangeNotification), this); | 624 this); |
| 618 g_signal_connect(G_OBJECT(socks_client_), "changed", | 625 g_signal_connect(G_OBJECT(https_client_), |
| 619 G_CALLBACK(OnGSettingsChangeNotification), this); | 626 "changed", |
| 627 G_CALLBACK(OnGSettingsChangeNotification), |
| 628 this); |
| 629 g_signal_connect(G_OBJECT(ftp_client_), |
| 630 "changed", |
| 631 G_CALLBACK(OnGSettingsChangeNotification), |
| 632 this); |
| 633 g_signal_connect(G_OBJECT(socks_client_), |
| 634 "changed", |
| 635 G_CALLBACK(OnGSettingsChangeNotification), |
| 636 this); |
| 620 // Simulate a change to avoid possibly losing updates before this point. | 637 // Simulate a change to avoid possibly losing updates before this point. |
| 621 OnChangeNotification(); | 638 OnChangeNotification(); |
| 622 return true; | 639 return true; |
| 623 } | 640 } |
| 624 | 641 |
| 625 virtual base::SingleThreadTaskRunner* GetNotificationTaskRunner() OVERRIDE { | 642 virtual base::SingleThreadTaskRunner* GetNotificationTaskRunner() OVERRIDE { |
| 626 return task_runner_.get(); | 643 return task_runner_.get(); |
| 627 } | 644 } |
| 628 | 645 |
| 629 virtual ProxyConfigSource GetConfigSource() OVERRIDE { | 646 virtual ProxyConfigSource GetConfigSource() OVERRIDE { |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 688 return GetStringListByPath(client_, "ignore-hosts", result); | 705 return GetStringListByPath(client_, "ignore-hosts", result); |
| 689 } | 706 } |
| 690 return false; // Placate compiler. | 707 return false; // Placate compiler. |
| 691 } | 708 } |
| 692 | 709 |
| 693 virtual bool BypassListIsReversed() OVERRIDE { | 710 virtual bool BypassListIsReversed() OVERRIDE { |
| 694 // This is a KDE-specific setting. | 711 // This is a KDE-specific setting. |
| 695 return false; | 712 return false; |
| 696 } | 713 } |
| 697 | 714 |
| 698 virtual bool MatchHostsUsingSuffixMatching() OVERRIDE { | 715 virtual bool MatchHostsUsingSuffixMatching() OVERRIDE { return false; } |
| 699 return false; | |
| 700 } | |
| 701 | 716 |
| 702 private: | 717 private: |
| 703 bool GetStringByPath(GSettings* client, const char* key, | 718 bool GetStringByPath(GSettings* client, |
| 719 const char* key, |
| 704 std::string* result) { | 720 std::string* result) { |
| 705 DCHECK(task_runner_->BelongsToCurrentThread()); | 721 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 706 gchar* value = libgio_loader_.g_settings_get_string(client, key); | 722 gchar* value = libgio_loader_.g_settings_get_string(client, key); |
| 707 if (!value) | 723 if (!value) |
| 708 return false; | 724 return false; |
| 709 *result = value; | 725 *result = value; |
| 710 g_free(value); | 726 g_free(value); |
| 711 return true; | 727 return true; |
| 712 } | 728 } |
| 713 bool GetBoolByPath(GSettings* client, const char* key, bool* result) { | 729 bool GetBoolByPath(GSettings* client, const char* key, bool* result) { |
| 714 DCHECK(task_runner_->BelongsToCurrentThread()); | 730 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 715 *result = static_cast<bool>( | 731 *result = |
| 716 libgio_loader_.g_settings_get_boolean(client, key)); | 732 static_cast<bool>(libgio_loader_.g_settings_get_boolean(client, key)); |
| 717 return true; | 733 return true; |
| 718 } | 734 } |
| 719 bool GetIntByPath(GSettings* client, const char* key, int* result) { | 735 bool GetIntByPath(GSettings* client, const char* key, int* result) { |
| 720 DCHECK(task_runner_->BelongsToCurrentThread()); | 736 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 721 *result = libgio_loader_.g_settings_get_int(client, key); | 737 *result = libgio_loader_.g_settings_get_int(client, key); |
| 722 return true; | 738 return true; |
| 723 } | 739 } |
| 724 bool GetStringListByPath(GSettings* client, const char* key, | 740 bool GetStringListByPath(GSettings* client, |
| 741 const char* key, |
| 725 std::vector<std::string>* result) { | 742 std::vector<std::string>* result) { |
| 726 DCHECK(task_runner_->BelongsToCurrentThread()); | 743 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 727 gchar** list = libgio_loader_.g_settings_get_strv(client, key); | 744 gchar** list = libgio_loader_.g_settings_get_strv(client, key); |
| 728 if (!list) | 745 if (!list) |
| 729 return false; | 746 return false; |
| 730 for (size_t i = 0; list[i]; ++i) { | 747 for (size_t i = 0; list[i]; ++i) { |
| 731 result->push_back(static_cast<char*>(list[i])); | 748 result->push_back(static_cast<char*>(list[i])); |
| 732 g_free(list[i]); | 749 g_free(list[i]); |
| 733 } | 750 } |
| 734 g_free(list); | 751 g_free(list); |
| 735 return true; | 752 return true; |
| 736 } | 753 } |
| 737 | 754 |
| 738 // This is the callback from the debounce timer. | 755 // This is the callback from the debounce timer. |
| 739 void OnDebouncedNotification() { | 756 void OnDebouncedNotification() { |
| 740 DCHECK(task_runner_->BelongsToCurrentThread()); | 757 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 741 CHECK(notify_delegate_); | 758 CHECK(notify_delegate_); |
| 742 // Forward to a method on the proxy config service delegate object. | 759 // Forward to a method on the proxy config service delegate object. |
| 743 notify_delegate_->OnCheckProxyConfigSettings(); | 760 notify_delegate_->OnCheckProxyConfigSettings(); |
| 744 } | 761 } |
| 745 | 762 |
| 746 void OnChangeNotification() { | 763 void OnChangeNotification() { |
| 747 // We don't use Reset() because the timer may not yet be running. | 764 // We don't use Reset() because the timer may not yet be running. |
| 748 // (In that case Stop() is a no-op.) | 765 // (In that case Stop() is a no-op.) |
| 749 debounce_timer_.Stop(); | 766 debounce_timer_.Stop(); |
| 750 debounce_timer_.Start(FROM_HERE, | 767 debounce_timer_.Start( |
| 768 FROM_HERE, |
| 751 base::TimeDelta::FromMilliseconds(kDebounceTimeoutMilliseconds), | 769 base::TimeDelta::FromMilliseconds(kDebounceTimeoutMilliseconds), |
| 752 this, &SettingGetterImplGSettings::OnDebouncedNotification); | 770 this, |
| 771 &SettingGetterImplGSettings::OnDebouncedNotification); |
| 753 } | 772 } |
| 754 | 773 |
| 755 // gsettings notification callback, dispatched on the default glib main loop. | 774 // gsettings notification callback, dispatched on the default glib main loop. |
| 756 static void OnGSettingsChangeNotification(GSettings* client, gchar* key, | 775 static void OnGSettingsChangeNotification(GSettings* client, |
| 776 gchar* key, |
| 757 gpointer user_data) { | 777 gpointer user_data) { |
| 758 VLOG(1) << "gsettings change notification for key " << key; | 778 VLOG(1) << "gsettings change notification for key " << key; |
| 759 // We don't track which key has changed, just that something did change. | 779 // We don't track which key has changed, just that something did change. |
| 760 SettingGetterImplGSettings* setting_getter = | 780 SettingGetterImplGSettings* setting_getter = |
| 761 reinterpret_cast<SettingGetterImplGSettings*>(user_data); | 781 reinterpret_cast<SettingGetterImplGSettings*>(user_data); |
| 762 setting_getter->OnChangeNotification(); | 782 setting_getter->OnChangeNotification(); |
| 763 } | 783 } |
| 764 | 784 |
| 765 GSettings* client_; | 785 GSettings* client_; |
| 766 GSettings* http_client_; | 786 GSettings* http_client_; |
| 767 GSettings* https_client_; | 787 GSettings* https_client_; |
| 768 GSettings* ftp_client_; | 788 GSettings* ftp_client_; |
| 769 GSettings* socks_client_; | 789 GSettings* socks_client_; |
| 770 ProxyConfigServiceLinux::Delegate* notify_delegate_; | 790 ProxyConfigServiceLinux::Delegate* notify_delegate_; |
| 771 base::OneShotTimer<SettingGetterImplGSettings> debounce_timer_; | 791 base::OneShotTimer<SettingGetterImplGSettings> debounce_timer_; |
| 772 | 792 |
| 773 // Task runner for the thread that we make gsettings calls on. It should | 793 // Task runner for the thread that we make gsettings calls on. It should |
| 774 // be the UI thread and all our methods should be called on this | 794 // be the UI thread and all our methods should be called on this |
| 775 // thread. Only for assertions. | 795 // thread. Only for assertions. |
| 776 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | 796 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
| 777 | 797 |
| 778 LibGioLoader libgio_loader_; | 798 LibGioLoader libgio_loader_; |
| 779 | 799 |
| 780 DISALLOW_COPY_AND_ASSIGN(SettingGetterImplGSettings); | 800 DISALLOW_COPY_AND_ASSIGN(SettingGetterImplGSettings); |
| 781 }; | 801 }; |
| 782 | 802 |
| 783 bool SettingGetterImplGSettings::LoadAndCheckVersion( | 803 bool SettingGetterImplGSettings::LoadAndCheckVersion(base::Environment* env) { |
| 784 base::Environment* env) { | |
| 785 // LoadAndCheckVersion() must be called *before* Init()! | 804 // LoadAndCheckVersion() must be called *before* Init()! |
| 786 DCHECK(!client_); | 805 DCHECK(!client_); |
| 787 | 806 |
| 788 // The APIs to query gsettings were introduced after the minimum glib | 807 // The APIs to query gsettings were introduced after the minimum glib |
| 789 // version we target, so we can't link directly against them. We load them | 808 // version we target, so we can't link directly against them. We load them |
| 790 // dynamically at runtime, and if they don't exist, return false here. (We | 809 // dynamically at runtime, and if they don't exist, return false here. (We |
| 791 // support linking directly via gyp flags though.) Additionally, even when | 810 // support linking directly via gyp flags though.) Additionally, even when |
| 792 // they are present, we do two additional checks to make sure we should use | 811 // they are present, we do two additional checks to make sure we should use |
| 793 // them and not gconf. First, we attempt to load the schema for proxy | 812 // them and not gconf. First, we attempt to load the schema for proxy |
| 794 // settings. Second, we check for the program that was used in older | 813 // settings. Second, we check for the program that was used in older |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 842 } | 861 } |
| 843 #endif // defined(USE_GIO) | 862 #endif // defined(USE_GIO) |
| 844 | 863 |
| 845 // This is the KDE version that reads kioslaverc and simulates gconf. | 864 // This is the KDE version that reads kioslaverc and simulates gconf. |
| 846 // Doing this allows the main Delegate code, as well as the unit tests | 865 // Doing this allows the main Delegate code, as well as the unit tests |
| 847 // for it, to stay the same - and the settings map fairly well besides. | 866 // for it, to stay the same - and the settings map fairly well besides. |
| 848 class SettingGetterImplKDE : public ProxyConfigServiceLinux::SettingGetter, | 867 class SettingGetterImplKDE : public ProxyConfigServiceLinux::SettingGetter, |
| 849 public base::MessagePumpLibevent::Watcher { | 868 public base::MessagePumpLibevent::Watcher { |
| 850 public: | 869 public: |
| 851 explicit SettingGetterImplKDE(base::Environment* env_var_getter) | 870 explicit SettingGetterImplKDE(base::Environment* env_var_getter) |
| 852 : inotify_fd_(-1), notify_delegate_(NULL), indirect_manual_(false), | 871 : inotify_fd_(-1), |
| 853 auto_no_pac_(false), reversed_bypass_list_(false), | 872 notify_delegate_(NULL), |
| 854 env_var_getter_(env_var_getter), file_loop_(NULL) { | 873 indirect_manual_(false), |
| 874 auto_no_pac_(false), |
| 875 reversed_bypass_list_(false), |
| 876 env_var_getter_(env_var_getter), |
| 877 file_loop_(NULL) { |
| 855 // This has to be called on the UI thread (http://crbug.com/69057). | 878 // This has to be called on the UI thread (http://crbug.com/69057). |
| 856 base::ThreadRestrictions::ScopedAllowIO allow_io; | 879 base::ThreadRestrictions::ScopedAllowIO allow_io; |
| 857 | 880 |
| 858 // Derive the location of the kde config dir from the environment. | 881 // Derive the location of the kde config dir from the environment. |
| 859 std::string home; | 882 std::string home; |
| 860 if (env_var_getter->GetVar("KDEHOME", &home) && !home.empty()) { | 883 if (env_var_getter->GetVar("KDEHOME", &home) && !home.empty()) { |
| 861 // $KDEHOME is set. Use it unconditionally. | 884 // $KDEHOME is set. Use it unconditionally. |
| 862 kde_config_dir_ = KDEHomeToConfigPath(base::FilePath(home)); | 885 kde_config_dir_ = KDEHomeToConfigPath(base::FilePath(home)); |
| 863 } else { | 886 } else { |
| 864 // $KDEHOME is unset. Try to figure out what to use. This seems to be | 887 // $KDEHOME is unset. Try to figure out what to use. This seems to be |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 955 | 978 |
| 956 virtual bool SetUpNotifications( | 979 virtual bool SetUpNotifications( |
| 957 ProxyConfigServiceLinux::Delegate* delegate) OVERRIDE { | 980 ProxyConfigServiceLinux::Delegate* delegate) OVERRIDE { |
| 958 DCHECK(inotify_fd_ >= 0); | 981 DCHECK(inotify_fd_ >= 0); |
| 959 DCHECK(base::MessageLoop::current() == file_loop_); | 982 DCHECK(base::MessageLoop::current() == file_loop_); |
| 960 // We can't just watch the kioslaverc file directly, since KDE will write | 983 // We can't just watch the kioslaverc file directly, since KDE will write |
| 961 // a new copy of it and then rename it whenever settings are changed and | 984 // a new copy of it and then rename it whenever settings are changed and |
| 962 // inotify watches inodes (so we'll be watching the old deleted file after | 985 // inotify watches inodes (so we'll be watching the old deleted file after |
| 963 // the first change, and it will never change again). So, we watch the | 986 // the first change, and it will never change again). So, we watch the |
| 964 // directory instead. We then act only on changes to the kioslaverc entry. | 987 // directory instead. We then act only on changes to the kioslaverc entry. |
| 965 if (inotify_add_watch(inotify_fd_, kde_config_dir_.value().c_str(), | 988 if (inotify_add_watch(inotify_fd_, |
| 989 kde_config_dir_.value().c_str(), |
| 966 IN_MODIFY | IN_MOVED_TO) < 0) | 990 IN_MODIFY | IN_MOVED_TO) < 0) |
| 967 return false; | 991 return false; |
| 968 notify_delegate_ = delegate; | 992 notify_delegate_ = delegate; |
| 969 if (!file_loop_->WatchFileDescriptor(inotify_fd_, | 993 if (!file_loop_->WatchFileDescriptor(inotify_fd_, |
| 970 true, | 994 true, |
| 971 base::MessageLoopForIO::WATCH_READ, | 995 base::MessageLoopForIO::WATCH_READ, |
| 972 &inotify_watcher_, | 996 &inotify_watcher_, |
| 973 this)) | 997 this)) |
| 974 return false; | 998 return false; |
| 975 // Simulate a change to avoid possibly losing updates before this point. | 999 // Simulate a change to avoid possibly losing updates before this point. |
| 976 OnChangeNotification(); | 1000 OnChangeNotification(); |
| 977 return true; | 1001 return true; |
| 978 } | 1002 } |
| 979 | 1003 |
| 980 virtual base::SingleThreadTaskRunner* GetNotificationTaskRunner() OVERRIDE { | 1004 virtual base::SingleThreadTaskRunner* GetNotificationTaskRunner() OVERRIDE { |
| 981 return file_loop_ ? file_loop_->message_loop_proxy().get() : NULL; | 1005 return file_loop_ ? file_loop_->message_loop_proxy().get() : NULL; |
| 982 } | 1006 } |
| 983 | 1007 |
| 984 // Implement base::MessagePumpLibevent::Watcher. | 1008 // Implement base::MessagePumpLibevent::Watcher. |
| 985 virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE { | 1009 virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE { |
| 986 DCHECK_EQ(fd, inotify_fd_); | 1010 DCHECK_EQ(fd, inotify_fd_); |
| 987 DCHECK(base::MessageLoop::current() == file_loop_); | 1011 DCHECK(base::MessageLoop::current() == file_loop_); |
| 988 OnChangeNotification(); | 1012 OnChangeNotification(); |
| 989 } | 1013 } |
| 990 virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE { | 1014 virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE { NOTREACHED(); } |
| 991 NOTREACHED(); | |
| 992 } | |
| 993 | 1015 |
| 994 virtual ProxyConfigSource GetConfigSource() OVERRIDE { | 1016 virtual ProxyConfigSource GetConfigSource() OVERRIDE { |
| 995 return PROXY_CONFIG_SOURCE_KDE; | 1017 return PROXY_CONFIG_SOURCE_KDE; |
| 996 } | 1018 } |
| 997 | 1019 |
| 998 virtual bool GetString(StringSetting key, std::string* result) OVERRIDE { | 1020 virtual bool GetString(StringSetting key, std::string* result) OVERRIDE { |
| 999 string_map_type::iterator it = string_table_.find(key); | 1021 string_map_type::iterator it = string_table_.find(key); |
| 1000 if (it == string_table_.end()) | 1022 if (it == string_table_.end()) |
| 1001 return false; | 1023 return false; |
| 1002 *result = it->second; | 1024 *result = it->second; |
| 1003 return true; | 1025 return true; |
| 1004 } | 1026 } |
| 1005 virtual bool GetBool(BoolSetting key, bool* result) OVERRIDE { | 1027 virtual bool GetBool(BoolSetting key, bool* result) OVERRIDE { |
| 1006 // We don't ever have any booleans. | 1028 // We don't ever have any booleans. |
| 1007 return false; | 1029 return false; |
| 1008 } | 1030 } |
| 1009 virtual bool GetInt(IntSetting key, int* result) OVERRIDE { | 1031 virtual bool GetInt(IntSetting key, int* result) OVERRIDE { |
| 1010 // We don't ever have any integers. (See AddProxy() below about ports.) | 1032 // We don't ever have any integers. (See AddProxy() below about ports.) |
| 1011 return false; | 1033 return false; |
| 1012 } | 1034 } |
| 1013 virtual bool GetStringList(StringListSetting key, | 1035 virtual bool GetStringList(StringListSetting key, |
| 1014 std::vector<std::string>* result) OVERRIDE { | 1036 std::vector<std::string>* result) OVERRIDE { |
| 1015 strings_map_type::iterator it = strings_table_.find(key); | 1037 strings_map_type::iterator it = strings_table_.find(key); |
| 1016 if (it == strings_table_.end()) | 1038 if (it == strings_table_.end()) |
| 1017 return false; | 1039 return false; |
| 1018 *result = it->second; | 1040 *result = it->second; |
| 1019 return true; | 1041 return true; |
| 1020 } | 1042 } |
| 1021 | 1043 |
| 1022 virtual bool BypassListIsReversed() OVERRIDE { | 1044 virtual bool BypassListIsReversed() OVERRIDE { return reversed_bypass_list_; } |
| 1023 return reversed_bypass_list_; | |
| 1024 } | |
| 1025 | 1045 |
| 1026 virtual bool MatchHostsUsingSuffixMatching() OVERRIDE { | 1046 virtual bool MatchHostsUsingSuffixMatching() OVERRIDE { return true; } |
| 1027 return true; | |
| 1028 } | |
| 1029 | 1047 |
| 1030 private: | 1048 private: |
| 1031 void ResetCachedSettings() { | 1049 void ResetCachedSettings() { |
| 1032 string_table_.clear(); | 1050 string_table_.clear(); |
| 1033 strings_table_.clear(); | 1051 strings_table_.clear(); |
| 1034 indirect_manual_ = false; | 1052 indirect_manual_ = false; |
| 1035 auto_no_pac_ = false; | 1053 auto_no_pac_ = false; |
| 1036 reversed_bypass_list_ = false; | 1054 reversed_bypass_list_ = false; |
| 1037 } | 1055 } |
| 1038 | 1056 |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1118 reversed_bypass_list_ = (value == "true" || int_value); | 1136 reversed_bypass_list_ = (value == "true" || int_value); |
| 1119 } else if (key == "NoProxyFor") { | 1137 } else if (key == "NoProxyFor") { |
| 1120 AddHostList(PROXY_IGNORE_HOSTS, value); | 1138 AddHostList(PROXY_IGNORE_HOSTS, value); |
| 1121 } else if (key == "AuthMode") { | 1139 } else if (key == "AuthMode") { |
| 1122 // Check for authentication, just so we can warn. | 1140 // Check for authentication, just so we can warn. |
| 1123 int mode; | 1141 int mode; |
| 1124 base::StringToInt(value, &mode); | 1142 base::StringToInt(value, &mode); |
| 1125 if (mode) { | 1143 if (mode) { |
| 1126 // ProxyConfig does not support authentication parameters, but | 1144 // ProxyConfig does not support authentication parameters, but |
| 1127 // Chrome will prompt for the password later. So we ignore this. | 1145 // Chrome will prompt for the password later. So we ignore this. |
| 1128 LOG(WARNING) << | 1146 LOG(WARNING) |
| 1129 "Proxy authentication parameters ignored, see bug 16709"; | 1147 << "Proxy authentication parameters ignored, see bug 16709"; |
| 1130 } | 1148 } |
| 1131 } | 1149 } |
| 1132 } | 1150 } |
| 1133 | 1151 |
| 1134 void ResolveIndirect(StringSetting key) { | 1152 void ResolveIndirect(StringSetting key) { |
| 1135 string_map_type::iterator it = string_table_.find(key); | 1153 string_map_type::iterator it = string_table_.find(key); |
| 1136 if (it != string_table_.end()) { | 1154 if (it != string_table_.end()) { |
| 1137 std::string value; | 1155 std::string value; |
| 1138 if (env_var_getter_->GetVar(it->second.c_str(), &value)) | 1156 if (env_var_getter_->GetVar(it->second.c_str(), &value)) |
| 1139 it->second = value; | 1157 it->second = value; |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1255 UpdateCachedSettings(); | 1273 UpdateCachedSettings(); |
| 1256 CHECK(notify_delegate_); | 1274 CHECK(notify_delegate_); |
| 1257 // Forward to a method on the proxy config service delegate object. | 1275 // Forward to a method on the proxy config service delegate object. |
| 1258 notify_delegate_->OnCheckProxyConfigSettings(); | 1276 notify_delegate_->OnCheckProxyConfigSettings(); |
| 1259 } | 1277 } |
| 1260 | 1278 |
| 1261 // Called by OnFileCanReadWithoutBlocking() on the file thread. Reads | 1279 // Called by OnFileCanReadWithoutBlocking() on the file thread. Reads |
| 1262 // from the inotify file descriptor and starts up a debounce timer if | 1280 // from the inotify file descriptor and starts up a debounce timer if |
| 1263 // an event for kioslaverc is seen. | 1281 // an event for kioslaverc is seen. |
| 1264 void OnChangeNotification() { | 1282 void OnChangeNotification() { |
| 1265 DCHECK_GE(inotify_fd_, 0); | 1283 DCHECK_GE(inotify_fd_, 0); |
| 1266 DCHECK(base::MessageLoop::current() == file_loop_); | 1284 DCHECK(base::MessageLoop::current() == file_loop_); |
| 1267 char event_buf[(sizeof(inotify_event) + NAME_MAX + 1) * 4]; | 1285 char event_buf[(sizeof(inotify_event) + NAME_MAX + 1) * 4]; |
| 1268 bool kioslaverc_touched = false; | 1286 bool kioslaverc_touched = false; |
| 1269 ssize_t r; | 1287 ssize_t r; |
| 1270 while ((r = read(inotify_fd_, event_buf, sizeof(event_buf))) > 0) { | 1288 while ((r = read(inotify_fd_, event_buf, sizeof(event_buf))) > 0) { |
| 1271 // inotify returns variable-length structures, which is why we have | 1289 // inotify returns variable-length structures, which is why we have |
| 1272 // this strange-looking loop instead of iterating through an array. | 1290 // this strange-looking loop instead of iterating through an array. |
| 1273 char* event_ptr = event_buf; | 1291 char* event_ptr = event_buf; |
| 1274 while (event_ptr < event_buf + r) { | 1292 while (event_ptr < event_buf + r) { |
| 1275 inotify_event* event = reinterpret_cast<inotify_event*>(event_ptr); | 1293 inotify_event* event = reinterpret_cast<inotify_event*>(event_ptr); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1299 LOG(ERROR) << "inotify failure; no longer watching kioslaverc!"; | 1317 LOG(ERROR) << "inotify failure; no longer watching kioslaverc!"; |
| 1300 inotify_watcher_.StopWatchingFileDescriptor(); | 1318 inotify_watcher_.StopWatchingFileDescriptor(); |
| 1301 close(inotify_fd_); | 1319 close(inotify_fd_); |
| 1302 inotify_fd_ = -1; | 1320 inotify_fd_ = -1; |
| 1303 } | 1321 } |
| 1304 } | 1322 } |
| 1305 if (kioslaverc_touched) { | 1323 if (kioslaverc_touched) { |
| 1306 // We don't use Reset() because the timer may not yet be running. | 1324 // We don't use Reset() because the timer may not yet be running. |
| 1307 // (In that case Stop() is a no-op.) | 1325 // (In that case Stop() is a no-op.) |
| 1308 debounce_timer_.Stop(); | 1326 debounce_timer_.Stop(); |
| 1309 debounce_timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds( | 1327 debounce_timer_.Start( |
| 1310 kDebounceTimeoutMilliseconds), this, | 1328 FROM_HERE, |
| 1329 base::TimeDelta::FromMilliseconds(kDebounceTimeoutMilliseconds), |
| 1330 this, |
| 1311 &SettingGetterImplKDE::OnDebouncedNotification); | 1331 &SettingGetterImplKDE::OnDebouncedNotification); |
| 1312 } | 1332 } |
| 1313 } | 1333 } |
| 1314 | 1334 |
| 1315 typedef std::map<StringSetting, std::string> string_map_type; | 1335 typedef std::map<StringSetting, std::string> string_map_type; |
| 1316 typedef std::map<StringListSetting, | 1336 typedef std::map<StringListSetting, std::vector<std::string> > |
| 1317 std::vector<std::string> > strings_map_type; | 1337 strings_map_type; |
| 1318 | 1338 |
| 1319 int inotify_fd_; | 1339 int inotify_fd_; |
| 1320 base::MessagePumpLibevent::FileDescriptorWatcher inotify_watcher_; | 1340 base::MessagePumpLibevent::FileDescriptorWatcher inotify_watcher_; |
| 1321 ProxyConfigServiceLinux::Delegate* notify_delegate_; | 1341 ProxyConfigServiceLinux::Delegate* notify_delegate_; |
| 1322 base::OneShotTimer<SettingGetterImplKDE> debounce_timer_; | 1342 base::OneShotTimer<SettingGetterImplKDE> debounce_timer_; |
| 1323 base::FilePath kde_config_dir_; | 1343 base::FilePath kde_config_dir_; |
| 1324 bool indirect_manual_; | 1344 bool indirect_manual_; |
| 1325 bool auto_no_pac_; | 1345 bool auto_no_pac_; |
| 1326 bool reversed_bypass_list_; | 1346 bool reversed_bypass_list_; |
| 1327 // We don't own |env_var_getter_|. It's safe to hold a pointer to it, since | 1347 // We don't own |env_var_getter_|. It's safe to hold a pointer to it, since |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1357 SettingGetter::HostSettingToPortSetting(host_key); | 1377 SettingGetter::HostSettingToPortSetting(host_key); |
| 1358 setting_getter_->GetInt(port_key, &port); | 1378 setting_getter_->GetInt(port_key, &port); |
| 1359 if (port != 0) { | 1379 if (port != 0) { |
| 1360 // If a port is set and non-zero: | 1380 // If a port is set and non-zero: |
| 1361 host += ":" + base::IntToString(port); | 1381 host += ":" + base::IntToString(port); |
| 1362 } | 1382 } |
| 1363 | 1383 |
| 1364 // gconf settings do not appear to distinguish between SOCKS version. We | 1384 // gconf settings do not appear to distinguish between SOCKS version. We |
| 1365 // default to version 5. For more information on this policy decision, see: | 1385 // default to version 5. For more information on this policy decision, see: |
| 1366 // http://code.google.com/p/chromium/issues/detail?id=55912#c2 | 1386 // http://code.google.com/p/chromium/issues/detail?id=55912#c2 |
| 1367 ProxyServer::Scheme scheme = (host_key == SettingGetter::PROXY_SOCKS_HOST) ? | 1387 ProxyServer::Scheme scheme = (host_key == SettingGetter::PROXY_SOCKS_HOST) |
| 1368 ProxyServer::SCHEME_SOCKS5 : ProxyServer::SCHEME_HTTP; | 1388 ? ProxyServer::SCHEME_SOCKS5 |
| 1389 : ProxyServer::SCHEME_HTTP; |
| 1369 host = FixupProxyHostScheme(scheme, host); | 1390 host = FixupProxyHostScheme(scheme, host); |
| 1370 ProxyServer proxy_server = ProxyServer::FromURI(host, | 1391 ProxyServer proxy_server = |
| 1371 ProxyServer::SCHEME_HTTP); | 1392 ProxyServer::FromURI(host, ProxyServer::SCHEME_HTTP); |
| 1372 if (proxy_server.is_valid()) { | 1393 if (proxy_server.is_valid()) { |
| 1373 *result_server = proxy_server; | 1394 *result_server = proxy_server; |
| 1374 return true; | 1395 return true; |
| 1375 } | 1396 } |
| 1376 return false; | 1397 return false; |
| 1377 } | 1398 } |
| 1378 | 1399 |
| 1379 bool ProxyConfigServiceLinux::Delegate::GetConfigFromSettings( | 1400 bool ProxyConfigServiceLinux::Delegate::GetConfigFromSettings( |
| 1380 ProxyConfig* config) { | 1401 ProxyConfig* config) { |
| 1381 std::string mode; | 1402 std::string mode; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1409 config->set_auto_detect(true); | 1430 config->set_auto_detect(true); |
| 1410 return true; | 1431 return true; |
| 1411 } | 1432 } |
| 1412 | 1433 |
| 1413 if (mode != "manual") { | 1434 if (mode != "manual") { |
| 1414 // Mode is unrecognized. | 1435 // Mode is unrecognized. |
| 1415 return false; | 1436 return false; |
| 1416 } | 1437 } |
| 1417 bool use_http_proxy; | 1438 bool use_http_proxy; |
| 1418 if (setting_getter_->GetBool(SettingGetter::PROXY_USE_HTTP_PROXY, | 1439 if (setting_getter_->GetBool(SettingGetter::PROXY_USE_HTTP_PROXY, |
| 1419 &use_http_proxy) | 1440 &use_http_proxy) && |
| 1420 && !use_http_proxy) { | 1441 !use_http_proxy) { |
| 1421 // Another master switch for some reason. If set to false, then no | 1442 // Another master switch for some reason. If set to false, then no |
| 1422 // proxy. But we don't panic if the key doesn't exist. | 1443 // proxy. But we don't panic if the key doesn't exist. |
| 1423 return true; | 1444 return true; |
| 1424 } | 1445 } |
| 1425 | 1446 |
| 1426 bool same_proxy = false; | 1447 bool same_proxy = false; |
| 1427 // Indicates to use the http proxy for all protocols. This one may | 1448 // Indicates to use the http proxy for all protocols. This one may |
| 1428 // not exist (presumably on older versions); we assume false in that | 1449 // not exist (presumably on older versions); we assume false in that |
| 1429 // case. | 1450 // case. |
| 1430 setting_getter_->GetBool(SettingGetter::PROXY_USE_SAME_PROXY, | 1451 setting_getter_->GetBool(SettingGetter::PROXY_USE_SAME_PROXY, &same_proxy); |
| 1431 &same_proxy); | |
| 1432 | 1452 |
| 1433 ProxyServer proxy_for_http; | 1453 ProxyServer proxy_for_http; |
| 1434 ProxyServer proxy_for_https; | 1454 ProxyServer proxy_for_https; |
| 1435 ProxyServer proxy_for_ftp; | 1455 ProxyServer proxy_for_ftp; |
| 1436 ProxyServer socks_proxy; // (socks) | 1456 ProxyServer socks_proxy; // (socks) |
| 1437 | 1457 |
| 1438 // This counts how many of the above ProxyServers were defined and valid. | 1458 // This counts how many of the above ProxyServers were defined and valid. |
| 1439 size_t num_proxies_specified = 0; | 1459 size_t num_proxies_specified = 0; |
| 1440 | 1460 |
| 1441 // Extract the per-scheme proxies. If we failed to parse it, or no proxy was | 1461 // Extract the per-scheme proxies. If we failed to parse it, or no proxy was |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1457 } | 1477 } |
| 1458 } else if (num_proxies_specified > 0) { | 1478 } else if (num_proxies_specified > 0) { |
| 1459 if (socks_proxy.is_valid() && num_proxies_specified == 1) { | 1479 if (socks_proxy.is_valid() && num_proxies_specified == 1) { |
| 1460 // If the only proxy specified was for SOCKS, use it for all schemes. | 1480 // If the only proxy specified was for SOCKS, use it for all schemes. |
| 1461 config->proxy_rules().type = ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY; | 1481 config->proxy_rules().type = ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY; |
| 1462 config->proxy_rules().single_proxies.SetSingleProxyServer(socks_proxy); | 1482 config->proxy_rules().single_proxies.SetSingleProxyServer(socks_proxy); |
| 1463 } else { | 1483 } else { |
| 1464 // Otherwise use the indicated proxies per-scheme. | 1484 // Otherwise use the indicated proxies per-scheme. |
| 1465 config->proxy_rules().type = | 1485 config->proxy_rules().type = |
| 1466 ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME; | 1486 ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME; |
| 1467 config->proxy_rules().proxies_for_http. | 1487 config->proxy_rules().proxies_for_http.SetSingleProxyServer( |
| 1468 SetSingleProxyServer(proxy_for_http); | 1488 proxy_for_http); |
| 1469 config->proxy_rules().proxies_for_https. | 1489 config->proxy_rules().proxies_for_https.SetSingleProxyServer( |
| 1470 SetSingleProxyServer(proxy_for_https); | 1490 proxy_for_https); |
| 1471 config->proxy_rules().proxies_for_ftp.SetSingleProxyServer(proxy_for_ftp); | 1491 config->proxy_rules().proxies_for_ftp.SetSingleProxyServer(proxy_for_ftp); |
| 1472 config->proxy_rules().fallback_proxies.SetSingleProxyServer(socks_proxy); | 1492 config->proxy_rules().fallback_proxies.SetSingleProxyServer(socks_proxy); |
| 1473 } | 1493 } |
| 1474 } | 1494 } |
| 1475 | 1495 |
| 1476 if (config->proxy_rules().empty()) { | 1496 if (config->proxy_rules().empty()) { |
| 1477 // Manual mode but we couldn't parse any rules. | 1497 // Manual mode but we couldn't parse any rules. |
| 1478 return false; | 1498 return false; |
| 1479 } | 1499 } |
| 1480 | 1500 |
| 1481 // Check for authentication, just so we can warn. | 1501 // Check for authentication, just so we can warn. |
| 1482 bool use_auth = false; | 1502 bool use_auth = false; |
| 1483 setting_getter_->GetBool(SettingGetter::PROXY_USE_AUTHENTICATION, | 1503 setting_getter_->GetBool(SettingGetter::PROXY_USE_AUTHENTICATION, &use_auth); |
| 1484 &use_auth); | |
| 1485 if (use_auth) { | 1504 if (use_auth) { |
| 1486 // ProxyConfig does not support authentication parameters, but | 1505 // ProxyConfig does not support authentication parameters, but |
| 1487 // Chrome will prompt for the password later. So we ignore | 1506 // Chrome will prompt for the password later. So we ignore |
| 1488 // /system/http_proxy/*auth* settings. | 1507 // /system/http_proxy/*auth* settings. |
| 1489 LOG(WARNING) << "Proxy authentication parameters ignored, see bug 16709"; | 1508 LOG(WARNING) << "Proxy authentication parameters ignored, see bug 16709"; |
| 1490 } | 1509 } |
| 1491 | 1510 |
| 1492 // Now the bypass list. | 1511 // Now the bypass list. |
| 1493 std::vector<std::string> ignore_hosts_list; | 1512 std::vector<std::string> ignore_hosts_list; |
| 1494 config->proxy_rules().bypass_rules.Clear(); | 1513 config->proxy_rules().bypass_rules.Clear(); |
| 1495 if (setting_getter_->GetStringList(SettingGetter::PROXY_IGNORE_HOSTS, | 1514 if (setting_getter_->GetStringList(SettingGetter::PROXY_IGNORE_HOSTS, |
| 1496 &ignore_hosts_list)) { | 1515 &ignore_hosts_list)) { |
| 1497 std::vector<std::string>::const_iterator it(ignore_hosts_list.begin()); | 1516 std::vector<std::string>::const_iterator it(ignore_hosts_list.begin()); |
| 1498 for (; it != ignore_hosts_list.end(); ++it) { | 1517 for (; it != ignore_hosts_list.end(); ++it) { |
| 1499 if (setting_getter_->MatchHostsUsingSuffixMatching()) { | 1518 if (setting_getter_->MatchHostsUsingSuffixMatching()) { |
| 1500 config->proxy_rules().bypass_rules. | 1519 config->proxy_rules().bypass_rules.AddRuleFromStringUsingSuffixMatching( |
| 1501 AddRuleFromStringUsingSuffixMatching(*it); | 1520 *it); |
| 1502 } else { | 1521 } else { |
| 1503 config->proxy_rules().bypass_rules.AddRuleFromString(*it); | 1522 config->proxy_rules().bypass_rules.AddRuleFromString(*it); |
| 1504 } | 1523 } |
| 1505 } | 1524 } |
| 1506 } | 1525 } |
| 1507 // Note that there are no settings with semantics corresponding to | 1526 // Note that there are no settings with semantics corresponding to |
| 1508 // bypass of local names in GNOME. In KDE, "<local>" is supported | 1527 // bypass of local names in GNOME. In KDE, "<local>" is supported |
| 1509 // as a hostname rule. | 1528 // as a hostname rule. |
| 1510 | 1529 |
| 1511 // KDE allows one to reverse the bypass rules. | 1530 // KDE allows one to reverse the bypass rules. |
| 1512 config->proxy_rules().reverse_bypass = | 1531 config->proxy_rules().reverse_bypass = |
| 1513 setting_getter_->BypassListIsReversed(); | 1532 setting_getter_->BypassListIsReversed(); |
| 1514 | 1533 |
| 1515 return true; | 1534 return true; |
| 1516 } | 1535 } |
| 1517 | 1536 |
| 1518 ProxyConfigServiceLinux::Delegate::Delegate(base::Environment* env_var_getter) | 1537 ProxyConfigServiceLinux::Delegate::Delegate(base::Environment* env_var_getter) |
| 1519 : env_var_getter_(env_var_getter) { | 1538 : env_var_getter_(env_var_getter) { |
| 1520 // Figure out which SettingGetterImpl to use, if any. | 1539 // Figure out which SettingGetterImpl to use, if any. |
| 1521 switch (base::nix::GetDesktopEnvironment(env_var_getter)) { | 1540 switch (base::nix::GetDesktopEnvironment(env_var_getter)) { |
| 1522 case base::nix::DESKTOP_ENVIRONMENT_GNOME: | 1541 case base::nix::DESKTOP_ENVIRONMENT_GNOME: |
| 1523 case base::nix::DESKTOP_ENVIRONMENT_UNITY: | 1542 case base::nix::DESKTOP_ENVIRONMENT_UNITY: |
| 1524 #if defined(USE_GIO) | 1543 #if defined(USE_GIO) |
| 1525 { | 1544 { |
| 1526 scoped_ptr<SettingGetterImplGSettings> gs_getter( | 1545 scoped_ptr<SettingGetterImplGSettings> gs_getter( |
| 1527 new SettingGetterImplGSettings()); | 1546 new SettingGetterImplGSettings()); |
| 1528 // We have to load symbols and check the GNOME version in use to decide | 1547 // We have to load symbols and check the GNOME version in use to decide |
| 1529 // if we should use the gsettings getter. See LoadAndCheckVersion(). | 1548 // if we should use the gsettings getter. See LoadAndCheckVersion(). |
| 1530 if (gs_getter->LoadAndCheckVersion(env_var_getter)) | 1549 if (gs_getter->LoadAndCheckVersion(env_var_getter)) |
| 1531 setting_getter_.reset(gs_getter.release()); | 1550 setting_getter_.reset(gs_getter.release()); |
| 1532 } | 1551 } |
| 1533 #endif | 1552 #endif |
| 1534 #if defined(USE_GCONF) | 1553 #if defined(USE_GCONF) |
| 1535 // Fall back on gconf if gsettings is unavailable or incorrect. | 1554 // Fall back on gconf if gsettings is unavailable or incorrect. |
| 1536 if (!setting_getter_.get()) | 1555 if (!setting_getter_.get()) |
| 1537 setting_getter_.reset(new SettingGetterImplGConf()); | 1556 setting_getter_.reset(new SettingGetterImplGConf()); |
| 1538 #endif | 1557 #endif |
| 1539 break; | 1558 break; |
| 1540 case base::nix::DESKTOP_ENVIRONMENT_KDE3: | 1559 case base::nix::DESKTOP_ENVIRONMENT_KDE3: |
| 1541 case base::nix::DESKTOP_ENVIRONMENT_KDE4: | 1560 case base::nix::DESKTOP_ENVIRONMENT_KDE4: |
| 1542 setting_getter_.reset(new SettingGetterImplKDE(env_var_getter)); | 1561 setting_getter_.reset(new SettingGetterImplKDE(env_var_getter)); |
| 1543 break; | 1562 break; |
| 1544 case base::nix::DESKTOP_ENVIRONMENT_XFCE: | 1563 case base::nix::DESKTOP_ENVIRONMENT_XFCE: |
| 1545 case base::nix::DESKTOP_ENVIRONMENT_OTHER: | 1564 case base::nix::DESKTOP_ENVIRONMENT_OTHER: |
| 1546 break; | 1565 break; |
| 1547 } | 1566 } |
| 1548 } | 1567 } |
| 1549 | 1568 |
| 1550 ProxyConfigServiceLinux::Delegate::Delegate( | 1569 ProxyConfigServiceLinux::Delegate::Delegate(base::Environment* env_var_getter, |
| 1551 base::Environment* env_var_getter, SettingGetter* setting_getter) | 1570 SettingGetter* setting_getter) |
| 1552 : env_var_getter_(env_var_getter), setting_getter_(setting_getter) { | 1571 : env_var_getter_(env_var_getter), setting_getter_(setting_getter) { |
| 1553 } | 1572 } |
| 1554 | 1573 |
| 1555 void ProxyConfigServiceLinux::Delegate::SetUpAndFetchInitialConfig( | 1574 void ProxyConfigServiceLinux::Delegate::SetUpAndFetchInitialConfig( |
| 1556 base::SingleThreadTaskRunner* glib_thread_task_runner, | 1575 base::SingleThreadTaskRunner* glib_thread_task_runner, |
| 1557 base::SingleThreadTaskRunner* io_thread_task_runner, | 1576 base::SingleThreadTaskRunner* io_thread_task_runner, |
| 1558 base::MessageLoopForIO* file_loop) { | 1577 base::MessageLoopForIO* file_loop) { |
| 1559 // We should be running on the default glib main loop thread right | 1578 // We should be running on the default glib main loop thread right |
| 1560 // now. gconf can only be accessed from this thread. | 1579 // now. gconf can only be accessed from this thread. |
| 1561 DCHECK(glib_thread_task_runner->BelongsToCurrentThread()); | 1580 DCHECK(glib_thread_task_runner->BelongsToCurrentThread()); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1609 // fetch and before setting up notifications. We'll detect the common case | 1628 // fetch and before setting up notifications. We'll detect the common case |
| 1610 // of no changes in OnCheckProxyConfigSettings() (or sooner) and ignore it. | 1629 // of no changes in OnCheckProxyConfigSettings() (or sooner) and ignore it. |
| 1611 if (io_thread_task_runner && file_loop) { | 1630 if (io_thread_task_runner && file_loop) { |
| 1612 scoped_refptr<base::SingleThreadTaskRunner> required_loop = | 1631 scoped_refptr<base::SingleThreadTaskRunner> required_loop = |
| 1613 setting_getter_->GetNotificationTaskRunner(); | 1632 setting_getter_->GetNotificationTaskRunner(); |
| 1614 if (!required_loop.get() || required_loop->BelongsToCurrentThread()) { | 1633 if (!required_loop.get() || required_loop->BelongsToCurrentThread()) { |
| 1615 // In this case we are already on an acceptable thread. | 1634 // In this case we are already on an acceptable thread. |
| 1616 SetUpNotifications(); | 1635 SetUpNotifications(); |
| 1617 } else { | 1636 } else { |
| 1618 // Post a task to set up notifications. We don't wait for success. | 1637 // Post a task to set up notifications. We don't wait for success. |
| 1619 required_loop->PostTask(FROM_HERE, base::Bind( | 1638 required_loop->PostTask( |
| 1620 &ProxyConfigServiceLinux::Delegate::SetUpNotifications, this)); | 1639 FROM_HERE, |
| 1640 base::Bind(&ProxyConfigServiceLinux::Delegate::SetUpNotifications, |
| 1641 this)); |
| 1621 } | 1642 } |
| 1622 } | 1643 } |
| 1623 } | 1644 } |
| 1624 | 1645 |
| 1625 if (!got_config) { | 1646 if (!got_config) { |
| 1626 // We fall back on environment variables. | 1647 // We fall back on environment variables. |
| 1627 // | 1648 // |
| 1628 // Consulting environment variables doesn't need to be done from the | 1649 // Consulting environment variables doesn't need to be done from the |
| 1629 // default glib main loop, but it's a tiny enough amount of work. | 1650 // default glib main loop, but it's a tiny enough amount of work. |
| 1630 if (GetConfigFromEnv(&cached_config_)) { | 1651 if (GetConfigFromEnv(&cached_config_)) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1647 | 1668 |
| 1648 void ProxyConfigServiceLinux::Delegate::AddObserver(Observer* observer) { | 1669 void ProxyConfigServiceLinux::Delegate::AddObserver(Observer* observer) { |
| 1649 observers_.AddObserver(observer); | 1670 observers_.AddObserver(observer); |
| 1650 } | 1671 } |
| 1651 | 1672 |
| 1652 void ProxyConfigServiceLinux::Delegate::RemoveObserver(Observer* observer) { | 1673 void ProxyConfigServiceLinux::Delegate::RemoveObserver(Observer* observer) { |
| 1653 observers_.RemoveObserver(observer); | 1674 observers_.RemoveObserver(observer); |
| 1654 } | 1675 } |
| 1655 | 1676 |
| 1656 ProxyConfigService::ConfigAvailability | 1677 ProxyConfigService::ConfigAvailability |
| 1657 ProxyConfigServiceLinux::Delegate::GetLatestProxyConfig( | 1678 ProxyConfigServiceLinux::Delegate::GetLatestProxyConfig(ProxyConfig* config) { |
| 1658 ProxyConfig* config) { | |
| 1659 // This is called from the IO thread. | 1679 // This is called from the IO thread. |
| 1660 DCHECK(!io_thread_task_runner_.get() || | 1680 DCHECK(!io_thread_task_runner_.get() || |
| 1661 io_thread_task_runner_->BelongsToCurrentThread()); | 1681 io_thread_task_runner_->BelongsToCurrentThread()); |
| 1662 | 1682 |
| 1663 // Simply return the last proxy configuration that glib_default_loop | 1683 // Simply return the last proxy configuration that glib_default_loop |
| 1664 // notified us of. | 1684 // notified us of. |
| 1665 if (cached_config_.is_valid()) { | 1685 if (cached_config_.is_valid()) { |
| 1666 *config = cached_config_; | 1686 *config = cached_config_; |
| 1667 } else { | 1687 } else { |
| 1668 *config = ProxyConfig::CreateDirect(); | 1688 *config = ProxyConfig::CreateDirect(); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1686 ProxyConfig new_config; | 1706 ProxyConfig new_config; |
| 1687 bool valid = GetConfigFromSettings(&new_config); | 1707 bool valid = GetConfigFromSettings(&new_config); |
| 1688 if (valid) | 1708 if (valid) |
| 1689 new_config.set_id(1); // mark it as valid | 1709 new_config.set_id(1); // mark it as valid |
| 1690 | 1710 |
| 1691 // See if it is different from what we had before. | 1711 // See if it is different from what we had before. |
| 1692 if (new_config.is_valid() != reference_config_.is_valid() || | 1712 if (new_config.is_valid() != reference_config_.is_valid() || |
| 1693 !new_config.Equals(reference_config_)) { | 1713 !new_config.Equals(reference_config_)) { |
| 1694 // Post a task to the IO thread with the new configuration, so it can | 1714 // Post a task to the IO thread with the new configuration, so it can |
| 1695 // update |cached_config_|. | 1715 // update |cached_config_|. |
| 1696 io_thread_task_runner_->PostTask(FROM_HERE, base::Bind( | 1716 io_thread_task_runner_->PostTask( |
| 1697 &ProxyConfigServiceLinux::Delegate::SetNewProxyConfig, | 1717 FROM_HERE, |
| 1698 this, new_config)); | 1718 base::Bind(&ProxyConfigServiceLinux::Delegate::SetNewProxyConfig, |
| 1719 this, |
| 1720 new_config)); |
| 1699 // Update the thread-private copy in |reference_config_| as well. | 1721 // Update the thread-private copy in |reference_config_| as well. |
| 1700 reference_config_ = new_config; | 1722 reference_config_ = new_config; |
| 1701 } else { | 1723 } else { |
| 1702 VLOG(1) << "Detected no-op change to proxy settings. Doing nothing."; | 1724 VLOG(1) << "Detected no-op change to proxy settings. Doing nothing."; |
| 1703 } | 1725 } |
| 1704 } | 1726 } |
| 1705 | 1727 |
| 1706 void ProxyConfigServiceLinux::Delegate::SetNewProxyConfig( | 1728 void ProxyConfigServiceLinux::Delegate::SetNewProxyConfig( |
| 1707 const ProxyConfig& new_config) { | 1729 const ProxyConfig& new_config) { |
| 1708 DCHECK(io_thread_task_runner_->BelongsToCurrentThread()); | 1730 DCHECK(io_thread_task_runner_->BelongsToCurrentThread()); |
| 1709 VLOG(1) << "Proxy configuration changed"; | 1731 VLOG(1) << "Proxy configuration changed"; |
| 1710 cached_config_ = new_config; | 1732 cached_config_ = new_config; |
| 1711 FOR_EACH_OBSERVER( | 1733 FOR_EACH_OBSERVER( |
| 1712 Observer, observers_, | 1734 Observer, |
| 1735 observers_, |
| 1713 OnProxyConfigChanged(new_config, ProxyConfigService::CONFIG_VALID)); | 1736 OnProxyConfigChanged(new_config, ProxyConfigService::CONFIG_VALID)); |
| 1714 } | 1737 } |
| 1715 | 1738 |
| 1716 void ProxyConfigServiceLinux::Delegate::PostDestroyTask() { | 1739 void ProxyConfigServiceLinux::Delegate::PostDestroyTask() { |
| 1717 if (!setting_getter_.get()) | 1740 if (!setting_getter_.get()) |
| 1718 return; | 1741 return; |
| 1719 scoped_refptr<base::SingleThreadTaskRunner> shutdown_loop = | 1742 scoped_refptr<base::SingleThreadTaskRunner> shutdown_loop = |
| 1720 setting_getter_->GetNotificationTaskRunner(); | 1743 setting_getter_->GetNotificationTaskRunner(); |
| 1721 if (!shutdown_loop.get() || shutdown_loop->BelongsToCurrentThread()) { | 1744 if (!shutdown_loop.get() || shutdown_loop->BelongsToCurrentThread()) { |
| 1722 // Already on the right thread, call directly. | 1745 // Already on the right thread, call directly. |
| 1723 // This is the case for the unittests. | 1746 // This is the case for the unittests. |
| 1724 OnDestroy(); | 1747 OnDestroy(); |
| 1725 } else { | 1748 } else { |
| 1726 // Post to shutdown thread. Note that on browser shutdown, we may quit | 1749 // Post to shutdown thread. Note that on browser shutdown, we may quit |
| 1727 // this MessageLoop and exit the program before ever running this. | 1750 // this MessageLoop and exit the program before ever running this. |
| 1728 shutdown_loop->PostTask(FROM_HERE, base::Bind( | 1751 shutdown_loop->PostTask( |
| 1729 &ProxyConfigServiceLinux::Delegate::OnDestroy, this)); | 1752 FROM_HERE, |
| 1753 base::Bind(&ProxyConfigServiceLinux::Delegate::OnDestroy, this)); |
| 1730 } | 1754 } |
| 1731 } | 1755 } |
| 1732 void ProxyConfigServiceLinux::Delegate::OnDestroy() { | 1756 void ProxyConfigServiceLinux::Delegate::OnDestroy() { |
| 1733 scoped_refptr<base::SingleThreadTaskRunner> shutdown_loop = | 1757 scoped_refptr<base::SingleThreadTaskRunner> shutdown_loop = |
| 1734 setting_getter_->GetNotificationTaskRunner(); | 1758 setting_getter_->GetNotificationTaskRunner(); |
| 1735 DCHECK(!shutdown_loop.get() || shutdown_loop->BelongsToCurrentThread()); | 1759 DCHECK(!shutdown_loop.get() || shutdown_loop->BelongsToCurrentThread()); |
| 1736 setting_getter_->ShutDown(); | 1760 setting_getter_->ShutDown(); |
| 1737 } | 1761 } |
| 1738 | 1762 |
| 1739 ProxyConfigServiceLinux::ProxyConfigServiceLinux() | 1763 ProxyConfigServiceLinux::ProxyConfigServiceLinux() |
| 1740 : delegate_(new Delegate(base::Environment::Create())) { | 1764 : delegate_(new Delegate(base::Environment::Create())) { |
| 1741 } | 1765 } |
| 1742 | 1766 |
| 1743 ProxyConfigServiceLinux::~ProxyConfigServiceLinux() { | 1767 ProxyConfigServiceLinux::~ProxyConfigServiceLinux() { |
| 1744 delegate_->PostDestroyTask(); | 1768 delegate_->PostDestroyTask(); |
| 1745 } | 1769 } |
| 1746 | 1770 |
| 1747 ProxyConfigServiceLinux::ProxyConfigServiceLinux( | 1771 ProxyConfigServiceLinux::ProxyConfigServiceLinux( |
| 1748 base::Environment* env_var_getter) | 1772 base::Environment* env_var_getter) |
| 1749 : delegate_(new Delegate(env_var_getter)) { | 1773 : delegate_(new Delegate(env_var_getter)) { |
| 1750 } | 1774 } |
| 1751 | 1775 |
| 1752 ProxyConfigServiceLinux::ProxyConfigServiceLinux( | 1776 ProxyConfigServiceLinux::ProxyConfigServiceLinux( |
| 1753 base::Environment* env_var_getter, SettingGetter* setting_getter) | 1777 base::Environment* env_var_getter, |
| 1778 SettingGetter* setting_getter) |
| 1754 : delegate_(new Delegate(env_var_getter, setting_getter)) { | 1779 : delegate_(new Delegate(env_var_getter, setting_getter)) { |
| 1755 } | 1780 } |
| 1756 | 1781 |
| 1757 void ProxyConfigServiceLinux::AddObserver(Observer* observer) { | 1782 void ProxyConfigServiceLinux::AddObserver(Observer* observer) { |
| 1758 delegate_->AddObserver(observer); | 1783 delegate_->AddObserver(observer); |
| 1759 } | 1784 } |
| 1760 | 1785 |
| 1761 void ProxyConfigServiceLinux::RemoveObserver(Observer* observer) { | 1786 void ProxyConfigServiceLinux::RemoveObserver(Observer* observer) { |
| 1762 delegate_->RemoveObserver(observer); | 1787 delegate_->RemoveObserver(observer); |
| 1763 } | 1788 } |
| 1764 | 1789 |
| 1765 ProxyConfigService::ConfigAvailability | 1790 ProxyConfigService::ConfigAvailability |
| 1766 ProxyConfigServiceLinux::GetLatestProxyConfig(ProxyConfig* config) { | 1791 ProxyConfigServiceLinux::GetLatestProxyConfig(ProxyConfig* config) { |
| 1767 return delegate_->GetLatestProxyConfig(config); | 1792 return delegate_->GetLatestProxyConfig(config); |
| 1768 } | 1793 } |
| 1769 | 1794 |
| 1770 } // namespace net | 1795 } // namespace net |
| OLD | NEW |