You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

79 lines
2.6 KiB

  1. from django.conf import settings
  2. from django.contrib.sessions.backends.base import CreateError, SessionBase
  3. from django.core.cache import caches
  4. from django.utils.six.moves import range
  5. KEY_PREFIX = "django.contrib.sessions.cache"
  6. class SessionStore(SessionBase):
  7. """
  8. A cache-based session store.
  9. """
  10. cache_key_prefix = KEY_PREFIX
  11. def __init__(self, session_key=None):
  12. self._cache = caches[settings.SESSION_CACHE_ALIAS]
  13. super(SessionStore, self).__init__(session_key)
  14. @property
  15. def cache_key(self):
  16. return self.cache_key_prefix + self._get_or_create_session_key()
  17. def load(self):
  18. try:
  19. session_data = self._cache.get(self.cache_key)
  20. except Exception:
  21. # Some backends (e.g. memcache) raise an exception on invalid
  22. # cache keys. If this happens, reset the session. See #17810.
  23. session_data = None
  24. if session_data is not None:
  25. return session_data
  26. self._session_key = None
  27. return {}
  28. def create(self):
  29. # Because a cache can fail silently (e.g. memcache), we don't know if
  30. # we are failing to create a new session because of a key collision or
  31. # because the cache is missing. So we try for a (large) number of times
  32. # and then raise an exception. That's the risk you shoulder if using
  33. # cache backing.
  34. for i in range(10000):
  35. self._session_key = self._get_new_session_key()
  36. try:
  37. self.save(must_create=True)
  38. except CreateError:
  39. continue
  40. self.modified = True
  41. return
  42. raise RuntimeError(
  43. "Unable to create a new session key. "
  44. "It is likely that the cache is unavailable.")
  45. def save(self, must_create=False):
  46. if self.session_key is None:
  47. return self.create()
  48. if must_create:
  49. func = self._cache.add
  50. else:
  51. func = self._cache.set
  52. result = func(self.cache_key,
  53. self._get_session(no_load=must_create),
  54. self.get_expiry_age())
  55. if must_create and not result:
  56. raise CreateError
  57. def exists(self, session_key):
  58. return session_key and (self.cache_key_prefix + session_key) in self._cache
  59. def delete(self, session_key=None):
  60. if session_key is None:
  61. if self.session_key is None:
  62. return
  63. session_key = self.session_key
  64. self._cache.delete(self.cache_key_prefix + session_key)
  65. @classmethod
  66. def clear_expired(cls):
  67. pass