Repository: pallets/werkzeug (python)

Issue:
downloading from send_file unpacks gzipped files
The gzipped files returned with
````
return send_file( fpath, as_attachment=True ) 
````
are being downloaded unpacked. The file are saved as \*.gz but its content is plaintext.

This does not happen with 
Flask==1.1.2
werkzeug==1.0.1

Environment:
- Python version: 3.7.1
- Flask version: 2.0.1


Pull request description:
send_file set content-encoding if as_attachment is False
mimetypes.guess_mimetype() returns (mimetype, encoding).
If encoding is not none, set the Content-Encoding header of the response,
but only if `as_attachment` is `False`.

<!--
Before opening a PR, open a ticket describing the issue or feature the
PR will address. Follow the steps in CONTRIBUTING.rst.

Replace this comment with a description of the change. Describe how it
addresses the linked ticket.
-->

<!--
Link to relevant issues or previous PRs, one per line. Use "fixes" to
automatically close an issue.
-->

- fixes #2149

<!--
Ensure each step in CONTRIBUTING.rst is complete by adding an "x" to
each box below.

If only docs were changed, these aren't relevant and can be removed.
-->

Checklist:

- [x] Add tests that demonstrate the correct behavior of the change. Tests should fail without the change.
- [x] Add or update relevant docs, in the docs folder and in code.
- [x] Add an entry in `CHANGES.rst` summarizing the change and linking to the issue.
- [x] Add `.. versionchanged::` entries in any relevant code docs.
- [x] Run `pre-commit` hooks and fix any issues.
- [x] Run `pytest` and `tox`, no tests failed.


Patch:
diff --git a/CHANGES.rst b/CHANGES.rst
index 3ebba3fe..9b0c4686 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -14,6 +14,9 @@ Unreleased
     for ``Rule.match``. :issue:`2157`
 -   ``CombinedMultiDict.to_dict`` with ``flat=False`` considers all
     component dicts when building value lists. :issue:`2189`
+-   ``send_file`` only sets a detected ``Content-Encoding`` if
+    ``as_attachment`` is disabled to avoid browsers saving
+    decompressed ``.tar.gz`` files. :issue:`2149`
 
 
 Version 2.0.1
diff --git a/src/werkzeug/utils.py b/src/werkzeug/utils.py
index 7bb02bbc..4143c3fc 100644
--- a/src/werkzeug/utils.py
+++ b/src/werkzeug/utils.py
@@ -650,6 +650,10 @@ def send_file(
     :param _root_path: Do not use. For internal use only. Use
         :func:`send_from_directory` to safely send files under a path.
 
+    .. versionchanged:: 2.0.2
+        ``send_file`` only sets a detected ``Content-Encoding`` if
+        ``as_attachment`` is disabled.
+
     .. versionadded:: 2.0
         Adapted from Flask's implementation.
 
@@ -716,7 +720,9 @@ def send_file(
         if mimetype is None:
             mimetype = "application/octet-stream"
 
-        if encoding is not None:
+        # Don't send encoding for attachments, it causes browsers to
+        # save decompress tar.gz files.
+        if encoding is not None and not as_attachment:
             headers.set("Content-Encoding", encoding)
 
     if download_name is not None:


Test patch:
diff --git a/tests/test_send_file.py b/tests/test_send_file.py
index 159aeb5f..fc4299a9 100644
--- a/tests/test_send_file.py
+++ b/tests/test_send_file.py
@@ -160,11 +160,14 @@ def test_etag():
     assert rv.headers["ETag"] == '"unique"'
 
 
-def test_content_encoding():
-    rv = send_file(txt_path, environ, download_name="logo.svgz")
+@pytest.mark.parametrize("as_attachment", (True, False))
+def test_content_encoding(as_attachment):
+    rv = send_file(
+        txt_path, environ, download_name="logo.svgz", as_attachment=as_attachment
+    )
     rv.close()
     assert rv.mimetype == "image/svg+xml"
-    assert rv.content_encoding == "gzip"
+    assert rv.content_encoding == ("gzip" if not as_attachment else None)
 
 
 @pytest.mark.parametrize(