add remote_addr property for proxy fix

This commit is contained in:
Yun Xu 2017-07-14 09:29:16 -07:00
parent 55cb371569
commit 75378d3567
2 changed files with 46 additions and 2 deletions

View File

@ -45,7 +45,7 @@ class Request(dict):
__slots__ = (
'app', 'headers', 'version', 'method', '_cookies', 'transport',
'body', 'parsed_json', 'parsed_args', 'parsed_form', 'parsed_files',
'_ip', '_parsed_url', 'uri_template', 'stream'
'_ip', '_parsed_url', 'uri_template', 'stream', '_remote_addr'
)
def __init__(self, url_bytes, headers, version, method, transport):
@ -142,7 +142,7 @@ class Request(dict):
@property
def cookies(self):
if self._cookies is None:
cookie = self.headers.get('Cookie') or self.headers.get('cookie')
cookie = self.headers.get('Cookie')
if cookie is not None:
cookies = SimpleCookie()
cookies.load(cookie)
@ -159,6 +159,23 @@ class Request(dict):
(None, None))
return self._ip
@property
def remote_addr(self):
"""Attempt to return the original client ip based on X-Forwarded-For.
:return: original client ip.
"""
if not hasattr(self, '_remote_addr'):
forwarded_for = self.headers.get('X-Forwarded-For', '').split(',')
remote_addrs = [
addr for addr in [addr.strip() for addr in forwarded_for] if addr
]
if len(remote_addrs) > 0:
self._remote_addr = remote_addrs[0]
else:
self._remote_addr = ''
return self._remote_addr
@property
def scheme(self):
if self.app.websocket_enabled \

View File

@ -211,6 +211,32 @@ def test_content_type():
assert response.text == 'application/json'
def test_remote_addr():
app = Sanic('test_content_type')
@app.route('/')
async def handler(request):
return text(request.remote_addr)
headers = {
'X-Forwarded-For': '127.0.0.1, 127.0.1.2'
}
request, response = app.test_client.get('/', headers=headers)
assert request.remote_addr == '127.0.0.1'
assert response.text == '127.0.0.1'
request, response = app.test_client.get('/')
assert request.remote_addr == ''
assert response.text == ''
headers = {
'X-Forwarded-For': '127.0.0.1, , ,,127.0.1.2'
}
request, response = app.test_client.get('/', headers=headers)
assert request.remote_addr == '127.0.0.1'
assert response.text == '127.0.0.1'
def test_match_info():
app = Sanic('test_match_info')
@ -259,6 +285,7 @@ def test_post_form_urlencoded():
assert request.form.get('test') == 'OK'
@pytest.mark.parametrize(
'payload', [
'------sanic\r\n' \