summaryrefslogtreecommitdiff
path: root/qutebrowser/browser/webkit/network/webkitqutescheme.py
blob: 236ebcc0c09958d29382faf4829bf91191d71846 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:

# Copyright 2014-2017 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/>.

"""QtWebKit specific qute://* handlers and glue code."""

import mimetypes

from PyQt5.QtCore import QUrl
from PyQt5.QtNetwork import QNetworkReply, QNetworkAccessManager

from qutebrowser.browser import pdfjs, qutescheme
from qutebrowser.browser.webkit.network import schemehandler, networkreply
from qutebrowser.utils import log, usertypes, qtutils


class QuteSchemeHandler(schemehandler.SchemeHandler):

    """Scheme handler for qute:// URLs."""

    def createRequest(self, op, request, _outgoing_data, current_url):
        """Create a new request.

        Args:
             request: const QNetworkRequest & req
             op: Operation op
             _outgoing_data: QIODevice * outgoingData
             current_url: The page we're on currently.

        Return:
            A QNetworkReply.
        """
        if op != QNetworkAccessManager.GetOperation:
            return networkreply.ErrorNetworkReply(
                request, "Unsupported request type",
                QNetworkReply.ContentOperationNotPermittedError)

        url = request.url()

        if ((url.scheme(), url.host(), url.path()) ==
                ('qute', 'settings', '/set')):
            if current_url != QUrl('qute://settings/'):
                log.webview.warning("Blocking malicious request from {} to {}"
                                    .format(current_url.toDisplayString(),
                                            url.toDisplayString()))
                return networkreply.ErrorNetworkReply(
                    request, "Invalid qute://settings request",
                    QNetworkReply.ContentAccessDenied)

        try:
            mimetype, data = qutescheme.data_for_url(url)
        except qutescheme.NoHandlerFound:
            errorstr = "No handler found for {}!".format(url.toDisplayString())
            return networkreply.ErrorNetworkReply(
                request, errorstr, QNetworkReply.ContentNotFoundError,
                self.parent())
        except qutescheme.QuteSchemeOSError as e:
            return networkreply.ErrorNetworkReply(
                request, str(e), QNetworkReply.ContentNotFoundError,
                self.parent())
        except qutescheme.QuteSchemeError as e:
            return networkreply.ErrorNetworkReply(request, e.errorstring,
                                                  e.error, self.parent())
        except qutescheme.Redirect as e:
            qtutils.ensure_valid(e.url)
            return networkreply.RedirectNetworkReply(e.url, self.parent())

        return networkreply.FixedDataNetworkReply(request, data, mimetype,
                                                  self.parent())


@qutescheme.add_handler('pdfjs', backend=usertypes.Backend.QtWebKit)
def qute_pdfjs(url):
    """Handler for qute://pdfjs. Return the pdf.js viewer."""
    try:
        data = pdfjs.get_pdfjs_res(url.path())
    except pdfjs.PDFJSNotFound as e:
        # Logging as the error might get lost otherwise since we're not showing
        # the error page if a single asset is missing. This way we don't lose
        # information, as the failed pdfjs requests are still in the log.
        log.misc.warning(
            "pdfjs resource requested but not found: {}".format(e.path))
        raise qutescheme.QuteSchemeError("Can't find pdfjs resource "
                                         "'{}'".format(e.path),
                                         QNetworkReply.ContentNotFoundError)
    else:
        mimetype, _encoding = mimetypes.guess_type(url.fileName())
        assert mimetype is not None, url
        return mimetype, data