Reduced the chances of session object collision. The window of opportunity is

now about five Python instructions in get_or_create(). This doesn't guarantee
no collisions, but should fix many occurrences. Refs #1180.


git-svn-id: http://code.djangoproject.com/svn/django/trunk@4771 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Malcolm Tredinnick 2007-03-22 02:20:33 +00:00
parent 3f3f51d942
commit 29aa31d8f5
2 changed files with 24 additions and 2 deletions

View File

@ -83,7 +83,12 @@ class SessionMiddleware(object):
if accessed:
patch_vary_headers(response, ('Cookie',))
if modified or settings.SESSION_SAVE_EVERY_REQUEST:
session_key = request.session.session_key or Session.objects.get_new_session_key()
if request.session.session_key:
session_key = request.session.session_key
else:
obj = Session.objects.get_new_session_object()
session_key = obj.session_key
if settings.SESSION_EXPIRE_AT_BROWSER_CLOSE:
max_age = None
expires = None

View File

@ -1,4 +1,4 @@
import base64, md5, random, sys
import base64, md5, random, sys, datetime
import cPickle as pickle
from django.db import models
from django.utils.translation import gettext_lazy as _
@ -23,6 +23,23 @@ class SessionManager(models.Manager):
break
return session_key
def get_new_session_object(self):
"""
Returns a new session object.
"""
# FIXME: There is a *small* chance of collision here, meaning we will
# return an existing object. That can be fixed when we add a way to
# validate (and guarantee) that non-auto primary keys are unique. For
# now, we save immediately in order to reduce the "window of
# misfortune" as much as possible.
created = False
while not created:
obj, created = self.get_or_create(session_key=self.get_new_session_key(),
expire_date = datetime.datetime.now())
# Collision in key generation, so re-seed the generator
random.seed()
return obj
def save(self, session_key, session_dict, expire_date):
s = self.model(session_key, self.encode(session_dict), expire_date)
if session_dict: