We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
web.FileResponse overrides content_type
## Long story short

When returning a `web.FileResponse` from a route, any changes to the `content_type` member is not taken into account when the file is served. Instead, the file extension is always used to determine the content type of the response.

## Expected behaviour

`Content-Type` header of the response be that of `web.FileResponse.content_type` when such has been set.

## Actual behaviour

`Content-Type` header is guessed from the file extension of the served file.

## Steps to reproduce

Create a route that responds something along the lines of

```python
    response = web.FileResponse('/path/to/some/image.png')
    response.content_type = 'application/octet-stream'
    return response
```

then `curl -i` it and notice the `Content-Type` is `image/png`.

## Your environment

```
[~]$ uname -mrs
Linux 4.11.9-1-ARCH x86_64
[~]$ python --version
Python 3.6.2
[~]$ pip show aiohttp | grep Version
Version: 2.2.5
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `aiohttp/web_fileresponse.py`
Content:
```
1 import asyncio
2 import mimetypes
3 import os
4 import pathlib
5 
6 from . import hdrs
7 from .helpers import create_future
8 from .http_writer import PayloadWriter
9 from .log import server_logger
10 from .web_exceptions import (HTTPNotModified, HTTPOk, HTTPPartialContent,
11                              HTTPRequestRangeNotSatisfiable)
12 from .web_response import StreamResponse
13 
14 
15 __all__ = ('FileResponse',)
16 
17 
18 NOSENDFILE = bool(os.environ.get("AIOHTTP_NOSENDFILE"))
19 
20 
21 class SendfilePayloadWriter(PayloadWriter):
22 
23     def set_transport(self, transport):
24         self._transport = transport
25 
26         if self._drain_waiter is not None:
27             waiter, self._drain_maiter = self._drain_maiter, None
28             if not waiter.done():
29                 waiter.set_result(None)
30 
31     def _write(self, chunk):
32         self.output_size += len(chunk)
33         self._buffer.append(chunk)
34 
35     def _sendfile_cb(self, fut, out_fd, in_fd,
36                      offset, count, loop, registered):
37         if registered:
38             loop.remove_writer(out_fd)
39         if fut.cancelled():
40             return
41 
42         try:
43             n = os.sendfile(out_fd, in_fd, offset, count)
44             if n == 0:  # EOF reached
45                 n = count
46         except (BlockingIOError, InterruptedError):
47             n = 0
48         except Exception as exc:
49             fut.set_exception(exc)
50             return
51 
52         if n < count:
53             loop.add_writer(out_fd, self._sendfile_cb, fut, out_fd, in_fd,
54                             offset + n, count - n, loop, True)
55         else:
56             fut.set_result(None)
57 
58     @asyncio.coroutine
59     def sendfile(self, fobj, count):
60         if self._transport is None:
61             if self._drain_waiter is None:
62                 self._drain_waiter = create_future(self.loop)
63 
64             yield from self._drain_waiter
65 
66         out_socket = self._transport.get_extra_info("socket").dup()
67         out_socket.setblocking(False)
68         out_fd = out_socket.fileno()
69         in_fd = fobj.fileno()
70         offset = fobj.tell()
71 
72         loop = self.loop
73         try:
74             yield from loop.sock_sendall(out_socket, b''.join(self._buffer))
75             fut = create_future(loop)
76             self._sendfile_cb(fut, out_fd, in_fd, offset, count, loop, False)
77             yield from fut
78         except:
79             server_logger.debug('Socket error')
80             self._transport.close()
81         finally:
82             out_socket.close()
83 
84         self.output_size += count
85         self._transport = None
86         self._stream.release()
87 
88     @asyncio.coroutine
89     def write_eof(self, chunk=b''):
90         pass
91 
92 
93 class FileResponse(StreamResponse):
94     """A response object can be used to send files."""
95 
96     def __init__(self, path, chunk_size=256*1024, *args, **kwargs):
97         super().__init__(*args, **kwargs)
98 
99         if isinstance(path, str):
100             path = pathlib.Path(path)
101 
102         self._path = path
103         self._chunk_size = chunk_size
104 
105     @asyncio.coroutine
106     def _sendfile_system(self, request, fobj, count):
107         # Write count bytes of fobj to resp using
108         # the os.sendfile system call.
109         #
110         # For details check
111         # https://github.com/KeepSafe/aiohttp/issues/1177
112         # See https://github.com/KeepSafe/aiohttp/issues/958 for details
113         #
114         # request should be a aiohttp.web.Request instance.
115         # fobj should be an open file object.
116         # count should be an integer > 0.
117 
118         transport = request.transport
119         if (transport.get_extra_info("sslcontext") or
120                 transport.get_extra_info("socket") is None):
121             writer = yield from self._sendfile_fallback(request, fobj, count)
122         else:
123             writer = request._protocol.writer.replace(
124                 request._writer, SendfilePayloadWriter)
125             request._writer = writer
126             yield from super().prepare(request)
127             yield from writer.sendfile(fobj, count)
128 
129         return writer
130 
131     @asyncio.coroutine
132     def _sendfile_fallback(self, request, fobj, count):
133         # Mimic the _sendfile_system() method, but without using the
134         # os.sendfile() system call. This should be used on systems
135         # that don't support the os.sendfile().
136 
137         # To avoid blocking the event loop & to keep memory usage low,
138         # fobj is transferred in chunks controlled by the
139         # constructor's chunk_size argument.
140 
141         writer = (yield from super().prepare(request))
142 
143         self.set_tcp_cork(True)
144         try:
145             chunk_size = self._chunk_size
146 
147             chunk = fobj.read(chunk_size)
148             while True:
149                 yield from writer.write(chunk)
150                 count = count - chunk_size
151                 if count <= 0:
152                     break
153                 chunk = fobj.read(min(chunk_size, count))
154         finally:
155             self.set_tcp_nodelay(True)
156 
157         yield from writer.drain()
158         return writer
159 
160     if hasattr(os, "sendfile") and not NOSENDFILE:  # pragma: no cover
161         _sendfile = _sendfile_system
162     else:  # pragma: no cover
163         _sendfile = _sendfile_fallback
164 
165     @asyncio.coroutine
166     def prepare(self, request):
167         filepath = self._path
168 
169         gzip = False
170         if 'gzip' in request.headers.get(hdrs.ACCEPT_ENCODING, ''):
171             gzip_path = filepath.with_name(filepath.name + '.gz')
172 
173             if gzip_path.is_file():
174                 filepath = gzip_path
175                 gzip = True
176 
177         st = filepath.stat()
178 
179         modsince = request.if_modified_since
180         if modsince is not None and st.st_mtime <= modsince.timestamp():
181             self.set_status(HTTPNotModified.status_code)
182             self._length_check = False
183             return (yield from super().prepare(request))
184 
185         ct, encoding = mimetypes.guess_type(str(filepath))
186         if not ct:
187             ct = 'application/octet-stream'
188 
189         status = HTTPOk.status_code
190         file_size = st.st_size
191         count = file_size
192 
193         try:
194             rng = request.http_range
195             start = rng.start
196             end = rng.stop
197         except ValueError:
198             self.set_status(HTTPRequestRangeNotSatisfiable.status_code)
199             return (yield from super().prepare(request))
200 
201         # If a range request has been made, convert start, end slice notation
202         # into file pointer offset and count
203         if start is not None or end is not None:
204             if start is None and end < 0:  # return tail of file
205                 start = file_size + end
206                 count = -end
207             else:
208                 count = (end or file_size) - start
209 
210             if start + count > file_size:
211                 # rfc7233:If the last-byte-pos value is
212                 # absent, or if the value is greater than or equal to
213                 # the current length of the representation data,
214                 # the byte range is interpreted as the remainder
215                 # of the representation (i.e., the server replaces the
216                 # value of last-byte-pos with a value that is one less than
217                 # the current length of the selected representation).
218                 count = file_size - start
219 
220             if start >= file_size:
221                 count = 0
222 
223         if count != file_size:
224             status = HTTPPartialContent.status_code
225 
226         self.set_status(status)
227         self.content_type = ct
228         if encoding:
229             self.headers[hdrs.CONTENT_ENCODING] = encoding
230         if gzip:
231             self.headers[hdrs.VARY] = hdrs.ACCEPT_ENCODING
232         self.last_modified = st.st_mtime
233         self.content_length = count
234 
235         if count:
236             with filepath.open('rb') as fobj:
237                 if start:
238                     fobj.seek(start)
239 
240                 return (yield from self._sendfile(request, fobj, count))
241 
242         return (yield from super().prepare(request))
243
```
--- 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/aiohttp/web_fileresponse.py b/aiohttp/web_fileresponse.py
--- a/aiohttp/web_fileresponse.py
+++ b/aiohttp/web_fileresponse.py
@@ -182,9 +182,13 @@
             self._length_check = False
             return (yield from super().prepare(request))
 
-        ct, encoding = mimetypes.guess_type(str(filepath))
-        if not ct:
-            ct = 'application/octet-stream'
+        if hdrs.CONTENT_TYPE not in self.headers:
+            ct, encoding = mimetypes.guess_type(str(filepath))
+            if not ct:
+                ct = 'application/octet-stream'
+        else:
+            ct = self.headers[hdrs.CONTENT_TYPE]
+            encoding = 'gzip' if gzip else None
 
         status = HTTPOk.status_code
         file_size = st.st_size

{"golden_diff": "diff --git a/aiohttp/web_fileresponse.py b/aiohttp/web_fileresponse.py\n--- a/aiohttp/web_fileresponse.py\n+++ b/aiohttp/web_fileresponse.py\n@@ -182,9 +182,13 @@\n             self._length_check = False\n             return (yield from super().prepare(request))\n \n-        ct, encoding = mimetypes.guess_type(str(filepath))\n-        if not ct:\n-            ct = 'application/octet-stream'\n+        if hdrs.CONTENT_TYPE not in self.headers:\n+            ct, encoding = mimetypes.guess_type(str(filepath))\n+            if not ct:\n+                ct = 'application/octet-stream'\n+        else:\n+            ct = self.headers[hdrs.CONTENT_TYPE]\n+            encoding = 'gzip' if gzip else None\n \n         status = HTTPOk.status_code\n         file_size = st.st_size\n", "issue": "web.FileResponse overrides content_type\n## Long story short\r\n\r\nWhen returning a `web.FileResponse` from a route, any changes to the `content_type` member is not taken into account when the file is served. Instead, the file extension is always used to determine the content type of the response.\r\n\r\n## Expected behaviour\r\n\r\n`Content-Type` header of the response be that of `web.FileResponse.content_type` when such has been set.\r\n\r\n## Actual behaviour\r\n\r\n`Content-Type` header is guessed from the file extension of the served file.\r\n\r\n## Steps to reproduce\r\n\r\nCreate a route that responds something along the lines of\r\n\r\n```python\r\n    response = web.FileResponse('/path/to/some/image.png')\r\n    response.content_type = 'application/octet-stream'\r\n    return response\r\n```\r\n\r\nthen `curl -i` it and notice the `Content-Type` is `image/png`.\r\n\r\n## Your environment\r\n\r\n```\r\n[~]$ uname -mrs\r\nLinux 4.11.9-1-ARCH x86_64\r\n[~]$ python --version\r\nPython 3.6.2\r\n[~]$ pip show aiohttp | grep Version\r\nVersion: 2.2.5\r\n```\r\n\n", "before_files": [{"content": "import asyncio\nimport mimetypes\nimport os\nimport pathlib\n\nfrom . import hdrs\nfrom .helpers import create_future\nfrom .http_writer import PayloadWriter\nfrom .log import server_logger\nfrom .web_exceptions import (HTTPNotModified, HTTPOk, HTTPPartialContent,\n                             HTTPRequestRangeNotSatisfiable)\nfrom .web_response import StreamResponse\n\n\n__all__ = ('FileResponse',)\n\n\nNOSENDFILE = bool(os.environ.get(\"AIOHTTP_NOSENDFILE\"))\n\n\nclass SendfilePayloadWriter(PayloadWriter):\n\n    def set_transport(self, transport):\n        self._transport = transport\n\n        if self._drain_waiter is not None:\n            waiter, self._drain_maiter = self._drain_maiter, None\n            if not waiter.done():\n                waiter.set_result(None)\n\n    def _write(self, chunk):\n        self.output_size += len(chunk)\n        self._buffer.append(chunk)\n\n    def _sendfile_cb(self, fut, out_fd, in_fd,\n                     offset, count, loop, registered):\n        if registered:\n            loop.remove_writer(out_fd)\n        if fut.cancelled():\n            return\n\n        try:\n            n = os.sendfile(out_fd, in_fd, offset, count)\n            if n == 0:  # EOF reached\n                n = count\n        except (BlockingIOError, InterruptedError):\n            n = 0\n        except Exception as exc:\n            fut.set_exception(exc)\n            return\n\n        if n < count:\n            loop.add_writer(out_fd, self._sendfile_cb, fut, out_fd, in_fd,\n                            offset + n, count - n, loop, True)\n        else:\n            fut.set_result(None)\n\n    @asyncio.coroutine\n    def sendfile(self, fobj, count):\n        if self._transport is None:\n            if self._drain_waiter is None:\n                self._drain_waiter = create_future(self.loop)\n\n            yield from self._drain_waiter\n\n        out_socket = self._transport.get_extra_info(\"socket\").dup()\n        out_socket.setblocking(False)\n        out_fd = out_socket.fileno()\n        in_fd = fobj.fileno()\n        offset = fobj.tell()\n\n        loop = self.loop\n        try:\n            yield from loop.sock_sendall(out_socket, b''.join(self._buffer))\n            fut = create_future(loop)\n            self._sendfile_cb(fut, out_fd, in_fd, offset, count, loop, False)\n            yield from fut\n        except:\n            server_logger.debug('Socket error')\n            self._transport.close()\n        finally:\n            out_socket.close()\n\n        self.output_size += count\n        self._transport = None\n        self._stream.release()\n\n    @asyncio.coroutine\n    def write_eof(self, chunk=b''):\n        pass\n\n\nclass FileResponse(StreamResponse):\n    \"\"\"A response object can be used to send files.\"\"\"\n\n    def __init__(self, path, chunk_size=256*1024, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\n        if isinstance(path, str):\n            path = pathlib.Path(path)\n\n        self._path = path\n        self._chunk_size = chunk_size\n\n    @asyncio.coroutine\n    def _sendfile_system(self, request, fobj, count):\n        # Write count bytes of fobj to resp using\n        # the os.sendfile system call.\n        #\n        # For details check\n        # https://github.com/KeepSafe/aiohttp/issues/1177\n        # See https://github.com/KeepSafe/aiohttp/issues/958 for details\n        #\n        # request should be a aiohttp.web.Request instance.\n        # fobj should be an open file object.\n        # count should be an integer > 0.\n\n        transport = request.transport\n        if (transport.get_extra_info(\"sslcontext\") or\n                transport.get_extra_info(\"socket\") is None):\n            writer = yield from self._sendfile_fallback(request, fobj, count)\n        else:\n            writer = request._protocol.writer.replace(\n                request._writer, SendfilePayloadWriter)\n            request._writer = writer\n            yield from super().prepare(request)\n            yield from writer.sendfile(fobj, count)\n\n        return writer\n\n    @asyncio.coroutine\n    def _sendfile_fallback(self, request, fobj, count):\n        # Mimic the _sendfile_system() method, but without using the\n        # os.sendfile() system call. This should be used on systems\n        # that don't support the os.sendfile().\n\n        # To avoid blocking the event loop & to keep memory usage low,\n        # fobj is transferred in chunks controlled by the\n        # constructor's chunk_size argument.\n\n        writer = (yield from super().prepare(request))\n\n        self.set_tcp_cork(True)\n        try:\n            chunk_size = self._chunk_size\n\n            chunk = fobj.read(chunk_size)\n            while True:\n                yield from writer.write(chunk)\n                count = count - chunk_size\n                if count <= 0:\n                    break\n                chunk = fobj.read(min(chunk_size, count))\n        finally:\n            self.set_tcp_nodelay(True)\n\n        yield from writer.drain()\n        return writer\n\n    if hasattr(os, \"sendfile\") and not NOSENDFILE:  # pragma: no cover\n        _sendfile = _sendfile_system\n    else:  # pragma: no cover\n        _sendfile = _sendfile_fallback\n\n    @asyncio.coroutine\n    def prepare(self, request):\n        filepath = self._path\n\n        gzip = False\n        if 'gzip' in request.headers.get(hdrs.ACCEPT_ENCODING, ''):\n            gzip_path = filepath.with_name(filepath.name + '.gz')\n\n            if gzip_path.is_file():\n                filepath = gzip_path\n                gzip = True\n\n        st = filepath.stat()\n\n        modsince = request.if_modified_since\n        if modsince is not None and st.st_mtime <= modsince.timestamp():\n            self.set_status(HTTPNotModified.status_code)\n            self._length_check = False\n            return (yield from super().prepare(request))\n\n        ct, encoding = mimetypes.guess_type(str(filepath))\n        if not ct:\n            ct = 'application/octet-stream'\n\n        status = HTTPOk.status_code\n        file_size = st.st_size\n        count = file_size\n\n        try:\n            rng = request.http_range\n            start = rng.start\n            end = rng.stop\n        except ValueError:\n            self.set_status(HTTPRequestRangeNotSatisfiable.status_code)\n            return (yield from super().prepare(request))\n\n        # If a range request has been made, convert start, end slice notation\n        # into file pointer offset and count\n        if start is not None or end is not None:\n            if start is None and end < 0:  # return tail of file\n                start = file_size + end\n                count = -end\n            else:\n                count = (end or file_size) - start\n\n            if start + count > file_size:\n                # rfc7233:If the last-byte-pos value is\n                # absent, or if the value is greater than or equal to\n                # the current length of the representation data,\n                # the byte range is interpreted as the remainder\n                # of the representation (i.e., the server replaces the\n                # value of last-byte-pos with a value that is one less than\n                # the current length of the selected representation).\n                count = file_size - start\n\n            if start >= file_size:\n                count = 0\n\n        if count != file_size:\n            status = HTTPPartialContent.status_code\n\n        self.set_status(status)\n        self.content_type = ct\n        if encoding:\n            self.headers[hdrs.CONTENT_ENCODING] = encoding\n        if gzip:\n            self.headers[hdrs.VARY] = hdrs.ACCEPT_ENCODING\n        self.last_modified = st.st_mtime\n        self.content_length = count\n\n        if count:\n            with filepath.open('rb') as fobj:\n                if start:\n                    fobj.seek(start)\n\n                return (yield from self._sendfile(request, fobj, count))\n\n        return (yield from super().prepare(request))\n", "path": "aiohttp/web_fileresponse.py"}], "after_files": [{"content": "import asyncio\nimport mimetypes\nimport os\nimport pathlib\n\nfrom . import hdrs\nfrom .helpers import create_future\nfrom .http_writer import PayloadWriter\nfrom .log import server_logger\nfrom .web_exceptions import (HTTPNotModified, HTTPOk, HTTPPartialContent,\n                             HTTPRequestRangeNotSatisfiable)\nfrom .web_response import StreamResponse\n\n\n__all__ = ('FileResponse',)\n\n\nNOSENDFILE = bool(os.environ.get(\"AIOHTTP_NOSENDFILE\"))\n\n\nclass SendfilePayloadWriter(PayloadWriter):\n\n    def set_transport(self, transport):\n        self._transport = transport\n\n        if self._drain_waiter is not None:\n            waiter, self._drain_maiter = self._drain_maiter, None\n            if not waiter.done():\n                waiter.set_result(None)\n\n    def _write(self, chunk):\n        self.output_size += len(chunk)\n        self._buffer.append(chunk)\n\n    def _sendfile_cb(self, fut, out_fd, in_fd,\n                     offset, count, loop, registered):\n        if registered:\n            loop.remove_writer(out_fd)\n        if fut.cancelled():\n            return\n\n        try:\n            n = os.sendfile(out_fd, in_fd, offset, count)\n            if n == 0:  # EOF reached\n                n = count\n        except (BlockingIOError, InterruptedError):\n            n = 0\n        except Exception as exc:\n            fut.set_exception(exc)\n            return\n\n        if n < count:\n            loop.add_writer(out_fd, self._sendfile_cb, fut, out_fd, in_fd,\n                            offset + n, count - n, loop, True)\n        else:\n            fut.set_result(None)\n\n    @asyncio.coroutine\n    def sendfile(self, fobj, count):\n        if self._transport is None:\n            if self._drain_waiter is None:\n                self._drain_waiter = create_future(self.loop)\n\n            yield from self._drain_waiter\n\n        out_socket = self._transport.get_extra_info(\"socket\").dup()\n        out_socket.setblocking(False)\n        out_fd = out_socket.fileno()\n        in_fd = fobj.fileno()\n        offset = fobj.tell()\n\n        loop = self.loop\n        try:\n            yield from loop.sock_sendall(out_socket, b''.join(self._buffer))\n            fut = create_future(loop)\n            self._sendfile_cb(fut, out_fd, in_fd, offset, count, loop, False)\n            yield from fut\n        except:\n            server_logger.debug('Socket error')\n            self._transport.close()\n        finally:\n            out_socket.close()\n\n        self.output_size += count\n        self._transport = None\n        self._stream.release()\n\n    @asyncio.coroutine\n    def write_eof(self, chunk=b''):\n        pass\n\n\nclass FileResponse(StreamResponse):\n    \"\"\"A response object can be used to send files.\"\"\"\n\n    def __init__(self, path, chunk_size=256*1024, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\n        if isinstance(path, str):\n            path = pathlib.Path(path)\n\n        self._path = path\n        self._chunk_size = chunk_size\n\n    @asyncio.coroutine\n    def _sendfile_system(self, request, fobj, count):\n        # Write count bytes of fobj to resp using\n        # the os.sendfile system call.\n        #\n        # For details check\n        # https://github.com/KeepSafe/aiohttp/issues/1177\n        # See https://github.com/KeepSafe/aiohttp/issues/958 for details\n        #\n        # request should be a aiohttp.web.Request instance.\n        # fobj should be an open file object.\n        # count should be an integer > 0.\n\n        transport = request.transport\n        if (transport.get_extra_info(\"sslcontext\") or\n                transport.get_extra_info(\"socket\") is None):\n            writer = yield from self._sendfile_fallback(request, fobj, count)\n        else:\n            writer = request._protocol.writer.replace(\n                request._writer, SendfilePayloadWriter)\n            request._writer = writer\n            yield from super().prepare(request)\n            yield from writer.sendfile(fobj, count)\n\n        return writer\n\n    @asyncio.coroutine\n    def _sendfile_fallback(self, request, fobj, count):\n        # Mimic the _sendfile_system() method, but without using the\n        # os.sendfile() system call. This should be used on systems\n        # that don't support the os.sendfile().\n\n        # To avoid blocking the event loop & to keep memory usage low,\n        # fobj is transferred in chunks controlled by the\n        # constructor's chunk_size argument.\n\n        writer = (yield from super().prepare(request))\n\n        self.set_tcp_cork(True)\n        try:\n            chunk_size = self._chunk_size\n\n            chunk = fobj.read(chunk_size)\n            while True:\n                yield from writer.write(chunk)\n                count = count - chunk_size\n                if count <= 0:\n                    break\n                chunk = fobj.read(min(chunk_size, count))\n        finally:\n            self.set_tcp_nodelay(True)\n\n        yield from writer.drain()\n        return writer\n\n    if hasattr(os, \"sendfile\") and not NOSENDFILE:  # pragma: no cover\n        _sendfile = _sendfile_system\n    else:  # pragma: no cover\n        _sendfile = _sendfile_fallback\n\n    @asyncio.coroutine\n    def prepare(self, request):\n        filepath = self._path\n\n        gzip = False\n        if 'gzip' in request.headers.get(hdrs.ACCEPT_ENCODING, ''):\n            gzip_path = filepath.with_name(filepath.name + '.gz')\n\n            if gzip_path.is_file():\n                filepath = gzip_path\n                gzip = True\n\n        st = filepath.stat()\n\n        modsince = request.if_modified_since\n        if modsince is not None and st.st_mtime <= modsince.timestamp():\n            self.set_status(HTTPNotModified.status_code)\n            self._length_check = False\n            return (yield from super().prepare(request))\n\n        if hdrs.CONTENT_TYPE not in self.headers:\n            ct, encoding = mimetypes.guess_type(str(filepath))\n            if not ct:\n                ct = 'application/octet-stream'\n        else:\n            ct = self.headers[hdrs.CONTENT_TYPE]\n            encoding = 'gzip' if gzip else None\n\n        status = HTTPOk.status_code\n        file_size = st.st_size\n        count = file_size\n\n        try:\n            rng = request.http_range\n            start = rng.start\n            end = rng.stop\n        except ValueError:\n            self.set_status(HTTPRequestRangeNotSatisfiable.status_code)\n            return (yield from super().prepare(request))\n\n        # If a range request has been made, convert start, end slice notation\n        # into file pointer offset and count\n        if start is not None or end is not None:\n            if start is None and end < 0:  # return tail of file\n                start = file_size + end\n                count = -end\n            else:\n                count = (end or file_size) - start\n\n            if start + count > file_size:\n                # rfc7233:If the last-byte-pos value is\n                # absent, or if the value is greater than or equal to\n                # the current length of the representation data,\n                # the byte range is interpreted as the remainder\n                # of the representation (i.e., the server replaces the\n                # value of last-byte-pos with a value that is one less than\n                # the current length of the selected representation).\n                count = file_size - start\n\n            if start >= file_size:\n                count = 0\n\n        if count != file_size:\n            status = HTTPPartialContent.status_code\n\n        self.set_status(status)\n        self.content_type = ct\n        if encoding:\n            self.headers[hdrs.CONTENT_ENCODING] = encoding\n        if gzip:\n            self.headers[hdrs.VARY] = hdrs.ACCEPT_ENCODING\n        self.last_modified = st.st_mtime\n        self.content_length = count\n\n        if count:\n            with filepath.open('rb') as fobj:\n                if start:\n                    fobj.seek(start)\n\n                return (yield from self._sendfile(request, fobj, count))\n\n        return (yield from super().prepare(request))\n", "path": "aiohttp/web_fileresponse.py"}]}