Skip to content

Commit 5dd9a2a

Browse files
committed
Fixed #4199 -- Changed date formatting in HTTP expires header to be spec
compliant. Thanks, Chris Bennett. git-svn-id: http://code.djangoproject.com/svn/django/trunk@5712 bcc190cf-cafb-0310-a4f2-bffc1f526a37
1 parent d5129ee commit 5dd9a2a

File tree

5 files changed

+28
-15
lines changed

5 files changed

+28
-15
lines changed

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ answer newbie questions, and generally made Django that much better:
5757
Ned Batchelder <http://www.nedbatchelder.com/>
5858
Shannon -jj Behrens <http://jjinux.blogspot.com/>
5959
Esdras Beleza <linux@esdrasbeleza.com>
60+
Chris Bennett <chrisrbennett@yahoo.com>
6061
James Bennett
6162
Ben <afternoon@uk2.net>
6263
Paul Bissex <http://e-scribe.com/>

django/contrib/sessions/middleware.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
from django.contrib.sessions.models import Session
33
from django.core.exceptions import SuspiciousOperation
44
from django.utils.cache import patch_vary_headers
5+
from email.Utils import formatdate
56
import datetime
7+
import time
68

79
TEST_COOKIE_NAME = 'testcookie'
810
TEST_COOKIE_VALUE = 'worked'
@@ -37,7 +39,7 @@ def get(self, key, default=None):
3739
return self._session.get(key, default)
3840

3941
def pop(self, key, *args):
40-
self.modified = self.modified or key in self._session
42+
self.modified = self.modified or key in self._session
4143
return self._session.pop(key, *args)
4244

4345
def set_test_cookie(self):
@@ -98,7 +100,11 @@ def process_response(self, request, response):
98100
expires = None
99101
else:
100102
max_age = settings.SESSION_COOKIE_AGE
101-
expires = datetime.datetime.strftime(datetime.datetime.utcnow() + datetime.timedelta(seconds=settings.SESSION_COOKIE_AGE), "%a, %d-%b-%Y %H:%M:%S GMT")
103+
rfcdate = formatdate(time.time() + settings.SESSION_COOKIE_AGE)
104+
# Fixed length date must have '-' separation in the format
105+
# DD-MMM-YYYY for compliance with Netscape cookie standard
106+
expires = (rfcdate[:7] + "-" + rfcdate[8:11]
107+
+ "-" + rfcdate[12:26] + "GMT")
102108
new_session = Session.objects.save(session_key, request.session._session,
103109
datetime.datetime.now() + datetime.timedelta(seconds=settings.SESSION_COOKIE_AGE))
104110
response.set_cookie(settings.SESSION_COOKIE_NAME, session_key,

django/core/servers/basehttp.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,13 @@
99

1010
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
1111
from types import ListType, StringType
12-
import os, re, sys, time, urllib, mimetypes
12+
from email.Utils import formatdate
13+
import mimetypes
14+
import os
15+
import re
16+
import sys
17+
import time
18+
import urllib
1319

1420
__version__ = "0.1"
1521
__all__ = ['WSGIServer','WSGIRequestHandler','demo_app']
@@ -370,7 +376,7 @@ def send_preamble(self):
370376
self._write('HTTP/%s %s\r\n' % (self.http_version,self.status))
371377
if 'Date' not in self.headers:
372378
self._write(
373-
'Date: %s\r\n' % time.asctime(time.gmtime(time.time()))
379+
'Date: %s\r\n' % formatdate()[:26] + "GMT"
374380
)
375381
if self.server_software and 'Server' not in self.headers:
376382
self._write('Server: %s\r\n' % self.server_software)

django/middleware/http.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import datetime
1+
from email.Utils import formatdate
22

33
class ConditionalGetMiddleware(object):
44
"""
@@ -11,8 +11,7 @@ class ConditionalGetMiddleware(object):
1111
Also sets the Date and Content-Length response-headers.
1212
"""
1313
def process_response(self, request, response):
14-
now = datetime.datetime.utcnow()
15-
response['Date'] = now.strftime('%a, %d %b %Y %H:%M:%S GMT')
14+
response['Date'] = formatdate()[:26] + "GMT"
1615
if not response.has_header('Content-Length'):
1716
response['Content-Length'] = str(len(response.content))
1817

django/utils/cache.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@
1717
"Accept-language" header.
1818
"""
1919

20-
import datetime, md5, re
20+
import md5
21+
import re
22+
import time
23+
from email.Utils import formatdate
2124
from django.conf import settings
2225
from django.core.cache import cache
2326
from django.utils.encoding import smart_str
@@ -44,7 +47,7 @@ def dictitem(s):
4447
return (t[0].lower().replace('-', '_'), True)
4548

4649
def dictvalue(t):
47-
if t[1] == True:
50+
if t[1] is True:
4851
return t[0]
4952
else:
5053
return t[0] + '=' + smart_str(t[1])
@@ -73,16 +76,14 @@ def patch_response_headers(response, cache_timeout=None):
7376
"""
7477
if cache_timeout is None:
7578
cache_timeout = settings.CACHE_MIDDLEWARE_SECONDS
76-
now = datetime.datetime.utcnow()
79+
if cache_timeout < 0:
80+
cache_timeout = 0 # Can't have max-age negative
7781
if not response.has_header('ETag'):
7882
response['ETag'] = md5.new(response.content).hexdigest()
7983
if not response.has_header('Last-Modified'):
80-
response['Last-Modified'] = now.strftime('%a, %d %b %Y %H:%M:%S GMT')
84+
response['Last-Modified'] = formatdate()[:26] + "GMT"
8185
if not response.has_header('Expires'):
82-
expires = now + datetime.timedelta(0, cache_timeout)
83-
response['Expires'] = expires.strftime('%a, %d %b %Y %H:%M:%S GMT')
84-
if cache_timeout < 0:
85-
cache_timeout = 0 # Can't have max-age negative
86+
response['Expires'] = formatdate(time.time() + cache_timeout)[:26] + "GMT"
8687
patch_cache_control(response, max_age=cache_timeout)
8788

8889
def add_never_cache_headers(response):

0 commit comments

Comments
 (0)