Ensure session_interface.open_session is called after URL matching (#3776)

This commit is contained in:
Matthew Preble 2020-10-16 20:57:56 -05:00 committed by David Lord
parent 15f0fc2d24
commit 01621485fd
No known key found for this signature in database
GPG Key ID: 7A1C87E3F5BC42A8
3 changed files with 28 additions and 3 deletions

View File

@ -60,6 +60,9 @@ Unreleased
conditional requests instead of using a timed cache. :pr:`3828` conditional requests instead of using a timed cache. :pr:`3828`
- ``helpers.safe_join`` is deprecated. Use - ``helpers.safe_join`` is deprecated. Use
``werkzeug.utils.safe_join`` instead. :pr:`3828` ``werkzeug.utils.safe_join`` instead. :pr:`3828`
- The request context does route matching before opening the session.
This could allow a session interface to change behavior based on
``request.endpoint``. :issue:`3776`
Version 1.1.2 Version 1.1.2

View File

@ -361,6 +361,9 @@ class RequestContext:
_request_ctx_stack.push(self) _request_ctx_stack.push(self)
if self.url_adapter is not None:
self.match_request()
# Open the session at the moment that the request context is available. # Open the session at the moment that the request context is available.
# This allows a custom open_session method to use the request context. # This allows a custom open_session method to use the request context.
# Only open a new session if this is the first time the request was # Only open a new session if this is the first time the request was
@ -372,9 +375,6 @@ class RequestContext:
if self.session is None: if self.session is None:
self.session = session_interface.make_null_session(self.app) self.session = session_interface.make_null_session(self.app)
if self.url_adapter is not None:
self.match_request()
def pop(self, exc=_sentinel): def pop(self, exc=_sentinel):
"""Pops the request context and unbinds it by doing that. This will """Pops the request context and unbinds it by doing that. This will
also trigger the execution of functions registered by the also trigger the execution of functions registered by the

View File

@ -0,0 +1,22 @@
import flask
from flask.sessions import SessionInterface
def test_open_session_endpoint_not_none():
# Define a session interface that breaks if request.endpoint is None
class MySessionInterface(SessionInterface):
def save_session(self):
pass
def open_session(self, _, request):
assert request.endpoint is not None
def index():
return "Hello World!"
# Confirm a 200 response, indicating that request.endpoint was NOT None
app = flask.Flask(__name__)
app.route("/")(index)
app.session_interface = MySessionInterface()
response = app.test_client().open("/")
assert response.status_code == 200