Added del cookie and default path

This commit is contained in:
Channel Cat 2017-01-25 01:53:39 -08:00
parent 0ad31a471b
commit d0a121ad06
3 changed files with 60 additions and 5 deletions

View File

@ -32,12 +32,39 @@ async def test(request):
return response return response
``` ```
## Deleting cookies
Cookies can be removed semantically or explicitly.
```python
from sanic.response import text
@app.route("/cookie")
async def test(request):
response = text("Time to eat some cookies muahaha")
# This cookie will be set to expire in 0 seconds
del response.cookies['kill_me']
# This cookie will self destruct in 5 seconds
response.cookies['short_life'] = 'Glad to be here'
response.cookies['short_life']['max-age'] = 5
del response.cookies['favorite_color']
# This cookie will remain unchanged
response.cookies['favorite_color'] = 'blue'
response.cookies['favorite_color'] = 'pink'
del response.cookies['favorite_color']
return response
```
Response cookies can be set like dictionary values and have the following Response cookies can be set like dictionary values and have the following
parameters available: parameters available:
- `expires` (datetime): The time for the cookie to expire on the - `expires` (datetime): The time for the cookie to expire on the
client's browser. client's browser.
- `path` (string): The subset of URLs to which this cookie applies. - `path` (string): The subset of URLs to which this cookie applies. Defaults to 0.
- `comment` (string): A comment (metadata). - `comment` (string): A comment (metadata).
- `domain` (string): Specifies the domain for which the cookie is valid. An - `domain` (string): Specifies the domain for which the cookie is valid. An
explicitly specified domain must always start with a dot. explicitly specified domain must always start with a dot.

View File

@ -42,8 +42,9 @@ class CookieJar(dict):
""" """
CookieJar dynamically writes headers as cookies are added and removed CookieJar dynamically writes headers as cookies are added and removed
It gets around the limitation of one header per name by using the It gets around the limitation of one header per name by using the
MultiHeader class to provide a unique key that encodes to Set-Cookie MultiHeader class to provide a unique key that encodes to Set-Cookie.
""" """
def __init__(self, headers): def __init__(self, headers):
super().__init__() super().__init__()
self.headers = headers self.headers = headers
@ -54,6 +55,7 @@ class CookieJar(dict):
cookie_header = self.cookie_headers.get(key) cookie_header = self.cookie_headers.get(key)
if not cookie_header: if not cookie_header:
cookie = Cookie(key, value) cookie = Cookie(key, value)
cookie['path'] = '/'
cookie_header = MultiHeader("Set-Cookie") cookie_header = MultiHeader("Set-Cookie")
self.cookie_headers[key] = cookie_header self.cookie_headers[key] = cookie_header
self.headers[cookie_header] = cookie self.headers[cookie_header] = cookie
@ -62,8 +64,14 @@ class CookieJar(dict):
self[key].value = value self[key].value = value
def __delitem__(self, key): def __delitem__(self, key):
del self.cookie_headers[key] if key not in self.cookie_headers:
return super().__delitem__(key) self[key] = ''
self[key]['max-age'] = 0
else:
cookie_header = self.cookie_headers[key]
del self.headers[cookie_header]
del self.cookie_headers[key]
return super().__delitem__(key)
class Cookie(dict): class Cookie(dict):

View File

@ -3,6 +3,7 @@ from http.cookies import SimpleCookie
from sanic import Sanic from sanic import Sanic
from sanic.response import json, text from sanic.response import json, text
from sanic.utils import sanic_endpoint_test from sanic.utils import sanic_endpoint_test
import pytest
# ------------------------------------------------------------ # # ------------------------------------------------------------ #
@ -54,4 +55,23 @@ def test_cookie_options():
response_cookies.load(response.headers.get('Set-Cookie', {})) response_cookies.load(response.headers.get('Set-Cookie', {}))
assert response_cookies['test'].value == 'at you' assert response_cookies['test'].value == 'at you'
assert response_cookies['test']['httponly'] == True assert response_cookies['test']['httponly'] == True
def test_cookie_deletion():
app = Sanic('test_text')
@app.route('/')
def handler(request):
response = text("OK")
del response.cookies['i_want_to_die']
response.cookies['i_never_existed'] = 'testing'
del response.cookies['i_never_existed']
return response
request, response = sanic_endpoint_test(app)
response_cookies = SimpleCookie()
response_cookies.load(response.headers.get('Set-Cookie', {}))
assert int(response_cookies['i_want_to_die']['max-age']) == 0
with pytest.raises(KeyError):
hold_my_beer = response.cookies['i_never_existed']