Skip to content

Commit

Permalink
SharedDataMiddleware adds utf-8 charset
Browse files Browse the repository at this point in the history
  • Loading branch information
davidism committed Feb 6, 2020
1 parent 0474354 commit a8b2df2
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 9 deletions.
5 changes: 5 additions & 0 deletions CHANGES.rst
Expand Up @@ -101,6 +101,11 @@ Unreleased
- Range requests that span an entire file respond with 206 instead of
200, to be more compliant with :rfc:`7233`. This may help serving
media to older browsers. :issue:`410, 1704`
- The :class:`~middleware.shared_data.SharedDataMiddleware` default
``fallback_mimetype`` is ``application/octet-stream``. If a filename
looks like a text mimetype, the ``utf-8`` charset is added to it.
This matches the behavior of :class:`~wrappers.BaseResponse` and
Flask's ``send_file()``. :issue:`1689`


Version 0.16.1
Expand Down
24 changes: 15 additions & 9 deletions src/werkzeug/middleware/shared_data.py
Expand Up @@ -24,6 +24,7 @@
from ..http import http_date
from ..http import is_resource_modified
from ..security import safe_join
from ..utils import get_content_type
from ..wsgi import get_path_info
from ..wsgi import wrap_file

Expand Down Expand Up @@ -70,19 +71,24 @@ class SharedDataMiddleware(object):
module. If it's unable to figure out the charset it will fall back
to `fallback_mimetype`.
.. versionchanged:: 0.5
The cache timeout is configurable now.
.. versionadded:: 0.6
The `fallback_mimetype` parameter was added.
:param app: the application to wrap. If you don't want to wrap an
application you can pass it :exc:`NotFound`.
:param exports: a list or dict of exported files and folders.
:param disallow: a list of :func:`~fnmatch.fnmatch` rules.
:param fallback_mimetype: the fallback mimetype for unknown files.
:param cache: enable or disable caching headers.
:param cache_timeout: the cache timeout in seconds for the headers.
:param fallback_mimetype: The fallback mimetype for unknown files.
.. versionchanged:: 1.0
The default ``fallback_mimetype`` is
``application/octet-stream``. If a filename looks like a text
mimetype, the ``utf-8`` charset is added to it.
.. versionadded:: 0.6
Added ``fallback_mimetype``.
.. versionchanged:: 0.5
Added ``cache_timeout``.
"""

def __init__(
Expand All @@ -92,7 +98,7 @@ def __init__(
disallow=None,
cache=True,
cache_timeout=60 * 60 * 12,
fallback_mimetype="text/plain",
fallback_mimetype="application/octet-stream",
):
self.app = app
self.exports = []
Expand Down Expand Up @@ -254,7 +260,7 @@ def __call__(self, environ, start_response):
return self.app(environ, start_response)

guessed_type = mimetypes.guess_type(real_filename)
mime_type = guessed_type[0] or self.fallback_mimetype
mime_type = get_content_type(guessed_type[0] or self.fallback_mimetype, "utf-8")
f, mtime, file_size = file_loader()

headers = [("Date", http_date())]
Expand Down
4 changes: 4 additions & 0 deletions tests/middleware/test_shared_data.py
Expand Up @@ -47,6 +47,10 @@ def null_application(environ, start_response):
app_iter, status, headers = run_wsgi_app(app, create_environ(p))
assert status == "200 OK"

if p.endswith(".txt"):
content_type = next(v for k, v in headers if k == "Content-Type")
assert content_type == "text/plain; charset=utf-8"

with closing(app_iter) as app_iter:
data = b"".join(app_iter).strip()

Expand Down

0 comments on commit a8b2df2

Please sign in to comment.