We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Sanic `Request` object is falsey
```python
@app.route('/myroute')
async def someroute(request):
    if request:
        return 'some data'
    raise Exception("Woops")
```

This code will raise the exception because `bool(request)` is `False`. 

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `sanic/request.py`
Content:
```
1 import sys
2 import json
3 import socket
4 from cgi import parse_header
5 from collections import namedtuple
6 from http.cookies import SimpleCookie
7 from httptools import parse_url
8 from urllib.parse import parse_qs, urlunparse
9 
10 try:
11     from ujson import loads as json_loads
12 except ImportError:
13     if sys.version_info[:2] == (3, 5):
14         def json_loads(data):
15             # on Python 3.5 json.loads only supports str not bytes
16             return json.loads(data.decode())
17     else:
18         json_loads = json.loads
19 
20 from sanic.exceptions import InvalidUsage
21 from sanic.log import error_logger, logger
22 
23 DEFAULT_HTTP_CONTENT_TYPE = "application/octet-stream"
24 
25 
26 # HTTP/1.1: https://www.w3.org/Protocols/rfc2616/rfc2616-sec7.html#sec7.2.1
27 # > If the media type remains unknown, the recipient SHOULD treat it
28 # > as type "application/octet-stream"
29 
30 
31 class RequestParameters(dict):
32     """Hosts a dict with lists as values where get returns the first
33     value of the list and getlist returns the whole shebang
34     """
35 
36     def get(self, name, default=None):
37         """Return the first value, either the default or actual"""
38         return super().get(name, [default])[0]
39 
40     def getlist(self, name, default=None):
41         """Return the entire list"""
42         return super().get(name, default)
43 
44 
45 class Request(dict):
46     """Properties of an HTTP request such as URL, headers, etc."""
47     __slots__ = (
48         'app', 'headers', 'version', 'method', '_cookies', 'transport',
49         'body', 'parsed_json', 'parsed_args', 'parsed_form', 'parsed_files',
50         '_ip', '_parsed_url', 'uri_template', 'stream', '_remote_addr',
51         '_socket', '_port', '__weakref__'
52     )
53 
54     def __init__(self, url_bytes, headers, version, method, transport):
55         # TODO: Content-Encoding detection
56         self._parsed_url = parse_url(url_bytes)
57         self.app = None
58 
59         self.headers = headers
60         self.version = version
61         self.method = method
62         self.transport = transport
63 
64         # Init but do not inhale
65         self.body = []
66         self.parsed_json = None
67         self.parsed_form = None
68         self.parsed_files = None
69         self.parsed_args = None
70         self.uri_template = None
71         self._cookies = None
72         self.stream = None
73 
74     def __repr__(self):
75         if self.method is None or not self.path:
76             return '<{0}>'.format(self.__class__.__name__)
77         return '<{0}: {1} {2}>'.format(self.__class__.__name__,
78                                        self.method,
79                                        self.path)
80 
81     @property
82     def json(self):
83         if self.parsed_json is None:
84             self.load_json()
85 
86         return self.parsed_json
87 
88     def load_json(self, loads=json_loads):
89         try:
90             self.parsed_json = loads(self.body)
91         except Exception:
92             if not self.body:
93                 return None
94             raise InvalidUsage("Failed when parsing body as json")
95 
96         return self.parsed_json
97 
98     @property
99     def token(self):
100         """Attempt to return the auth header token.
101 
102         :return: token related to request
103         """
104         prefixes = ('Bearer', 'Token')
105         auth_header = self.headers.get('Authorization')
106 
107         if auth_header is not None:
108             for prefix in prefixes:
109                 if prefix in auth_header:
110                     return auth_header.partition(prefix)[-1].strip()
111 
112         return auth_header
113 
114     @property
115     def form(self):
116         if self.parsed_form is None:
117             self.parsed_form = RequestParameters()
118             self.parsed_files = RequestParameters()
119             content_type = self.headers.get(
120                 'Content-Type', DEFAULT_HTTP_CONTENT_TYPE)
121             content_type, parameters = parse_header(content_type)
122             try:
123                 if content_type == 'application/x-www-form-urlencoded':
124                     self.parsed_form = RequestParameters(
125                         parse_qs(self.body.decode('utf-8')))
126                 elif content_type == 'multipart/form-data':
127                     # TODO: Stream this instead of reading to/from memory
128                     boundary = parameters['boundary'].encode('utf-8')
129                     self.parsed_form, self.parsed_files = (
130                         parse_multipart_form(self.body, boundary))
131             except Exception:
132                 error_logger.exception("Failed when parsing form")
133 
134         return self.parsed_form
135 
136     @property
137     def files(self):
138         if self.parsed_files is None:
139             self.form  # compute form to get files
140 
141         return self.parsed_files
142 
143     @property
144     def args(self):
145         if self.parsed_args is None:
146             if self.query_string:
147                 self.parsed_args = RequestParameters(
148                     parse_qs(self.query_string))
149             else:
150                 self.parsed_args = RequestParameters()
151         return self.parsed_args
152 
153     @property
154     def raw_args(self):
155         return {k: v[0] for k, v in self.args.items()}
156 
157     @property
158     def cookies(self):
159         if self._cookies is None:
160             cookie = self.headers.get('Cookie')
161             if cookie is not None:
162                 cookies = SimpleCookie()
163                 cookies.load(cookie)
164                 self._cookies = {name: cookie.value
165                                  for name, cookie in cookies.items()}
166             else:
167                 self._cookies = {}
168         return self._cookies
169 
170     @property
171     def ip(self):
172         if not hasattr(self, '_socket'):
173             self._get_address()
174         return self._ip
175 
176     @property
177     def port(self):
178         if not hasattr(self, '_socket'):
179             self._get_address()
180         return self._port
181 
182     @property
183     def socket(self):
184         if not hasattr(self, '_socket'):
185             self._get_address()
186         return self._socket
187 
188     def _get_address(self):
189         sock = self.transport.get_extra_info('socket')
190 
191         if sock.family == socket.AF_INET:
192             self._socket = (self.transport.get_extra_info('peername') or
193                             (None, None))
194             self._ip, self._port = self._socket
195         elif sock.family == socket.AF_INET6:
196             self._socket = (self.transport.get_extra_info('peername') or
197                             (None, None, None, None))
198             self._ip, self._port, *_ = self._socket
199         else:
200             self._ip, self._port = (None, None)
201 
202     @property
203     def remote_addr(self):
204         """Attempt to return the original client ip based on X-Forwarded-For.
205 
206         :return: original client ip.
207         """
208         if not hasattr(self, '_remote_addr'):
209             forwarded_for = self.headers.get('X-Forwarded-For', '').split(',')
210             remote_addrs = [
211                 addr for addr in [
212                     addr.strip() for addr in forwarded_for
213                     ] if addr
214                 ]
215             if len(remote_addrs) > 0:
216                 self._remote_addr = remote_addrs[0]
217             else:
218                 self._remote_addr = ''
219         return self._remote_addr
220 
221     @property
222     def scheme(self):
223         if self.app.websocket_enabled \
224                 and self.headers.get('upgrade') == 'websocket':
225             scheme = 'ws'
226         else:
227             scheme = 'http'
228 
229         if self.transport.get_extra_info('sslcontext'):
230             scheme += 's'
231 
232         return scheme
233 
234     @property
235     def host(self):
236         # it appears that httptools doesn't return the host
237         # so pull it from the headers
238         return self.headers.get('Host', '')
239 
240     @property
241     def content_type(self):
242         return self.headers.get('Content-Type', DEFAULT_HTTP_CONTENT_TYPE)
243 
244     @property
245     def match_info(self):
246         """return matched info after resolving route"""
247         return self.app.router.get(self)[2]
248 
249     @property
250     def path(self):
251         return self._parsed_url.path.decode('utf-8')
252 
253     @property
254     def query_string(self):
255         if self._parsed_url.query:
256             return self._parsed_url.query.decode('utf-8')
257         else:
258             return ''
259 
260     @property
261     def url(self):
262         return urlunparse((
263             self.scheme,
264             self.host,
265             self.path,
266             None,
267             self.query_string,
268             None))
269 
270 
271 File = namedtuple('File', ['type', 'body', 'name'])
272 
273 
274 def parse_multipart_form(body, boundary):
275     """Parse a request body and returns fields and files
276 
277     :param body: bytes request body
278     :param boundary: bytes multipart boundary
279     :return: fields (RequestParameters), files (RequestParameters)
280     """
281     files = RequestParameters()
282     fields = RequestParameters()
283 
284     form_parts = body.split(boundary)
285     for form_part in form_parts[1:-1]:
286         file_name = None
287         content_type = 'text/plain'
288         content_charset = 'utf-8'
289         field_name = None
290         line_index = 2
291         line_end_index = 0
292         while not line_end_index == -1:
293             line_end_index = form_part.find(b'\r\n', line_index)
294             form_line = form_part[line_index:line_end_index].decode('utf-8')
295             line_index = line_end_index + 2
296 
297             if not form_line:
298                 break
299 
300             colon_index = form_line.index(':')
301             form_header_field = form_line[0:colon_index].lower()
302             form_header_value, form_parameters = parse_header(
303                 form_line[colon_index + 2:])
304 
305             if form_header_field == 'content-disposition':
306                 file_name = form_parameters.get('filename')
307                 field_name = form_parameters.get('name')
308             elif form_header_field == 'content-type':
309                 content_type = form_header_value
310                 content_charset = form_parameters.get('charset', 'utf-8')
311 
312         if field_name:
313             post_data = form_part[line_index:-4]
314             if file_name:
315                 form_file = File(type=content_type,
316                                  name=file_name,
317                                  body=post_data)
318                 if field_name in files:
319                     files[field_name].append(form_file)
320                 else:
321                     files[field_name] = [form_file]
322             else:
323                 value = post_data.decode(content_charset)
324                 if field_name in fields:
325                     fields[field_name].append(value)
326                 else:
327                     fields[field_name] = [value]
328         else:
329             logger.debug('Form-data field does not have a \'name\' parameter \
330                          in the Content-Disposition header')
331 
332     return fields, files
333
```
--- 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/sanic/request.py b/sanic/request.py
--- a/sanic/request.py
+++ b/sanic/request.py
@@ -78,6 +78,11 @@
                                        self.method,
                                        self.path)
 
+    def __bool__(self):
+        if self.transport:
+            return True
+        return False
+
     @property
     def json(self):
         if self.parsed_json is None:

{"golden_diff": "diff --git a/sanic/request.py b/sanic/request.py\n--- a/sanic/request.py\n+++ b/sanic/request.py\n@@ -78,6 +78,11 @@\n                                        self.method,\n                                        self.path)\n \n+    def __bool__(self):\n+        if self.transport:\n+            return True\n+        return False\n+\n     @property\n     def json(self):\n         if self.parsed_json is None:\n", "issue": "Sanic `Request` object is falsey\n```python\r\n@app.route('/myroute')\r\nasync def someroute(request):\r\n    if request:\r\n        return 'some data'\r\n    raise Exception(\"Woops\")\r\n```\r\n\r\nThis code will raise the exception because `bool(request)` is `False`. \n", "before_files": [{"content": "import sys\nimport json\nimport socket\nfrom cgi import parse_header\nfrom collections import namedtuple\nfrom http.cookies import SimpleCookie\nfrom httptools import parse_url\nfrom urllib.parse import parse_qs, urlunparse\n\ntry:\n    from ujson import loads as json_loads\nexcept ImportError:\n    if sys.version_info[:2] == (3, 5):\n        def json_loads(data):\n            # on Python 3.5 json.loads only supports str not bytes\n            return json.loads(data.decode())\n    else:\n        json_loads = json.loads\n\nfrom sanic.exceptions import InvalidUsage\nfrom sanic.log import error_logger, logger\n\nDEFAULT_HTTP_CONTENT_TYPE = \"application/octet-stream\"\n\n\n# HTTP/1.1: https://www.w3.org/Protocols/rfc2616/rfc2616-sec7.html#sec7.2.1\n# > If the media type remains unknown, the recipient SHOULD treat it\n# > as type \"application/octet-stream\"\n\n\nclass RequestParameters(dict):\n    \"\"\"Hosts a dict with lists as values where get returns the first\n    value of the list and getlist returns the whole shebang\n    \"\"\"\n\n    def get(self, name, default=None):\n        \"\"\"Return the first value, either the default or actual\"\"\"\n        return super().get(name, [default])[0]\n\n    def getlist(self, name, default=None):\n        \"\"\"Return the entire list\"\"\"\n        return super().get(name, default)\n\n\nclass Request(dict):\n    \"\"\"Properties of an HTTP request such as URL, headers, etc.\"\"\"\n    __slots__ = (\n        'app', 'headers', 'version', 'method', '_cookies', 'transport',\n        'body', 'parsed_json', 'parsed_args', 'parsed_form', 'parsed_files',\n        '_ip', '_parsed_url', 'uri_template', 'stream', '_remote_addr',\n        '_socket', '_port', '__weakref__'\n    )\n\n    def __init__(self, url_bytes, headers, version, method, transport):\n        # TODO: Content-Encoding detection\n        self._parsed_url = parse_url(url_bytes)\n        self.app = None\n\n        self.headers = headers\n        self.version = version\n        self.method = method\n        self.transport = transport\n\n        # Init but do not inhale\n        self.body = []\n        self.parsed_json = None\n        self.parsed_form = None\n        self.parsed_files = None\n        self.parsed_args = None\n        self.uri_template = None\n        self._cookies = None\n        self.stream = None\n\n    def __repr__(self):\n        if self.method is None or not self.path:\n            return '<{0}>'.format(self.__class__.__name__)\n        return '<{0}: {1} {2}>'.format(self.__class__.__name__,\n                                       self.method,\n                                       self.path)\n\n    @property\n    def json(self):\n        if self.parsed_json is None:\n            self.load_json()\n\n        return self.parsed_json\n\n    def load_json(self, loads=json_loads):\n        try:\n            self.parsed_json = loads(self.body)\n        except Exception:\n            if not self.body:\n                return None\n            raise InvalidUsage(\"Failed when parsing body as json\")\n\n        return self.parsed_json\n\n    @property\n    def token(self):\n        \"\"\"Attempt to return the auth header token.\n\n        :return: token related to request\n        \"\"\"\n        prefixes = ('Bearer', 'Token')\n        auth_header = self.headers.get('Authorization')\n\n        if auth_header is not None:\n            for prefix in prefixes:\n                if prefix in auth_header:\n                    return auth_header.partition(prefix)[-1].strip()\n\n        return auth_header\n\n    @property\n    def form(self):\n        if self.parsed_form is None:\n            self.parsed_form = RequestParameters()\n            self.parsed_files = RequestParameters()\n            content_type = self.headers.get(\n                'Content-Type', DEFAULT_HTTP_CONTENT_TYPE)\n            content_type, parameters = parse_header(content_type)\n            try:\n                if content_type == 'application/x-www-form-urlencoded':\n                    self.parsed_form = RequestParameters(\n                        parse_qs(self.body.decode('utf-8')))\n                elif content_type == 'multipart/form-data':\n                    # TODO: Stream this instead of reading to/from memory\n                    boundary = parameters['boundary'].encode('utf-8')\n                    self.parsed_form, self.parsed_files = (\n                        parse_multipart_form(self.body, boundary))\n            except Exception:\n                error_logger.exception(\"Failed when parsing form\")\n\n        return self.parsed_form\n\n    @property\n    def files(self):\n        if self.parsed_files is None:\n            self.form  # compute form to get files\n\n        return self.parsed_files\n\n    @property\n    def args(self):\n        if self.parsed_args is None:\n            if self.query_string:\n                self.parsed_args = RequestParameters(\n                    parse_qs(self.query_string))\n            else:\n                self.parsed_args = RequestParameters()\n        return self.parsed_args\n\n    @property\n    def raw_args(self):\n        return {k: v[0] for k, v in self.args.items()}\n\n    @property\n    def cookies(self):\n        if self._cookies is None:\n            cookie = self.headers.get('Cookie')\n            if cookie is not None:\n                cookies = SimpleCookie()\n                cookies.load(cookie)\n                self._cookies = {name: cookie.value\n                                 for name, cookie in cookies.items()}\n            else:\n                self._cookies = {}\n        return self._cookies\n\n    @property\n    def ip(self):\n        if not hasattr(self, '_socket'):\n            self._get_address()\n        return self._ip\n\n    @property\n    def port(self):\n        if not hasattr(self, '_socket'):\n            self._get_address()\n        return self._port\n\n    @property\n    def socket(self):\n        if not hasattr(self, '_socket'):\n            self._get_address()\n        return self._socket\n\n    def _get_address(self):\n        sock = self.transport.get_extra_info('socket')\n\n        if sock.family == socket.AF_INET:\n            self._socket = (self.transport.get_extra_info('peername') or\n                            (None, None))\n            self._ip, self._port = self._socket\n        elif sock.family == socket.AF_INET6:\n            self._socket = (self.transport.get_extra_info('peername') or\n                            (None, None, None, None))\n            self._ip, self._port, *_ = self._socket\n        else:\n            self._ip, self._port = (None, None)\n\n    @property\n    def remote_addr(self):\n        \"\"\"Attempt to return the original client ip based on X-Forwarded-For.\n\n        :return: original client ip.\n        \"\"\"\n        if not hasattr(self, '_remote_addr'):\n            forwarded_for = self.headers.get('X-Forwarded-For', '').split(',')\n            remote_addrs = [\n                addr for addr in [\n                    addr.strip() for addr in forwarded_for\n                    ] if addr\n                ]\n            if len(remote_addrs) > 0:\n                self._remote_addr = remote_addrs[0]\n            else:\n                self._remote_addr = ''\n        return self._remote_addr\n\n    @property\n    def scheme(self):\n        if self.app.websocket_enabled \\\n                and self.headers.get('upgrade') == 'websocket':\n            scheme = 'ws'\n        else:\n            scheme = 'http'\n\n        if self.transport.get_extra_info('sslcontext'):\n            scheme += 's'\n\n        return scheme\n\n    @property\n    def host(self):\n        # it appears that httptools doesn't return the host\n        # so pull it from the headers\n        return self.headers.get('Host', '')\n\n    @property\n    def content_type(self):\n        return self.headers.get('Content-Type', DEFAULT_HTTP_CONTENT_TYPE)\n\n    @property\n    def match_info(self):\n        \"\"\"return matched info after resolving route\"\"\"\n        return self.app.router.get(self)[2]\n\n    @property\n    def path(self):\n        return self._parsed_url.path.decode('utf-8')\n\n    @property\n    def query_string(self):\n        if self._parsed_url.query:\n            return self._parsed_url.query.decode('utf-8')\n        else:\n            return ''\n\n    @property\n    def url(self):\n        return urlunparse((\n            self.scheme,\n            self.host,\n            self.path,\n            None,\n            self.query_string,\n            None))\n\n\nFile = namedtuple('File', ['type', 'body', 'name'])\n\n\ndef parse_multipart_form(body, boundary):\n    \"\"\"Parse a request body and returns fields and files\n\n    :param body: bytes request body\n    :param boundary: bytes multipart boundary\n    :return: fields (RequestParameters), files (RequestParameters)\n    \"\"\"\n    files = RequestParameters()\n    fields = RequestParameters()\n\n    form_parts = body.split(boundary)\n    for form_part in form_parts[1:-1]:\n        file_name = None\n        content_type = 'text/plain'\n        content_charset = 'utf-8'\n        field_name = None\n        line_index = 2\n        line_end_index = 0\n        while not line_end_index == -1:\n            line_end_index = form_part.find(b'\\r\\n', line_index)\n            form_line = form_part[line_index:line_end_index].decode('utf-8')\n            line_index = line_end_index + 2\n\n            if not form_line:\n                break\n\n            colon_index = form_line.index(':')\n            form_header_field = form_line[0:colon_index].lower()\n            form_header_value, form_parameters = parse_header(\n                form_line[colon_index + 2:])\n\n            if form_header_field == 'content-disposition':\n                file_name = form_parameters.get('filename')\n                field_name = form_parameters.get('name')\n            elif form_header_field == 'content-type':\n                content_type = form_header_value\n                content_charset = form_parameters.get('charset', 'utf-8')\n\n        if field_name:\n            post_data = form_part[line_index:-4]\n            if file_name:\n                form_file = File(type=content_type,\n                                 name=file_name,\n                                 body=post_data)\n                if field_name in files:\n                    files[field_name].append(form_file)\n                else:\n                    files[field_name] = [form_file]\n            else:\n                value = post_data.decode(content_charset)\n                if field_name in fields:\n                    fields[field_name].append(value)\n                else:\n                    fields[field_name] = [value]\n        else:\n            logger.debug('Form-data field does not have a \\'name\\' parameter \\\n                         in the Content-Disposition header')\n\n    return fields, files\n", "path": "sanic/request.py"}], "after_files": [{"content": "import sys\nimport json\nimport socket\nfrom cgi import parse_header\nfrom collections import namedtuple\nfrom http.cookies import SimpleCookie\nfrom httptools import parse_url\nfrom urllib.parse import parse_qs, urlunparse\n\ntry:\n    from ujson import loads as json_loads\nexcept ImportError:\n    if sys.version_info[:2] == (3, 5):\n        def json_loads(data):\n            # on Python 3.5 json.loads only supports str not bytes\n            return json.loads(data.decode())\n    else:\n        json_loads = json.loads\n\nfrom sanic.exceptions import InvalidUsage\nfrom sanic.log import error_logger, logger\n\nDEFAULT_HTTP_CONTENT_TYPE = \"application/octet-stream\"\n\n\n# HTTP/1.1: https://www.w3.org/Protocols/rfc2616/rfc2616-sec7.html#sec7.2.1\n# > If the media type remains unknown, the recipient SHOULD treat it\n# > as type \"application/octet-stream\"\n\n\nclass RequestParameters(dict):\n    \"\"\"Hosts a dict with lists as values where get returns the first\n    value of the list and getlist returns the whole shebang\n    \"\"\"\n\n    def get(self, name, default=None):\n        \"\"\"Return the first value, either the default or actual\"\"\"\n        return super().get(name, [default])[0]\n\n    def getlist(self, name, default=None):\n        \"\"\"Return the entire list\"\"\"\n        return super().get(name, default)\n\n\nclass Request(dict):\n    \"\"\"Properties of an HTTP request such as URL, headers, etc.\"\"\"\n    __slots__ = (\n        'app', 'headers', 'version', 'method', '_cookies', 'transport',\n        'body', 'parsed_json', 'parsed_args', 'parsed_form', 'parsed_files',\n        '_ip', '_parsed_url', 'uri_template', 'stream', '_remote_addr',\n        '_socket', '_port', '__weakref__'\n    )\n\n    def __init__(self, url_bytes, headers, version, method, transport):\n        # TODO: Content-Encoding detection\n        self._parsed_url = parse_url(url_bytes)\n        self.app = None\n\n        self.headers = headers\n        self.version = version\n        self.method = method\n        self.transport = transport\n\n        # Init but do not inhale\n        self.body = []\n        self.parsed_json = None\n        self.parsed_form = None\n        self.parsed_files = None\n        self.parsed_args = None\n        self.uri_template = None\n        self._cookies = None\n        self.stream = None\n\n    def __repr__(self):\n        if self.method is None or not self.path:\n            return '<{0}>'.format(self.__class__.__name__)\n        return '<{0}: {1} {2}>'.format(self.__class__.__name__,\n                                       self.method,\n                                       self.path)\n\n    def __bool__(self):\n        if self.transport:\n            return True\n        return False\n\n    @property\n    def json(self):\n        if self.parsed_json is None:\n            self.load_json()\n\n        return self.parsed_json\n\n    def load_json(self, loads=json_loads):\n        try:\n            self.parsed_json = loads(self.body)\n        except Exception:\n            if not self.body:\n                return None\n            raise InvalidUsage(\"Failed when parsing body as json\")\n\n        return self.parsed_json\n\n    @property\n    def token(self):\n        \"\"\"Attempt to return the auth header token.\n\n        :return: token related to request\n        \"\"\"\n        prefixes = ('Bearer', 'Token')\n        auth_header = self.headers.get('Authorization')\n\n        if auth_header is not None:\n            for prefix in prefixes:\n                if prefix in auth_header:\n                    return auth_header.partition(prefix)[-1].strip()\n\n        return auth_header\n\n    @property\n    def form(self):\n        if self.parsed_form is None:\n            self.parsed_form = RequestParameters()\n            self.parsed_files = RequestParameters()\n            content_type = self.headers.get(\n                'Content-Type', DEFAULT_HTTP_CONTENT_TYPE)\n            content_type, parameters = parse_header(content_type)\n            try:\n                if content_type == 'application/x-www-form-urlencoded':\n                    self.parsed_form = RequestParameters(\n                        parse_qs(self.body.decode('utf-8')))\n                elif content_type == 'multipart/form-data':\n                    # TODO: Stream this instead of reading to/from memory\n                    boundary = parameters['boundary'].encode('utf-8')\n                    self.parsed_form, self.parsed_files = (\n                        parse_multipart_form(self.body, boundary))\n            except Exception:\n                error_logger.exception(\"Failed when parsing form\")\n\n        return self.parsed_form\n\n    @property\n    def files(self):\n        if self.parsed_files is None:\n            self.form  # compute form to get files\n\n        return self.parsed_files\n\n    @property\n    def args(self):\n        if self.parsed_args is None:\n            if self.query_string:\n                self.parsed_args = RequestParameters(\n                    parse_qs(self.query_string))\n            else:\n                self.parsed_args = RequestParameters()\n        return self.parsed_args\n\n    @property\n    def raw_args(self):\n        return {k: v[0] for k, v in self.args.items()}\n\n    @property\n    def cookies(self):\n        if self._cookies is None:\n            cookie = self.headers.get('Cookie')\n            if cookie is not None:\n                cookies = SimpleCookie()\n                cookies.load(cookie)\n                self._cookies = {name: cookie.value\n                                 for name, cookie in cookies.items()}\n            else:\n                self._cookies = {}\n        return self._cookies\n\n    @property\n    def ip(self):\n        if not hasattr(self, '_socket'):\n            self._get_address()\n        return self._ip\n\n    @property\n    def port(self):\n        if not hasattr(self, '_socket'):\n            self._get_address()\n        return self._port\n\n    @property\n    def socket(self):\n        if not hasattr(self, '_socket'):\n            self._get_address()\n        return self._socket\n\n    def _get_address(self):\n        sock = self.transport.get_extra_info('socket')\n\n        if sock.family == socket.AF_INET:\n            self._socket = (self.transport.get_extra_info('peername') or\n                            (None, None))\n            self._ip, self._port = self._socket\n        elif sock.family == socket.AF_INET6:\n            self._socket = (self.transport.get_extra_info('peername') or\n                            (None, None, None, None))\n            self._ip, self._port, *_ = self._socket\n        else:\n            self._ip, self._port = (None, None)\n\n    @property\n    def remote_addr(self):\n        \"\"\"Attempt to return the original client ip based on X-Forwarded-For.\n\n        :return: original client ip.\n        \"\"\"\n        if not hasattr(self, '_remote_addr'):\n            forwarded_for = self.headers.get('X-Forwarded-For', '').split(',')\n            remote_addrs = [\n                addr for addr in [\n                    addr.strip() for addr in forwarded_for\n                    ] if addr\n                ]\n            if len(remote_addrs) > 0:\n                self._remote_addr = remote_addrs[0]\n            else:\n                self._remote_addr = ''\n        return self._remote_addr\n\n    @property\n    def scheme(self):\n        if self.app.websocket_enabled \\\n                and self.headers.get('upgrade') == 'websocket':\n            scheme = 'ws'\n        else:\n            scheme = 'http'\n\n        if self.transport.get_extra_info('sslcontext'):\n            scheme += 's'\n\n        return scheme\n\n    @property\n    def host(self):\n        # it appears that httptools doesn't return the host\n        # so pull it from the headers\n        return self.headers.get('Host', '')\n\n    @property\n    def content_type(self):\n        return self.headers.get('Content-Type', DEFAULT_HTTP_CONTENT_TYPE)\n\n    @property\n    def match_info(self):\n        \"\"\"return matched info after resolving route\"\"\"\n        return self.app.router.get(self)[2]\n\n    @property\n    def path(self):\n        return self._parsed_url.path.decode('utf-8')\n\n    @property\n    def query_string(self):\n        if self._parsed_url.query:\n            return self._parsed_url.query.decode('utf-8')\n        else:\n            return ''\n\n    @property\n    def url(self):\n        return urlunparse((\n            self.scheme,\n            self.host,\n            self.path,\n            None,\n            self.query_string,\n            None))\n\n\nFile = namedtuple('File', ['type', 'body', 'name'])\n\n\ndef parse_multipart_form(body, boundary):\n    \"\"\"Parse a request body and returns fields and files\n\n    :param body: bytes request body\n    :param boundary: bytes multipart boundary\n    :return: fields (RequestParameters), files (RequestParameters)\n    \"\"\"\n    files = RequestParameters()\n    fields = RequestParameters()\n\n    form_parts = body.split(boundary)\n    for form_part in form_parts[1:-1]:\n        file_name = None\n        content_type = 'text/plain'\n        content_charset = 'utf-8'\n        field_name = None\n        line_index = 2\n        line_end_index = 0\n        while not line_end_index == -1:\n            line_end_index = form_part.find(b'\\r\\n', line_index)\n            form_line = form_part[line_index:line_end_index].decode('utf-8')\n            line_index = line_end_index + 2\n\n            if not form_line:\n                break\n\n            colon_index = form_line.index(':')\n            form_header_field = form_line[0:colon_index].lower()\n            form_header_value, form_parameters = parse_header(\n                form_line[colon_index + 2:])\n\n            if form_header_field == 'content-disposition':\n                file_name = form_parameters.get('filename')\n                field_name = form_parameters.get('name')\n            elif form_header_field == 'content-type':\n                content_type = form_header_value\n                content_charset = form_parameters.get('charset', 'utf-8')\n\n        if field_name:\n            post_data = form_part[line_index:-4]\n            if file_name:\n                form_file = File(type=content_type,\n                                 name=file_name,\n                                 body=post_data)\n                if field_name in files:\n                    files[field_name].append(form_file)\n                else:\n                    files[field_name] = [form_file]\n            else:\n                value = post_data.decode(content_charset)\n                if field_name in fields:\n                    fields[field_name].append(value)\n                else:\n                    fields[field_name] = [value]\n        else:\n            logger.debug('Form-data field does not have a \\'name\\' parameter \\\n                         in the Content-Disposition header')\n\n    return fields, files\n", "path": "sanic/request.py"}]}