109 lines
3.8 KiB
Python
109 lines
3.8 KiB
Python
# (c) 2005 Ian Bicking and contributors; written for Paste (http://pythonpaste.org)
|
|
# Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
|
|
|
|
"""
|
|
Creates a session object.
|
|
|
|
In your application, use::
|
|
|
|
environ['paste.flup_session_service'].session
|
|
|
|
This will return a dictionary. The contents of this dictionary will
|
|
be saved to disk when the request is completed. The session will be
|
|
created when you first fetch the session dictionary, and a cookie will
|
|
be sent in that case. There's current no way to use sessions without
|
|
cookies, and there's no way to delete a session except to clear its
|
|
data.
|
|
"""
|
|
|
|
from paste import httpexceptions
|
|
from paste import wsgilib
|
|
import flup.middleware.session
|
|
flup_session = flup.middleware.session
|
|
|
|
# This is a dictionary of existing stores, keyed by a tuple of
|
|
# store type and parameters
|
|
store_cache = {}
|
|
|
|
class NoDefault(object):
|
|
pass
|
|
|
|
class SessionMiddleware(object):
|
|
|
|
session_classes = {
|
|
'memory': (flup_session.MemorySessionStore,
|
|
[('session_timeout', 'timeout', int, 60)]),
|
|
'disk': (flup_session.DiskSessionStore,
|
|
[('session_timeout', 'timeout', int, 60),
|
|
('session_dir', 'storeDir', str, '/tmp/sessions')]),
|
|
'shelve': (flup_session.ShelveSessionStore,
|
|
[('session_timeout', 'timeout', int, 60),
|
|
('session_file', 'storeFile', str,
|
|
'/tmp/session.shelve')]),
|
|
}
|
|
|
|
|
|
def __init__(self, app,
|
|
global_conf=None,
|
|
session_type=NoDefault,
|
|
cookie_name=NoDefault,
|
|
**store_config
|
|
):
|
|
self.application = app
|
|
if session_type is NoDefault:
|
|
session_type = global_conf.get('session_type', 'disk')
|
|
self.session_type = session_type
|
|
try:
|
|
self.store_class, self.store_args = self.session_classes[self.session_type]
|
|
except KeyError:
|
|
raise KeyError(
|
|
"The session_type %s is unknown (I know about %s)"
|
|
% (self.session_type,
|
|
', '.join(self.session_classes.keys())))
|
|
kw = {}
|
|
for config_name, kw_name, coercer, default in self.store_args:
|
|
value = coercer(store_config.get(config_name, default))
|
|
kw[kw_name] = value
|
|
self.store = self.store_class(**kw)
|
|
if cookie_name is NoDefault:
|
|
cookie_name = global_conf.get('session_cookie', '_SID_')
|
|
self.cookie_name = cookie_name
|
|
|
|
def __call__(self, environ, start_response):
|
|
service = flup_session.SessionService(
|
|
self.store, environ, cookieName=self.cookie_name,
|
|
fieldName=self.cookie_name)
|
|
environ['paste.flup_session_service'] = service
|
|
|
|
def cookie_start_response(status, headers, exc_info=None):
|
|
service.addCookie(headers)
|
|
return start_response(status, headers, exc_info)
|
|
|
|
try:
|
|
app_iter = self.application(environ, cookie_start_response)
|
|
except httpexceptions.HTTPException as e:
|
|
headers = (e.headers or {}).items()
|
|
service.addCookie(headers)
|
|
e.headers = dict(headers)
|
|
service.close()
|
|
raise
|
|
except:
|
|
service.close()
|
|
raise
|
|
|
|
return wsgilib.add_close(app_iter, service.close)
|
|
|
|
def make_session_middleware(app, global_conf,
|
|
session_type=NoDefault,
|
|
cookie_name=NoDefault,
|
|
**store_config):
|
|
"""
|
|
Wraps the application in a session-managing middleware.
|
|
The session service can then be found in
|
|
``environ['paste.flup_session_service']``
|
|
"""
|
|
return SessionMiddleware(
|
|
app, global_conf=global_conf,
|
|
session_type=session_type, cookie_name=cookie_name,
|
|
**store_config)
|