Skip to content

Commit db074fc

Browse files
committed
refactor: make mime_type_allowlist class prop to configure from interfaces.py
The list of mime types that are served to the browser was located in a list inside a function. The allow_html_file setting provided a limited mechanism to add/remove the text/html mime type from the list. Move the list from the function to the Client class level so that the admin can add/remove from the list as required using interfaces.py. Also remove application/pdf by default and provide docs in admin_guide.txt on how to reenable viewing pdf's in the browser.
1 parent 76c771c commit db074fc

File tree

2 files changed

+69
-22
lines changed

2 files changed

+69
-22
lines changed

doc/admin_guide.txt

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,47 @@ get the gzip version and not a brotli compressed version. This
324324
mechanism allows the admin to allow use of brotli and zstd for
325325
dynamic content, but not for static content.
326326

327+
.. _browser_handling_attached_files:
328+
329+
.. index:: single: interfaces.py; Controlling browser handling of attached files
330+
331+
Controlling Browser Handling of Attached Files
332+
==============================================
333+
334+
You may be aware of the ``allow_html_file`` `config.ini setting
335+
<reference.html#config-ini-section-web>`_. When set to yes, it permits
336+
html files to be attached and displayed in the browser as html
337+
files. The underlying mechanism used to enable/disable attaching HTML
338+
is exposed using ``interfaces.py``.
339+
340+
Similar to ``Client.precompressed_mime_types`` above, there is a
341+
``Client.mime_type_allowlist``. If a mime type is present in this
342+
list, an attachment with this mime type is served to the browser. If
343+
the mime type is not present, the mime type is set to
344+
``application/octet-stream`` which causes the browser to download the
345+
attachment to a file.
346+
347+
In release 2.4.0, the mime type ``application/pdf`` was removed from
348+
the precompressed_mime_types list. This prevents the browser from
349+
executing scripts that may be included in the PDF file. If you trust
350+
the individuals uploading PDF files to your tracker and wish to allow
351+
viewing PDF files from your tracker, you can do so by editing your
352+
tracker's "interfaces.py" file. Adding::
353+
354+
from roundup.cgi.client import Client
355+
Client.mime_type_allowlist.append('application/pdf')
356+
357+
will permit the PDF files to be viewed in the browser rather than
358+
downloaded to a file.
359+
360+
Similarly, you can remove a mime type (e.g. audio/oog) using::
361+
362+
from roundup.cgi.client import Client
363+
Client.mime_type_allowlist.remove('audio/oog')
364+
365+
which will force the browser to save the attachment to a file rather
366+
than playing the audio file.
367+
327368
.. index:: single: interfaces.py; setting REST maximum result limit
328369

329370
Configuring REST Maximum Result Limit

roundup/cgi/client.py

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,32 @@ class Client:
373373
except ImportError:
374374
pass
375375

376+
# everything not here is served as 'application/octet-stream'
377+
# Moved to class so it can be modified from interfaces.py
378+
# Adding:
379+
# from roundup.cgi.client import Client
380+
# Client.mime_type_allowlist.append('application/pdf')
381+
# will permit pdf files to be displayed in the browser rather than
382+
# downloaded to a file.
383+
384+
mime_type_allowlist = [
385+
'text/plain',
386+
'text/x-csrc', # .c
387+
'text/x-chdr', # .h
388+
'text/x-patch', # .patch and .diff
389+
'text/x-python', # .py
390+
'text/xml',
391+
'text/csv',
392+
'text/css',
393+
'image/gif',
394+
'image/jpeg',
395+
'image/png',
396+
'image/svg+xml',
397+
'image/webp',
398+
'audio/ogg',
399+
'video/webm',
400+
]
401+
376402
# mime types of files that are already compressed and should not be
377403
# compressed on the fly. Can be extended/reduced using interfaces.py.
378404
# This excludes types from being compressed. Should we have a list
@@ -1859,28 +1885,8 @@ def serve_file(self, designator, dre=dre):
18591885
# --- mime-type security
18601886
# mime type detection is performed in cgi.form_parser
18611887

1862-
# everything not here is served as 'application/octet-stream'
1863-
mime_type_allowlist = [
1864-
'text/plain',
1865-
'text/x-csrc', # .c
1866-
'text/x-chdr', # .h
1867-
'text/x-patch', # .patch and .diff
1868-
'text/x-python', # .py
1869-
'text/xml',
1870-
'text/csv',
1871-
'text/css',
1872-
'application/pdf',
1873-
'image/gif',
1874-
'image/jpeg',
1875-
'image/png',
1876-
'image/svg+xml',
1877-
'image/webp',
1878-
'audio/ogg',
1879-
'video/webm',
1880-
]
1881-
18821888
if self.instance.config['WEB_ALLOW_HTML_FILE']:
1883-
mime_type_allowlist.append('text/html')
1889+
self.mime_type_allowlist.append('text/html')
18841890

18851891
try:
18861892
mime_type = klass.get(nodeid, 'type')
@@ -1890,7 +1896,7 @@ def serve_file(self, designator, dre=dre):
18901896
if not mime_type:
18911897
mime_type = 'text/plain'
18921898

1893-
if mime_type not in mime_type_allowlist:
1899+
if mime_type not in self.mime_type_allowlist:
18941900
mime_type = 'application/octet-stream'
18951901

18961902
# --/ mime-type security

0 commit comments

Comments
 (0)