Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #5816 -- Fixed a regression from [6333] that generates incorrec…

…t cookie "expires" dates when using a locale other than English. Introduced `http_date` and `cookie_date` utility functions. Thanks for the report Michael Lemaire. Thanks for the patch Karen Tracey and `SmileyChris`.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@6634 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 8c442f21dc7079a880eb626d20b84fc090563dff 1 parent 39f2851
Gary Wilson Jr. authored October 31, 2007
12  django/contrib/sessions/middleware.py
... ...
@@ -1,9 +1,8 @@
1 1
 import time
2  
-import datetime
3  
-from email.Utils import formatdate
4 2
 
5 3
 from django.conf import settings
6 4
 from django.utils.cache import patch_vary_headers
  5
+from django.utils.http import cookie_date
7 6
 
8 7
 TEST_COOKIE_NAME = 'testcookie'
9 8
 TEST_COOKIE_VALUE = 'worked'
@@ -32,13 +31,8 @@ def process_response(self, request, response):
32 31
                     expires = None
33 32
                 else:
34 33
                     max_age = settings.SESSION_COOKIE_AGE
35  
-                    rfcdate = formatdate(time.time() + settings.SESSION_COOKIE_AGE)
36  
-
37  
-                    # Fixed length date must have '-' separation in the format
38  
-                    # DD-MMM-YYYY for compliance with Netscape cookie standard
39  
-                    expires = datetime.datetime.strftime(datetime.datetime.utcnow() + \
40  
-                              datetime.timedelta(seconds=settings.SESSION_COOKIE_AGE), "%a, %d-%b-%Y %H:%M:%S GMT")
41  
-
  34
+                    expires_time = time.time() + settings.SESSION_COOKIE_AGE
  35
+                    expires = cookie_date(expires_time)
42 36
                 # Save the seesion data and refresh the client cookie.
43 37
                 request.session.save()
44 38
                 response.set_cookie(settings.SESSION_COOKIE_NAME,
6  django/core/servers/basehttp.py
@@ -9,14 +9,14 @@
9 9
 
10 10
 from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
11 11
 from types import ListType, StringType
12  
-from email.Utils import formatdate
13 12
 import mimetypes
14 13
 import os
15 14
 import re
16 15
 import sys
17  
-import time
18 16
 import urllib
19 17
 
  18
+from django.utils.http import http_date
  19
+
20 20
 __version__ = "0.1"
21 21
 __all__ = ['WSGIServer','WSGIRequestHandler','demo_app']
22 22
 
@@ -376,7 +376,7 @@ def send_preamble(self):
376 376
                 self._write('HTTP/%s %s\r\n' % (self.http_version,self.status))
377 377
                 if 'Date' not in self.headers:
378 378
                     self._write(
379  
-                        'Date: %s\r\n' % (formatdate()[:26] + "GMT")
  379
+                        'Date: %s\r\n' % http_date()
380 380
                     )
381 381
                 if self.server_software and 'Server' not in self.headers:
382 382
                     self._write('Server: %s\r\n' % self.server_software)
4  django/middleware/http.py
... ...
@@ -1,4 +1,4 @@
1  
-from email.Utils import formatdate
  1
+from django.utils.http import http_date
2 2
 
3 3
 class ConditionalGetMiddleware(object):
4 4
     """
@@ -11,7 +11,7 @@ class ConditionalGetMiddleware(object):
11 11
     Also sets the Date and Content-Length response-headers.
12 12
     """
13 13
     def process_response(self, request, response):
14  
-        response['Date'] = formatdate()[:26] + "GMT"
  14
+        response['Date'] = http_date()
15 15
         if not response.has_header('Content-Length'):
16 16
             response['Content-Length'] = str(len(response.content))
17 17
 
6  django/utils/cache.py
@@ -20,11 +20,11 @@
20 20
 import md5
21 21
 import re
22 22
 import time
23  
-from email.Utils import formatdate
24 23
 
25 24
 from django.conf import settings
26 25
 from django.core.cache import cache
27 26
 from django.utils.encoding import smart_str, iri_to_uri
  27
+from django.utils.http import http_date
28 28
 
29 29
 cc_delim_re = re.compile(r'\s*,\s*')
30 30
 
@@ -89,9 +89,9 @@ def patch_response_headers(response, cache_timeout=None):
89 89
     if not response.has_header('ETag'):
90 90
         response['ETag'] = md5.new(response.content).hexdigest()
91 91
     if not response.has_header('Last-Modified'):
92  
-        response['Last-Modified'] = formatdate()[:26] + "GMT"
  92
+        response['Last-Modified'] = http_date()
93 93
     if not response.has_header('Expires'):
94  
-        response['Expires'] = formatdate(time.time() + cache_timeout)[:26] + "GMT"
  94
+        response['Expires'] = http_date(time.time() + cache_timeout)
95 95
     patch_cache_control(response, max_age=cache_timeout)
96 96
 
97 97
 def add_never_cache_headers(response):
28  django/utils/http.py
... ...
@@ -1,4 +1,6 @@
1 1
 import urllib
  2
+from email.Utils import formatdate
  3
+
2 4
 from django.utils.encoding import smart_str, force_unicode
3 5
 from django.utils.functional import allow_lazy
4 6
 
@@ -37,3 +39,29 @@ def urlencode(query, doseq=0):
37 39
             for k, v in query],
38 40
         doseq)
39 41
 
  42
+def cookie_date(epoch_seconds=None):
  43
+    """
  44
+    Formats the time to ensure compatibility with Netscape's cookie standard.
  45
+
  46
+    Accepts a floating point number expressed in seconds since the epoch, in
  47
+    UTC - such as that outputted by time.time(). If set to None, defaults to
  48
+    the current time.
  49
+
  50
+    Outputs a string in the format 'Wdy, DD-Mon-YYYY HH:MM:SS GMT'.
  51
+    """
  52
+    rfcdate = formatdate(epoch_seconds)
  53
+    return '%s-%s-%s GMT' % (rfcdate[:7], rfcdate[8:11], rfcdate[12:25])
  54
+
  55
+def http_date(epoch_seconds=None):
  56
+    """
  57
+    Formats the time to match the RFC1123 date format as specified by HTTP
  58
+    RFC2616 section 3.3.1.
  59
+
  60
+    Accepts a floating point number expressed in seconds since the epoch, in
  61
+    UTC - such as that outputted by time.time(). If set to None, defaults to
  62
+    the current time.
  63
+
  64
+    Outputs a string in the format 'Wdy, DD Mon YYYY HH:MM:SS GMT'.
  65
+    """
  66
+    rfcdate = formatdate(epoch_seconds)
  67
+    return '%s GMT' % rfcdate[:25]
8  django/views/static.py
@@ -7,13 +7,14 @@
7 7
 import os
8 8
 import posixpath
9 9
 import re
10  
-import rfc822
11 10
 import stat
12 11
 import urllib
  12
+from email.Utils import parsedate_tz, mktime_tz
13 13
 
14 14
 from django.template import loader
15 15
 from django.http import Http404, HttpResponse, HttpResponseRedirect, HttpResponseNotModified
16 16
 from django.template import Template, Context, TemplateDoesNotExist
  17
+from django.utils.http import http_date
17 18
 
18 19
 def serve(request, path, document_root=None, show_indexes=False):
19 20
     """
@@ -60,7 +61,7 @@ def serve(request, path, document_root=None, show_indexes=False):
60 61
     mimetype = mimetypes.guess_type(fullpath)[0]
61 62
     contents = open(fullpath, 'rb').read()
62 63
     response = HttpResponse(contents, mimetype=mimetype)
63  
-    response["Last-Modified"] = rfc822.formatdate(statobj[stat.ST_MTIME])
  64
+    response["Last-Modified"] = http_date(statobj[stat.ST_MTIME])
64 65
     return response
65 66
 
66 67
 DEFAULT_DIRECTORY_INDEX_TEMPLATE = """
@@ -119,8 +120,7 @@ def was_modified_since(header=None, mtime=0, size=0):
119 120
             raise ValueError
120 121
         matches = re.match(r"^([^;]+)(; length=([0-9]+))?$", header,
121 122
                            re.IGNORECASE)
122  
-        header_mtime = rfc822.mktime_tz(rfc822.parsedate_tz(
123  
-            matches.group(1)))
  123
+        header_mtime = mktime_tz(parsedate_tz(matches.group(1)))
124 124
         header_len = matches.group(3)
125 125
         if header_len and int(header_len) != size:
126 126
             raise ValueError
8  tests/regressiontests/text/tests.py
@@ -27,6 +27,14 @@
27 27
 >>> urlquote_plus(u'Paris & Orl\xe9ans', safe="&")
28 28
 u'Paris+&+Orl%C3%A9ans'
29 29
 
  30
+### cookie_date, http_date ###############################################
  31
+>>> from django.utils.http import cookie_date, http_date
  32
+>>> t = 1167616461.0
  33
+>>> cookie_date(t)
  34
+'Mon, 01-Jan-2007 01:54:21 GMT'
  35
+>>> http_date(t)
  36
+'Mon, 01 Jan 2007 01:54:21 GMT'
  37
+
30 38
 ### iri_to_uri ###########################################################
31 39
 >>> from django.utils.encoding import iri_to_uri
32 40
 >>> iri_to_uri(u'red%09ros\xe9#red')

0 notes on commit 8c442f2

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