diff -r b758351d191f -r cc9b7e14412b web/lib/django/http/__init__.py --- a/web/lib/django/http/__init__.py Wed May 19 17:43:59 2010 +0200 +++ b/web/lib/django/http/__init__.py Tue May 25 02:43:45 2010 +0200 @@ -1,6 +1,6 @@ import os import re -from Cookie import SimpleCookie, CookieError +from Cookie import BaseCookie, SimpleCookie, CookieError from pprint import pformat from urllib import urlencode from urlparse import urljoin @@ -183,7 +183,7 @@ return result def __deepcopy__(self, memo): - import copy + import django.utils.copycompat as copy result = self.__class__('', mutable=True) memo[id(self)] = result for key, value in dict.items(self): @@ -248,16 +248,46 @@ output.extend([urlencode({k: smart_str(v, self.encoding)}) for v in list_]) return '&'.join(output) +class CompatCookie(SimpleCookie): + """ + Cookie class that handles some issues with browser compatibility. + """ + def value_encode(self, val): + # Some browsers do not support quoted-string from RFC 2109, + # including some versions of Safari and Internet Explorer. + # These browsers split on ';', and some versions of Safari + # are known to split on ', '. Therefore, we encode ';' and ',' + + # SimpleCookie already does the hard work of encoding and decoding. + # It uses octal sequences like '\\012' for newline etc. + # and non-ASCII chars. We just make use of this mechanism, to + # avoid introducing two encoding schemes which would be confusing + # and especially awkward for javascript. + + # NB, contrary to Python docs, value_encode returns a tuple containing + # (real val, encoded_val) + val, encoded = super(CompatCookie, self).value_encode(val) + + encoded = encoded.replace(";", "\\073").replace(",","\\054") + # If encoded now contains any quoted chars, we need double quotes + # around the whole string. + if "\\" in encoded and not encoded.startswith('"'): + encoded = '"' + encoded + '"' + + return val, encoded + def parse_cookie(cookie): if cookie == '': return {} - try: - c = SimpleCookie() - c.load(cookie) - except CookieError: - # Invalid cookie - return {} - + if not isinstance(cookie, BaseCookie): + try: + c = CompatCookie() + c.load(cookie) + except CookieError: + # Invalid cookie + return {} + else: + c = cookie cookiedict = {} for key in c.keys(): cookiedict[key] = c.get(key).value @@ -286,7 +316,7 @@ else: self._container = [content] self._is_string = True - self.cookies = SimpleCookie() + self.cookies = CompatCookie() if status: self.status_code = status @@ -404,14 +434,14 @@ def __init__(self, redirect_to): HttpResponse.__init__(self) - self['Location'] = redirect_to + self['Location'] = iri_to_uri(redirect_to) class HttpResponsePermanentRedirect(HttpResponse): status_code = 301 def __init__(self, redirect_to): HttpResponse.__init__(self) - self['Location'] = redirect_to + self['Location'] = iri_to_uri(redirect_to) class HttpResponseNotModified(HttpResponse): status_code = 304