Commit a935d436 authored by Luke Plant's avatar Luke Plant
Browse files

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
parent 58276bd3
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -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
+40 −0
Original line number Diff line number Diff line
@@ -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])