Fixed #5816 -- Fixed a regression from [6333] that generates incorrect 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
This commit is contained in:
Gary Wilson Jr 2007-10-31 03:59:40 +00:00
parent 39f28512b9
commit 8c442f21dc
7 changed files with 51 additions and 21 deletions

View File

@ -1,9 +1,8 @@
import time
import datetime
from email.Utils import formatdate
from django.conf import settings
from django.utils.cache import patch_vary_headers
from django.utils.http import cookie_date
TEST_COOKIE_NAME = 'testcookie'
TEST_COOKIE_VALUE = 'worked'
@ -32,13 +31,8 @@ class SessionMiddleware(object):
expires = None
else:
max_age = settings.SESSION_COOKIE_AGE
rfcdate = formatdate(time.time() + settings.SESSION_COOKIE_AGE)
# Fixed length date must have '-' separation in the format
# DD-MMM-YYYY for compliance with Netscape cookie standard
expires = datetime.datetime.strftime(datetime.datetime.utcnow() + \
datetime.timedelta(seconds=settings.SESSION_COOKIE_AGE), "%a, %d-%b-%Y %H:%M:%S GMT")
expires_time = time.time() + settings.SESSION_COOKIE_AGE
expires = cookie_date(expires_time)
# Save the seesion data and refresh the client cookie.
request.session.save()
response.set_cookie(settings.SESSION_COOKIE_NAME,

View File

@ -9,14 +9,14 @@ been reviewed for security issues. Don't use it for production use.
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from types import ListType, StringType
from email.Utils import formatdate
import mimetypes
import os
import re
import sys
import time
import urllib
from django.utils.http import http_date
__version__ = "0.1"
__all__ = ['WSGIServer','WSGIRequestHandler','demo_app']
@ -376,7 +376,7 @@ class ServerHandler(object):
self._write('HTTP/%s %s\r\n' % (self.http_version,self.status))
if 'Date' not in self.headers:
self._write(
'Date: %s\r\n' % (formatdate()[:26] + "GMT")
'Date: %s\r\n' % http_date()
)
if self.server_software and 'Server' not in self.headers:
self._write('Server: %s\r\n' % self.server_software)

View File

@ -1,4 +1,4 @@
from email.Utils import formatdate
from django.utils.http import http_date
class ConditionalGetMiddleware(object):
"""
@ -11,7 +11,7 @@ class ConditionalGetMiddleware(object):
Also sets the Date and Content-Length response-headers.
"""
def process_response(self, request, response):
response['Date'] = formatdate()[:26] + "GMT"
response['Date'] = http_date()
if not response.has_header('Content-Length'):
response['Content-Length'] = str(len(response.content))

View File

@ -20,11 +20,11 @@ An example: i18n middleware would need to distinguish caches by the
import md5
import re
import time
from email.Utils import formatdate
from django.conf import settings
from django.core.cache import cache
from django.utils.encoding import smart_str, iri_to_uri
from django.utils.http import http_date
cc_delim_re = re.compile(r'\s*,\s*')
@ -89,9 +89,9 @@ def patch_response_headers(response, cache_timeout=None):
if not response.has_header('ETag'):
response['ETag'] = md5.new(response.content).hexdigest()
if not response.has_header('Last-Modified'):
response['Last-Modified'] = formatdate()[:26] + "GMT"
response['Last-Modified'] = http_date()
if not response.has_header('Expires'):
response['Expires'] = formatdate(time.time() + cache_timeout)[:26] + "GMT"
response['Expires'] = http_date(time.time() + cache_timeout)
patch_cache_control(response, max_age=cache_timeout)
def add_never_cache_headers(response):

View File

@ -1,4 +1,6 @@
import urllib
from email.Utils import formatdate
from django.utils.encoding import smart_str, force_unicode
from django.utils.functional import allow_lazy
@ -37,3 +39,29 @@ def urlencode(query, doseq=0):
for k, v in query],
doseq)
def cookie_date(epoch_seconds=None):
"""
Formats the time to ensure compatibility with Netscape's cookie standard.
Accepts a floating point number expressed in seconds since the epoch, in
UTC - such as that outputted by time.time(). If set to None, defaults to
the current time.
Outputs a string in the format 'Wdy, DD-Mon-YYYY HH:MM:SS GMT'.
"""
rfcdate = formatdate(epoch_seconds)
return '%s-%s-%s GMT' % (rfcdate[:7], rfcdate[8:11], rfcdate[12:25])
def http_date(epoch_seconds=None):
"""
Formats the time to match the RFC1123 date format as specified by HTTP
RFC2616 section 3.3.1.
Accepts a floating point number expressed in seconds since the epoch, in
UTC - such as that outputted by time.time(). If set to None, defaults to
the current time.
Outputs a string in the format 'Wdy, DD Mon YYYY HH:MM:SS GMT'.
"""
rfcdate = formatdate(epoch_seconds)
return '%s GMT' % rfcdate[:25]

View File

@ -7,13 +7,14 @@ import mimetypes
import os
import posixpath
import re
import rfc822
import stat
import urllib
from email.Utils import parsedate_tz, mktime_tz
from django.template import loader
from django.http import Http404, HttpResponse, HttpResponseRedirect, HttpResponseNotModified
from django.template import Template, Context, TemplateDoesNotExist
from django.utils.http import http_date
def serve(request, path, document_root=None, show_indexes=False):
"""
@ -60,7 +61,7 @@ def serve(request, path, document_root=None, show_indexes=False):
mimetype = mimetypes.guess_type(fullpath)[0]
contents = open(fullpath, 'rb').read()
response = HttpResponse(contents, mimetype=mimetype)
response["Last-Modified"] = rfc822.formatdate(statobj[stat.ST_MTIME])
response["Last-Modified"] = http_date(statobj[stat.ST_MTIME])
return response
DEFAULT_DIRECTORY_INDEX_TEMPLATE = """
@ -119,8 +120,7 @@ def was_modified_since(header=None, mtime=0, size=0):
raise ValueError
matches = re.match(r"^([^;]+)(; length=([0-9]+))?$", header,
re.IGNORECASE)
header_mtime = rfc822.mktime_tz(rfc822.parsedate_tz(
matches.group(1)))
header_mtime = mktime_tz(parsedate_tz(matches.group(1)))
header_len = matches.group(3)
if header_len and int(header_len) != size:
raise ValueError

View File

@ -27,6 +27,14 @@ u'Paris+%26+Orl%C3%A9ans'
>>> urlquote_plus(u'Paris & Orl\xe9ans', safe="&")
u'Paris+&+Orl%C3%A9ans'
### cookie_date, http_date ###############################################
>>> from django.utils.http import cookie_date, http_date
>>> t = 1167616461.0
>>> cookie_date(t)
'Mon, 01-Jan-2007 01:54:21 GMT'
>>> http_date(t)
'Mon, 01 Jan 2007 01:54:21 GMT'
### iri_to_uri ###########################################################
>>> from django.utils.encoding import iri_to_uri
>>> iri_to_uri(u'red%09ros\xe9#red')