Let qute:* handlers decide their mimetype

This means we have to guess less, and handlers can give us HTML as text
which we then encode for them.
This commit is contained in:
Florian Bruhin 2016-09-14 12:18:53 +02:00
parent 3a27c45ac9
commit 982d00ff84
2 changed files with 30 additions and 23 deletions

View File

@ -24,7 +24,6 @@ Module attributes:
_HANDLERS: The handlers registered via decorators. _HANDLERS: The handlers registered via decorators.
""" """
import mimetypes
import urllib.parse import urllib.parse
import qutebrowser import qutebrowser
@ -104,7 +103,7 @@ class add_handler: # pylint: disable=invalid-name
error='{} is not available with this ' error='{} is not available with this '
'backend'.format(url.toDisplayString()), 'backend'.format(url.toDisplayString()),
icon='') icon='')
return html.encode('UTF-8', errors='xmlcharrefreplace') return 'text/html', html
def data_for_url(url): def data_for_url(url):
@ -129,15 +128,18 @@ def data_for_url(url):
except KeyError: except KeyError:
raise NoHandlerFound(url) raise NoHandlerFound(url)
try: try:
data = handler(url) mimetype, data = handler(url)
except OSError as e: except OSError as e:
# FIXME:qtwebengine how to handle this? # FIXME:qtwebengine how to handle this?
raise QuteSchemeOSError(e) raise QuteSchemeOSError(e)
except QuteSchemeError as e: except QuteSchemeError as e:
raise raise
mimetype, _encoding = mimetypes.guess_type(url.fileName())
if mimetype is None: assert mimetype is not None, url
mimetype = 'text/html' if mimetype == 'text/html' and isinstance(data, str):
# We let handlers return HTML as text
data = data.encode('utf-8', errors='xmlcharrefreplace')
return mimetype, data return mimetype, data
@ -153,29 +155,29 @@ def qute_bookmarks(_url):
title='Bookmarks', title='Bookmarks',
bookmarks=bookmarks, bookmarks=bookmarks,
quickmarks=quickmarks) quickmarks=quickmarks)
return html.encode('UTF-8', errors='xmlcharrefreplace') return 'text/html', html
@add_handler('pyeval') @add_handler('pyeval')
def qute_pyeval(_url): def qute_pyeval(_url):
"""Handler for qute:pyeval. Return HTML content as bytes.""" """Handler for qute:pyeval."""
html = jinja.render('pre.html', title='pyeval', content=pyeval_output) html = jinja.render('pre.html', title='pyeval', content=pyeval_output)
return html.encode('UTF-8', errors='xmlcharrefreplace') return 'text/html', html
@add_handler('version') @add_handler('version')
@add_handler('verizon') @add_handler('verizon')
def qute_version(_url): def qute_version(_url):
"""Handler for qute:version. Return HTML content as bytes.""" """Handler for qute:version."""
html = jinja.render('version.html', title='Version info', html = jinja.render('version.html', title='Version info',
version=version.version(), version=version.version(),
copyright=qutebrowser.__copyright__) copyright=qutebrowser.__copyright__)
return html.encode('UTF-8', errors='xmlcharrefreplace') return 'text/html', html
@add_handler('plainlog') @add_handler('plainlog')
def qute_plainlog(url): def qute_plainlog(url):
"""Handler for qute:plainlog. Return HTML content as bytes. """Handler for qute:plainlog.
An optional query parameter specifies the minimum log level to print. An optional query parameter specifies the minimum log level to print.
For example, qute://log?level=warning prints warnings and errors. For example, qute://log?level=warning prints warnings and errors.
@ -190,12 +192,12 @@ def qute_plainlog(url):
level = 'vdebug' level = 'vdebug'
text = log.ram_handler.dump_log(html=False, level=level) text = log.ram_handler.dump_log(html=False, level=level)
html = jinja.render('pre.html', title='log', content=text) html = jinja.render('pre.html', title='log', content=text)
return html.encode('UTF-8', errors='xmlcharrefreplace') return 'text/html', html
@add_handler('log') @add_handler('log')
def qute_log(url): def qute_log(url):
"""Handler for qute:log. Return HTML content as bytes. """Handler for qute:log.
An optional query parameter specifies the minimum log level to print. An optional query parameter specifies the minimum log level to print.
For example, qute://log?level=warning prints warnings and errors. For example, qute://log?level=warning prints warnings and errors.
@ -211,18 +213,18 @@ def qute_log(url):
html_log = log.ram_handler.dump_log(html=True, level=level) html_log = log.ram_handler.dump_log(html=True, level=level)
html = jinja.render('log.html', title='log', content=html_log) html = jinja.render('log.html', title='log', content=html_log)
return html.encode('UTF-8', errors='xmlcharrefreplace') return 'text/html', html
@add_handler('gpl') @add_handler('gpl')
def qute_gpl(_url): def qute_gpl(_url):
"""Handler for qute:gpl. Return HTML content as bytes.""" """Handler for qute:gpl. Return HTML content as string."""
return utils.read_file('html/COPYING.html').encode('ASCII') return 'text/html', utils.read_file('html/COPYING.html')
@add_handler('help') @add_handler('help')
def qute_help(url): def qute_help(url):
"""Handler for qute:help. Return HTML content as bytes.""" """Handler for qute:help."""
try: try:
utils.read_file('html/doc/index.html') utils.read_file('html/doc/index.html')
except OSError: except OSError:
@ -236,7 +238,7 @@ def qute_help(url):
"If you're running a released version this is a bug, please " "If you're running a released version this is a bug, please "
"use :report to report it.", "use :report to report it.",
icon='') icon='')
return html.encode('UTF-8', errors='xmlcharrefreplace') return 'text/html', html
urlpath = url.path() urlpath = url.path()
if not urlpath or urlpath == '/': if not urlpath or urlpath == '/':
urlpath = 'index.html' urlpath = 'index.html'
@ -247,7 +249,7 @@ def qute_help(url):
"re-run scripts/asciidoc2html.py.") "re-run scripts/asciidoc2html.py.")
path = 'html/doc/{}'.format(urlpath) path = 'html/doc/{}'.format(urlpath)
if urlpath.endswith('.png'): if urlpath.endswith('.png'):
return utils.read_file(path, binary=True) return 'image/png', utils.read_file(path, binary=True)
else: else:
data = utils.read_file(path) data = utils.read_file(path)
return data.encode('UTF-8', errors='xmlcharrefreplace') return 'text/html', data

View File

@ -19,6 +19,7 @@
"""QtWebKit specific qute:* handlers and glue code.""" """QtWebKit specific qute:* handlers and glue code."""
import mimetypes
import functools import functools
import configparser import configparser
@ -91,14 +92,14 @@ def qute_settings(_url):
config_getter = functools.partial(objreg.get('config').get, raw=True) config_getter = functools.partial(objreg.get('config').get, raw=True)
html = jinja.render('settings.html', title='settings', config=configdata, html = jinja.render('settings.html', title='settings', config=configdata,
confget=config_getter) confget=config_getter)
return html.encode('UTF-8', errors='xmlcharrefreplace') return 'text/html', html
@qutescheme.add_handler('pdfjs', backend=usertypes.Backend.QtWebKit) @qutescheme.add_handler('pdfjs', backend=usertypes.Backend.QtWebKit)
def qute_pdfjs(url): def qute_pdfjs(url):
"""Handler for qute://pdfjs. Return the pdf.js viewer.""" """Handler for qute://pdfjs. Return the pdf.js viewer."""
try: try:
return pdfjs.get_pdfjs_res(url.path()) data = pdfjs.get_pdfjs_res(url.path())
except pdfjs.PDFJSNotFound as e: except pdfjs.PDFJSNotFound as e:
# Logging as the error might get lost otherwise since we're not showing # 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 # the error page if a single asset is missing. This way we don't lose
@ -108,3 +109,7 @@ def qute_pdfjs(url):
raise qutescheme.QuteSchemeError("Can't find pdfjs resource " raise qutescheme.QuteSchemeError("Can't find pdfjs resource "
"'{}'".format(e.path), "'{}'".format(e.path),
QNetworkReply.ContentNotFoundError) QNetworkReply.ContentNotFoundError)
else:
mimetype, _encoding = mimetypes.guess_type(url.fileName())
assert mimetype is not None, url
return mimetype, data