From a935d436e9e11e1801ca5e9421a055e1f04eb125 Mon Sep 17 00:00:00 2001 From: Luke Plant Date: Sun, 11 Dec 2011 21:04:56 +0000 Subject: [PATCH] Fixed #15863 - SimpleCookies are not correctly serialized with the file 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 --- django/http/__init__.py | 11 ++++++++ tests/regressiontests/cache/tests.py | 40 ++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/django/http/__init__.py b/django/http/__init__.py index fee3f04cd3..476a62501c 100644 --- a/django/http/__init__.py +++ b/django/http/__init__.py @@ -587,6 +587,17 @@ class HttpResponse(object): 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 diff --git a/tests/regressiontests/cache/tests.py b/tests/regressiontests/cache/tests.py index 307588c4ea..779e3fedf8 100644 --- a/tests/regressiontests/cache/tests.py +++ b/tests/regressiontests/cache/tests.py @@ -176,6 +176,17 @@ class DummyCacheTests(unittest.TestCase): 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") @@ -741,6 +752,35 @@ class BaseCacheTests(object): 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])