Skip to content

Commit

Permalink
Reduced the chances of session object collision. The window of opport…
Browse files Browse the repository at this point in the history
…unity 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
  • Loading branch information
mtredinnick committed Mar 22, 2007
1 parent b2e903b commit 4d09863
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 2 deletions.
7 changes: 6 additions & 1 deletion django/contrib/sessions/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,12 @@ def process_response(self, request, response):
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
Expand Down
19 changes: 18 additions & 1 deletion django/contrib/sessions/models.py
Original file line number Diff line number Diff line change
@@ -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 _
Expand All @@ -23,6 +23,23 @@ def get_new_session_key(self):
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:
Expand Down

0 comments on commit 4d09863

Please sign in to comment.