Merge branch 'master' into master
This commit is contained in:
@@ -17,7 +17,7 @@ from sanic.handlers import ErrorHandler
|
||||
from sanic.log import log
|
||||
from sanic.response import HTTPResponse, StreamingHTTPResponse
|
||||
from sanic.router import Router
|
||||
from sanic.server import serve, serve_multiple, HttpProtocol
|
||||
from sanic.server import serve, serve_multiple, HttpProtocol, Signal
|
||||
from sanic.static import register as static_register
|
||||
from sanic.testing import SanicTestClient
|
||||
from sanic.views import CompositionView
|
||||
@@ -293,7 +293,7 @@ class Sanic:
|
||||
attach_to=middleware_or_request)
|
||||
|
||||
# Static Files
|
||||
def static(self, uri, file_or_directory, pattern='.+',
|
||||
def static(self, uri, file_or_directory, pattern=r'/?.+',
|
||||
use_modified_since=True, use_content_range=False):
|
||||
"""Register a root to serve files from. The input can either be a
|
||||
file or a directory. See
|
||||
@@ -687,11 +687,13 @@ class Sanic:
|
||||
'port': port,
|
||||
'sock': sock,
|
||||
'ssl': ssl,
|
||||
'signal': Signal(),
|
||||
'debug': debug,
|
||||
'request_handler': self.handle_request,
|
||||
'error_handler': self.error_handler,
|
||||
'request_timeout': self.config.REQUEST_TIMEOUT,
|
||||
'request_max_size': self.config.REQUEST_MAX_SIZE,
|
||||
'keep_alive': self.config.KEEP_ALIVE,
|
||||
'loop': loop,
|
||||
'register_sys_signals': register_sys_signals,
|
||||
'backlog': backlog,
|
||||
|
||||
@@ -116,7 +116,7 @@ if type(_addr) is str and not os.path.exists(_addr):
|
||||
|
||||
|
||||
class Config(dict):
|
||||
def __init__(self, defaults=None, load_env=True):
|
||||
def __init__(self, defaults=None, load_env=True, keep_alive=True):
|
||||
super().__init__(defaults or {})
|
||||
self.LOGO = """
|
||||
▄▄▄▄▄
|
||||
@@ -141,6 +141,7 @@ class Config(dict):
|
||||
"""
|
||||
self.REQUEST_MAX_SIZE = 100000000 # 100 megababies
|
||||
self.REQUEST_TIMEOUT = 60 # 60 seconds
|
||||
self.KEEP_ALIVE = keep_alive
|
||||
|
||||
if load_env:
|
||||
self.load_environment_vars()
|
||||
@@ -208,11 +209,11 @@ class Config(dict):
|
||||
self[key] = getattr(obj, key)
|
||||
|
||||
def load_environment_vars(self):
|
||||
"""
|
||||
Looks for any SANIC_ prefixed environment variables and applies
|
||||
them to the configuration if present.
|
||||
"""
|
||||
for k, v in os.environ.items():
|
||||
"""
|
||||
Looks for any SANIC_ prefixed environment variables and applies
|
||||
them to the configuration if present.
|
||||
"""
|
||||
if k.startswith(SANIC_PREFIX):
|
||||
_, config_key = k.split(SANIC_PREFIX, 1)
|
||||
self[config_key] = v
|
||||
|
||||
@@ -78,9 +78,10 @@ class Request(dict):
|
||||
:return: token related to request
|
||||
"""
|
||||
auth_header = self.headers.get('Authorization')
|
||||
if auth_header is not None:
|
||||
return auth_header.split()[1]
|
||||
return auth_header
|
||||
if 'Token ' in auth_header:
|
||||
return auth_header.partition('Token ')[-1]
|
||||
else:
|
||||
return auth_header
|
||||
|
||||
@property
|
||||
def form(self):
|
||||
|
||||
@@ -210,7 +210,7 @@ class HTTPResponse(BaseHTTPResponse):
|
||||
# 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)
|
||||
status = ALL_STATUS_CODES.get(self.status, b'UNKNOWN RESPONSE')
|
||||
|
||||
return (b'HTTP/%b %d %b\r\n'
|
||||
b'Connection: %b\r\n'
|
||||
|
||||
@@ -16,6 +16,7 @@ REGEX_TYPES = {
|
||||
'int': (int, r'\d+'),
|
||||
'number': (float, r'[0-9\\.]+'),
|
||||
'alpha': (str, r'[A-Za-z]+'),
|
||||
'path': (str, r'[^/].*?'),
|
||||
}
|
||||
|
||||
ROUTER_CACHE_SIZE = 1024
|
||||
@@ -71,7 +72,8 @@ class Router:
|
||||
self.routes_always_check = []
|
||||
self.hosts = set()
|
||||
|
||||
def parse_parameter_string(self, parameter_string):
|
||||
@classmethod
|
||||
def parse_parameter_string(cls, parameter_string):
|
||||
"""Parse a parameter string into its constituent name, type, and
|
||||
pattern
|
||||
|
||||
@@ -161,10 +163,10 @@ class Router:
|
||||
parameters.append(parameter)
|
||||
|
||||
# Mark the whole route as unhashable if it has the hash key in it
|
||||
if re.search('(^|[^^]){1}/', pattern):
|
||||
if re.search(r'(^|[^^]){1}/', pattern):
|
||||
properties['unhashable'] = True
|
||||
# Mark the route as unhashable if it matches the hash key
|
||||
elif re.search(pattern, '/'):
|
||||
elif re.search(r'/', pattern):
|
||||
properties['unhashable'] = True
|
||||
|
||||
return '({})'.format(pattern)
|
||||
|
||||
@@ -73,7 +73,8 @@ class HttpProtocol(asyncio.Protocol):
|
||||
|
||||
def __init__(self, *, loop, request_handler, error_handler,
|
||||
signal=Signal(), connections=set(), request_timeout=60,
|
||||
request_max_size=None, request_class=None, has_log=True):
|
||||
request_max_size=None, request_class=None, has_log=True,
|
||||
keep_alive=True):
|
||||
self.loop = loop
|
||||
self.transport = None
|
||||
self.request = None
|
||||
@@ -92,10 +93,13 @@ class HttpProtocol(asyncio.Protocol):
|
||||
self._timeout_handler = None
|
||||
self._last_request_time = None
|
||||
self._request_handler_task = None
|
||||
self._keep_alive = keep_alive
|
||||
|
||||
@property
|
||||
def keep_alive(self):
|
||||
return self.parser.should_keep_alive() and not self.signal.stopped
|
||||
return (self._keep_alive
|
||||
and not self.signal.stopped
|
||||
and self.parser.should_keep_alive())
|
||||
|
||||
# -------------------------------------------- #
|
||||
# Connection
|
||||
@@ -357,7 +361,8 @@ def serve(host, port, request_handler, error_handler, before_start=None,
|
||||
request_timeout=60, ssl=None, sock=None, request_max_size=None,
|
||||
reuse_port=False, loop=None, protocol=HttpProtocol, backlog=100,
|
||||
register_sys_signals=True, run_async=False, connections=None,
|
||||
signal=Signal(), request_class=None, has_log=True):
|
||||
signal=Signal(), request_class=None, has_log=True, keep_alive=True):
|
||||
signal=Signal(), request_class=None, keep_alive=True):
|
||||
"""Start asynchronous HTTP Server on an individual process.
|
||||
|
||||
:param host: Address to host on
|
||||
@@ -406,7 +411,8 @@ def serve(host, port, request_handler, error_handler, before_start=None,
|
||||
request_timeout=request_timeout,
|
||||
request_max_size=request_max_size,
|
||||
request_class=request_class,
|
||||
has_log=has_log
|
||||
has_log=has_log,
|
||||
keep_alive=keep_alive,
|
||||
)
|
||||
|
||||
server_coroutine = loop.create_server(
|
||||
|
||||
@@ -48,14 +48,18 @@ def register(app, uri, file_or_directory, pattern,
|
||||
# Merge served directory and requested file if provided
|
||||
# Strip all / that in the beginning of the URL to help prevent python
|
||||
# from herping a derp and treating the uri as an absolute path
|
||||
file_path = file_or_directory
|
||||
root_path = file_path = file_or_directory
|
||||
if file_uri:
|
||||
file_path = path.join(
|
||||
file_or_directory, sub('^[/]*', '', file_uri))
|
||||
|
||||
# URL decode the path sent by the browser otherwise we won't be able to
|
||||
# match filenames which got encoded (filenames with spaces etc)
|
||||
file_path = unquote(file_path)
|
||||
file_path = path.abspath(unquote(file_path))
|
||||
if not file_path.startswith(path.abspath(unquote(root_path))):
|
||||
raise FileNotFound('File not found',
|
||||
path=file_or_directory,
|
||||
relative_url=file_uri)
|
||||
try:
|
||||
headers = {}
|
||||
# Check if the client has been sent this file before
|
||||
|
||||
@@ -3,6 +3,7 @@ import sys
|
||||
import signal
|
||||
import asyncio
|
||||
import logging
|
||||
|
||||
try:
|
||||
import ssl
|
||||
except ImportError:
|
||||
@@ -50,8 +51,8 @@ class GunicornWorker(base.Worker):
|
||||
debug=is_debug,
|
||||
protocol=protocol,
|
||||
ssl=self.ssl_context,
|
||||
run_async=True
|
||||
)
|
||||
run_async=True)
|
||||
self._server_settings['signal'] = self.signal
|
||||
self._server_settings.pop('sock')
|
||||
trigger_events(self._server_settings.get('before_start', []),
|
||||
self.loop)
|
||||
@@ -97,7 +98,6 @@ class GunicornWorker(base.Worker):
|
||||
self.servers.append(await serve(
|
||||
sock=sock,
|
||||
connections=self.connections,
|
||||
signal=self.signal,
|
||||
**self._server_settings
|
||||
))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user