Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #17931 -- Accepted aware datetimes to set cookies expiry dates.…

… Thanks jaddison for the report.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@17766 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit c8e2f7591d6ea3545aeb32fa4c92cbeb9a622546 1 parent c7cc4cf
Aymeric Augustin authored March 18, 2012
12  django/http/__init__.py
@@ -121,6 +121,7 @@ def __init__(self, *args, **kwargs):
121 121
 from django.utils.datastructures import MultiValueDict, ImmutableList
122 122
 from django.utils.encoding import smart_str, iri_to_uri, force_unicode
123 123
 from django.utils.http import cookie_date
  124
+from django.utils import timezone
124 125
 
125 126
 RESERVED_CHARS="!*'();:@&=+$,/?%#[]"
126 127
 
@@ -641,13 +642,18 @@ def set_cookie(self, key, value='', max_age=None, expires=None, path='/',
641 642
         """
642 643
         Sets a cookie.
643 644
 
644  
-        ``expires`` can be a string in the correct format or a
645  
-        ``datetime.datetime`` object in UTC. If ``expires`` is a datetime
646  
-        object then ``max_age`` will be calculated.
  645
+        ``expires`` can be:
  646
+        - a string in the correct format,
  647
+        - a naive ``datetime.datetime`` object in UTC,
  648
+        - an aware ``datetime.datetime`` object in any time zone.
  649
+        If it is a ``datetime.datetime`` object then ``max_age`` will be calculated.
  650
+
647 651
         """
648 652
         self.cookies[key] = value
649 653
         if expires is not None:
650 654
             if isinstance(expires, datetime.datetime):
  655
+                if timezone.is_aware(expires):
  656
+                    expires = timezone.make_naive(expires, timezone.utc)
651 657
                 delta = expires - expires.utcnow()
652 658
                 # Add one second so the date matches exactly (a fraction of
653 659
                 # time gets lost between converting to a timedelta and
10  tests/regressiontests/requests/tests.py
@@ -12,6 +12,7 @@
12 12
 from django.test.utils import get_warnings_state, restore_warnings_state
13 13
 from django.utils import unittest
14 14
 from django.utils.http import cookie_date
  15
+from django.utils.timezone import utc
15 16
 
16 17
 
17 18
 class RequestsTests(unittest.TestCase):
@@ -207,6 +208,15 @@ def test_near_expiration(self):
207 208
         datetime_cookie = response.cookies['datetime']
208 209
         self.assertEqual(datetime_cookie['max-age'], 10)
209 210
 
  211
+    def test_aware_expiration(self):
  212
+        "Cookie accepts an aware datetime as expiration time"
  213
+        response = HttpResponse()
  214
+        expires = (datetime.utcnow() + timedelta(seconds=10)).replace(tzinfo=utc)
  215
+        time.sleep(0.001)
  216
+        response.set_cookie('datetime', expires=expires)
  217
+        datetime_cookie = response.cookies['datetime']
  218
+        self.assertEqual(datetime_cookie['max-age'], 10)
  219
+
210 220
     def test_far_expiration(self):
211 221
         "Cookie will expire when an distant expiration time is provided"
212 222
         response = HttpResponse()

0 notes on commit c8e2f75

Please sign in to comment.
Something went wrong with that request. Please try again.