| 1 | import warnings |
|---|
| 2 | |
|---|
| 3 | try: |
|---|
| 4 | from paste.registry import StackedObjectProxy |
|---|
| 5 | beaker_session = StackedObjectProxy(name="Beaker Session") |
|---|
| 6 | beaker_cache = StackedObjectProxy(name="Cache Manager") |
|---|
| 7 | except: |
|---|
| 8 | beaker_cache = None |
|---|
| 9 | beaker_session = None |
|---|
| 10 | |
|---|
| 11 | from beaker.cache import CacheManager |
|---|
| 12 | from beaker.session import Session, SessionObject |
|---|
| 13 | from beaker.util import coerce_cache_params, coerce_session_params, \ |
|---|
| 14 | parse_cache_config_options |
|---|
| 15 | |
|---|
| 16 | |
|---|
| 17 | class CacheMiddleware(object): |
|---|
| 18 | cache = beaker_cache |
|---|
| 19 | |
|---|
| 20 | def __init__(self, app, config=None, environ_key='beaker.cache', **kwargs): |
|---|
| 21 | """Initialize the Cache Middleware |
|---|
| 22 | |
|---|
| 23 | The Cache middleware will make a Cache instance available |
|---|
| 24 | every request under the ``environ['beaker.cache']`` key by |
|---|
| 25 | default. The location in environ can be changed by setting |
|---|
| 26 | ``environ_key``. |
|---|
| 27 | |
|---|
| 28 | ``config`` |
|---|
| 29 | dict All settings should be prefixed by 'cache.'. This |
|---|
| 30 | method of passing variables is intended for Paste and other |
|---|
| 31 | setups that accumulate multiple component settings in a |
|---|
| 32 | single dictionary. If config contains *no cache. prefixed |
|---|
| 33 | args*, then *all* of the config options will be used to |
|---|
| 34 | intialize the Cache objects. |
|---|
| 35 | |
|---|
| 36 | ``environ_key`` |
|---|
| 37 | Location where the Cache instance will keyed in the WSGI |
|---|
| 38 | environ |
|---|
| 39 | |
|---|
| 40 | ``**kwargs`` |
|---|
| 41 | All keyword arguments are assumed to be cache settings and |
|---|
| 42 | will override any settings found in ``config`` |
|---|
| 43 | |
|---|
| 44 | """ |
|---|
| 45 | self.app = app |
|---|
| 46 | config = config or {} |
|---|
| 47 | |
|---|
| 48 | self.options = {} |
|---|
| 49 | |
|---|
| 50 | # Update the options with the parsed config |
|---|
| 51 | self.options.update(parse_cache_config_options(config)) |
|---|
| 52 | |
|---|
| 53 | # Add any options from kwargs, but leave out the defaults this |
|---|
| 54 | # time |
|---|
| 55 | self.options.update( |
|---|
| 56 | parse_cache_config_options(kwargs, include_defaults=False)) |
|---|
| 57 | |
|---|
| 58 | # Assume all keys are intended for cache if none are prefixed with |
|---|
| 59 | # 'cache.' |
|---|
| 60 | if not self.options and config: |
|---|
| 61 | self.options = config |
|---|
| 62 | |
|---|
| 63 | self.options.update(kwargs) |
|---|
| 64 | self.cache_manager = CacheManager(**self.options) |
|---|
| 65 | self.environ_key = environ_key |
|---|
| 66 | |
|---|
| 67 | def __call__(self, environ, start_response): |
|---|
| 68 | if environ.get('paste.registry'): |
|---|
| 69 | if environ['paste.registry'].reglist: |
|---|
| 70 | environ['paste.registry'].register(self.cache, |
|---|
| 71 | self.cache_manager) |
|---|
| 72 | environ[self.environ_key] = self.cache_manager |
|---|
| 73 | return self.app(environ, start_response) |
|---|
| 74 | |
|---|
| 75 | |
|---|
| 76 | class SessionMiddleware(object): |
|---|
| 77 | session = beaker_session |
|---|
| 78 | |
|---|
| 79 | def __init__(self, wrap_app, config=None, environ_key='beaker.session', |
|---|
| 80 | **kwargs): |
|---|
| 81 | """Initialize the Session Middleware |
|---|
| 82 | |
|---|
| 83 | The Session middleware will make a lazy session instance |
|---|
| 84 | available every request under the ``environ['beaker.session']`` |
|---|
| 85 | key by default. The location in environ can be changed by |
|---|
| 86 | setting ``environ_key``. |
|---|
| 87 | |
|---|
| 88 | ``config`` |
|---|
| 89 | dict All settings should be prefixed by 'session.'. This |
|---|
| 90 | method of passing variables is intended for Paste and other |
|---|
| 91 | setups that accumulate multiple component settings in a |
|---|
| 92 | single dictionary. If config contains *no cache. prefixed |
|---|
| 93 | args*, then *all* of the config options will be used to |
|---|
| 94 | intialize the Cache objects. |
|---|
| 95 | |
|---|
| 96 | ``environ_key`` |
|---|
| 97 | Location where the Session instance will keyed in the WSGI |
|---|
| 98 | environ |
|---|
| 99 | |
|---|
| 100 | ``**kwargs`` |
|---|
| 101 | All keyword arguments are assumed to be session settings and |
|---|
| 102 | will override any settings found in ``config`` |
|---|
| 103 | |
|---|
| 104 | """ |
|---|
| 105 | config = config or {} |
|---|
| 106 | |
|---|
| 107 | # Load up the default params |
|---|
| 108 | self.options = dict(invalidate_corrupt=True, type=None, |
|---|
| 109 | data_dir=None, key='beaker.session.id', |
|---|
| 110 | timeout=None, secret=None, log_file=None) |
|---|
| 111 | |
|---|
| 112 | # Pull out any config args meant for beaker session. if there are any |
|---|
| 113 | for dct in [config, kwargs]: |
|---|
| 114 | for key, val in dct.iteritems(): |
|---|
| 115 | if key.startswith('beaker.session.'): |
|---|
| 116 | self.options[key[15:]] = val |
|---|
| 117 | if key.startswith('session.'): |
|---|
| 118 | self.options[key[8:]] = val |
|---|
| 119 | if key.startswith('session_'): |
|---|
| 120 | warnings.warn('Session options should start with session. ' |
|---|
| 121 | 'instead of session_.', DeprecationWarning, 2) |
|---|
| 122 | self.options[key[8:]] = val |
|---|
| 123 | |
|---|
| 124 | # Coerce and validate session params |
|---|
| 125 | coerce_session_params(self.options) |
|---|
| 126 | |
|---|
| 127 | # Assume all keys are intended for cache if none are prefixed with |
|---|
| 128 | # 'cache.' |
|---|
| 129 | if not self.options and config: |
|---|
| 130 | self.options = config |
|---|
| 131 | |
|---|
| 132 | self.options.update(kwargs) |
|---|
| 133 | self.wrap_app = wrap_app |
|---|
| 134 | self.environ_key = environ_key |
|---|
| 135 | |
|---|
| 136 | def __call__(self, environ, start_response): |
|---|
| 137 | session = SessionObject(environ, **self.options) |
|---|
| 138 | if environ.get('paste.registry'): |
|---|
| 139 | if environ['paste.registry'].reglist: |
|---|
| 140 | environ['paste.registry'].register(self.session, session) |
|---|
| 141 | environ[self.environ_key] = session |
|---|
| 142 | environ['beaker.get_session'] = self._get_session |
|---|
| 143 | |
|---|
| 144 | def session_start_response(status, headers, exc_info = None): |
|---|
| 145 | if session.accessed(): |
|---|
| 146 | session.persist() |
|---|
| 147 | if session.__dict__['_headers']['set_cookie']: |
|---|
| 148 | cookie = session.__dict__['_headers']['cookie_out'] |
|---|
| 149 | if cookie: |
|---|
| 150 | headers.append(('Set-cookie', cookie)) |
|---|
| 151 | return start_response(status, headers, exc_info) |
|---|
| 152 | return self.wrap_app(environ, session_start_response) |
|---|
| 153 | |
|---|
| 154 | def _get_session(self): |
|---|
| 155 | return Session({}, use_cookies=False, **self.options) |
|---|
| 156 | |
|---|
| 157 | |
|---|
| 158 | def session_filter_factory(global_conf, **kwargs): |
|---|
| 159 | def filter(app): |
|---|
| 160 | return SessionMiddleware(app, global_conf, **kwargs) |
|---|
| 161 | return filter |
|---|
| 162 | |
|---|
| 163 | |
|---|
| 164 | def session_filter_app_factory(app, global_conf, **kwargs): |
|---|
| 165 | return SessionMiddleware(app, global_conf, **kwargs) |
|---|