Merge pull request #614 from dkruchinin/middleware

Response middleware should be called even if server replies with an error
This commit is contained in:
Raphael Deem 2017-04-06 11:49:44 -07:00 committed by GitHub
commit 7e3496f8aa
2 changed files with 56 additions and 25 deletions

View File

@ -444,17 +444,7 @@ class Sanic:
# -------------------------------------------- # # -------------------------------------------- #
request.app = self request.app = self
response = await self._run_request_middleware(request)
response = False
# The if improves speed. I don't know why
if self.request_middleware:
for middleware in self.request_middleware:
response = middleware(request)
if isawaitable(response):
response = await response
if response:
break
# No middleware results # No middleware results
if not response: if not response:
# -------------------------------------------- # # -------------------------------------------- #
@ -472,20 +462,6 @@ class Sanic:
response = handler(request, *args, **kwargs) response = handler(request, *args, **kwargs)
if isawaitable(response): if isawaitable(response):
response = await response response = await response
# -------------------------------------------- #
# 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
except Exception as e: except Exception as e:
# -------------------------------------------- # # -------------------------------------------- #
# Response Generation Failed # Response Generation Failed
@ -503,6 +479,17 @@ class Sanic:
else: else:
response = HTTPResponse( response = HTTPResponse(
"An error occurred while handling an error") "An error occurred while handling an error")
finally:
# -------------------------------------------- #
# Response Middleware
# -------------------------------------------- #
try:
response = await self._run_response_middleware(request,
response)
except:
log.exception(
'Exception occured in one of response middleware handlers'
)
# pass the response to the correct callback # pass the response to the correct callback
if isinstance(response, StreamingHTTPResponse): if isinstance(response, StreamingHTTPResponse):
@ -615,6 +602,28 @@ class Sanic:
return await serve(**server_settings) return await serve(**server_settings)
async def _run_request_middleware(self, request):
# The if improves speed. I don't know why
if self.request_middleware:
for middleware in self.request_middleware:
response = middleware(request)
if isawaitable(response):
response = await response
if response:
return response
return None
async def _run_response_middleware(self, request, response):
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
return response
def _helper(self, host="127.0.0.1", port=8000, debug=False, def _helper(self, host="127.0.0.1", port=8000, debug=False,
before_start=None, after_start=None, before_stop=None, before_start=None, after_start=None, before_stop=None,
after_stop=None, ssl=None, sock=None, workers=1, loop=None, after_stop=None, ssl=None, sock=None, workers=1, loop=None,

View File

@ -2,6 +2,7 @@ from json import loads as json_loads, dumps as json_dumps
from sanic import Sanic from sanic import Sanic
from sanic.request import Request from sanic.request import Request
from sanic.response import json, text, HTTPResponse from sanic.response import json, text, HTTPResponse
from sanic.exceptions import NotFound
# ------------------------------------------------------------ # # ------------------------------------------------------------ #
@ -53,6 +54,27 @@ def test_middleware_response():
assert isinstance(results[2], HTTPResponse) assert isinstance(results[2], HTTPResponse)
def test_middleware_response_exception():
app = Sanic('test_middleware_response_exception')
result = {'status_code': None}
@app.middleware('response')
async def process_response(reqest, response):
result['status_code'] = response.status
return response
@app.exception(NotFound)
async def error_handler(request, exception):
return text('OK', exception.status_code)
@app.route('/')
async def handler(request):
return text('FAIL')
request, response = app.test_client.get('/page_not_found')
assert response.text == 'OK'
assert result['status_code'] == 404
def test_middleware_override_request(): def test_middleware_override_request():
app = Sanic('test_middleware_override_request') app = Sanic('test_middleware_override_request')