78 lines
2.8 KiB
Python
78 lines
2.8 KiB
Python
from __future__ import unicode_literals
|
|
|
|
import sys
|
|
|
|
from django.utils import six
|
|
from django.utils.encoding import force_str
|
|
from django.utils.six.moves import http_cookies
|
|
|
|
# http://bugs.python.org/issue2193 is fixed in Python 3.3+.
|
|
_cookie_allows_colon_in_names = six.PY3
|
|
|
|
# Cookie pickling bug is fixed in Python 2.7.9 and Python 3.4.3+
|
|
# http://bugs.python.org/issue22775
|
|
cookie_pickles_properly = (
|
|
(sys.version_info[:2] == (2, 7) and sys.version_info >= (2, 7, 9)) or
|
|
sys.version_info >= (3, 4, 3)
|
|
)
|
|
|
|
if _cookie_allows_colon_in_names and cookie_pickles_properly:
|
|
SimpleCookie = http_cookies.SimpleCookie
|
|
else:
|
|
Morsel = http_cookies.Morsel
|
|
|
|
class SimpleCookie(http_cookies.SimpleCookie):
|
|
if not cookie_pickles_properly:
|
|
def __setitem__(self, key, value):
|
|
# Apply the fix from http://bugs.python.org/issue22775 where
|
|
# it's not fixed in Python itself
|
|
if isinstance(value, Morsel):
|
|
# allow assignment of constructed Morsels (e.g. for pickling)
|
|
dict.__setitem__(self, key, value)
|
|
else:
|
|
super(SimpleCookie, self).__setitem__(key, value)
|
|
|
|
if not _cookie_allows_colon_in_names:
|
|
def load(self, rawdata):
|
|
self.bad_cookies = set()
|
|
if isinstance(rawdata, six.text_type):
|
|
rawdata = force_str(rawdata)
|
|
super(SimpleCookie, self).load(rawdata)
|
|
for key in self.bad_cookies:
|
|
del self[key]
|
|
|
|
# override private __set() method:
|
|
# (needed for using our Morsel, and for laxness with CookieError
|
|
def _BaseCookie__set(self, key, real_value, coded_value):
|
|
key = force_str(key)
|
|
try:
|
|
M = self.get(key, Morsel())
|
|
M.set(key, real_value, coded_value)
|
|
dict.__setitem__(self, key, M)
|
|
except http_cookies.CookieError:
|
|
if not hasattr(self, 'bad_cookies'):
|
|
self.bad_cookies = set()
|
|
self.bad_cookies.add(key)
|
|
dict.__setitem__(self, key, http_cookies.Morsel())
|
|
|
|
|
|
def parse_cookie(cookie):
|
|
"""
|
|
Return a dictionary parsed from a `Cookie:` header string.
|
|
"""
|
|
cookiedict = {}
|
|
if six.PY2:
|
|
cookie = force_str(cookie)
|
|
for chunk in cookie.split(str(';')):
|
|
if str('=') in chunk:
|
|
key, val = chunk.split(str('='), 1)
|
|
else:
|
|
# Assume an empty name per
|
|
# https://bugzilla.mozilla.org/show_bug.cgi?id=169091
|
|
key, val = str(''), chunk
|
|
key, val = key.strip(), val.strip()
|
|
if key or val:
|
|
# unquote using Python's algorithm.
|
|
cookiedict[key] = http_cookies._unquote(val)
|
|
return cookiedict
|