Merge branch 'master' into 178

This commit is contained in:
Eli Uriegas
2016-12-30 12:15:08 -06:00
committed by GitHub
23 changed files with 445 additions and 80 deletions

View File

@@ -1,6 +1,6 @@
from .sanic import Sanic
from .blueprints import Blueprint
__version__ = '0.1.8'
__version__ = '0.1.9'
__all__ = ['Sanic', 'Blueprint']

View File

@@ -1,5 +1,3 @@
import logging
logging.basicConfig(
level=logging.INFO, format="%(asctime)s: %(levelname)s: %(message)s")
log = logging.getLogger(__name__)

View File

@@ -23,6 +23,10 @@ class RouteExists(Exception):
pass
class RouteDoesNotExist(Exception):
pass
class Router:
"""
Router supports basic routing with parameters and method checks
@@ -109,6 +113,23 @@ class Router:
else:
self.routes_static[uri] = route
def remove(self, uri, clean_cache=True):
try:
route = self.routes_all.pop(uri)
except KeyError:
raise RouteDoesNotExist("Route was not registered: {}".format(uri))
if route in self.routes_always_check:
self.routes_always_check.remove(route)
elif url_hash(uri) in self.routes_dynamic \
and route in self.routes_dynamic[url_hash(uri)]:
self.routes_dynamic[url_hash(uri)].remove(route)
else:
self.routes_static.pop(uri)
if clean_cache:
self._get.cache_clear()
def get(self, request):
"""
Gets a request handler based on the URL of the request, or raises an

View File

@@ -3,13 +3,14 @@ from collections import deque
from functools import partial
from inspect import isawaitable, stack, getmodulename
from multiprocessing import Process, Event
from select import select
from signal import signal, SIGTERM, SIGINT
from time import sleep
from traceback import format_exc
import logging
from .config import Config
from .exceptions import Handler
from .log import log, logging
from .log import log
from .response import HTTPResponse
from .router import Router
from .server import serve
@@ -18,7 +19,13 @@ from .exceptions import ServerError
class Sanic:
def __init__(self, name=None, router=None, error_handler=None):
def __init__(self, name=None, router=None,
error_handler=None, logger=None):
if logger is None:
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s: %(levelname)s: %(message)s"
)
if name is None:
frame_records = stack()[1]
name = getmodulename(frame_records[1])
@@ -73,6 +80,9 @@ class Sanic:
self.route(uri=uri, methods=methods)(handler)
return handler
def remove_route(self, uri, clean_cache=True):
self.router.remove(uri, clean_cache)
# Decorator
def exception(self, *exceptions):
"""
@@ -193,18 +203,18 @@ class Sanic:
if isawaitable(response):
response = await response
# -------------------------------------------- #
# Response Middleware
# -------------------------------------------- #
# -------------------------------------------- #
# Response Middleware
# -------------------------------------------- #
if self.response_middleware:
for middleware in self.response_middleware:
_response = middleware(request, response)
if isawaitable(_response):
_response = await _response
if _response:
response = _response
break
if self.response_middleware:
for middleware in self.response_middleware:
_response = middleware(request, response)
if isawaitable(_response):
_response = await _response
if _response:
response = _response
break
except Exception as e:
# -------------------------------------------- #
@@ -345,8 +355,7 @@ class Sanic:
# Infinitely wait for the stop event
try:
while not stop_event.is_set():
sleep(0.3)
select(stop_event)
except:
pass

View File

@@ -6,6 +6,7 @@ from signal import SIGINT, SIGTERM
from time import time
from httptools import HttpRequestParser
from httptools.parser.errors import HttpParserError
from .exceptions import ServerError
try:
import uvloop as async_loop
@@ -173,8 +174,9 @@ class HttpProtocol(asyncio.Protocol):
"Writing error failed, connection closed {}".format(e))
def bail_out(self, message):
log.debug(message)
self.transport.close()
exception = ServerError(message)
self.write_error(exception)
log.error(message)
def cleanup(self):
self.parser = None

View File

@@ -2,6 +2,7 @@ from aiofiles.os import stat
from os import path
from re import sub
from time import strftime, gmtime
from urllib.parse import unquote
from .exceptions import FileNotFound, InvalidUsage
from .response import file, HTTPResponse
@@ -32,12 +33,17 @@ def register(app, uri, file_or_directory, pattern, use_modified_since):
# served. os.path.realpath seems to be very slow
if file_uri and '../' in file_uri:
raise InvalidUsage("Invalid URL")
# 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 = path.join(file_or_directory, sub('^[/]*', '', file_uri)) \
if file_uri else file_or_directory
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)
try:
headers = {}
# Check if the client has been sent this file before