Repository: kevin1024/vcrpy

Issue:
[BUG] decode_compressed_response raises exception on empty responses.
```python
>>> import vcr
>>> import requests
>>> with vcr.use_cassette('/tmp/foo.yaml', decode_compressed_response=True):
...     requests.head('https://httpbin.org/gzip')
... 
Traceback (most recent call last):
  Input In [8] in <cell line: 1>
    requests.head('https://httpbin.org/gzip')
  File ~/.local/pipx/venvs/ipython/lib/python3.9/site-packages/requests/api.py:100 in head
    return request("head", url, **kwargs)
  File ~/.local/pipx/venvs/ipython/lib/python3.9/site-packages/requests/api.py:59 in request
    return session.request(method=method, url=url, **kwargs)
  File ~/.local/pipx/venvs/ipython/lib/python3.9/site-packages/requests/sessions.py:587 in request
    resp = self.send(prep, **send_kwargs)
  File ~/.local/pipx/venvs/ipython/lib/python3.9/site-packages/requests/sessions.py:701 in send
    r = adapter.send(request, **kwargs)
  File ~/.local/pipx/venvs/ipython/lib/python3.9/site-packages/requests/adapters.py:489 in send
    resp = conn.urlopen(
  File ~/.local/pipx/venvs/ipython/lib/python3.9/site-packages/urllib3/connectionpool.py:703 in urlopen
    httplib_response = self._make_request(
  File ~/.local/pipx/venvs/ipython/lib/python3.9/site-packages/urllib3/connectionpool.py:440 in _make_request
    httplib_response = conn.getresponse(buffering=True)
  File ~/.virtualenvs/tmp/lib/python3.9/site-packages/vcr/stubs/__init__.py:260 in getresponse
    self.cassette.append(self._vcr_request, response)
  File ~/.virtualenvs/tmp/lib/python3.9/site-packages/vcr/cassette.py:235 in append
    response = self._before_record_response(response)
  File ~/.virtualenvs/tmp/lib/python3.9/site-packages/vcr/config.py:176 in before_record_response
    response = function(response)
  File ~/.virtualenvs/tmp/lib/python3.9/site-packages/vcr/filters.py:168 in decode_response
    new_body = decompress_body(response["body"]["string"], encoding)
  File ~/.virtualenvs/tmp/lib/python3.9/site-packages/vcr/filters.py:154 in decompress_body
    return zlib.decompress(body, zlib.MAX_WBITS | 16)
error: Error -5 while decompressing data: incomplete or truncated stream
```

Discussion:
codecov-commenter: # [Codecov](https://codecov.io/gh/kevin1024/vcrpy/pull/662?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) Report
> Merging [#662](https://codecov.io/gh/kevin1024/vcrpy/pull/662?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) (338031f) into [master](https://codecov.io/gh/kevin1024/vcrpy/commit/f3f66086a149722812345aaf1bb304ff39d105ef?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) (f3f6608) will **decrease** coverage by `0.40%`.
> The diff coverage is `100.00%`.

```diff
@@            Coverage Diff             @@
##           master     #662      +/-   ##
==========================================
- Coverage   89.85%   89.44%   -0.41%     
==========================================
  Files          27       26       -1     
  Lines        1734     1725       -9     
  Branches      285      243      -42     
==========================================
- Hits         1558     1543      -15     
- Misses        140      146       +6     
  Partials       36       36              
```


| [Impacted Files](https://codecov.io/gh/kevin1024/vcrpy/pull/662?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) | Coverage Δ | |
|---|---|---|
| [vcr/filters.py](https://codecov.io/gh/kevin1024/vcrpy/pull/662/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-dmNyL2ZpbHRlcnMucHk=) | `94.33% <100.00%> (+0.10%)` | :arrow_up: |
| [vcr/serializers/yamlserializer.py](https://codecov.io/gh/kevin1024/vcrpy/pull/662/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-dmNyL3NlcmlhbGl6ZXJzL3lhbWxzZXJpYWxpemVyLnB5) | `77.77% <0.00%> (-22.23%)` | :arrow_down: |
| [vcr/stubs/httpx\_stubs.py](https://codecov.io/gh/kevin1024/vcrpy/pull/662/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-dmNyL3N0dWJzL2h0dHB4X3N0dWJzLnB5) | `95.87% <0.00%> (-2.07%)` | :arrow_down: |
| [vcr/migration.py](https://codecov.io/gh/kevin1024/vcrpy/pull/662/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-dmNyL21pZ3JhdGlvbi5weQ==) | `74.48% <0.00%> (-2.05%)` | :arrow_down: |
| [vcr/cassette.py](https://codecov.io/gh/kevin1024/vcrpy/pull/662/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-dmNyL2Nhc3NldHRlLnB5) | `96.19% <0.00%> (-0.02%)` | :arrow_down: |
| [vcr/serialize.py](https://codecov.io/gh/kevin1024/vcrpy/pull/662/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-dmNyL3NlcmlhbGl6ZS5weQ==) | `100.00% <0.00%> (ø)` | |
| [vcr/stubs/compat.py](https://codecov.io/gh/kevin1024/vcrpy/pull/662/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-dmNyL3N0dWJzL2NvbXBhdC5weQ==) | `100.00% <0.00%> (ø)` | |
| [vcr/\_\_init\_\_.py](https://codecov.io/gh/kevin1024/vcrpy/pull/662/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-dmNyL19faW5pdF9fLnB5) | | |

:mega: We’re building smart automated test selection to slash your CI/CD build times. [Learn more](https://about.codecov.io/iterative-testing/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None)

jairhenrique: @CharString tks!

Patch:
diff --git a/vcr/filters.py b/vcr/filters.py
index 8e00b64..df3dd30 100644
--- a/vcr/filters.py
+++ b/vcr/filters.py
@@ -150,6 +150,8 @@ def decode_response(response):
         """Returns decompressed body according to encoding using zlib.
         to (de-)compress gzip format, use wbits = zlib.MAX_WBITS | 16
         """
+        if not body:
+            return ""
         if encoding == "gzip":
             return zlib.decompress(body, zlib.MAX_WBITS | 16)
         else:  # encoding == 'deflate'


Test patch:
diff --git a/tests/integration/test_filter.py b/tests/integration/test_filter.py
index b42bb34..da75f6d 100644
--- a/tests/integration/test_filter.py
+++ b/tests/integration/test_filter.py
@@ -106,6 +106,18 @@ def test_decompress_gzip(tmpdir, httpbin):
     assert_is_json(decoded_response)
 
 
+def test_decomptess_empty_body(tmpdir, httpbin):
+    url = httpbin.url + "/gzip"
+    request = Request(url, headers={"Accept-Encoding": ["gzip, deflate"]}, method="HEAD")
+    cass_file = str(tmpdir.join("gzip_empty_response.yaml"))
+    with vcr.use_cassette(cass_file, decode_compressed_response=True):
+        response = urlopen(request).read()
+    with vcr.use_cassette(cass_file) as cass:
+        decoded_response = urlopen(request).read()
+        assert_cassette_has_one_response(cass)
+    assert decoded_response == response
+
+
 def test_decompress_deflate(tmpdir, httpbin):
     url = httpbin.url + "/deflate"
     request = Request(url, headers={"Accept-Encoding": ["gzip, deflate"]})