From e6c5599494e5408c81b046d2b7410e9e4a98a7b5 Mon Sep 17 00:00:00 2001 From: Luke Plant Date: Sun, 24 Jan 2010 00:04:02 +0000 Subject: [PATCH] Reduced CookieStorage.max_cookie_size to 75% of 4K to be nice to Internet Explorer Internet Explorer, up to at least version 7, allows only 4K cookie data *per domain*, rather than per cookie, so we ensure that stored messages leave some room for other cookies. git-svn-id: http://code.djangoproject.com/svn/django/trunk@12287 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/contrib/messages/storage/cookie.py | 8 ++++++-- django/contrib/messages/tests/cookie.py | 12 +++++++++--- django/contrib/messages/tests/fallback.py | 4 +++- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/django/contrib/messages/storage/cookie.py b/django/contrib/messages/storage/cookie.py index 412d4195fc..48811a796d 100644 --- a/django/contrib/messages/storage/cookie.py +++ b/django/contrib/messages/storage/cookie.py @@ -1,10 +1,11 @@ import hmac from django.conf import settings -from django.utils.hashcompat import sha_hmac from django.contrib.messages import constants from django.contrib.messages.storage.base import BaseStorage, Message +from django.http import CompatCookie from django.utils import simplejson as json +from django.utils.hashcompat import sha_hmac class MessageEncoder(json.JSONEncoder): @@ -46,7 +47,10 @@ class CookieStorage(BaseStorage): Stores messages in a cookie. """ cookie_name = 'messages' - max_cookie_size = 4096 + # We should be able to store 4K in a cookie, but Internet Explorer + # imposes 4K as the *total* limit for a domain. To allow other + # cookies, we go for 3/4 of 4K. + max_cookie_size = 3072 not_finished = '__messagesnotfinished__' def _get(self, *args, **kwargs): diff --git a/django/contrib/messages/tests/cookie.py b/django/contrib/messages/tests/cookie.py index 0a0bca0568..9aadcf47b2 100644 --- a/django/contrib/messages/tests/cookie.py +++ b/django/contrib/messages/tests/cookie.py @@ -69,19 +69,25 @@ class CookieTest(BaseTest): storage = self.get_storage() response = self.get_response() + # When storing as a cookie, the cookie has constant overhead of approx + # 54 chars, and each message has a constant overhead of about 37 chars + # and a variable overhead of zero in the best case. We aim for a message + # size which will fit 4 messages into the cookie, but not 5. + # See also FallbackTest.test_session_fallback + msg_size = int((CookieStorage.max_cookie_size - 54) / 4.5 - 37) for i in range(5): - storage.add(constants.INFO, str(i) * 900) + storage.add(constants.INFO, str(i) * msg_size) unstored_messages = storage.update(response) cookie_storing = self.stored_messages_count(storage, response) self.assertEqual(cookie_storing, 4) self.assertEqual(len(unstored_messages), 1) - self.assert_(unstored_messages[0].message == '0' * 900) + self.assert_(unstored_messages[0].message == '0' * msg_size) def test_json_encoder_decoder(self): """ - Tests that an complex nested data structure containing Message + Tests that a complex nested data structure containing Message instances is properly encoded/decoded by the custom JSON encoder/decoder classes. """ diff --git a/django/contrib/messages/tests/fallback.py b/django/contrib/messages/tests/fallback.py index 794cfc4428..9e4f657877 100644 --- a/django/contrib/messages/tests/fallback.py +++ b/django/contrib/messages/tests/fallback.py @@ -147,8 +147,10 @@ class FallbackTest(BaseTest): storage = self.get_storage() response = self.get_response() + # see comment in CookieText.test_cookie_max_length + msg_size = int((CookieStorage.max_cookie_size - 54) / 4.5 - 37) for i in range(5): - storage.add(constants.INFO, str(i) * 900) + storage.add(constants.INFO, str(i) * msg_size) storage.update(response) cookie_storing = self.stored_cookie_messages_count(storage, response)