| 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 #if defined(USE_GCONF) | 8 #if defined(USE_GCONF) |
| 9 #include <gconf/gconf-client.h> | 9 #include <gconf/gconf-client.h> |
| 10 #endif // defined(USE_GCONF) | 10 #endif // defined(USE_GCONF) |
| 11 #include <limits.h> | 11 #include <limits.h> |
| 12 #include <stdio.h> | 12 #include <stdio.h> |
| 13 #include <stdlib.h> | 13 #include <stdlib.h> |
| 14 #include <sys/inotify.h> | 14 #include <sys/inotify.h> |
| 15 #include <unistd.h> | 15 #include <unistd.h> |
| 16 | 16 |
| 17 #include <map> | 17 #include <map> |
| 18 #include <utility> | 18 #include <utility> |
| 19 | 19 |
| 20 #include "base/bind.h" | 20 #include "base/bind.h" |
| 21 #include "base/compiler_specific.h" | 21 #include "base/compiler_specific.h" |
| 22 #include "base/debug/leak_annotations.h" | 22 #include "base/debug/leak_annotations.h" |
| 23 #include "base/files/file_descriptor_watcher_posix.h" |
| 23 #include "base/files/file_path.h" | 24 #include "base/files/file_path.h" |
| 24 #include "base/files/file_util.h" | 25 #include "base/files/file_util.h" |
| 25 #include "base/files/scoped_file.h" | 26 #include "base/files/scoped_file.h" |
| 26 #include "base/logging.h" | 27 #include "base/logging.h" |
| 27 #include "base/macros.h" | 28 #include "base/macros.h" |
| 28 #include "base/message_loop/message_loop.h" | |
| 29 #include "base/nix/xdg_util.h" | 29 #include "base/nix/xdg_util.h" |
| 30 #include "base/single_thread_task_runner.h" | 30 #include "base/single_thread_task_runner.h" |
| 31 #include "base/strings/string_number_conversions.h" | 31 #include "base/strings/string_number_conversions.h" |
| 32 #include "base/strings/string_tokenizer.h" | 32 #include "base/strings/string_tokenizer.h" |
| 33 #include "base/strings/string_util.h" | 33 #include "base/strings/string_util.h" |
| 34 #include "base/threading/thread_restrictions.h" | 34 #include "base/threading/thread_restrictions.h" |
| 35 #include "base/timer/timer.h" | 35 #include "base/timer/timer.h" |
| 36 #include "net/base/net_errors.h" | 36 #include "net/base/net_errors.h" |
| 37 #include "net/http/http_util.h" | 37 #include "net/http/http_util.h" |
| 38 #include "net/proxy/proxy_config.h" | 38 #include "net/proxy/proxy_config.h" |
| (...skipping 812 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 851 } | 851 } |
| 852 | 852 |
| 853 VLOG(1) << "All gsettings tests OK. Will get proxy config from gsettings."; | 853 VLOG(1) << "All gsettings tests OK. Will get proxy config from gsettings."; |
| 854 return true; | 854 return true; |
| 855 } | 855 } |
| 856 #endif // defined(USE_GIO) | 856 #endif // defined(USE_GIO) |
| 857 | 857 |
| 858 // This is the KDE version that reads kioslaverc and simulates gconf. | 858 // This is the KDE version that reads kioslaverc and simulates gconf. |
| 859 // Doing this allows the main Delegate code, as well as the unit tests | 859 // Doing this allows the main Delegate code, as well as the unit tests |
| 860 // for it, to stay the same - and the settings map fairly well besides. | 860 // for it, to stay the same - and the settings map fairly well besides. |
| 861 class SettingGetterImplKDE : public ProxyConfigServiceLinux::SettingGetter, | 861 class SettingGetterImplKDE : public ProxyConfigServiceLinux::SettingGetter { |
| 862 public base::MessagePumpLibevent::Watcher { | |
| 863 public: | 862 public: |
| 864 explicit SettingGetterImplKDE(base::Environment* env_var_getter) | 863 explicit SettingGetterImplKDE(base::Environment* env_var_getter) |
| 865 : inotify_fd_(-1), | 864 : inotify_fd_(-1), |
| 866 inotify_watcher_(FROM_HERE), | |
| 867 notify_delegate_(nullptr), | 865 notify_delegate_(nullptr), |
| 868 debounce_timer_(new base::OneShotTimer()), | 866 debounce_timer_(new base::OneShotTimer()), |
| 869 indirect_manual_(false), | 867 indirect_manual_(false), |
| 870 auto_no_pac_(false), | 868 auto_no_pac_(false), |
| 871 reversed_bypass_list_(false), | 869 reversed_bypass_list_(false), |
| 872 env_var_getter_(env_var_getter), | 870 env_var_getter_(env_var_getter), |
| 873 file_task_runner_(nullptr) { | 871 file_task_runner_(nullptr) { |
| 874 // This has to be called on the UI thread (http://crbug.com/69057). | 872 // This has to be called on the UI thread (http://crbug.com/69057). |
| 875 base::ThreadRestrictions::ScopedAllowIO allow_io; | 873 base::ThreadRestrictions::ScopedAllowIO allow_io; |
| 876 | 874 |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 964 // The initial read is done on the current thread, not | 962 // The initial read is done on the current thread, not |
| 965 // |file_task_runner_|, since we will need to have it for | 963 // |file_task_runner_|, since we will need to have it for |
| 966 // SetUpAndFetchInitialConfig(). | 964 // SetUpAndFetchInitialConfig(). |
| 967 UpdateCachedSettings(); | 965 UpdateCachedSettings(); |
| 968 return true; | 966 return true; |
| 969 } | 967 } |
| 970 | 968 |
| 971 void ShutDown() override { | 969 void ShutDown() override { |
| 972 if (inotify_fd_ >= 0) { | 970 if (inotify_fd_ >= 0) { |
| 973 ResetCachedSettings(); | 971 ResetCachedSettings(); |
| 974 inotify_watcher_.StopWatchingFileDescriptor(); | 972 inotify_watcher_.reset(); |
| 975 close(inotify_fd_); | 973 close(inotify_fd_); |
| 976 inotify_fd_ = -1; | 974 inotify_fd_ = -1; |
| 977 } | 975 } |
| 978 debounce_timer_.reset(); | 976 debounce_timer_.reset(); |
| 979 } | 977 } |
| 980 | 978 |
| 981 bool SetUpNotifications( | 979 bool SetUpNotifications( |
| 982 ProxyConfigServiceLinux::Delegate* delegate) override { | 980 ProxyConfigServiceLinux::Delegate* delegate) override { |
| 983 DCHECK_GE(inotify_fd_, 0); | 981 DCHECK_GE(inotify_fd_, 0); |
| 984 DCHECK(file_task_runner_->BelongsToCurrentThread()); | 982 DCHECK(file_task_runner_->BelongsToCurrentThread()); |
| 985 // 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 |
| 986 // 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 |
| 987 // 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 |
| 988 // 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 |
| 989 // 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. |
| 990 if (inotify_add_watch(inotify_fd_, kde_config_dir_.value().c_str(), | 988 if (inotify_add_watch(inotify_fd_, kde_config_dir_.value().c_str(), |
| 991 IN_MODIFY | IN_MOVED_TO) < 0) { | 989 IN_MODIFY | IN_MOVED_TO) < 0) { |
| 992 return false; | 990 return false; |
| 993 } | 991 } |
| 994 notify_delegate_ = delegate; | 992 notify_delegate_ = delegate; |
| 995 if (!base::MessageLoopForIO::current()->WatchFileDescriptor( | 993 inotify_watcher_ = base::FileDescriptorWatcher::WatchReadable( |
| 996 inotify_fd_, true, base::MessageLoopForIO::WATCH_READ, | 994 inotify_fd_, base::Bind(&SettingGetterImplKDE::OnChangeNotification, |
| 997 &inotify_watcher_, this)) { | 995 base::Unretained(this))); |
| 998 return false; | |
| 999 } | |
| 1000 // Simulate a change to avoid possibly losing updates before this point. | 996 // Simulate a change to avoid possibly losing updates before this point. |
| 1001 OnChangeNotification(); | 997 OnChangeNotification(); |
| 1002 return true; | 998 return true; |
| 1003 } | 999 } |
| 1004 | 1000 |
| 1005 const scoped_refptr<base::SingleThreadTaskRunner>& GetNotificationTaskRunner() | 1001 const scoped_refptr<base::SingleThreadTaskRunner>& GetNotificationTaskRunner() |
| 1006 override { | 1002 override { |
| 1007 return file_task_runner_; | 1003 return file_task_runner_; |
| 1008 } | 1004 } |
| 1009 | 1005 |
| 1010 // Implement base::MessagePumpLibevent::Watcher. | |
| 1011 void OnFileCanReadWithoutBlocking(int fd) override { | |
| 1012 DCHECK_EQ(fd, inotify_fd_); | |
| 1013 DCHECK(file_task_runner_->BelongsToCurrentThread()); | |
| 1014 OnChangeNotification(); | |
| 1015 } | |
| 1016 void OnFileCanWriteWithoutBlocking(int fd) override { NOTREACHED(); } | |
| 1017 | |
| 1018 ProxyConfigSource GetConfigSource() override { | 1006 ProxyConfigSource GetConfigSource() override { |
| 1019 return PROXY_CONFIG_SOURCE_KDE; | 1007 return PROXY_CONFIG_SOURCE_KDE; |
| 1020 } | 1008 } |
| 1021 | 1009 |
| 1022 bool GetString(StringSetting key, std::string* result) override { | 1010 bool GetString(StringSetting key, std::string* result) override { |
| 1023 string_map_type::iterator it = string_table_.find(key); | 1011 string_map_type::iterator it = string_table_.find(key); |
| 1024 if (it == string_table_.end()) | 1012 if (it == string_table_.end()) |
| 1025 return false; | 1013 return false; |
| 1026 *result = it->second; | 1014 *result = it->second; |
| 1027 return true; | 1015 return true; |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1310 // new behavior (EINVAL) so we can reuse the code below. | 1298 // new behavior (EINVAL) so we can reuse the code below. |
| 1311 errno = EINVAL; | 1299 errno = EINVAL; |
| 1312 if (errno != EAGAIN) { | 1300 if (errno != EAGAIN) { |
| 1313 PLOG(WARNING) << "error reading inotify file descriptor"; | 1301 PLOG(WARNING) << "error reading inotify file descriptor"; |
| 1314 if (errno == EINVAL) { | 1302 if (errno == EINVAL) { |
| 1315 // Our buffer is not large enough to read the next event. This should | 1303 // Our buffer is not large enough to read the next event. This should |
| 1316 // not happen (because its size is calculated to always be sufficiently | 1304 // not happen (because its size is calculated to always be sufficiently |
| 1317 // large), but if it does we'd warn continuously since |inotify_fd_| | 1305 // large), but if it does we'd warn continuously since |inotify_fd_| |
| 1318 // would be forever ready to read. Close it and stop watching instead. | 1306 // would be forever ready to read. Close it and stop watching instead. |
| 1319 LOG(ERROR) << "inotify failure; no longer watching kioslaverc!"; | 1307 LOG(ERROR) << "inotify failure; no longer watching kioslaverc!"; |
| 1320 inotify_watcher_.StopWatchingFileDescriptor(); | 1308 inotify_watcher_.reset(); |
| 1321 close(inotify_fd_); | 1309 close(inotify_fd_); |
| 1322 inotify_fd_ = -1; | 1310 inotify_fd_ = -1; |
| 1323 } | 1311 } |
| 1324 } | 1312 } |
| 1325 if (kioslaverc_touched) { | 1313 if (kioslaverc_touched) { |
| 1326 // We don't use Reset() because the timer may not yet be running. | 1314 // We don't use Reset() because the timer may not yet be running. |
| 1327 // (In that case Stop() is a no-op.) | 1315 // (In that case Stop() is a no-op.) |
| 1328 debounce_timer_->Stop(); | 1316 debounce_timer_->Stop(); |
| 1329 debounce_timer_->Start(FROM_HERE, base::TimeDelta::FromMilliseconds( | 1317 debounce_timer_->Start(FROM_HERE, base::TimeDelta::FromMilliseconds( |
| 1330 kDebounceTimeoutMilliseconds), this, | 1318 kDebounceTimeoutMilliseconds), this, |
| 1331 &SettingGetterImplKDE::OnDebouncedNotification); | 1319 &SettingGetterImplKDE::OnDebouncedNotification); |
| 1332 } | 1320 } |
| 1333 } | 1321 } |
| 1334 | 1322 |
| 1335 typedef std::map<StringSetting, std::string> string_map_type; | 1323 typedef std::map<StringSetting, std::string> string_map_type; |
| 1336 typedef std::map<StringListSetting, | 1324 typedef std::map<StringListSetting, |
| 1337 std::vector<std::string> > strings_map_type; | 1325 std::vector<std::string> > strings_map_type; |
| 1338 | 1326 |
| 1339 int inotify_fd_; | 1327 int inotify_fd_; |
| 1340 base::MessagePumpLibevent::FileDescriptorWatcher inotify_watcher_; | 1328 std::unique_ptr<base::FileDescriptorWatcher::Controller> inotify_watcher_; |
| 1341 ProxyConfigServiceLinux::Delegate* notify_delegate_; | 1329 ProxyConfigServiceLinux::Delegate* notify_delegate_; |
| 1342 std::unique_ptr<base::OneShotTimer> debounce_timer_; | 1330 std::unique_ptr<base::OneShotTimer> debounce_timer_; |
| 1343 base::FilePath kde_config_dir_; | 1331 base::FilePath kde_config_dir_; |
| 1344 bool indirect_manual_; | 1332 bool indirect_manual_; |
| 1345 bool auto_no_pac_; | 1333 bool auto_no_pac_; |
| 1346 bool reversed_bypass_list_; | 1334 bool reversed_bypass_list_; |
| 1347 // We don't own |env_var_getter_|. It's safe to hold a pointer to it, since | 1335 // We don't own |env_var_getter_|. It's safe to hold a pointer to it, since |
| 1348 // both it and us are owned by ProxyConfigServiceLinux::Delegate, and have the | 1336 // both it and us are owned by ProxyConfigServiceLinux::Delegate, and have the |
| 1349 // same lifetime. | 1337 // same lifetime. |
| 1350 base::Environment* env_var_getter_; | 1338 base::Environment* env_var_getter_; |
| (...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1782 void ProxyConfigServiceLinux::RemoveObserver(Observer* observer) { | 1770 void ProxyConfigServiceLinux::RemoveObserver(Observer* observer) { |
| 1783 delegate_->RemoveObserver(observer); | 1771 delegate_->RemoveObserver(observer); |
| 1784 } | 1772 } |
| 1785 | 1773 |
| 1786 ProxyConfigService::ConfigAvailability | 1774 ProxyConfigService::ConfigAvailability |
| 1787 ProxyConfigServiceLinux::GetLatestProxyConfig(ProxyConfig* config) { | 1775 ProxyConfigServiceLinux::GetLatestProxyConfig(ProxyConfig* config) { |
| 1788 return delegate_->GetLatestProxyConfig(config); | 1776 return delegate_->GetLatestProxyConfig(config); |
| 1789 } | 1777 } |
| 1790 | 1778 |
| 1791 } // namespace net | 1779 } // namespace net |
| OLD | NEW |