fix(Response): Instruct browser to remove cookies
Modify the Response object to actually set the expires token for the cookie that is being unset to a point in the past, causing the browser to immediately remove the now-expired cookie, which will remove the cookie from future Request objects. The previous behavior of Response's unset_cookie function was just to delete the given name from the SimpleCookie object if it existed. However, this causes a problem in that the browser is not told to remove the cookie on its side, causing all future Request objects to still contain the cookie that was supposed to have been unset/removed. Co-Authored-By: Kurt Griffiths <mail@kgriffs.com>
This commit is contained in:
@@ -251,9 +251,24 @@ class Response(object):
|
||||
self._cookies[name]["httponly"] = http_only
|
||||
|
||||
def unset_cookie(self, name):
|
||||
"""Unset a cookie in the response."""
|
||||
if self._cookies is not None and name in self._cookies:
|
||||
del self._cookies[name]
|
||||
"""Unset a cookie in the response
|
||||
|
||||
Note:
|
||||
This will clear the contents of the cookie, and instruct
|
||||
the browser to immediately expire its own copy of the
|
||||
cookie, if any.
|
||||
"""
|
||||
if self._cookies is None:
|
||||
self._cookies = SimpleCookie()
|
||||
|
||||
self._cookies[name] = ""
|
||||
|
||||
# NOTE(Freezerburn): SimpleCookie apparently special cases the
|
||||
# expires attribute to automatically use strftime and set the
|
||||
# time as a delta from the current time. We use -1 here to
|
||||
# basically tell the browser to immediately expire the cookie,
|
||||
# thus removing it from future request objects.
|
||||
self._cookies[name]["expires"] = -1
|
||||
|
||||
def get_header(self, name):
|
||||
"""Retrieve the raw string value for the given header.
|
||||
|
||||
@@ -128,6 +128,7 @@ def http_date_to_dt(http_date, obs_date=False):
|
||||
|
||||
time_formats = (
|
||||
'%a, %d %b %Y %H:%M:%S %Z',
|
||||
'%a, %d-%b-%Y %H:%M:%S %Z',
|
||||
'%A, %d-%b-%y %H:%M:%S %Z',
|
||||
'%a %b %d %H:%M:%S %Y',
|
||||
)
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import re
|
||||
import sys
|
||||
import falcon
|
||||
import falcon.testing as testing
|
||||
|
||||
from falcon.util import TimezoneGMT
|
||||
from datetime import datetime, timedelta, tzinfo
|
||||
|
||||
from six.moves.http_cookies import Morsel
|
||||
from testtools.matchers import LessThan
|
||||
|
||||
import falcon
|
||||
import falcon.testing as testing
|
||||
from falcon.util import TimezoneGMT, http_date_to_dt
|
||||
|
||||
|
||||
class TimezoneGMTPlus1(tzinfo):
|
||||
@@ -109,12 +111,23 @@ class TestCookies(testing.TestBase):
|
||||
def test_response_unset_cookie(self):
|
||||
resp = falcon.Response()
|
||||
resp.unset_cookie("bad")
|
||||
resp.set_cookie("bad", "cookie", max_age=301)
|
||||
resp.set_cookie("bad", "cookie", max_age=300)
|
||||
resp.unset_cookie("bad")
|
||||
|
||||
morsels = list(resp._cookies.values())
|
||||
self.assertEqual(len(morsels), 1)
|
||||
|
||||
self.assertEqual(len(morsels), 0)
|
||||
bad_cookie = morsels[0]
|
||||
self.assertEqual(bad_cookie['expires'], -1)
|
||||
|
||||
output = bad_cookie.OutputString()
|
||||
self.assertTrue('bad=;' in output or 'bad="";' in output)
|
||||
|
||||
match = re.search('expires=([^;]+)', output)
|
||||
self.assertIsNotNone(match)
|
||||
|
||||
expiration = http_date_to_dt(match.group(1), obs_date=True)
|
||||
self.assertThat(expiration, LessThan(datetime.utcnow()))
|
||||
|
||||
def test_cookie_timezone(self):
|
||||
tz = TimezoneGMT()
|
||||
|
||||
@@ -79,6 +79,15 @@ class TestFalconUtils(testtools.TestCase):
|
||||
falcon.http_date_to_dt('Thu, 04 Apr 2013 10:28:54 GMT'),
|
||||
datetime(2013, 4, 4, 10, 28, 54))
|
||||
|
||||
self.assertRaises(
|
||||
ValueError,
|
||||
falcon.http_date_to_dt, 'Thu, 04-Apr-2013 10:28:54 GMT')
|
||||
|
||||
self.assertEqual(
|
||||
falcon.http_date_to_dt('Thu, 04-Apr-2013 10:28:54 GMT',
|
||||
obs_date=True),
|
||||
datetime(2013, 4, 4, 10, 28, 54))
|
||||
|
||||
self.assertRaises(
|
||||
ValueError,
|
||||
falcon.http_date_to_dt, 'Sun Nov 6 08:49:37 1994')
|
||||
|
||||
Reference in New Issue
Block a user