Skip to content

Commit

Permalink
Fixed #15863 - SimpleCookies are not correctly serialized with the fi…
Browse files Browse the repository at this point in the history
…le or database cache backends

Thanks to rakuco for the report and for the tests.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@17200 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information
spookylukey committed Dec 11, 2011
1 parent 58276bd commit a935d43
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 0 deletions.
11 changes: 11 additions & 0 deletions django/http/__init__.py
Expand Up @@ -587,6 +587,17 @@ def __delitem__(self, header):
def __getitem__(self, header):
return self._headers[header.lower()][1]

def __getstate__(self):
# SimpleCookie is not pickeable with pickle.HIGHEST_PROTOCOL, so we
# serialise to a string instead
state = self.__dict__.copy()
state['cookies'] = str(state['cookies'])
return state

def __setstate__(self, state):
self.__dict__.update(state)
self.cookies = SimpleCookie(self.cookies)

def has_header(self, header):
"""Case-insensitive check for a header."""
return header.lower() in self._headers
Expand Down
40 changes: 40 additions & 0 deletions tests/regressiontests/cache/tests.py
Expand Up @@ -176,6 +176,17 @@ def test_decr_version(self):
class BaseCacheTests(object):
# A common set of tests to apply to all cache backends

def _get_request_cache(self, path):
request = HttpRequest()
request.META = {
'SERVER_NAME': 'testserver',
'SERVER_PORT': 80,
}
request.path = request.path_info = path
request._cache_update_cache = True
request.method = 'GET'
return request

def test_simple(self):
# Simple cache set/get works
self.cache.set("key", "value")
Expand Down Expand Up @@ -741,6 +752,35 @@ def test_custom_key_func(self):
self.assertEqual(self.custom_key_cache2.get('answer2'), 42)


def test_cache_write_unpickable_object(self):
update_middleware = UpdateCacheMiddleware()
update_middleware.cache = self.cache

fetch_middleware = FetchFromCacheMiddleware()
fetch_middleware.cache = self.cache

request = self._get_request_cache('/cache/test')
get_cache_data = FetchFromCacheMiddleware().process_request(request)
self.assertEqual(get_cache_data, None)

response = HttpResponse()
content = 'Testing cookie serialization.'
response.content = content
response.set_cookie('foo', 'bar')

update_middleware.process_response(request, response)

get_cache_data = fetch_middleware.process_request(request)
self.assertNotEqual(get_cache_data, None)
self.assertEqual(get_cache_data.content, content)
self.assertEqual(get_cache_data.cookies, response.cookies)

update_middleware.process_response(request, get_cache_data)
get_cache_data = fetch_middleware.process_request(request)
self.assertNotEqual(get_cache_data, None)
self.assertEqual(get_cache_data.content, content)
self.assertEqual(get_cache_data.cookies, response.cookies)

def custom_key_func(key, key_prefix, version):
"A customized cache key function"
return 'CUSTOM-' + '-'.join([key_prefix, str(version), key])
Expand Down

0 comments on commit a935d43

Please sign in to comment.