Skip to content

Commit

Permalink
Fixed mutliple set-cookie header issue with session. (closes webpy#45)
Browse files Browse the repository at this point in the history
The Session class was extended from ThreadedDict, which is extended from
threading.local. It looks like __init__ is called once for each thread
for thread local objects. That made session to add multiple processors
to the application, one for each thread/request.

Fixed this issue by keeping the threadeddict as an attribute instead of
extending from it.
  • Loading branch information
anandology committed Feb 27, 2011
1 parent 7d49fd1 commit 23583b4
Showing 1 changed file with 23 additions and 3 deletions.
26 changes: 23 additions & 3 deletions web/session.py
Expand Up @@ -38,19 +38,39 @@ class SessionExpired(web.HTTPError):
def __init__(self, message): def __init__(self, message):
web.HTTPError.__init__(self, '200 OK', {}, data=message) web.HTTPError.__init__(self, '200 OK', {}, data=message)


class Session(utils.ThreadedDict): class Session(object):
"""Session management for web.py """Session management for web.py
""" """
__slots__ = ["store", "_initializer", "_last_cleanup_time", "_config"] __slots__ = [
"store", "_initializer", "_last_cleanup_time", "_config", "_data",
"__getitem__", "__setitem__", "__delitem__"
]


def __init__(self, app, store, initializer=None): def __init__(self, app, store, initializer=None):
self.store = store self.store = store
self._initializer = initializer self._initializer = initializer
self._last_cleanup_time = 0 self._last_cleanup_time = 0
self._config = utils.storage(web.config.session_parameters) self._config = utils.storage(web.config.session_parameters)
self._data = utils.threadeddict()

self.__getitem__ = self._data.__getitem__
self.__setitem__ = self._data.__setitem__
self.__delitem__ = self._data.__delitem__


if app: if app:
app.add_processor(self._processor) app.add_processor(self._processor)

def __getattr__(self, name):
return getattr(self._data, name)

def __setattr__(self, name, value):
if name in self.__slots__:
object.__setattr__(self, name, value)
else:
setattr(self._data, name, value)

def __delattr__(self, name):
delattr(self._data, name)


def _processor(self, handler): def _processor(self, handler):
"""Application processor to setup session for every request""" """Application processor to setup session for every request"""
Expand Down Expand Up @@ -111,7 +131,7 @@ def _save(self):


if not self.get('_killed'): if not self.get('_killed'):
web.setcookie(cookie_name, self.session_id, domain=cookie_domain, httponly=httponly) web.setcookie(cookie_name, self.session_id, domain=cookie_domain, httponly=httponly)
self.store[self.session_id] = dict(self) self.store[self.session_id] = dict(self._data)
else: else:
web.setcookie(cookie_name, self.session_id, expires=-1, domain=cookie_domain, httponly=httponly) web.setcookie(cookie_name, self.session_id, expires=-1, domain=cookie_domain, httponly=httponly)


Expand Down

0 comments on commit 23583b4

Please sign in to comment.