Last active
June 1, 2022 19:19
-
-
Save mmerickel/574506bdfb733f4b140d to your computer and use it in GitHub Desktop.
session proxy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
cookie_state = { | |
'session_id': session_id, | |
'is_deleted': False, | |
} | |
def update_cookie(request, response): | |
exc = getattr(request, 'exception', None) | |
# exit early if there's an exception and the user specified | |
# to not set cookies on exception | |
if exc is not None and not cookie_on_exception: | |
return | |
if cookie_state['is_deleted']: | |
response.delete_cookie(...) | |
else: | |
session_id = cookie_state['session_id'] | |
cookieval = signed_serialize(session_key, secret) | |
response.set_cookie( | |
cookie_name, | |
value=cookieval, | |
max_age=cookie_max_age, | |
domain=cookie_domain, | |
secure=cookie_secure, | |
httponly=cookie_httponly, | |
) | |
request.add_response_callback(update_cookie) | |
def creator(): | |
cookie_state['session_id'] = id_generator() | |
cookie_state['is_deleted'] = False | |
return cookie_state['session_id'] | |
def deleter(): | |
cookie_state['is_deleted'] = True |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class SessionState(object): | |
def __init__(self, managed_dict, created, timeout, new): | |
self.managed_dict = managed_dict | |
self.created = created | |
self.timeout = timeout | |
self.new = new | |
class RedisSession(object): | |
def __init__( | |
self, | |
redis, | |
timeout, | |
creator, | |
deleter, | |
serialize=cPickle.dumps, | |
deserialize=cPickle.loads, | |
): | |
self.redis = redis | |
self.default_timeout = timeout | |
self._creator = creator | |
self._deleter = deleter | |
self.serialize = serialize | |
self.deserialize = deserialize | |
self._session_state = None | |
def _load(self, session_id): | |
"""Called by the factory to preload a session.""" | |
self.session_id = session_id | |
del self._session_state | |
@reify | |
def _session_state(self): | |
try: | |
if self.session_id is not None: | |
blob = self.from_redis() | |
if isinstance(blob, dict): | |
# bw-compat with old-style session blobs | |
managed_dict = blob | |
created = blob['created'] # is this even tracked atm? | |
timeout = blob['_rs_timeout'] | |
return SessionState(managed_dict, created, timeout, False) | |
else: | |
# new-style session blob | |
managed_dict, created, timeout = blob | |
return SessionState(managed_dict, created, timeout, False) | |
except ValueError: | |
# session failed to deserialize for some reason | |
# we'll fall through and create a new one | |
pass | |
# grab a new session id from the lifecycle manager | |
self.session_id = self._creator() | |
return SessionState({}, time.time(), self.default_timeout, True) | |
def to_redis(self): | |
blob = self.managed_dict, self.created, self.timeout | |
return self.serialize(blob) | |
@property | |
def new(self): | |
return self._session_state.new | |
@property | |
def created(self): | |
return self._session_state.created | |
@property | |
def managed_dict(self): | |
return self._session_state.managed_dict | |
_timeout_getter = lambda self: self._session_state.timeout | |
def _timeout_setter(self, value): | |
self._session_state.timeout = timeout | |
self.changed() | |
timeout = property(_timeout_getter, _timeout_setter) | |
def invalidate(self): | |
self.clear() | |
del self._session_state | |
self.session_id = None | |
# notify the lifecycle manager that the current session is gone | |
self._deleter() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment