Merge pull request #634 from kgriffs/Freezerburn-patch-1-rebase

fix(Response): Instruct browser to remove cookies
This commit is contained in:
Kurt Griffiths
2015-10-16 12:55:34 -05:00
5 changed files with 48 additions and 9 deletions

View File

@@ -52,3 +52,4 @@ below in order of date of first contribution:
* Carl George (carlgeorge)
* Adam Yala (adamyala)
* Grigory Bakunov (bobuk)
* Vincent Raiken (Freezerburn)

View File

@@ -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.

View File

@@ -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',
)

View File

@@ -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()

View File

@@ -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')