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: if accessed:
patch_vary_headers(response, ('Cookie',)) patch_vary_headers(response, ('Cookie',))
if modified or settings.SESSION_SAVE_EVERY_REQUEST: 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: if settings.SESSION_EXPIRE_AT_BROWSER_CLOSE:
max_age = None max_age = None
expires = None expires = None

View File

@ -1,4 +1,4 @@
import base64, md5, random, sys import base64, md5, random, sys, datetime
import cPickle as pickle import cPickle as pickle
from django.db import models from django.db import models
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@ -23,6 +23,23 @@ class SessionManager(models.Manager):
break break
return session_key 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): def save(self, session_key, session_dict, expire_date):
s = self.model(session_key, self.encode(session_dict), expire_date) s = self.model(session_key, self.encode(session_dict), expire_date)
if session_dict: if session_dict: