Merge branch 'master' into 977
This commit is contained in:
commit
63bbcb5152
|
@ -1,4 +1,7 @@
|
|||
include README.rst
|
||||
include MANIFEST.in
|
||||
include LICENSE
|
||||
include setup.py
|
||||
|
||||
recursive-exclude * __pycache__
|
||||
recursive-exclude * *.py[co]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Extensions
|
||||
|
||||
A list of Sanic extensions created by the community.
|
||||
|
||||
- [Sanic-Plugins-Framework](https://github.com/ashleysommer/sanicpluginsframework): Library for easily creating and using Sanic plugins.
|
||||
- [Sessions](https://github.com/subyraman/sanic_session): Support for sessions.
|
||||
Allows using redis, memcache or an in memory store.
|
||||
- [CORS](https://github.com/ashleysommer/sanic-cors): A port of flask-cors.
|
||||
|
|
|
@ -75,6 +75,10 @@ The following variables are accessible as properties on `Request` objects:
|
|||
|
||||
- `ip` (str) - IP address of the requester.
|
||||
|
||||
- `port` (str) - Port address of the requester.
|
||||
|
||||
- `socket` (tuple) - (IP, port) of the requester.
|
||||
|
||||
- `app` - a reference to the Sanic application object that is handling this request. This is useful when inside blueprints or other handlers in modules that do not have access to the global `app` object.
|
||||
|
||||
```python
|
||||
|
|
|
@ -586,7 +586,7 @@ class Sanic:
|
|||
try:
|
||||
response = await self._run_response_middleware(request,
|
||||
response)
|
||||
except:
|
||||
except BaseException:
|
||||
error_logger.exception(
|
||||
'Exception occured in one of response middleware handlers'
|
||||
)
|
||||
|
@ -654,7 +654,7 @@ class Sanic:
|
|||
serve(**server_settings)
|
||||
else:
|
||||
serve_multiple(server_settings, workers)
|
||||
except:
|
||||
except BaseException:
|
||||
error_logger.exception(
|
||||
'Experienced exception while trying to serve')
|
||||
raise
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from sanic.response import ALL_STATUS_CODES, COMMON_STATUS_CODES
|
||||
from sanic.response import STATUS_CODES
|
||||
|
||||
TRACEBACK_STYLE = '''
|
||||
<style>
|
||||
|
@ -275,8 +275,7 @@ def abort(status_code, message=None):
|
|||
in response.py for the given status code.
|
||||
"""
|
||||
if message is None:
|
||||
message = COMMON_STATUS_CODES.get(status_code,
|
||||
ALL_STATUS_CODES.get(status_code))
|
||||
message = STATUS_CODES.get(status_code)
|
||||
# These are stored as bytes in the STATUS_CODES dict
|
||||
message = message.decode('utf8')
|
||||
sanic_exception = _sanic_exceptions.get(status_code, SanicException)
|
||||
|
|
|
@ -47,7 +47,7 @@ class Request(dict):
|
|||
'app', 'headers', 'version', 'method', '_cookies', 'transport',
|
||||
'body', 'parsed_json', 'parsed_args', 'parsed_form', 'parsed_files',
|
||||
'_ip', '_parsed_url', 'uri_template', 'stream', '_remote_addr',
|
||||
'endpoint',
|
||||
'_socket', '_port', 'endpoint'
|
||||
)
|
||||
|
||||
def __init__(self, url_bytes, headers, version, method, transport):
|
||||
|
@ -169,11 +169,27 @@ class Request(dict):
|
|||
|
||||
@property
|
||||
def ip(self):
|
||||
if not hasattr(self, '_ip'):
|
||||
self._ip = (self.transport.get_extra_info('peername') or
|
||||
(None, None))
|
||||
if not hasattr(self, '_socket'):
|
||||
self._get_address()
|
||||
return self._ip
|
||||
|
||||
@property
|
||||
def port(self):
|
||||
if not hasattr(self, '_socket'):
|
||||
self._get_address()
|
||||
return self._port
|
||||
|
||||
@property
|
||||
def socket(self):
|
||||
if not hasattr(self, '_socket'):
|
||||
self._get_socket()
|
||||
return self._socket
|
||||
|
||||
def _get_address(self):
|
||||
self._socket = (self.transport.get_extra_info('peername') or
|
||||
(None, None))
|
||||
self._ip, self._port = self._socket
|
||||
|
||||
@property
|
||||
def remote_addr(self):
|
||||
"""Attempt to return the original client ip based on X-Forwarded-For.
|
||||
|
|
|
@ -3,20 +3,14 @@ from os import path
|
|||
|
||||
try:
|
||||
from ujson import dumps as json_dumps
|
||||
except:
|
||||
except BaseException:
|
||||
from json import dumps as json_dumps
|
||||
|
||||
from aiofiles import open as open_async
|
||||
|
||||
from sanic.cookies import CookieJar
|
||||
|
||||
COMMON_STATUS_CODES = {
|
||||
200: b'OK',
|
||||
400: b'Bad Request',
|
||||
404: b'Not Found',
|
||||
500: b'Internal Server Error',
|
||||
}
|
||||
ALL_STATUS_CODES = {
|
||||
STATUS_CODES = {
|
||||
100: b'Continue',
|
||||
101: b'Switching Protocols',
|
||||
102: b'Processing',
|
||||
|
@ -162,11 +156,10 @@ class StreamingHTTPResponse(BaseHTTPResponse):
|
|||
|
||||
headers = self._parse_headers()
|
||||
|
||||
# Try to pull from the common codes first
|
||||
# Speeds up response rate 6% over pulling from all
|
||||
status = COMMON_STATUS_CODES.get(self.status)
|
||||
if not status:
|
||||
status = ALL_STATUS_CODES.get(self.status)
|
||||
if self.status is 200:
|
||||
status = b'OK'
|
||||
else:
|
||||
status = STATUS_CODES.get(self.status)
|
||||
|
||||
return (b'HTTP/%b %d %b\r\n'
|
||||
b'%b'
|
||||
|
@ -209,11 +202,10 @@ class HTTPResponse(BaseHTTPResponse):
|
|||
|
||||
headers = self._parse_headers()
|
||||
|
||||
# Try to pull from the common codes first
|
||||
# Speeds up response rate 6% over pulling from all
|
||||
status = COMMON_STATUS_CODES.get(self.status)
|
||||
if not status:
|
||||
status = ALL_STATUS_CODES.get(self.status, b'UNKNOWN RESPONSE')
|
||||
if self.status is 200:
|
||||
status = b'OK'
|
||||
else:
|
||||
status = STATUS_CODES.get(self.status, b'UNKNOWN RESPONSE')
|
||||
|
||||
return (b'HTTP/%b %d %b\r\n'
|
||||
b'Connection: %b\r\n'
|
||||
|
|
|
@ -312,7 +312,7 @@ class HttpProtocol(asyncio.Protocol):
|
|||
else:
|
||||
extra['byte'] = -1
|
||||
|
||||
if self.request:
|
||||
if self.request is not None:
|
||||
extra['host'] = '{0}:{1}'.format(self.request.ip[0],
|
||||
self.request.ip[1])
|
||||
extra['request'] = '{0} {1}'.format(self.request.method,
|
||||
|
@ -588,7 +588,7 @@ def serve(host, port, request_handler, error_handler, before_start=None,
|
|||
|
||||
try:
|
||||
http_server = loop.run_until_complete(server_coroutine)
|
||||
except:
|
||||
except BaseException:
|
||||
logger.exception("Unable to start server")
|
||||
return
|
||||
|
||||
|
|
|
@ -76,14 +76,14 @@ class SanicTestClient:
|
|||
try:
|
||||
request, response = results
|
||||
return request, response
|
||||
except:
|
||||
except BaseException:
|
||||
raise ValueError(
|
||||
"Request and response object expected, got ({})".format(
|
||||
results))
|
||||
else:
|
||||
try:
|
||||
return results[-1]
|
||||
except:
|
||||
except BaseException:
|
||||
raise ValueError(
|
||||
"Request object expected, got ({})".format(results))
|
||||
|
||||
|
|
|
@ -13,10 +13,18 @@ class WebSocketProtocol(HttpProtocol):
|
|||
self.websocket_max_size = websocket_max_size
|
||||
self.websocket_max_queue = websocket_max_queue
|
||||
|
||||
def connection_timeout(self):
|
||||
# timeouts make no sense for websocket routes
|
||||
# timeouts make no sense for websocket routes
|
||||
def request_timeout_callback(self):
|
||||
if self.websocket is None:
|
||||
super().connection_timeout()
|
||||
super().request_timeout_callback()
|
||||
|
||||
def response_timeout_callback(self):
|
||||
if self.websocket is None:
|
||||
super().response_timeout_callback()
|
||||
|
||||
def keep_alive_timeout_callback(self):
|
||||
if self.websocket is None:
|
||||
super().keep_alive_timeout_callback()
|
||||
|
||||
def connection_lost(self, exc):
|
||||
if self.websocket is not None:
|
||||
|
|
|
@ -23,6 +23,9 @@ from sanic.websocket import WebSocketProtocol
|
|||
|
||||
class GunicornWorker(base.Worker):
|
||||
|
||||
http_protocol = HttpProtocol
|
||||
websocket_protocol = WebSocketProtocol
|
||||
|
||||
def __init__(self, *args, **kw): # pragma: no cover
|
||||
super().__init__(*args, **kw)
|
||||
cfg = self.cfg
|
||||
|
@ -46,8 +49,9 @@ class GunicornWorker(base.Worker):
|
|||
|
||||
def run(self):
|
||||
is_debug = self.log.loglevel == logging.DEBUG
|
||||
protocol = (WebSocketProtocol if self.app.callable.websocket_enabled
|
||||
else HttpProtocol)
|
||||
protocol = (
|
||||
self.websocket_protocol if self.app.callable.websocket_enabled
|
||||
else self.http_protocol)
|
||||
self._server_settings = self.app.callable._helper(
|
||||
loop=self.loop,
|
||||
debug=is_debug,
|
||||
|
@ -70,13 +74,13 @@ class GunicornWorker(base.Worker):
|
|||
trigger_events(self._server_settings.get('before_stop', []),
|
||||
self.loop)
|
||||
self.loop.run_until_complete(self.close())
|
||||
except:
|
||||
except BaseException:
|
||||
traceback.print_exc()
|
||||
finally:
|
||||
try:
|
||||
trigger_events(self._server_settings.get('after_stop', []),
|
||||
self.loop)
|
||||
except:
|
||||
except BaseException:
|
||||
traceback.print_exc()
|
||||
finally:
|
||||
self.loop.close()
|
||||
|
|
|
@ -27,6 +27,16 @@ def test_sync():
|
|||
|
||||
assert response.text == 'Hello'
|
||||
|
||||
def test_remote_address():
|
||||
app = Sanic('test_text')
|
||||
|
||||
@app.route('/')
|
||||
def handler(request):
|
||||
return text("{}".format(request.ip))
|
||||
|
||||
request, response = app.test_client.get('/')
|
||||
|
||||
assert response.text == '127.0.0.1'
|
||||
|
||||
def test_text():
|
||||
app = Sanic('test_text')
|
||||
|
|
Loading…
Reference in New Issue
Block a user