Django

Code

Ticket #7515: clear_and_destroy2.diff

File clear_and_destroy2.diff, 8.4 kB (added by mrts, 4 months ago)

Remove redundant .save()s from tests and update to r8158

  • django/contrib/sessions/middleware.py

    old new  
    1616        try: 
    1717            accessed = request.session.accessed 
    1818            modified = request.session.modified 
     19            destroyed = request.session.destroyed 
    1920        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? 
    2026            pass 
    2127        else: 
    2228            if accessed: 
    2329                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: 
    2531                if request.session.get_expire_at_browser_close(): 
    2632                    max_age = None 
    2733                    expires = None 
     
    3036                    expires_time = time.time() + max_age 
    3137                    expires = cookie_date(expires_time) 
    3238                # 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() 
    3457                response.set_cookie(settings.SESSION_COOKIE_NAME, 
    3558                        request.session.session_key, max_age=max_age, 
    3659                        expires=expires, domain=settings.SESSION_COOKIE_DOMAIN, 
  • django/contrib/sessions/tests.py

    old new  
    2222>>> db_session.delete(db_session.session_key) 
    2323>>> db_session.exists(db_session.session_key) 
    2424False 
     25>>> db_session['foo'] = 'bar' 
     26>>> db_session.save() 
     27>>> db_session.exists(db_session.session_key) 
     28True 
     29>>> prev_key = db_session.session_key 
     30>>> db_session.destroy() 
     31>>> db_session.exists(db_session.session_key) 
     32False 
     33>>> db_session.exists(prev_key) 
     34False 
     35>>> db_session.session_key == prev_key 
     36False 
     37>>> len(db_session.session_key) 
     3832 
     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) 
     46True 
    2547 
    2648>>> file_session = FileSession() 
    2749>>> file_session.modified 
     
    3961>>> file_session.delete(file_session.session_key) 
    4062>>> file_session.exists(file_session.session_key) 
    4163False 
     64>>> file_session['foo'] = 'bar' 
     65>>> file_session.save() 
     66>>> file_session.exists(file_session.session_key) 
     67True 
     68>>> prev_key = file_session.session_key 
     69>>> file_session.destroy() 
     70>>> file_session.exists(file_session.session_key) 
     71False 
     72>>> file_session.exists(prev_key) 
     73False 
     74>>> file_session.session_key == prev_key 
     75False 
     76>>> len(file_session.session_key) 
     7732 
     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) 
     85True 
    4286 
    4387# Make sure the file backend checks for a good storage dir 
    4488>>> settings.SESSION_FILE_PATH = "/if/this/directory/exists/you/have/a/weird/computer" 
     
    61105>>> cache_session.delete(cache_session.session_key) 
    62106>>> cache_session.exists(cache_session.session_key) 
    63107False 
     108>>> cache_session['foo'] = 'bar' 
     109>>> cache_session.save() 
     110>>> cache_session.exists(cache_session.session_key) 
     111True 
     112>>> prev_key = cache_session.session_key 
     113>>> cache_session.destroy() 
     114>>> cache_session.exists(cache_session.session_key) 
     115False 
     116>>> cache_session.exists(prev_key) 
     117False 
     118>>> cache_session.session_key == prev_key 
     119False 
     120>>> len(cache_session.session_key) 
     12132 
     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) 
     129True 
    64130 
    65131>>> s = SessionBase() 
    66132>>> s._session['some key'] = 'exists' # Pre-populate the session with some data 
     
    147213>>> list(i) 
    148214[('x', 1)] 
    149215 
    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) 
    151225 
     226 
    152227######################### 
    153228# Custom session expiry # 
    154229######################### 
  • django/contrib/sessions/backends/base.py

    old new  
    2525        self._session_key = session_key 
    2626        self.accessed = False 
    2727        self.modified = False 
     28        self.destroyed = False 
    2829 
    2930    def __contains__(self, key): 
    3031        return key in self._session 
     
    5354        self.modified = self.modified or key in self._session 
    5455        return self._session.pop(key, *args) 
    5556 
     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 
    5674    def setdefault(self, key, value): 
    5775        if key in self._session: 
    5876            return self._session[key] 
     
    107125    def iteritems(self): 
    108126        return self._session.iteritems() 
    109127 
    110     def _get_new_session_key(self): 
     128    def _get_new_session_key(self, safe=False): 
    111129        "Returns session key that isn't being used." 
    112130        # The random module is seeded when this Apache child is created. 
    113131        # Use settings.SECRET_KEY as added salt. 
     
    119137        while 1: 
    120138            session_key = md5.new("%s%s%s%s" % (random.randint(0, sys.maxint - 1), 
    121139                                  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 
    124151        return session_key 
    125152 
    126153    def _get_session_key(self): 
  • docs/sessions.txt

    old new  
    106106 
    107107    * ``setdefault()`` (**New in Django development version**) 
    108108 
     109    * ``clear()`` (**New in Django development version**) 
     110 
    109111It also has these methods: 
    110112 
     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 
    111121    * ``set_test_cookie()`` 
    112122 
    113123      Sets a test cookie to determine whether the user's browser supports