summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Bruhin <me@the-compiler.org>2021-08-25 09:16:54 +0200
committerFlorian Bruhin <me@the-compiler.org>2021-08-25 10:05:28 +0200
commitd6306783d097d9d53405b75ebecb706b8e13668c (patch)
tree7122fa3174b507aa512fa4f5953ef43cf8443e58
parentc022893a76ab388a552b420728edb19fcb122bb8 (diff)
downloadqutebrowser-d6306783d097d9d53405b75ebecb706b8e13668c.tar.gz
qutebrowser-d6306783d097d9d53405b75ebecb706b8e13668c.zip
Move download origin handling to DownloadItem
-rw-r--r--doc/help/settings.asciidoc2
-rw-r--r--qutebrowser/browser/downloads.py34
-rw-r--r--qutebrowser/browser/qtnetworkdownloads.py14
-rw-r--r--qutebrowser/browser/webengine/webenginedownloads.py17
-rw-r--r--qutebrowser/config/configdata.yml1
5 files changed, 52 insertions, 16 deletions
diff --git a/doc/help/settings.asciidoc b/doc/help/settings.asciidoc
index 1e943c235..a069ffdda 100644
--- a/doc/help/settings.asciidoc
+++ b/doc/help/settings.asciidoc
@@ -2896,8 +2896,6 @@ For per-domain settings, the relevant URL is the URL initiating the download, no
This setting supports URL patterns.
-This setting is only available with the QtWebEngine backend.
-
Type: <<types,Bool>>
Default: +pass:[true]+
diff --git a/qutebrowser/browser/downloads.py b/qutebrowser/browser/downloads.py
index fa4ac9da2..4f7897c9d 100644
--- a/qutebrowser/browser/downloads.py
+++ b/qutebrowser/browser/downloads.py
@@ -611,7 +611,11 @@ class AbstractDownloadItem(QObject):
message.error(str(e))
def url(self) -> QUrl:
- """Get the download's origin URL."""
+ """Get the download's URL (i.e. where the file is downloaded from)."""
+ raise NotImplementedError
+
+ def origin(self) -> QUrl:
+ """Get the download's origin URL (i.e. the page starting the download)."""
raise NotImplementedError
def _get_open_filename(self):
@@ -819,6 +823,34 @@ class AbstractDownloadItem(QObject):
self.pdfjs_requested.emit(os.path.basename(filename),
self.url())
+ def cancel_for_origin(self) -> bool:
+ """Cancel the download based on URL/origin.
+
+ For some special cases, we want to cancel downloads immediately, before
+ downloading:
+
+ - file:// downloads from file:// URLs (open the file instead)
+ - http:// downloads from https:// URLs (mixed content)
+ """
+ origin = self.origin()
+ url = self.url()
+ if not origin.isValid():
+ return False
+
+ if url.scheme() == "file" and origin.scheme() == "file":
+ utils.open_file(url.toLocalFile())
+ self.cancel()
+ return True
+
+ if (url.scheme() == "http" and
+ origin.isValid() and origin.scheme() == "https" and
+ config.instance.get("downloads.prevent_mixed_content", url=origin)):
+ self._die("Aborting insecure download from secure page "
+ "(see downloads.prevent_mixed_content).")
+ return True
+
+ return False
+
def set_target(self, target):
"""Set the target for a given download.
diff --git a/qutebrowser/browser/qtnetworkdownloads.py b/qutebrowser/browser/qtnetworkdownloads.py
index e178fb0e5..f048d293d 100644
--- a/qutebrowser/browser/qtnetworkdownloads.py
+++ b/qutebrowser/browser/qtnetworkdownloads.py
@@ -202,6 +202,17 @@ class DownloadItem(downloads.AbstractDownloadItem):
# Note: self._reply is deleted when the download finishes
return self._url
+ def origin(self) -> QUrl:
+ if self._reply is None:
+ return QUrl()
+ origin = self._reply.request().originatingObject()
+ try:
+ return origin.url()
+ except AttributeError:
+ # Raised either if origin is None or some object that doesn't
+ # have its own url.
+ return QUrl()
+
def _ensure_can_set_filename(self, filename):
if self.fileobj is not None: # pragma: no cover
raise ValueError("fileobj was already set! filename: {}, "
@@ -549,6 +560,9 @@ class DownloadManager(downloads.AbstractDownloadManager):
download = DownloadItem(reply, manager=self)
self._init_item(download, auto_remove, suggested_filename)
+ if download.cancel_for_origin():
+ return download
+
if target is not None:
download.set_target(target)
return download
diff --git a/qutebrowser/browser/webengine/webenginedownloads.py b/qutebrowser/browser/webengine/webenginedownloads.py
index 364347206..f216f9e67 100644
--- a/qutebrowser/browser/webengine/webenginedownloads.py
+++ b/qutebrowser/browser/webengine/webenginedownloads.py
@@ -120,6 +120,10 @@ class DownloadItem(downloads.AbstractDownloadItem):
def url(self) -> QUrl:
return self._qt_item.url()
+ def origin(self) -> QUrl:
+ page = self._qt_item.page()
+ return page.url() if page else QUrl()
+
def _set_fileobj(self, fileobj, *, autoclose=True):
raise downloads.UnsupportedOperationError
@@ -294,18 +298,7 @@ class DownloadManager(downloads.AbstractDownloadManager):
download.set_target(target)
return
- if url.scheme() == "file" and origin.isValid() and origin.scheme() == "file":
- utils.open_file(url.toLocalFile())
- qt_item.cancel()
- return
-
- if (url.scheme() == "http" and
- origin.isValid() and origin.scheme() == "https" and
- config.instance.get("downloads.prevent_mixed_content", url=origin)):
- # FIXME show failed download instead
- message.error("Aborting insecure download from secure page "
- "(see downloads.prevent_mixed_content).")
- qt_item.cancel()
+ if download.cancel_for_origin():
return
# Ask the user for a filename - needs to be blocking!
diff --git a/qutebrowser/config/configdata.yml b/qutebrowser/config/configdata.yml
index 7b0cd05f4..e62fa6f9f 100644
--- a/qutebrowser/config/configdata.yml
+++ b/qutebrowser/config/configdata.yml
@@ -1359,7 +1359,6 @@ downloads.prevent_mixed_content:
type: Bool
default: true
supports_pattern: true
- backend: QtWebEngine
desc:
Automatically abort insecure (HTTP) downloads originating from secure
(HTTPS) pages.