diff --git a/django/http/__init__.py b/django/http/__init__.py index fee3f04cd34c3..476a62501c1a4 100644 --- a/django/http/__init__.py +++ b/django/http/__init__.py @@ -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 diff --git a/tests/regressiontests/cache/tests.py b/tests/regressiontests/cache/tests.py index 307588c4ead30..779e3fedf8a63 100644 --- a/tests/regressiontests/cache/tests.py +++ b/tests/regressiontests/cache/tests.py @@ -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") @@ -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])