diff --git a/qutebrowser/browser/browsertab.py b/qutebrowser/browser/browsertab.py index eb0e55c4b..b925d7d7a 100644 --- a/qutebrowser/browser/browsertab.py +++ b/qutebrowser/browser/browsertab.py @@ -99,6 +99,7 @@ class TabData: Only used for QtWebKit. pinned: Flag to pin the tab. fullscreen: Whether the tab has a video shown fullscreen currently. + netrc_used: flag to avoid endless loop when using netrc """ keep_icon = attr.ib(False) @@ -107,6 +108,7 @@ class TabData: override_target = attr.ib(None) pinned = attr.ib(False) fullscreen = attr.ib(False) + netrc_used = False class AbstractAction: @@ -724,6 +726,7 @@ class AbstractTab(QWidget): self._progress = 0 self._has_ssl_errors = False self.data.viewing_source = False + self.data.netrc_used = False self._set_load_status(usertypes.LoadStatus.loading) self.load_started.emit() @@ -764,7 +767,6 @@ class AbstractTab(QWidget): self.load_finished.emit(ok) if not self.title(): self.title_changed.emit(self.url().toDisplayString()) - self.zoom.set_current() @pyqtSlot() diff --git a/qutebrowser/browser/shared.py b/qutebrowser/browser/shared.py index b6bfefe7b..e6084a7f8 100644 --- a/qutebrowser/browser/shared.py +++ b/qutebrowser/browser/shared.py @@ -19,7 +19,9 @@ """Various utilities shared between webpage/webview subclasses.""" +import os import html +import netrc from qutebrowser.config import config from qutebrowser.utils import usertypes, message, log, objreg, jinja, utils @@ -260,3 +262,29 @@ def get_user_stylesheet(): css += '\nhtml > ::-webkit-scrollbar { width: 0px; height: 0px; }' return css + + +def netrc_authentication(url, authenticator): + """performs authorization using netrc.""" + if 'HOME' in os.environ: + # We'll get an OSError by netrc if 'HOME' isn't available in + # os.environ. We don't want to log that, so we prevent it + # altogether. + user, password = None, None + try: + net = netrc.netrc(config.val.content.netrc_file) + authenticators = net.authenticators(url.host()) + if authenticators is not None: + (user, _account, password) = authenticators + except FileNotFoundError: + log.misc.debug("No .netrc file found") + except OSError: + log.misc.exception("Unable to read the netrc file") + except netrc.NetrcParseError: + log.misc.exception("Error when parsing the netrc file") + + if user is not None: + authenticator.setUser(user) + authenticator.setPassword(password) + return True + return False diff --git a/qutebrowser/browser/webengine/webenginetab.py b/qutebrowser/browser/webengine/webenginetab.py index 9328698bc..a50d8e2a3 100644 --- a/qutebrowser/browser/webengine/webenginetab.py +++ b/qutebrowser/browser/webengine/webenginetab.py @@ -19,6 +19,7 @@ """Wrapper over a QWebEngineView.""" +import os import math import functools import html as html_utils @@ -739,11 +740,15 @@ class WebEngineTab(browsertab.AbstractTab): @pyqtSlot(QUrl, 'QAuthenticator*') def _on_authentication_required(self, url, authenticator): - # FIXME:qtwebengine support .netrc - answer = shared.authentication_required( - url, authenticator, abort_on=[self.shutting_down, - self.load_started]) - if answer is None: + netrc = None + if not self.data.netrc_used and 'HOME' in os.environ: + self.data.netrc_used = True + netrc = shared.netrc_authentication(url, authenticator) + if not netrc: + abort_on = [self.shutting_down, self.load_started] + answer = shared.authentication_required(url, authenticator, + abort_on) + if not netrc and answer is None: try: # pylint: disable=no-member, useless-suppression sip.assign(authenticator, QAuthenticator()) diff --git a/qutebrowser/browser/webkit/network/networkmanager.py b/qutebrowser/browser/webkit/network/networkmanager.py index a19687eb1..5e9d6f991 100644 --- a/qutebrowser/browser/webkit/network/networkmanager.py +++ b/qutebrowser/browser/webkit/network/networkmanager.py @@ -19,9 +19,7 @@ """Our own QNetworkAccessManager.""" -import os import collections -import netrc import html import attr @@ -270,28 +268,11 @@ class NetworkManager(QNetworkAccessManager): @pyqtSlot('QNetworkReply*', 'QAuthenticator*') def on_authentication_required(self, reply, authenticator): """Called when a website needs authentication.""" - user, password = None, None - if not hasattr(reply, "netrc_used") and 'HOME' in os.environ: - # We'll get an OSError by netrc if 'HOME' isn't available in - # os.environ. We don't want to log that, so we prevent it - # altogether. - reply.netrc_used = True - try: - net = netrc.netrc(config.val.content.netrc_file) - authenticators = net.authenticators(reply.url().host()) - if authenticators is not None: - (user, _account, password) = authenticators - except FileNotFoundError: - log.misc.debug("No .netrc file found") - except OSError: - log.misc.exception("Unable to read the netrc file") - except netrc.NetrcParseError: - log.misc.exception("Error when parsing the netrc file") - - if user is not None: - authenticator.setUser(user) - authenticator.setPassword(password) - else: + netrc = False + if not hasattr(reply, "netrc_used"): + setattr(reply, "netrc_used", True) + netrc = shared.netrc_authentication(reply.url(), authenticator) + if not netrc: abort_on = self._get_abort_signals(reply) shared.authentication_required(reply.url(), authenticator, abort_on=abort_on)