Changeset 375
- Timestamp:
- 06/24/05 11:39:20
- Files:
-
- trunk/cherrypy/_cpconfig.py (modified) (1 diff)
- trunk/cherrypy/_cputil.py (modified) (2 diffs)
- trunk/cherrypy/lib/filter/sessionfilter/basesession.py (modified) (1 diff)
- trunk/cherrypy/lib/filter/sessionfilter/dbmsession.py (modified) (2 diffs)
- trunk/cherrypy/lib/filter/sessionfilter/filesession.py (modified) (1 diff)
- trunk/cherrypy/lib/filter/sessionfilter/sessionconfig.py (modified) (1 diff)
- trunk/cherrypy/lib/filter/sessionfilter/sessionerrors.py (modified) (1 diff)
- trunk/cherrypy/lib/filter/sessionfilter/sessionfilter.py (modified) (7 diffs)
- trunk/cherrypy/test/test_tutorials.py (modified) (2 diffs)
- trunk/cherrypy/tutorial/tut07_sessions.py (modified) (1 diff)
- trunk/cherrypy/tutorial/tut09_sessionfilter.py (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/cherrypy/_cpconfig.py
r357 r375 34 34 'server.threadPool': 0, 35 35 36 'session.storageType': 'ram', 37 'session.timeout': 60, 38 'session.cleanUpDelay': 60, 39 'session.cookieName': 'CherryPySession', 40 'session.storageFileDir': '', 36 'sessionFilter.on' : False, 41 37 42 'sessionFilter.on': False, 43 'sessionFilter.timeout': 60, 44 'sessionFilter.cleanUpDelay': 60, 45 'sessionFilter.storageType' : 'ram', 46 'sessionFilter.cookieName': 'CherryPySession', 47 'sessionFilter.storageFileDir': '.sessionFiles', 48 49 'sessionFilter.new': 'sessionMap', # legacy setting 38 'sessionFilter.default.on': True, 39 'sessionFilter.default.timeout': 60, 40 'sessionFilter.default.cleanUpDelay': 60, 41 'sessionFilter.default.storageType' : 'ram', 42 'sessionFilter.default.cookieName': 'CherryPySession', 43 'sessionFilter.default.storageFileDir': '.sessionFiles' 50 44 } 51 45 trunk/cherrypy/_cputil.py
r343 r375 40 40 41 41 42 def getSpecialAttribute(name): 43 """ Return the special function """ 44 45 # First, we look in the right-most object if this special function is implemented. 46 # If not, then we try the previous object and so on until we reach cpg.root 47 # If it's still not there, we use the implementation from this module. 48 42 def getObjectTrail(): 43 """ Return all objects from the currenct object to cpg """ 49 44 root = getattr(cpg, 'root', None) 50 45 if root: 51 moduleList = [root]46 objectTrail = [cpg, root] 52 47 # Try object path 53 48 try: … … 62 57 try: 63 58 root = getattr(root, newObj) 64 moduleList.append(root)59 objectTrail.append(root) 65 60 except AttributeError: 66 61 break 67 62 68 moduleList.reverse() 69 for module in moduleList: 70 func = getattr(module, name, None) 71 if func != None: 72 return func 63 return objectTrail 64 return None 65 66 def getSpecialAttribute(name): 67 """ Return the special attribute """ 68 69 # First, we look in the right-most object if this special attribute is implemented. 70 # If not, then we try the previous object and so on until we reach cpg.root 71 # If it's still not there, we use the implementation from this module. 72 73 objectList = getObjectTrail() 74 if objectList: 75 76 objectList.reverse() 77 for obj in objectList: 78 attr = getattr(obj, name, None) 79 if attr != None: 80 return attr 73 81 74 82 try: trunk/cherrypy/lib/filter/sessionfilter/basesession.py
r303 r375 105 105 self.__sessionCache[sessionKey] = session 106 106 107 if self.sessionName == 'sessionMap':108 # raise a warning perhaps109 setattr(cpg.request, self.sessionName, session)110 107 setattr(cpg.sessions, self.sessionName, session) 111 108 trunk/cherrypy/lib/filter/sessionfilter/dbmsession.py
r298 r375 35 35 from simplesessiondict import SimpleSessionDict 36 36 37 import os.path 38 37 39 class DBMSession(BaseSession): 38 40 def __init__(self, sessionName): … … 41 43 BaseSession.__init__(self, sessionName) 42 44 43 sessionName=cpg.config.get('sessionFilter.new', None) 44 sessionFile=cpg.config.get('%s.dbFile' % sessionName, '%s.db' % sessionName) 45 # we must make sure the db file is unique 46 defaultFile = '%s-%i.db' % (sessionName, hash(self)) 47 dbFilePrefix=cpg.config.get('sessionFilter.%s.dbFilePrefix' % sessionName, '') 48 49 sessionFile = os.path.join(dbFilePrefix, defaultFile) 50 45 51 self.__data = shelve.open(sessionFile, 'c') 46 52 trunk/cherrypy/lib/filter/sessionfilter/filesession.py
r346 r375 47 47 def __storageDir(self): 48 48 cpg = cherrypy.cpg 49 storageDir = sessionconfig.retrieve('storageFileDir', self.sessionName, '.sessionFiles') 49 50 storageDir = sessionconfig.retrieve('storageFileDir', self.sessionName) 50 51 return storageDir 51 52 trunk/cherrypy/lib/filter/sessionfilter/sessionconfig.py
r282 r375 49 49 def retrieve(keyName, sessionName, default = None): 50 50 cpg = cherrypy.cpg 51 value = cpg.config.get('%s.%s' % (sessionName, keyName), None)52 if value == None:53 value = cpg.config.get('sessionFilter.%s' % keyName, None)54 51 missing = object() 52 value = cpg.config.get('sessionFilter.%s.%s' % (sessionName, keyName), missing) 53 if value is missing: 54 value = cpg.config.get('sessionFilter.default.%s' % keyName, default) 55 55 return value trunk/cherrypy/lib/filter/sessionfilter/sessionerrors.py
r275 r375 38 38 """ Possibly raised a browser sends a none with a session idwhen the sessions Expire """ 39 39 40 class SessionIncompatibleError(SessionError): 41 """ raised if the configured storage type is not compatible with the application """ 42 40 43 class SessionImmutableError(SessionError): 41 44 """ immutable exception """ trunk/cherrypy/lib/filter/sessionfilter/sessionfilter.py
r319 r375 1 1 2 from cherrypy.lib.filter.basefilter import BaseFilter3 2 import cherrypy.cpg 4 3 5 import time , re4 import time 6 5 7 from sessionerrors import SessionNotFoundError 6 from sessionerrors import SessionNotFoundError, SessionIncompatibleError 8 7 9 8 import sessionconfig 9 from cherrypy._cputil import getObjectTrail 10 10 11 def _getSessions(): 12 """ checks the config file for the sessions """ 13 cpg = cherrypy.cpg 11 def _getSessions2(): 12 cpg =cherrypy.cpg 13 sessions = {} 14 15 objectTrail = getObjectTrail() 14 16 15 sessions = {} 17 for n in xrange(len(objectTrail)): 18 obj = objectTrail[n] 19 objPath = '/'.join(cpg.request.path.split('/')[0:n+1]) 20 if not objPath: 21 objPath = '/' 22 23 try: 24 sessionList = obj._cpSessionList 25 except AttributeError: 26 27 if obj == cpg: 28 obj._cpSessionList = [{'sessionName':'default'}] 29 sessionList = obj._cpSessionList 30 else: 31 sessionList = [] 32 33 for sessionIndex in xrange(len(sessionList)): 34 sessionManager = sessionList[sessionIndex] 35 36 37 if isinstance(sessionManager, dict): 38 # must be initilized 39 sessionName = sessionManager['sessionName'] 40 compatible = sessionManager.get('compatible', []) 41 incompatible = sessionManager.get('icompatible', []) 42 43 # unless it is off initilize 44 if cpg.config.get('sessionFilter.%s.on' % sessionName, True): 45 46 storageType = sessionconfig.retrieve('storageType', sessionName) 16 47 17 sessionNames = cpg.config.getAll('sessionFilter.new') 18 for sessionPath in sessionNames: 19 sessionName = sessionNames[sessionPath] 20 sessionManager = cpg.config.get('%s.sessionManager' % sessionName, None) 21 if not sessionManager: 22 storageType = sessionconfig.retrieve('storageType', sessionName) 48 if compatible and not storageType in compatible or \ 49 incompatible and not storageType in incompatible: 50 raise SessionIncompatibleError 51 52 sessionManager = sessionconfig._sessionTypes[storageType](sessionName) 53 sessionManager.lastCleanUp = time.time() 54 sessionManager.path = objPath 55 56 obj._cpSessionList[sessionIndex] = sessionManager 57 58 elif isinstance(sessionManager, str): 59 # unless it is off initilize 60 if cpg.config.get('sessionFilter.%s.on' % sessionManager, True): 61 storageType = sessionconfig.retrieve('storageType', sessionManager) 62 sessionManager = sessionconfig._sessionTypes[storageType](sessionManager) 63 sessionManager.lastCleanUp = time.time() 64 65 sessionManager.path = objPath 66 obj._cpSessionList[sessionIndex] = sessionManager 67 23 68 24 try: 25 sessionManager = sessionconfig._sessionTypes[storageType](sessionName) 26 except KeyError: 27 storageType = cpg.config.get('%s.customStorageClass' % sessionName) 28 if storageType: 29 try: 30 storageClass = cherrypy._cputil.getSpecialAttribute(storageType) 31 sessionManager = storageClass(sessionName) 32 except cherrypy.cperror.InternalError: 33 raise SessionBadStorageTypeError(storageType) 34 raise 69 else: # try and clean up 70 cleanUpDelay = sessionconfig.retrieve('cleanUpDelay', sessionManager.sessionName) 71 now = time.time() 72 lastCleanUp = sessionManager.lastCleanUp 73 if lastCleanUp + cleanUpDelay * 60 <= now: 74 sessionManager.cleanUpOldSessions() 35 75 36 sessionManager.path = sessionPath 37 sessionManager.name = sessionName 38 sessionManager.lastCleanUp = time.time() 39 40 cpg.config.update( 41 { 42 sessionPath : {'%s.sessionManager' % sessionName : sessionManager} 43 } 44 ) 45 else: # try and clean up 46 cleanUpDelay = sessionconfig.retrieve('cleanUpDelay', sessionName) 47 now = time.time() 48 lastCleanUp = sessionManager.lastCleanUp 49 if lastCleanUp + cleanUpDelay * 60 <= now: 50 sessionManager.cleanUpOldSessions() 51 52 sessions[sessionName] = sessionManager 76 sessions[sessionManager.sessionName] = sessionManager 53 77 54 78 return sessions 55 79 56 class SessionFilter (BaseFilter):80 class SessionFilter: 57 81 """ 58 82 Input filter - get the sessionId (or generate a new one) and load up the session data 59 83 """ 60 84 61 85 def __initSessions(self): 62 86 cpg = cherrypy.cpg 63 sessions = _getSessions() 87 sessions = _getSessions2() 88 # sessions = _getSessions() 64 89 sessionKeys = self.getSessionKeys() 65 90 … … 73 98 sessionManager.loadSession(newKey) 74 99 75 self.setSessionKey(newKey, sessionManager .name)100 self.setSessionKey(newKey, sessionManager) 76 101 77 102 def getSessionKeys(self): … … 82 107 83 108 sessionKeys= {} 84 85 sessions = cpg.config.getAll('sessionFilter.new') 86 for sessionPath in sessions: 87 sessionName = sessions[sessionPath] 88 cookieName = cpg.config.get('%s.cookieName' % sessionName, None) 89 if not cookieName: 90 cookieName = (cpg.config.get('sessionFilter.cookieName') + 91 '|' + sessionName + 92 '|' + re.sub('/','_', sessionPath)) 93 cpg.config.update({ 94 sessionPath : {'%s.cookieName' % sessionName : cookieName} 95 }) 109 sessions = _getSessions2() 110 for sessionName in sessions: 111 sessionManager = sessions[sessionName] 112 113 cookiePrefix = sessionconfig.retrieve('cookieName', sessionName, None) 114 115 cookieName = '%s_%s_%i' % (cookiePrefix, sessionName, hash(sessionManager)) 116 96 117 try: 97 118 sessionKeys[sessionName] = cpg.request.simpleCookie[cookieName].value … … 99 120 sessionKeys[sessionName] = None 100 121 return sessionKeys 122 101 123 102 def setSessionKey(self, sessionKey, session Name):124 def setSessionKey(self, sessionKey, sessionManager): 103 125 """ 104 126 Sets the session key in a cookie. Aplications should not call this function, … … 108 130 cpg = cherrypy.cpg 109 131 110 cookieName = cpg.config.get('%s.cookieName' % sessionName, None) 132 sessionName = sessionManager.sessionName 133 134 cookiePrefix = sessionconfig.retrieve('cookieName', sessionName, None) 135 136 cookieName = '%s_%s_%i' % (cookiePrefix, sessionName, hash(sessionManager)) 111 137 112 138 cpg.response.simpleCookie[cookieName] = sessionKey 113 139 cpg.response.simpleCookie[cookieName]['version'] = 1 114 115 path = cpg.config.get('%s.sessionManager' % sessionName, returnSection = True) 116 cpg.response.simpleCookie[cookieName]['path'] = path 140 141 cpg.response.simpleCookie[cookieName]['path'] = sessionManager.path 117 142 118 143 119 144 def __saveSessions(self): 120 145 cpg = cherrypy.cpg 121 sessions = _getSessions() 146 #sessions = _getSessions() 147 sessions = _getSessions2() 122 148 123 149 for sessionName in sessions: … … 128 154 def beforeMain(self): 129 155 cpg = cherrypy.cpg 130 if (cpg.config.get('sessionFilter.on', False)131 and not cpg.config.get('staticFilter.on', False)):156 if not cpg.config.get('staticFilter.on', False) and \ 157 cpg.config.get('sessionFilter.on'): 132 158 self.__initSessions() 133 159 134 160 def beforeFinalize(self): 135 161 cpg = cherrypy.cpg 136 if (cpg.config.get('sessionFilter.on', False)137 and not cpg.config.get('staticFilter.on', False)):162 if not cpg.config.get('staticFilter.on', False) and \ 163 cpg.config.get('sessionFilter.on'): 138 164 self.__saveSessions() 139 165 … … 141 167 #this breaks a test case 142 168 def beforeErrorResponse(self): 169 cpg = cherrypy.cpg 143 170 # Still save session data 144 if (cpg.config.get('sessionFilter.on', False) 145 and not cpg.config.get('staticFilter.on', False)): 146 self.__saveSessions() 171 if not cpg.config.get('staticFilter.on', False) and \ 172 cpg.config.get('sessionFilter.on'): 147 173 ''' trunk/cherrypy/test/test_tutorials.py
r366 r375 129 129 'Hendrik Mans, CherryPy co-developer & crazy German ' 130 130 '(<a href="./">back</a>)') 131 132 131 def test07Sessions(self): 133 132 load_tut_module("tut07_sessions") … … 154 153 'Remi<br/>Carlos<br/>Hendrik<br/>Lorenzo Lamas<br/>' 155 154 '</body></html>') 156 157 155 def test09SessionFilter(self): 158 156 load_tut_module("tut09_sessionfilter") trunk/cherrypy/tutorial/tut07_sessions.py
r341 r375 15 15 def index(self): 16 16 # Increase the silly hit counter 17 count = cpg. request.sessionMap.get('count', 0) + 117 count = cpg.sessions.default.get('count', 0) + 1 18 18 19 19 # Store the new value in the session dictionary 20 cpg. request.sessionMap['count'] = count20 cpg.sessions.default['count'] = count 21 21 22 22 # And display a silly hit count message! trunk/cherrypy/tutorial/tut09_sessionfilter.py
r341 r375 5 5 from cherrypy import cpg 6 6 7 # you will never need to import the RamSession 8 # we only import it to demostrate how to manually use 9 # a storage adaptor as would with a customized storage adaptor 10 from cherrypy.lib.filter.sessionfilter.ramsession import RamSession 11 7 12 class HitCounter: 8 13 _cpSessionList=[] 14 # this list will contain site wide sessions 15 # in almost all cases this will be defined on a class by class basis, 16 # but for this simple example we use a seperate session list for each method 17 # for simplicity 18 9 19 # this is just a primative template function 10 20 def __examplePage(self, poweredBy, count, links, sessionKey): … … 19 29 yield '\n</body></html>' 20 30 21 # a list of the pages used in the example so we add pages31 # a list of the pages used in the example so we can add pages 22 32 # without changing any code 23 33 samplePages = ['admin', 'index', 'forum'] 24 34 25 35 def index(self): 26 # this function uses the sessionMap which is turned on by defualt36 # this function uses the default session 27 37 # it may not be the defualt in future versions 28 38 29 39 # Increase the silly hit counter 30 count = cpg.sessions. sessionMap.get('count', 0) + 140 count = cpg.sessions.default.get('count', 0) + 1 31 41 32 42 # Store the new value in the session dictionary 33 # cpg.sessions. sessionMapis available by default34 cpg.sessions. sessionMap['count'] = count43 # cpg.sessions.default is available by default 44 cpg.sessions.default['count'] = count 35 45 36 46 # And display a silly hit count message! 37 key = cpg.sessions. sessionMap.key47 key = cpg.sessions.default.key 38 48 return self.__examplePage('ram', count, self.samplePages, key) 39 49 … … 41 51 42 52 def admin(self): 43 # this function uses the admin Sessionwhich is defined in53 # this function uses the admin which is defined in 44 54 # the config file "tut10_sessionFilter.conf", otherwise 45 55 # it mirrors the session function 46 56 47 adminCount = cpg.sessions.admin Session.get('adminCount', 0) + 148 cpg.sessions.admin Session['adminCount'] = adminCount57 adminCount = cpg.sessions.admin.get('adminCount', 0) + 1 58 cpg.sessions.admin['adminCount'] = adminCount 49 59 50 key = cpg.sessions.admin Session.key60 key = cpg.sessions.admin.key 51 61 return self.__examplePage('ram', adminCount, self.samplePages, key) 62 52 63 admin.exposed = True 64 admin._cpSessionList=['admin'] 53 65 54 66 def forum(self): 55 # this function uses the forumSession which is defined in 67 # this function uses its own forum session which is defined in 68 # the 56 69 # the config file "tut10_sessionFilter.conf", otherwise 57 70 # it mirrors the session function 58 71 59 forumCount = cpg.sessions.forum Session.get('forumCount', 0) + 160 cpg.sessions.forum Session['forumCount'] = forumCount72 forumCount = cpg.sessions.forum.get('forumCount', 0) + 1 73 cpg.sessions.forum['forumCount'] = forumCount 61 74 62 key = cpg.sessions.forum Session.key75 key = cpg.sessions.forum.key 63 76 return self.__examplePage('ram', forumCount, self.samplePages, key) 77 64 78 forum.exposed=True 79 forum._cpSessionList=['forum'] 65 80 66 81 cpg.root = HitCounter() 67 82 68 83 if __name__ == '__main__': 84 cpg.config.update(file = "tutorial.conf") 69 85 cpg.config.update(file = 'tut10_sessionfilter.conf') 70 86 cpg.server.start()

