Ticket #7515: clear_and_destroy.diff
File clear_and_destroy.diff, 8.5 KB (added by , 16 years ago) |
---|
-
django/contrib/sessions/middleware.py
21 21 try: 22 22 accessed = request.session.accessed 23 23 modified = request.session.modified 24 destroyed = request.session.destroyed 24 25 except AttributeError: 26 # request doesn't have 'session' attribute 27 # FIXME: is it such a good idea to hide this exception? 28 # if process_request() fails to set request.session we should 29 # raise here as well instead of silently failing, 30 # perhaps a SessionNotSetError? 25 31 pass 26 32 else: 27 33 if accessed: 28 34 patch_vary_headers(response, ('Cookie',)) 29 if modified or settings.SESSION_SAVE_EVERY_REQUEST:35 if modified or destroyed or settings.SESSION_SAVE_EVERY_REQUEST: 30 36 if request.session.get_expire_at_browser_close(): 31 37 max_age = None 32 38 expires = None … … 35 41 expires_time = time.time() + max_age 36 42 expires = cookie_date(expires_time) 37 43 # Save the session data and refresh the client cookie. 38 request.session.save() 44 needs_saving = modified or settings.SESSION_SAVE_EVERY_REQUEST 45 if destroyed and not needs_saving: 46 # New session not modified after destruction. 47 # Note that not saving here results in new key generation 48 # in load() on the next request. If this is undesirable, 49 # the three-branched needs_saving logic is not required. 50 pass 51 elif destroyed and needs_saving: 52 # New session modified after destruction. We 53 # need to guarantee no exception from the persistance 54 # layer can block sending the new session cookie to 55 # client. 56 try: 57 request.session.save() 58 except: 59 pass 60 else: 61 request.session.save() 39 62 response.set_cookie(settings.SESSION_COOKIE_NAME, 40 63 request.session.session_key, max_age=max_age, 41 64 expires=expires, domain=settings.SESSION_COOKIE_DOMAIN, -
django/contrib/sessions/tests.py
22 22 >>> db_session.delete(db_session.session_key) 23 23 >>> db_session.exists(db_session.session_key) 24 24 False 25 >>> db_session['foo'] = 'bar' 26 >>> db_session.save() 27 >>> db_session.exists(db_session.session_key) 28 True 29 >>> prev_key = db_session.session_key 30 >>> db_session.save() 31 >>> db_session.destroy() 32 >>> db_session.exists(db_session.session_key) 33 False 34 >>> db_session.exists(prev_key) 35 False 36 >>> db_session.session_key == prev_key 37 False 38 >>> len(db_session.session_key) 39 32 40 >>> db_session.modified, db_session.accessed 41 (False, True) 42 >>> db_session['foo'] = 'bar' 43 >>> db_session.modified, db_session.accessed 44 (True, True) 45 >>> db_session.save() 46 >>> db_session.exists(db_session.session_key) 47 True 25 48 26 49 >>> file_session = FileSession() 27 50 >>> file_session.modified … … 39 62 >>> file_session.delete(file_session.session_key) 40 63 >>> file_session.exists(file_session.session_key) 41 64 False 65 >>> file_session['foo'] = 'bar' 66 >>> file_session.save() 67 >>> file_session.exists(file_session.session_key) 68 True 69 >>> prev_key = file_session.session_key 70 >>> file_session.save() 71 >>> file_session.destroy() 72 >>> file_session.exists(file_session.session_key) 73 False 74 >>> file_session.exists(prev_key) 75 False 76 >>> file_session.session_key == prev_key 77 False 78 >>> len(file_session.session_key) 79 32 80 >>> file_session.modified, file_session.accessed 81 (False, True) 82 >>> file_session['foo'] = 'bar' 83 >>> file_session.modified, file_session.accessed 84 (True, True) 85 >>> file_session.save() 86 >>> file_session.exists(file_session.session_key) 87 True 42 88 43 89 # Make sure the file backend checks for a good storage dir 44 90 >>> settings.SESSION_FILE_PATH = "/if/this/directory/exists/you/have/a/weird/computer" … … 61 107 >>> cache_session.delete(cache_session.session_key) 62 108 >>> cache_session.exists(cache_session.session_key) 63 109 False 110 >>> cache_session['foo'] = 'bar' 111 >>> cache_session.save() 112 >>> cache_session.exists(cache_session.session_key) 113 True 114 >>> prev_key = cache_session.session_key 115 >>> cache_session.save() 116 >>> cache_session.destroy() 117 >>> cache_session.exists(cache_session.session_key) 118 False 119 >>> cache_session.exists(prev_key) 120 False 121 >>> cache_session.session_key == prev_key 122 False 123 >>> len(cache_session.session_key) 124 32 125 >>> cache_session.modified, cache_session.accessed 126 (False, True) 127 >>> cache_session['foo'] = 'bar' 128 >>> cache_session.modified, cache_session.accessed 129 (True, True) 130 >>> cache_session.save() 131 >>> cache_session.exists(cache_session.session_key) 132 True 64 133 65 134 >>> s = SessionBase() 66 135 >>> s._session['some key'] = 'exists' # Pre-populate the session with some data … … 147 216 >>> list(i) 148 217 [('x', 1)] 149 218 150 219 # test .clear() 220 >>> s.modified = s.accessed = False 221 >>> s.items() 222 [('x', 1)] 223 >>> s.clear() 224 >>> s.items() 225 [] 226 >>> s.accessed, s.modified 227 (True, True) 151 228 229 152 230 ######################### 153 231 # Custom session expiry # 154 232 ######################### -
django/contrib/sessions/backends/base.py
25 25 self._session_key = session_key 26 26 self.accessed = False 27 27 self.modified = False 28 self.destroyed = False 28 29 29 30 def __contains__(self, key): 30 31 return key in self._session … … 53 54 self.modified = self.modified or key in self._session 54 55 return self._session.pop(key, *args) 55 56 57 def clear(self): 58 self._session.clear() 59 self.modified = True 60 61 def destroy(self): 62 self._session.clear() 63 try: 64 # remove old session, may fail 65 self.delete(self._session_key) 66 except: 67 # ignore exceptions to guarantee session key reset 68 pass 69 self._session_key = self._get_new_session_key(safe=True) 70 self.modified = False 71 self.accessed = True 72 self.destroyed = True 73 56 74 def setdefault(self, key, value): 57 75 if key in self._session: 58 76 return self._session[key] … … 107 125 def iteritems(self): 108 126 return self._session.iteritems() 109 127 110 def _get_new_session_key(self ):128 def _get_new_session_key(self, safe=False): 111 129 "Returns session key that isn't being used." 112 130 # The random module is seeded when this Apache child is created. 113 131 # Use settings.SECRET_KEY as added salt. … … 119 137 while 1: 120 138 session_key = md5.new("%s%s%s%s" % (random.randint(0, sys.maxint - 1), 121 139 pid, time.time(), settings.SECRET_KEY)).hexdigest() 122 if not self.exists(session_key): 123 break 140 if safe: 141 try: 142 if not self.exists(session_key): 143 break 144 except: 145 # Depends on the assumption that key collisions are rare, 146 # see ticket #1180 147 pass 148 else: 149 if not self.exists(session_key): 150 break 124 151 return session_key 125 152 126 153 def _get_session_key(self): -
docs/sessions.txt
106 106 107 107 * ``setdefault()`` (**New in Django development version**) 108 108 109 * ``clear()`` (**New in Django development version**) 110 109 111 It also has these methods: 110 112 113 * ``destroy()`` 114 115 **New in Django development version** 116 117 Clears session data, deletes the old session from session storage and 118 creates a new empty session in exception-safe manner. This is the 119 recommended, safe way of resetting sessions on e.g. user logout. 120 111 121 * ``set_test_cookie()`` 112 122 113 123 Sets a test cookie to determine whether the user's browser supports