We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Handle HEAD responses with Brotli decoder
Currently if you receive a response with `Content-Encoding: br` set and no body we get an error because Brotli doesn't like being called on an empty stream.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `httpx/decoders.py`
Content:
```
1 """
2 Handlers for Content-Encoding.
3 
4 See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding
5 """
6 import codecs
7 import typing
8 import zlib
9 
10 import chardet
11 
12 from .exceptions import DecodingError
13 
14 try:
15     import brotli
16 except ImportError:  # pragma: nocover
17     brotli = None
18 
19 
20 class Decoder:
21     def decode(self, data: bytes) -> bytes:
22         raise NotImplementedError()  # pragma: nocover
23 
24     def flush(self) -> bytes:
25         raise NotImplementedError()  # pragma: nocover
26 
27 
28 class IdentityDecoder(Decoder):
29     """
30     Handle unencoded data.
31     """
32 
33     def decode(self, data: bytes) -> bytes:
34         return data
35 
36     def flush(self) -> bytes:
37         return b""
38 
39 
40 class DeflateDecoder(Decoder):
41     """
42     Handle 'deflate' decoding.
43 
44     See: https://stackoverflow.com/questions/1838699
45     """
46 
47     def __init__(self) -> None:
48         self.decompressor = zlib.decompressobj(-zlib.MAX_WBITS)
49 
50     def decode(self, data: bytes) -> bytes:
51         try:
52             return self.decompressor.decompress(data)
53         except zlib.error as exc:
54             raise DecodingError from exc
55 
56     def flush(self) -> bytes:
57         try:
58             return self.decompressor.flush()
59         except zlib.error as exc:  # pragma: nocover
60             raise DecodingError from exc
61 
62 
63 class GZipDecoder(Decoder):
64     """
65     Handle 'gzip' decoding.
66 
67     See: https://stackoverflow.com/questions/1838699
68     """
69 
70     def __init__(self) -> None:
71         self.decompressor = zlib.decompressobj(zlib.MAX_WBITS | 16)
72 
73     def decode(self, data: bytes) -> bytes:
74         try:
75             return self.decompressor.decompress(data)
76         except zlib.error as exc:
77             raise DecodingError from exc
78 
79     def flush(self) -> bytes:
80         try:
81             return self.decompressor.flush()
82         except zlib.error as exc:  # pragma: nocover
83             raise DecodingError from exc
84 
85 
86 class BrotliDecoder(Decoder):
87     """
88     Handle 'brotli' decoding.
89 
90     Requires `pip install brotlipy`. See: https://brotlipy.readthedocs.io/
91         or   `pip install brotli`. See https://github.com/google/brotli
92     Supports both 'brotlipy' and 'Brotli' packages since they share an import
93     name. The top branches are for 'brotlipy' and bottom branches for 'Brotli'
94     """
95 
96     def __init__(self) -> None:
97         assert (
98             brotli is not None
99         ), "The 'brotlipy' or 'brotli' library must be installed to use 'BrotliDecoder'"
100         self.decompressor = brotli.Decompressor()
101 
102     def decode(self, data: bytes) -> bytes:
103         try:
104             if hasattr(self.decompressor, "decompress"):
105                 return self.decompressor.decompress(data)
106             return self.decompressor.process(data)  # pragma: nocover
107         except brotli.error as exc:
108             raise DecodingError from exc
109 
110     def flush(self) -> bytes:
111         try:
112             if hasattr(self.decompressor, "finish"):
113                 self.decompressor.finish()
114             return b""
115         except brotli.error as exc:  # pragma: nocover
116             raise DecodingError from exc
117 
118 
119 class MultiDecoder(Decoder):
120     """
121     Handle the case where multiple encodings have been applied.
122     """
123 
124     def __init__(self, children: typing.Sequence[Decoder]) -> None:
125         """
126         'children' should be a sequence of decoders in the order in which
127         each was applied.
128         """
129         # Note that we reverse the order for decoding.
130         self.children = list(reversed(children))
131 
132     def decode(self, data: bytes) -> bytes:
133         for child in self.children:
134             data = child.decode(data)
135         return data
136 
137     def flush(self) -> bytes:
138         data = b""
139         for child in self.children:
140             data = child.decode(data) + child.flush()
141         return data
142 
143 
144 class TextDecoder:
145     """
146     Handles incrementally decoding bytes into text
147     """
148 
149     def __init__(self, encoding: typing.Optional[str] = None):
150         self.decoder: typing.Optional[codecs.IncrementalDecoder] = (
151             None if encoding is None else codecs.getincrementaldecoder(encoding)()
152         )
153         self.detector = chardet.universaldetector.UniversalDetector()
154 
155         # This buffer is only needed if 'decoder' is 'None'
156         # we want to trigger errors if data is getting added to
157         # our internal buffer for some silly reason while
158         # a decoder is discovered.
159         self.buffer: typing.Optional[bytearray] = None if self.decoder else bytearray()
160 
161     def decode(self, data: bytes) -> str:
162         try:
163             if self.decoder is not None:
164                 text = self.decoder.decode(data)
165             else:
166                 assert self.buffer is not None
167                 text = ""
168                 self.detector.feed(data)
169                 self.buffer += data
170 
171                 # Should be more than enough data to process, we don't
172                 # want to buffer too long as chardet will wait until
173                 # detector.close() is used to give back common
174                 # encodings like 'utf-8'.
175                 if len(self.buffer) >= 4096:
176                     self.decoder = codecs.getincrementaldecoder(
177                         self._detector_result()
178                     )()
179                     text = self.decoder.decode(bytes(self.buffer), False)
180                     self.buffer = None
181 
182             return text
183         except UnicodeDecodeError:  # pragma: nocover
184             raise DecodingError() from None
185 
186     def flush(self) -> str:
187         try:
188             if self.decoder is None:
189                 # Empty string case as chardet is guaranteed to not have a guess.
190                 assert self.buffer is not None
191                 if len(self.buffer) == 0:
192                     return ""
193                 return bytes(self.buffer).decode(self._detector_result())
194 
195             return self.decoder.decode(b"", True)
196         except UnicodeDecodeError:  # pragma: nocover
197             raise DecodingError() from None
198 
199     def _detector_result(self) -> str:
200         self.detector.close()
201         result = self.detector.result["encoding"]
202         if not result:  # pragma: nocover
203             raise DecodingError("Unable to determine encoding of content")
204 
205         return result
206 
207 
208 SUPPORTED_DECODERS = {
209     "identity": IdentityDecoder,
210     "gzip": GZipDecoder,
211     "deflate": DeflateDecoder,
212     "br": BrotliDecoder,
213 }
214 
215 
216 if brotli is None:
217     SUPPORTED_DECODERS.pop("br")  # pragma: nocover
218 
219 
220 ACCEPT_ENCODING = ", ".join(
221     [key for key in SUPPORTED_DECODERS.keys() if key != "identity"]
222 )
223
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/httpx/decoders.py b/httpx/decoders.py
--- a/httpx/decoders.py
+++ b/httpx/decoders.py
@@ -98,8 +98,12 @@
             brotli is not None
         ), "The 'brotlipy' or 'brotli' library must be installed to use 'BrotliDecoder'"
         self.decompressor = brotli.Decompressor()
+        self.seen_data = False
 
     def decode(self, data: bytes) -> bytes:
+        if not data:
+            return b""
+        self.seen_data = True
         try:
             if hasattr(self.decompressor, "decompress"):
                 return self.decompressor.decompress(data)
@@ -108,6 +112,8 @@
             raise DecodingError from exc
 
     def flush(self) -> bytes:
+        if not self.seen_data:
+            return b""
         try:
             if hasattr(self.decompressor, "finish"):
                 self.decompressor.finish()

{"golden_diff": "diff --git a/httpx/decoders.py b/httpx/decoders.py\n--- a/httpx/decoders.py\n+++ b/httpx/decoders.py\n@@ -98,8 +98,12 @@\n             brotli is not None\n         ), \"The 'brotlipy' or 'brotli' library must be installed to use 'BrotliDecoder'\"\n         self.decompressor = brotli.Decompressor()\n+        self.seen_data = False\n \n     def decode(self, data: bytes) -> bytes:\n+        if not data:\n+            return b\"\"\n+        self.seen_data = True\n         try:\n             if hasattr(self.decompressor, \"decompress\"):\n                 return self.decompressor.decompress(data)\n@@ -108,6 +112,8 @@\n             raise DecodingError from exc\n \n     def flush(self) -> bytes:\n+        if not self.seen_data:\n+            return b\"\"\n         try:\n             if hasattr(self.decompressor, \"finish\"):\n                 self.decompressor.finish()\n", "issue": "Handle HEAD responses with Brotli decoder\nCurrently if you receive a response with `Content-Encoding: br` set and no body we get an error because Brotli doesn't like being called on an empty stream.\n", "before_files": [{"content": "\"\"\"\nHandlers for Content-Encoding.\n\nSee: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding\n\"\"\"\nimport codecs\nimport typing\nimport zlib\n\nimport chardet\n\nfrom .exceptions import DecodingError\n\ntry:\n    import brotli\nexcept ImportError:  # pragma: nocover\n    brotli = None\n\n\nclass Decoder:\n    def decode(self, data: bytes) -> bytes:\n        raise NotImplementedError()  # pragma: nocover\n\n    def flush(self) -> bytes:\n        raise NotImplementedError()  # pragma: nocover\n\n\nclass IdentityDecoder(Decoder):\n    \"\"\"\n    Handle unencoded data.\n    \"\"\"\n\n    def decode(self, data: bytes) -> bytes:\n        return data\n\n    def flush(self) -> bytes:\n        return b\"\"\n\n\nclass DeflateDecoder(Decoder):\n    \"\"\"\n    Handle 'deflate' decoding.\n\n    See: https://stackoverflow.com/questions/1838699\n    \"\"\"\n\n    def __init__(self) -> None:\n        self.decompressor = zlib.decompressobj(-zlib.MAX_WBITS)\n\n    def decode(self, data: bytes) -> bytes:\n        try:\n            return self.decompressor.decompress(data)\n        except zlib.error as exc:\n            raise DecodingError from exc\n\n    def flush(self) -> bytes:\n        try:\n            return self.decompressor.flush()\n        except zlib.error as exc:  # pragma: nocover\n            raise DecodingError from exc\n\n\nclass GZipDecoder(Decoder):\n    \"\"\"\n    Handle 'gzip' decoding.\n\n    See: https://stackoverflow.com/questions/1838699\n    \"\"\"\n\n    def __init__(self) -> None:\n        self.decompressor = zlib.decompressobj(zlib.MAX_WBITS | 16)\n\n    def decode(self, data: bytes) -> bytes:\n        try:\n            return self.decompressor.decompress(data)\n        except zlib.error as exc:\n            raise DecodingError from exc\n\n    def flush(self) -> bytes:\n        try:\n            return self.decompressor.flush()\n        except zlib.error as exc:  # pragma: nocover\n            raise DecodingError from exc\n\n\nclass BrotliDecoder(Decoder):\n    \"\"\"\n    Handle 'brotli' decoding.\n\n    Requires `pip install brotlipy`. See: https://brotlipy.readthedocs.io/\n        or   `pip install brotli`. See https://github.com/google/brotli\n    Supports both 'brotlipy' and 'Brotli' packages since they share an import\n    name. The top branches are for 'brotlipy' and bottom branches for 'Brotli'\n    \"\"\"\n\n    def __init__(self) -> None:\n        assert (\n            brotli is not None\n        ), \"The 'brotlipy' or 'brotli' library must be installed to use 'BrotliDecoder'\"\n        self.decompressor = brotli.Decompressor()\n\n    def decode(self, data: bytes) -> bytes:\n        try:\n            if hasattr(self.decompressor, \"decompress\"):\n                return self.decompressor.decompress(data)\n            return self.decompressor.process(data)  # pragma: nocover\n        except brotli.error as exc:\n            raise DecodingError from exc\n\n    def flush(self) -> bytes:\n        try:\n            if hasattr(self.decompressor, \"finish\"):\n                self.decompressor.finish()\n            return b\"\"\n        except brotli.error as exc:  # pragma: nocover\n            raise DecodingError from exc\n\n\nclass MultiDecoder(Decoder):\n    \"\"\"\n    Handle the case where multiple encodings have been applied.\n    \"\"\"\n\n    def __init__(self, children: typing.Sequence[Decoder]) -> None:\n        \"\"\"\n        'children' should be a sequence of decoders in the order in which\n        each was applied.\n        \"\"\"\n        # Note that we reverse the order for decoding.\n        self.children = list(reversed(children))\n\n    def decode(self, data: bytes) -> bytes:\n        for child in self.children:\n            data = child.decode(data)\n        return data\n\n    def flush(self) -> bytes:\n        data = b\"\"\n        for child in self.children:\n            data = child.decode(data) + child.flush()\n        return data\n\n\nclass TextDecoder:\n    \"\"\"\n    Handles incrementally decoding bytes into text\n    \"\"\"\n\n    def __init__(self, encoding: typing.Optional[str] = None):\n        self.decoder: typing.Optional[codecs.IncrementalDecoder] = (\n            None if encoding is None else codecs.getincrementaldecoder(encoding)()\n        )\n        self.detector = chardet.universaldetector.UniversalDetector()\n\n        # This buffer is only needed if 'decoder' is 'None'\n        # we want to trigger errors if data is getting added to\n        # our internal buffer for some silly reason while\n        # a decoder is discovered.\n        self.buffer: typing.Optional[bytearray] = None if self.decoder else bytearray()\n\n    def decode(self, data: bytes) -> str:\n        try:\n            if self.decoder is not None:\n                text = self.decoder.decode(data)\n            else:\n                assert self.buffer is not None\n                text = \"\"\n                self.detector.feed(data)\n                self.buffer += data\n\n                # Should be more than enough data to process, we don't\n                # want to buffer too long as chardet will wait until\n                # detector.close() is used to give back common\n                # encodings like 'utf-8'.\n                if len(self.buffer) >= 4096:\n                    self.decoder = codecs.getincrementaldecoder(\n                        self._detector_result()\n                    )()\n                    text = self.decoder.decode(bytes(self.buffer), False)\n                    self.buffer = None\n\n            return text\n        except UnicodeDecodeError:  # pragma: nocover\n            raise DecodingError() from None\n\n    def flush(self) -> str:\n        try:\n            if self.decoder is None:\n                # Empty string case as chardet is guaranteed to not have a guess.\n                assert self.buffer is not None\n                if len(self.buffer) == 0:\n                    return \"\"\n                return bytes(self.buffer).decode(self._detector_result())\n\n            return self.decoder.decode(b\"\", True)\n        except UnicodeDecodeError:  # pragma: nocover\n            raise DecodingError() from None\n\n    def _detector_result(self) -> str:\n        self.detector.close()\n        result = self.detector.result[\"encoding\"]\n        if not result:  # pragma: nocover\n            raise DecodingError(\"Unable to determine encoding of content\")\n\n        return result\n\n\nSUPPORTED_DECODERS = {\n    \"identity\": IdentityDecoder,\n    \"gzip\": GZipDecoder,\n    \"deflate\": DeflateDecoder,\n    \"br\": BrotliDecoder,\n}\n\n\nif brotli is None:\n    SUPPORTED_DECODERS.pop(\"br\")  # pragma: nocover\n\n\nACCEPT_ENCODING = \", \".join(\n    [key for key in SUPPORTED_DECODERS.keys() if key != \"identity\"]\n)\n", "path": "httpx/decoders.py"}], "after_files": [{"content": "\"\"\"\nHandlers for Content-Encoding.\n\nSee: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding\n\"\"\"\nimport codecs\nimport typing\nimport zlib\n\nimport chardet\n\nfrom .exceptions import DecodingError\n\ntry:\n    import brotli\nexcept ImportError:  # pragma: nocover\n    brotli = None\n\n\nclass Decoder:\n    def decode(self, data: bytes) -> bytes:\n        raise NotImplementedError()  # pragma: nocover\n\n    def flush(self) -> bytes:\n        raise NotImplementedError()  # pragma: nocover\n\n\nclass IdentityDecoder(Decoder):\n    \"\"\"\n    Handle unencoded data.\n    \"\"\"\n\n    def decode(self, data: bytes) -> bytes:\n        return data\n\n    def flush(self) -> bytes:\n        return b\"\"\n\n\nclass DeflateDecoder(Decoder):\n    \"\"\"\n    Handle 'deflate' decoding.\n\n    See: https://stackoverflow.com/questions/1838699\n    \"\"\"\n\n    def __init__(self) -> None:\n        self.decompressor = zlib.decompressobj(-zlib.MAX_WBITS)\n\n    def decode(self, data: bytes) -> bytes:\n        try:\n            return self.decompressor.decompress(data)\n        except zlib.error as exc:\n            raise DecodingError from exc\n\n    def flush(self) -> bytes:\n        try:\n            return self.decompressor.flush()\n        except zlib.error as exc:  # pragma: nocover\n            raise DecodingError from exc\n\n\nclass GZipDecoder(Decoder):\n    \"\"\"\n    Handle 'gzip' decoding.\n\n    See: https://stackoverflow.com/questions/1838699\n    \"\"\"\n\n    def __init__(self) -> None:\n        self.decompressor = zlib.decompressobj(zlib.MAX_WBITS | 16)\n\n    def decode(self, data: bytes) -> bytes:\n        try:\n            return self.decompressor.decompress(data)\n        except zlib.error as exc:\n            raise DecodingError from exc\n\n    def flush(self) -> bytes:\n        try:\n            return self.decompressor.flush()\n        except zlib.error as exc:  # pragma: nocover\n            raise DecodingError from exc\n\n\nclass BrotliDecoder(Decoder):\n    \"\"\"\n    Handle 'brotli' decoding.\n\n    Requires `pip install brotlipy`. See: https://brotlipy.readthedocs.io/\n        or   `pip install brotli`. See https://github.com/google/brotli\n    Supports both 'brotlipy' and 'Brotli' packages since they share an import\n    name. The top branches are for 'brotlipy' and bottom branches for 'Brotli'\n    \"\"\"\n\n    def __init__(self) -> None:\n        assert (\n            brotli is not None\n        ), \"The 'brotlipy' or 'brotli' library must be installed to use 'BrotliDecoder'\"\n        self.decompressor = brotli.Decompressor()\n        self.seen_data = False\n\n    def decode(self, data: bytes) -> bytes:\n        if not data:\n            return b\"\"\n        self.seen_data = True\n        try:\n            if hasattr(self.decompressor, \"decompress\"):\n                return self.decompressor.decompress(data)\n            return self.decompressor.process(data)  # pragma: nocover\n        except brotli.error as exc:\n            raise DecodingError from exc\n\n    def flush(self) -> bytes:\n        if not self.seen_data:\n            return b\"\"\n        try:\n            if hasattr(self.decompressor, \"finish\"):\n                self.decompressor.finish()\n            return b\"\"\n        except brotli.error as exc:  # pragma: nocover\n            raise DecodingError from exc\n\n\nclass MultiDecoder(Decoder):\n    \"\"\"\n    Handle the case where multiple encodings have been applied.\n    \"\"\"\n\n    def __init__(self, children: typing.Sequence[Decoder]) -> None:\n        \"\"\"\n        'children' should be a sequence of decoders in the order in which\n        each was applied.\n        \"\"\"\n        # Note that we reverse the order for decoding.\n        self.children = list(reversed(children))\n\n    def decode(self, data: bytes) -> bytes:\n        for child in self.children:\n            data = child.decode(data)\n        return data\n\n    def flush(self) -> bytes:\n        data = b\"\"\n        for child in self.children:\n            data = child.decode(data) + child.flush()\n        return data\n\n\nclass TextDecoder:\n    \"\"\"\n    Handles incrementally decoding bytes into text\n    \"\"\"\n\n    def __init__(self, encoding: typing.Optional[str] = None):\n        self.decoder: typing.Optional[codecs.IncrementalDecoder] = (\n            None if encoding is None else codecs.getincrementaldecoder(encoding)()\n        )\n        self.detector = chardet.universaldetector.UniversalDetector()\n\n        # This buffer is only needed if 'decoder' is 'None'\n        # we want to trigger errors if data is getting added to\n        # our internal buffer for some silly reason while\n        # a decoder is discovered.\n        self.buffer: typing.Optional[bytearray] = None if self.decoder else bytearray()\n\n    def decode(self, data: bytes) -> str:\n        try:\n            if self.decoder is not None:\n                text = self.decoder.decode(data)\n            else:\n                assert self.buffer is not None\n                text = \"\"\n                self.detector.feed(data)\n                self.buffer += data\n\n                # Should be more than enough data to process, we don't\n                # want to buffer too long as chardet will wait until\n                # detector.close() is used to give back common\n                # encodings like 'utf-8'.\n                if len(self.buffer) >= 4096:\n                    self.decoder = codecs.getincrementaldecoder(\n                        self._detector_result()\n                    )()\n                    text = self.decoder.decode(bytes(self.buffer), False)\n                    self.buffer = None\n\n            return text\n        except UnicodeDecodeError:  # pragma: nocover\n            raise DecodingError() from None\n\n    def flush(self) -> str:\n        try:\n            if self.decoder is None:\n                # Empty string case as chardet is guaranteed to not have a guess.\n                assert self.buffer is not None\n                if len(self.buffer) == 0:\n                    return \"\"\n                return bytes(self.buffer).decode(self._detector_result())\n\n            return self.decoder.decode(b\"\", True)\n        except UnicodeDecodeError:  # pragma: nocover\n            raise DecodingError() from None\n\n    def _detector_result(self) -> str:\n        self.detector.close()\n        result = self.detector.result[\"encoding\"]\n        if not result:  # pragma: nocover\n            raise DecodingError(\"Unable to determine encoding of content\")\n\n        return result\n\n\nSUPPORTED_DECODERS = {\n    \"identity\": IdentityDecoder,\n    \"gzip\": GZipDecoder,\n    \"deflate\": DeflateDecoder,\n    \"br\": BrotliDecoder,\n}\n\n\nif brotli is None:\n    SUPPORTED_DECODERS.pop(\"br\")  # pragma: nocover\n\n\nACCEPT_ENCODING = \", \".join(\n    [key for key in SUPPORTED_DECODERS.keys() if key != \"identity\"]\n)\n", "path": "httpx/decoders.py"}]}