summaryrefslogtreecommitdiff
path: root/qutebrowser/browser/webkit/rfc6266.py
diff options
context:
space:
mode:
Diffstat (limited to 'qutebrowser/browser/webkit/rfc6266.py')
-rw-r--r--qutebrowser/browser/webkit/rfc6266.py130
1 files changed, 0 insertions, 130 deletions
diff --git a/qutebrowser/browser/webkit/rfc6266.py b/qutebrowser/browser/webkit/rfc6266.py
deleted file mode 100644
index cc5ba31e1..000000000
--- a/qutebrowser/browser/webkit/rfc6266.py
+++ /dev/null
@@ -1,130 +0,0 @@
-# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
-
-# Copyright 2014-2020 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
-#
-# This file is part of qutebrowser.
-#
-# qutebrowser is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# qutebrowser is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
-
-"""Parsing for the RFC 6266 (Content-Disposition) header."""
-
-import email.headerregistry
-import email.errors
-import dataclasses
-from typing import Type
-
-from qutebrowser.utils import utils
-
-
-class Error(Exception):
-
- """Base class for RFC6266 errors."""
-
-
-@dataclasses.dataclass
-class DefectWrapper:
-
- """Wrapper around a email.error for comparison."""
-
- error_class: Type[email.errors.MessageDefect]
- line: str
-
- def __eq__(self, other):
- return (
- isinstance(other, self.error_class)
- and other.line == self.line # type: ignore[attr-defined]
- )
-
-
-class ContentDisposition:
-
- """Records various indications and hints about content disposition.
-
- These can be used to know if a file should be downloaded or
- displayed directly, and to hint what filename it should have
- in the download case.
- """
-
- # Ignoring this defect fixes the attfnboth2 test case. It does *not* fix attfnboth
- # one which has a slightly different wording ("duplicate(s) ignored" instead of
- # "duplicate ignored"), because even if we did ignore that one, it still wouldn't
- # work properly...
- _IGNORED_DEFECT = DefectWrapper(
- email.errors.InvalidHeaderDefect, # type: ignore[attr-defined]
- 'duplicate parameter name; duplicate ignored'
- )
-
- def __init__(self, disposition, params):
- """Used internally after parsing the header."""
- self.disposition = disposition
- self.params = params
- assert 'filename*' not in self.params # Handled by headerregistry
-
- @classmethod
- def parse(cls, value):
- """Build a _ContentDisposition from header values."""
- # We allow non-ascii here (it will only be parsed inside of qdtext, and
- # rejected by the grammar if it appears in other places), although parsing
- # it can be ambiguous. Parsing it ensures that a non-ambiguous filename*
- # value won't get dismissed because of an unrelated ambiguity in the
- # filename parameter. But it does mean we occasionally give
- # less-than-certain values for some legacy senders.
- try:
- decoded = value.decode('iso-8859-1')
- except UnicodeDecodeError as e:
- raise Error(e)
-
- reg = email.headerregistry.HeaderRegistry()
-
- try:
- parsed = reg('Content-Disposition', decoded)
- except IndexError:
- # WORKAROUND for https://bugs.python.org/issue37491
- # Fixed in Python 3.7.5 and 3.8.0.
- raise Error("Missing closing quote character")
-
- if parsed.defects:
- defects = list(parsed.defects)
- if defects != [cls._IGNORED_DEFECT]: # type: ignore[comparison-overlap]
- raise Error(defects)
-
- assert isinstance(parsed, email.headerregistry.ContentDispositionHeader), parsed
- return cls(disposition=parsed.content_disposition, params=parsed.params)
-
- def filename(self):
- """The filename from the Content-Disposition header or None.
-
- On safety:
-
- This property records the intent of the sender.
-
- You shouldn't use this sender-controlled value as a filesystem path, it
- can be insecure. Serving files with this filename can be dangerous as
- well, due to a certain browser using the part after the dot for
- mime-sniffing. Saving it to a database is fine by itself though.
- """
- return self.params.get('filename')
-
- def is_inline(self):
- """Return if the file should be handled inline.
-
- If not, and unless your application supports other dispositions
- than the standard inline and attachment, it should be handled
- as an attachment.
- """
- return self.disposition in {None, 'inline'}
-
- def __repr__(self):
- return utils.get_repr(self, constructor=True,
- disposition=self.disposition, params=self.params)