Fixed #28965 -- Updated Set-Cookie's Expires date format to follow RFC 7231.
This commit is contained in:
parent
5f456408a0
commit
0afffae4ec
|
@ -6,7 +6,7 @@ from django.contrib.sessions.backends.base import UpdateError
|
||||||
from django.core.exceptions import SuspiciousOperation
|
from django.core.exceptions import SuspiciousOperation
|
||||||
from django.utils.cache import patch_vary_headers
|
from django.utils.cache import patch_vary_headers
|
||||||
from django.utils.deprecation import MiddlewareMixin
|
from django.utils.deprecation import MiddlewareMixin
|
||||||
from django.utils.http import cookie_date
|
from django.utils.http import http_date
|
||||||
|
|
||||||
|
|
||||||
class SessionMiddleware(MiddlewareMixin):
|
class SessionMiddleware(MiddlewareMixin):
|
||||||
|
@ -50,7 +50,7 @@ class SessionMiddleware(MiddlewareMixin):
|
||||||
else:
|
else:
|
||||||
max_age = request.session.get_expiry_age()
|
max_age = request.session.get_expiry_age()
|
||||||
expires_time = time.time() + max_age
|
expires_time = time.time() + max_age
|
||||||
expires = cookie_date(expires_time)
|
expires = http_date(expires_time)
|
||||||
# Save the session data and refresh the client cookie.
|
# Save the session data and refresh the client cookie.
|
||||||
# Skip session save for 500 responses, refs #3881.
|
# Skip session save for 500 responses, refs #3881.
|
||||||
if response.status_code != 500:
|
if response.status_code != 500:
|
||||||
|
|
|
@ -14,7 +14,7 @@ from django.core.serializers.json import DjangoJSONEncoder
|
||||||
from django.http.cookie import SimpleCookie
|
from django.http.cookie import SimpleCookie
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.utils.encoding import force_bytes, iri_to_uri
|
from django.utils.encoding import force_bytes, iri_to_uri
|
||||||
from django.utils.http import cookie_date
|
from django.utils.http import http_date
|
||||||
|
|
||||||
_charset_from_content_type_re = re.compile(r';\s*charset=(?P<charset>[^\s;]+)', re.I)
|
_charset_from_content_type_re = re.compile(r';\s*charset=(?P<charset>[^\s;]+)', re.I)
|
||||||
|
|
||||||
|
@ -185,8 +185,7 @@ class HttpResponseBase:
|
||||||
self.cookies[key]['max-age'] = max_age
|
self.cookies[key]['max-age'] = max_age
|
||||||
# IE requires expires, so set it if hasn't been already.
|
# IE requires expires, so set it if hasn't been already.
|
||||||
if not expires:
|
if not expires:
|
||||||
self.cookies[key]['expires'] = cookie_date(time.time() +
|
self.cookies[key]['expires'] = http_date(time.time() + max_age)
|
||||||
max_age)
|
|
||||||
if path is not None:
|
if path is not None:
|
||||||
self.cookies[key]['path'] = path
|
self.cookies[key]['path'] = path
|
||||||
if domain is not None:
|
if domain is not None:
|
||||||
|
@ -207,7 +206,7 @@ class HttpResponseBase:
|
||||||
|
|
||||||
def delete_cookie(self, key, path='/', domain=None):
|
def delete_cookie(self, key, path='/', domain=None):
|
||||||
self.set_cookie(key, max_age=0, path=path, domain=domain,
|
self.set_cookie(key, max_age=0, path=path, domain=domain,
|
||||||
expires='Thu, 01-Jan-1970 00:00:00 GMT')
|
expires='Thu, 01 Jan 1970 00:00:00 GMT')
|
||||||
|
|
||||||
# Common methods used by subclasses
|
# Common methods used by subclasses
|
||||||
|
|
||||||
|
|
|
@ -232,6 +232,12 @@ Miscellaneous
|
||||||
* The minimum supported version of ``mysqlclient`` is increased from 1.3.3 to
|
* The minimum supported version of ``mysqlclient`` is increased from 1.3.3 to
|
||||||
1.3.7.
|
1.3.7.
|
||||||
|
|
||||||
|
* The date format of ``Set-Cookie``'s ``Expires`` directive is changed to
|
||||||
|
follow :rfc:`7231#section-7.1.1.1` instead of Netscape's cookie standard.
|
||||||
|
Hyphens present in dates like ``Tue, 25-Dec-2018 22:26:13 GMT`` are removed.
|
||||||
|
This change should be merely cosmetic except perhaps for antiquated browsers
|
||||||
|
that don't parse the new format.
|
||||||
|
|
||||||
.. _deprecated-features-2.1:
|
.. _deprecated-features-2.1:
|
||||||
|
|
||||||
Features deprecated in 2.1
|
Features deprecated in 2.1
|
||||||
|
|
|
@ -82,7 +82,7 @@ class CookieTests(BaseTests, SimpleTestCase):
|
||||||
storage.update(response)
|
storage.update(response)
|
||||||
self.assertEqual(response.cookies['messages'].value, '')
|
self.assertEqual(response.cookies['messages'].value, '')
|
||||||
self.assertEqual(response.cookies['messages']['domain'], '.example.com')
|
self.assertEqual(response.cookies['messages']['domain'], '.example.com')
|
||||||
self.assertEqual(response.cookies['messages']['expires'], 'Thu, 01-Jan-1970 00:00:00 GMT')
|
self.assertEqual(response.cookies['messages']['expires'], 'Thu, 01 Jan 1970 00:00:00 GMT')
|
||||||
|
|
||||||
def test_get_bad_cookie(self):
|
def test_get_bad_cookie(self):
|
||||||
request = self.get_request()
|
request = self.get_request()
|
||||||
|
|
|
@ -14,7 +14,7 @@ from django.http.request import split_domain_port
|
||||||
from django.test import RequestFactory, SimpleTestCase, override_settings
|
from django.test import RequestFactory, SimpleTestCase, override_settings
|
||||||
from django.test.client import FakePayload
|
from django.test.client import FakePayload
|
||||||
from django.test.utils import freeze_time
|
from django.test.utils import freeze_time
|
||||||
from django.utils.http import cookie_date
|
from django.utils.http import http_date
|
||||||
from django.utils.timezone import utc
|
from django.utils.timezone import utc
|
||||||
|
|
||||||
|
|
||||||
|
@ -234,7 +234,7 @@ class RequestsTests(SimpleTestCase):
|
||||||
response.set_cookie('c', 'old-value')
|
response.set_cookie('c', 'old-value')
|
||||||
self.assertEqual(response.cookies['c']['expires'], '')
|
self.assertEqual(response.cookies['c']['expires'], '')
|
||||||
response.delete_cookie('c')
|
response.delete_cookie('c')
|
||||||
self.assertEqual(response.cookies['c']['expires'], 'Thu, 01-Jan-1970 00:00:00 GMT')
|
self.assertEqual(response.cookies['c']['expires'], 'Thu, 01 Jan 1970 00:00:00 GMT')
|
||||||
response.set_cookie('c', 'new-value')
|
response.set_cookie('c', 'new-value')
|
||||||
self.assertEqual(response.cookies['c']['expires'], '')
|
self.assertEqual(response.cookies['c']['expires'], '')
|
||||||
|
|
||||||
|
@ -246,7 +246,7 @@ class RequestsTests(SimpleTestCase):
|
||||||
self.assertIn(
|
self.assertIn(
|
||||||
datetime_cookie['expires'],
|
datetime_cookie['expires'],
|
||||||
# assertIn accounts for slight time dependency (#23450)
|
# assertIn accounts for slight time dependency (#23450)
|
||||||
('Sat, 01-Jan-2028 04:05:06 GMT', 'Sat, 01-Jan-2028 04:05:07 GMT')
|
('Sat, 01 Jan 2028 04:05:06 GMT', 'Sat, 01 Jan 2028 04:05:07 GMT')
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_max_age_expiration(self):
|
def test_max_age_expiration(self):
|
||||||
|
@ -257,7 +257,7 @@ class RequestsTests(SimpleTestCase):
|
||||||
response.set_cookie('max_age', max_age=10)
|
response.set_cookie('max_age', max_age=10)
|
||||||
max_age_cookie = response.cookies['max_age']
|
max_age_cookie = response.cookies['max_age']
|
||||||
self.assertEqual(max_age_cookie['max-age'], 10)
|
self.assertEqual(max_age_cookie['max-age'], 10)
|
||||||
self.assertEqual(max_age_cookie['expires'], cookie_date(set_cookie_time + 10))
|
self.assertEqual(max_age_cookie['expires'], http_date(set_cookie_time + 10))
|
||||||
|
|
||||||
def test_httponly_cookie(self):
|
def test_httponly_cookie(self):
|
||||||
response = HttpResponse()
|
response = HttpResponse()
|
||||||
|
|
|
@ -730,9 +730,9 @@ class SessionMiddlewareTests(TestCase):
|
||||||
|
|
||||||
# The cookie was deleted, not recreated.
|
# The cookie was deleted, not recreated.
|
||||||
# A deleted cookie header looks like:
|
# A deleted cookie header looks like:
|
||||||
# Set-Cookie: sessionid=; expires=Thu, 01-Jan-1970 00:00:00 GMT; Max-Age=0; Path=/
|
# Set-Cookie: sessionid=; expires=Thu, 01 Jan 1970 00:00:00 GMT; Max-Age=0; Path=/
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
'Set-Cookie: {}=""; expires=Thu, 01-Jan-1970 00:00:00 GMT; '
|
'Set-Cookie: {}=""; expires=Thu, 01 Jan 1970 00:00:00 GMT; '
|
||||||
'Max-Age=0; Path=/'.format(
|
'Max-Age=0; Path=/'.format(
|
||||||
settings.SESSION_COOKIE_NAME,
|
settings.SESSION_COOKIE_NAME,
|
||||||
),
|
),
|
||||||
|
@ -758,11 +758,11 @@ class SessionMiddlewareTests(TestCase):
|
||||||
# The cookie was deleted, not recreated.
|
# The cookie was deleted, not recreated.
|
||||||
# A deleted cookie header with a custom domain and path looks like:
|
# A deleted cookie header with a custom domain and path looks like:
|
||||||
# Set-Cookie: sessionid=; Domain=.example.local;
|
# Set-Cookie: sessionid=; Domain=.example.local;
|
||||||
# expires=Thu, 01-Jan-1970 00:00:00 GMT; Max-Age=0;
|
# expires=Thu, 01 Jan 1970 00:00:00 GMT; Max-Age=0;
|
||||||
# Path=/example/
|
# Path=/example/
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
'Set-Cookie: {}=""; Domain=.example.local; expires=Thu, '
|
'Set-Cookie: {}=""; Domain=.example.local; expires=Thu, '
|
||||||
'01-Jan-1970 00:00:00 GMT; Max-Age=0; Path=/example/'.format(
|
'01 Jan 1970 00:00:00 GMT; Max-Age=0; Path=/example/'.format(
|
||||||
settings.SESSION_COOKIE_NAME,
|
settings.SESSION_COOKIE_NAME,
|
||||||
),
|
),
|
||||||
str(response.cookies[settings.SESSION_COOKIE_NAME])
|
str(response.cookies[settings.SESSION_COOKIE_NAME])
|
||||||
|
|
Loading…
Reference in New Issue