Reverse named_response_middlware execution order, to match normal response middleware execution order.

Fixes #1847
Adds a test to ensure fix is correct
Adds an example which demonstrates correct blueprint-middlware execution order behavior.
This commit is contained in:
Ashley Sommer 2020-05-14 09:54:47 +10:00
parent e7001b0074
commit 44973125c1
3 changed files with 77 additions and 2 deletions

View File

@ -0,0 +1,43 @@
from sanic import Sanic, Blueprint
from sanic.response import text
'''
Demonstrates that blueprint request middleware are executed in the order they
are added. And blueprint response middleware are executed in _reverse_ order.
On a valid request, it should print "1 2 3 6 5 4" to terminal
'''
app = Sanic(__name__)
bp = Blueprint("bp_"+__name__)
@bp.middleware('request')
def request_middleware_1(request):
print('1')
@bp.middleware('request')
def request_middleware_2(request):
print('2')
@bp.middleware('request')
def request_middleware_3(request):
print('3')
@bp.middleware('response')
def resp_middleware_4(request, response):
print('4')
@bp.middleware('response')
def resp_middleware_5(request, response):
print('5')
@bp.middleware('response')
def resp_middleware_6(request, response):
print('6')
@bp.route('/')
def pop_handler(request):
return text('hello world')
app.blueprint(bp, url_prefix='/bp')
app.run(host="0.0.0.0", port=8000, debug=True, auto_reload=False)

View File

@ -653,7 +653,7 @@ class Sanic:
if _rn not in self.named_response_middleware: if _rn not in self.named_response_middleware:
self.named_response_middleware[_rn] = deque() self.named_response_middleware[_rn] = deque()
if middleware not in self.named_response_middleware[_rn]: if middleware not in self.named_response_middleware[_rn]:
self.named_response_middleware[_rn].append(middleware) self.named_response_middleware[_rn].appendleft(middleware)
# Decorator # Decorator
def middleware(self, middleware_or_request): def middleware(self, middleware_or_request):

View File

@ -253,7 +253,7 @@ def test_several_bp_with_host(app):
def test_bp_middleware(app): def test_bp_middleware(app):
blueprint = Blueprint("test_middleware") blueprint = Blueprint("test_bp_middleware")
@blueprint.middleware("response") @blueprint.middleware("response")
async def process_response(request, response): async def process_response(request, response):
@ -270,6 +270,38 @@ def test_bp_middleware(app):
assert response.status == 200 assert response.status == 200
assert response.text == "FAIL" assert response.text == "FAIL"
def test_bp_middleware_order(app):
blueprint = Blueprint("test_bp_middleware_order")
order = list()
@blueprint.middleware("request")
def mw_1(request):
order.append(1)
@blueprint.middleware("request")
def mw_2(request):
order.append(2)
@blueprint.middleware("request")
def mw_3(request):
order.append(3)
@blueprint.middleware("response")
def mw_4(request, response):
order.append(6)
@blueprint.middleware("response")
def mw_5(request, response):
order.append(5)
@blueprint.middleware("response")
def mw_6(request, response):
order.append(4)
@blueprint.route("/")
def process_response(request):
return text("OK")
app.blueprint(blueprint)
order.clear()
request, response = app.test_client.get("/")
assert response.status == 200
assert order == [1, 2, 3, 4, 5, 6]
def test_bp_exception_handler(app): def test_bp_exception_handler(app):
blueprint = Blueprint("test_middleware") blueprint = Blueprint("test_middleware")