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:
parent
39f28512b9
commit
8c442f21dc
|
@ -1,9 +1,8 @@
|
||||||
import time
|
import time
|
||||||
import datetime
|
|
||||||
from email.Utils import formatdate
|
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.utils.cache import patch_vary_headers
|
from django.utils.cache import patch_vary_headers
|
||||||
|
from django.utils.http import cookie_date
|
||||||
|
|
||||||
TEST_COOKIE_NAME = 'testcookie'
|
TEST_COOKIE_NAME = 'testcookie'
|
||||||
TEST_COOKIE_VALUE = 'worked'
|
TEST_COOKIE_VALUE = 'worked'
|
||||||
|
@ -32,13 +31,8 @@ class SessionMiddleware(object):
|
||||||
expires = None
|
expires = None
|
||||||
else:
|
else:
|
||||||
max_age = settings.SESSION_COOKIE_AGE
|
max_age = settings.SESSION_COOKIE_AGE
|
||||||
rfcdate = formatdate(time.time() + settings.SESSION_COOKIE_AGE)
|
expires_time = time.time() + settings.SESSION_COOKIE_AGE
|
||||||
|
expires = cookie_date(expires_time)
|
||||||
# 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")
|
|
||||||
|
|
||||||
# Save the seesion data and refresh the client cookie.
|
# Save the seesion data and refresh the client cookie.
|
||||||
request.session.save()
|
request.session.save()
|
||||||
response.set_cookie(settings.SESSION_COOKIE_NAME,
|
response.set_cookie(settings.SESSION_COOKIE_NAME,
|
||||||
|
|
|
@ -9,14 +9,14 @@ been reviewed for security issues. Don't use it for production use.
|
||||||
|
|
||||||
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
|
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
|
||||||
from types import ListType, StringType
|
from types import ListType, StringType
|
||||||
from email.Utils import formatdate
|
|
||||||
import mimetypes
|
import mimetypes
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import time
|
|
||||||
import urllib
|
import urllib
|
||||||
|
|
||||||
|
from django.utils.http import http_date
|
||||||
|
|
||||||
__version__ = "0.1"
|
__version__ = "0.1"
|
||||||
__all__ = ['WSGIServer','WSGIRequestHandler','demo_app']
|
__all__ = ['WSGIServer','WSGIRequestHandler','demo_app']
|
||||||
|
|
||||||
|
@ -376,7 +376,7 @@ class ServerHandler(object):
|
||||||
self._write('HTTP/%s %s\r\n' % (self.http_version,self.status))
|
self._write('HTTP/%s %s\r\n' % (self.http_version,self.status))
|
||||||
if 'Date' not in self.headers:
|
if 'Date' not in self.headers:
|
||||||
self._write(
|
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:
|
if self.server_software and 'Server' not in self.headers:
|
||||||
self._write('Server: %s\r\n' % self.server_software)
|
self._write('Server: %s\r\n' % self.server_software)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from email.Utils import formatdate
|
from django.utils.http import http_date
|
||||||
|
|
||||||
class ConditionalGetMiddleware(object):
|
class ConditionalGetMiddleware(object):
|
||||||
"""
|
"""
|
||||||
|
@ -11,7 +11,7 @@ class ConditionalGetMiddleware(object):
|
||||||
Also sets the Date and Content-Length response-headers.
|
Also sets the Date and Content-Length response-headers.
|
||||||
"""
|
"""
|
||||||
def process_response(self, request, response):
|
def process_response(self, request, response):
|
||||||
response['Date'] = formatdate()[:26] + "GMT"
|
response['Date'] = http_date()
|
||||||
if not response.has_header('Content-Length'):
|
if not response.has_header('Content-Length'):
|
||||||
response['Content-Length'] = str(len(response.content))
|
response['Content-Length'] = str(len(response.content))
|
||||||
|
|
||||||
|
|
|
@ -20,11 +20,11 @@ An example: i18n middleware would need to distinguish caches by the
|
||||||
import md5
|
import md5
|
||||||
import re
|
import re
|
||||||
import time
|
import time
|
||||||
from email.Utils import formatdate
|
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
from django.utils.encoding import smart_str, iri_to_uri
|
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*')
|
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'):
|
if not response.has_header('ETag'):
|
||||||
response['ETag'] = md5.new(response.content).hexdigest()
|
response['ETag'] = md5.new(response.content).hexdigest()
|
||||||
if not response.has_header('Last-Modified'):
|
if not response.has_header('Last-Modified'):
|
||||||
response['Last-Modified'] = formatdate()[:26] + "GMT"
|
response['Last-Modified'] = http_date()
|
||||||
if not response.has_header('Expires'):
|
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)
|
patch_cache_control(response, max_age=cache_timeout)
|
||||||
|
|
||||||
def add_never_cache_headers(response):
|
def add_never_cache_headers(response):
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
import urllib
|
import urllib
|
||||||
|
from email.Utils import formatdate
|
||||||
|
|
||||||
from django.utils.encoding import smart_str, force_unicode
|
from django.utils.encoding import smart_str, force_unicode
|
||||||
from django.utils.functional import allow_lazy
|
from django.utils.functional import allow_lazy
|
||||||
|
|
||||||
|
@ -37,3 +39,29 @@ def urlencode(query, doseq=0):
|
||||||
for k, v in query],
|
for k, v in query],
|
||||||
doseq)
|
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]
|
||||||
|
|
|
@ -7,13 +7,14 @@ import mimetypes
|
||||||
import os
|
import os
|
||||||
import posixpath
|
import posixpath
|
||||||
import re
|
import re
|
||||||
import rfc822
|
|
||||||
import stat
|
import stat
|
||||||
import urllib
|
import urllib
|
||||||
|
from email.Utils import parsedate_tz, mktime_tz
|
||||||
|
|
||||||
from django.template import loader
|
from django.template import loader
|
||||||
from django.http import Http404, HttpResponse, HttpResponseRedirect, HttpResponseNotModified
|
from django.http import Http404, HttpResponse, HttpResponseRedirect, HttpResponseNotModified
|
||||||
from django.template import Template, Context, TemplateDoesNotExist
|
from django.template import Template, Context, TemplateDoesNotExist
|
||||||
|
from django.utils.http import http_date
|
||||||
|
|
||||||
def serve(request, path, document_root=None, show_indexes=False):
|
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]
|
mimetype = mimetypes.guess_type(fullpath)[0]
|
||||||
contents = open(fullpath, 'rb').read()
|
contents = open(fullpath, 'rb').read()
|
||||||
response = HttpResponse(contents, mimetype=mimetype)
|
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
|
return response
|
||||||
|
|
||||||
DEFAULT_DIRECTORY_INDEX_TEMPLATE = """
|
DEFAULT_DIRECTORY_INDEX_TEMPLATE = """
|
||||||
|
@ -119,8 +120,7 @@ def was_modified_since(header=None, mtime=0, size=0):
|
||||||
raise ValueError
|
raise ValueError
|
||||||
matches = re.match(r"^([^;]+)(; length=([0-9]+))?$", header,
|
matches = re.match(r"^([^;]+)(; length=([0-9]+))?$", header,
|
||||||
re.IGNORECASE)
|
re.IGNORECASE)
|
||||||
header_mtime = rfc822.mktime_tz(rfc822.parsedate_tz(
|
header_mtime = mktime_tz(parsedate_tz(matches.group(1)))
|
||||||
matches.group(1)))
|
|
||||||
header_len = matches.group(3)
|
header_len = matches.group(3)
|
||||||
if header_len and int(header_len) != size:
|
if header_len and int(header_len) != size:
|
||||||
raise ValueError
|
raise ValueError
|
||||||
|
|
|
@ -27,6 +27,14 @@ u'Paris+%26+Orl%C3%A9ans'
|
||||||
>>> urlquote_plus(u'Paris & Orl\xe9ans', safe="&")
|
>>> urlquote_plus(u'Paris & Orl\xe9ans', safe="&")
|
||||||
u'Paris+&+Orl%C3%A9ans'
|
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 ###########################################################
|
### iri_to_uri ###########################################################
|
||||||
>>> from django.utils.encoding import iri_to_uri
|
>>> from django.utils.encoding import iri_to_uri
|
||||||
>>> iri_to_uri(u'red%09ros\xe9#red')
|
>>> iri_to_uri(u'red%09ros\xe9#red')
|
||||||
|
|
Loading…
Reference in New Issue