mirror of
https://github.com/django/daphne.git
synced 2025-04-21 01:02:06 +03:00
Update channel_session decorator to rehydrate http_session (#348)
* Update channel_session decorator to rehydrate http_session Update the http_session decorator to write the http session key to the channel_session when available. This allows the channel_session decorator to rehydrate the http_session after the initial websocket connection. closes #318 * Add persist=True option to http_session * Add explicit option to store the session key in the channel session * Update docs * Add test case * Add channel_and_http_session decorator This decorator enables both sessions and maintains the http_session for the lifetime of the websocket connection.
This commit is contained in:
parent
d4f7125cd5
commit
b115f8fa04
|
@ -183,3 +183,27 @@ def http_session(func):
|
|||
session.save()
|
||||
return result
|
||||
return inner
|
||||
|
||||
|
||||
def channel_and_http_session(func):
|
||||
"""
|
||||
Enables both the channel_session and http_session.
|
||||
|
||||
Stores the http session key in the channel_session on websocket.connect messages.
|
||||
It will then hydrate the http_session from that same key on subsequent messages.
|
||||
"""
|
||||
@http_session
|
||||
@channel_session
|
||||
@functools.wraps(func)
|
||||
def inner(message, *args, **kwargs):
|
||||
# Store the session key in channel_session
|
||||
if message.http_session is not None and settings.SESSION_COOKIE_NAME not in message.channel_session:
|
||||
message.channel_session[settings.SESSION_COOKIE_NAME] = message.http_session.session_key
|
||||
# Hydrate the http_session from session_key
|
||||
elif message.http_session is None and settings.SESSION_COOKIE_NAME in message.channel_session:
|
||||
session_engine = import_module(settings.SESSION_ENGINE)
|
||||
session = session_engine.SessionStore(session_key=message.channel_session[settings.SESSION_COOKIE_NAME])
|
||||
message.http_session = session
|
||||
# Run the consumer
|
||||
return func(message, *args, **kwargs)
|
||||
return inner
|
||||
|
|
|
@ -3,7 +3,8 @@ from __future__ import unicode_literals
|
|||
from django.conf import settings
|
||||
from django.test import override_settings
|
||||
from channels.message import Message
|
||||
from channels.sessions import channel_session, http_session, enforce_ordering, session_for_reply_channel
|
||||
from channels.sessions import channel_session, channel_and_http_session, http_session, enforce_ordering, \
|
||||
session_for_reply_channel
|
||||
from channels.tests import ChannelTestCase
|
||||
from channels import DEFAULT_CHANNEL_LAYER, channel_layers
|
||||
|
||||
|
@ -105,6 +106,41 @@ class SessionTests(ChannelTestCase):
|
|||
session2 = session_for_reply_channel("test-reply")
|
||||
self.assertEqual(session2["species"], "horse")
|
||||
|
||||
def test_channel_and_http_session(self):
|
||||
"""
|
||||
Tests that channel_and_http_session decorator stores the http session key and hydrates it when expected
|
||||
"""
|
||||
# Make a session to try against
|
||||
session = session_for_reply_channel("test-reply-session")
|
||||
# Construct message to send
|
||||
message = Message({
|
||||
"reply_channel": "test-reply-session",
|
||||
"http_version": "1.1",
|
||||
"method": "GET",
|
||||
"path": "/test2/",
|
||||
"headers": {
|
||||
"host": b"example.com",
|
||||
"cookie": ("%s=%s" % (settings.SESSION_COOKIE_NAME, session.session_key)).encode("ascii"),
|
||||
},
|
||||
}, None, None)
|
||||
|
||||
@channel_and_http_session
|
||||
def inner(message):
|
||||
pass
|
||||
|
||||
inner(message)
|
||||
|
||||
# It should store the session key
|
||||
self.assertEqual(message.channel_session[settings.SESSION_COOKIE_NAME], session.session_key)
|
||||
|
||||
# Construct a new message
|
||||
message2 = Message({"reply_channel": "test-reply-session", "path": "/"}, None, None)
|
||||
|
||||
inner(message2)
|
||||
|
||||
# It should hydrate the http_session
|
||||
self.assertEqual(message2.http_session.session_key, session.session_key)
|
||||
|
||||
def test_enforce_ordering_slight(self):
|
||||
"""
|
||||
Tests that slight mode of enforce_ordering works
|
||||
|
|
Loading…
Reference in New Issue
Block a user