Ticket #7515: clear_and_destroy2.diff
File clear_and_destroy2.diff, 8.4 KB (added by , 16 years ago) |
---|
-
django/contrib/sessions/middleware.py
16 16 try: 17 17 accessed = request.session.accessed 18 18 modified = request.session.modified 19 destroyed = request.session.destroyed 19 20 except AttributeError: 21 # request doesn't have 'session' attribute 22 # FIXME: is it such a good idea to hide this exception? 23 # if process_request() fails to set request.session we should 24 # raise here as well instead of silently failing, 25 # perhaps a SessionNotSetError? 20 26 pass 21 27 else: 22 28 if accessed: 23 29 patch_vary_headers(response, ('Cookie',)) 24 if modified or settings.SESSION_SAVE_EVERY_REQUEST:30 if modified or destroyed or settings.SESSION_SAVE_EVERY_REQUEST: 25 31 if request.session.get_expire_at_browser_close(): 26 32 max_age = None 27 33 expires = None … … 30 36 expires_time = time.time() + max_age 31 37 expires = cookie_date(expires_time) 32 38 # Save the session data and refresh the client cookie. 33 request.session.save() 39 needs_saving = modified or settings.SESSION_SAVE_EVERY_REQUEST 40 if destroyed and not needs_saving: 41 # New session not modified after destruction. 42 # Note that not saving here results in new key generation 43 # in load() on the next request. If this is undesirable, 44 # the three-branched needs_saving logic is not required. 45 pass 46 elif destroyed and needs_saving: 47 # New session modified after destruction. We 48 # need to guarantee no exception from the persistance 49 # layer can block sending the new session cookie to 50 # client. 51 try: 52 request.session.save() 53 except: 54 pass 55 else: 56 request.session.save() 34 57 response.set_cookie(settings.SESSION_COOKIE_NAME, 35 58 request.session.session_key, max_age=max_age, 36 59 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.destroy() 31 >>> db_session.exists(db_session.session_key) 32 False 33 >>> db_session.exists(prev_key) 34 False 35 >>> db_session.session_key == prev_key 36 False 37 >>> len(db_session.session_key) 38 32 39 >>> db_session.modified, db_session.accessed 40 (False, True) 41 >>> db_session['foo'] = 'bar' 42 >>> db_session.modified, db_session.accessed 43 (True, True) 44 >>> db_session.save() 45 >>> db_session.exists(db_session.session_key) 46 True 25 47 26 48 >>> file_session = FileSession() 27 49 >>> file_session.modified … … 39 61 >>> file_session.delete(file_session.session_key) 40 62 >>> file_session.exists(file_session.session_key) 41 63 False 64 >>> file_session['foo'] = 'bar' 65 >>> file_session.save() 66 >>> file_session.exists(file_session.session_key) 67 True 68 >>> prev_key = file_session.session_key 69 >>> file_session.destroy() 70 >>> file_session.exists(file_session.session_key) 71 False 72 >>> file_session.exists(prev_key) 73 False 74 >>> file_session.session_key == prev_key 75 False 76 >>> len(file_session.session_key) 77 32 78 >>> file_session.modified, file_session.accessed 79 (False, True) 80 >>> file_session['foo'] = 'bar' 81 >>> file_session.modified, file_session.accessed 82 (True, True) 83 >>> file_session.save() 84 >>> file_session.exists(file_session.session_key) 85 True 42 86 43 87 # Make sure the file backend checks for a good storage dir 44 88 >>> settings.SESSION_FILE_PATH = "/if/this/directory/exists/you/have/a/weird/computer" … … 61 105 >>> cache_session.delete(cache_session.session_key) 62 106 >>> cache_session.exists(cache_session.session_key) 63 107 False 108 >>> cache_session['foo'] = 'bar' 109 >>> cache_session.save() 110 >>> cache_session.exists(cache_session.session_key) 111 True 112 >>> prev_key = cache_session.session_key 113 >>> cache_session.destroy() 114 >>> cache_session.exists(cache_session.session_key) 115 False 116 >>> cache_session.exists(prev_key) 117 False 118 >>> cache_session.session_key == prev_key 119 False 120 >>> len(cache_session.session_key) 121 32 122 >>> cache_session.modified, cache_session.accessed 123 (False, True) 124 >>> cache_session['foo'] = 'bar' 125 >>> cache_session.modified, cache_session.accessed 126 (True, True) 127 >>> cache_session.save() 128 >>> cache_session.exists(cache_session.session_key) 129 True 64 130 65 131 >>> s = SessionBase() 66 132 >>> s._session['some key'] = 'exists' # Pre-populate the session with some data … … 147 213 >>> list(i) 148 214 [('x', 1)] 149 215 150 216 # test .clear() 217 >>> s.modified = s.accessed = False 218 >>> s.items() 219 [('x', 1)] 220 >>> s.clear() 221 >>> s.items() 222 [] 223 >>> s.accessed, s.modified 224 (True, True) 151 225 226 152 227 ######################### 153 228 # Custom session expiry # 154 229 ######################### -
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