From 842c69dfdd73c8e6218f6a75d74993054f09103c Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 6 May 2015 10:23:56 +0200 Subject: [PATCH] Cache proxy authentication credentials. --- qutebrowser/browser/network/networkmanager.py | 36 +++++++++++-------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/qutebrowser/browser/network/networkmanager.py b/qutebrowser/browser/network/networkmanager.py index 1ee04f034..b7a544262 100644 --- a/qutebrowser/browser/network/networkmanager.py +++ b/qutebrowser/browser/network/networkmanager.py @@ -40,6 +40,8 @@ from qutebrowser.browser.network import qutescheme, networkreply HOSTBLOCK_ERROR_STRING = '%HOSTBLOCK%' +ProxyId = collections.namedtuple('ProxyId', 'type, hostname, port') +_proxy_auth_cache = {} def init(): @@ -171,16 +173,6 @@ class NetworkManager(QNetworkAccessManager): q.deleteLater() return q.answer - def _fill_authenticator(self, authenticator, answer): - """Fill a given QAuthenticator object with an answer.""" - if answer is not None: - # Since the answer could be something else than (user, password) - # pylint seems to think we're unpacking a non-sequence. However we - # *did* explicitly ask for a tuple, so it *will* always be one. - user, password = answer - authenticator.setUser(user) - authenticator.setPassword(password) - def shutdown(self): """Abort all running requests.""" self.setNetworkAccessible(QNetworkAccessManager.NotAccessible) @@ -255,14 +247,28 @@ class NetworkManager(QNetworkAccessManager): answer = self._ask("Username ({}):".format(authenticator.realm()), mode=usertypes.PromptMode.user_pwd, owner=reply) - self._fill_authenticator(authenticator, answer) + if answer is not None: + user, password = answer # pylint: disable=unpacking-non-sequence + authenticator.setUser(user) + authenticator.setPassword(password) @pyqtSlot('QNetworkProxy', 'QAuthenticator') - def on_proxy_authentication_required(self, _proxy, authenticator): + def on_proxy_authentication_required(self, proxy, authenticator): """Called when a proxy needs authentication.""" - answer = self._ask("Proxy username ({}):".format( - authenticator.realm()), mode=usertypes.PromptMode.user_pwd) - self._fill_authenticator(authenticator, answer) + proxy_id = ProxyId(proxy.type(), proxy.hostName(), proxy.port()) + if proxy_id in _proxy_auth_cache: + user, password = _proxy_auth_cache[proxy_id] + authenticator.setUser(user) + authenticator.setPassword(password) + else: + answer = self._ask("Proxy username ({}):".format( + authenticator.realm()), mode=usertypes.PromptMode.user_pwd) + if answer is not None: + # pylint: disable=unpacking-non-sequence + user, password = answer + authenticator.setUser(user) + authenticator.setPassword(password) + _proxy_auth_cache[proxy_id] = answer @config.change_filter('general', 'private-browsing') def on_config_changed(self):