Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Reduced the chances of session object collision. The window of opport…

…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...
commit 29aa31d8f5dd10ed30e539bebc17735e3b4ae89c 1 parent 3f3f51d
Malcolm Tredinnick authored March 22, 2007
7  django/contrib/sessions/middleware.py
@@ -83,7 +83,12 @@ def process_response(self, request, response):
83 83
             if accessed:
84 84
                 patch_vary_headers(response, ('Cookie',))
85 85
             if modified or settings.SESSION_SAVE_EVERY_REQUEST:
86  
-                session_key = request.session.session_key or Session.objects.get_new_session_key()
  86
+                if request.session.session_key:
  87
+                    session_key = request.session.session_key
  88
+                else:
  89
+                    obj = Session.objects.get_new_session_object()
  90
+                    session_key = obj.session_key
  91
+
87 92
                 if settings.SESSION_EXPIRE_AT_BROWSER_CLOSE:
88 93
                     max_age = None
89 94
                     expires = None
19  django/contrib/sessions/models.py
... ...
@@ -1,4 +1,4 @@
1  
-import base64, md5, random, sys
  1
+import base64, md5, random, sys, datetime
2 2
 import cPickle as pickle
3 3
 from django.db import models
4 4
 from django.utils.translation import gettext_lazy as _
@@ -23,6 +23,23 @@ def get_new_session_key(self):
23 23
                 break
24 24
         return session_key
25 25
 
  26
+    def get_new_session_object(self):
  27
+        """
  28
+        Returns a new session object.
  29
+        """
  30
+        # FIXME: There is a *small* chance of collision here, meaning we will
  31
+        # return an existing object. That can be fixed when we add a way to
  32
+        # validate (and guarantee) that non-auto primary keys are unique. For
  33
+        # now, we save immediately in order to reduce the "window of
  34
+        # misfortune" as much as possible.
  35
+        created = False
  36
+        while not created:
  37
+            obj, created = self.get_or_create(session_key=self.get_new_session_key(),
  38
+                    expire_date = datetime.datetime.now())
  39
+            # Collision in key generation, so re-seed the generator
  40
+            random.seed()
  41
+        return obj
  42
+
26 43
     def save(self, session_key, session_dict, expire_date):
27 44
         s = self.model(session_key, self.encode(session_dict), expire_date)
28 45
         if session_dict:

0 notes on commit 29aa31d

Please sign in to comment.
Something went wrong with that request. Please try again.