web/lib/django/http/__init__.py
changeset 29 cc9b7e14412b
parent 0 0d40e90630ef
equal deleted inserted replaced
28:b758351d191f 29:cc9b7e14412b
     1 import os
     1 import os
     2 import re
     2 import re
     3 from Cookie import SimpleCookie, CookieError
     3 from Cookie import BaseCookie, SimpleCookie, CookieError
     4 from pprint import pformat
     4 from pprint import pformat
     5 from urllib import urlencode
     5 from urllib import urlencode
     6 from urlparse import urljoin
     6 from urlparse import urljoin
     7 try:
     7 try:
     8     # The mod_python version is more efficient, so try importing it first.
     8     # The mod_python version is more efficient, so try importing it first.
   181         for key, value in dict.items(self):
   181         for key, value in dict.items(self):
   182             dict.__setitem__(result, key, value)
   182             dict.__setitem__(result, key, value)
   183         return result
   183         return result
   184 
   184 
   185     def __deepcopy__(self, memo):
   185     def __deepcopy__(self, memo):
   186         import copy
   186         import django.utils.copycompat as copy
   187         result = self.__class__('', mutable=True)
   187         result = self.__class__('', mutable=True)
   188         memo[id(self)] = result
   188         memo[id(self)] = result
   189         for key, value in dict.items(self):
   189         for key, value in dict.items(self):
   190             dict.__setitem__(result, copy.deepcopy(key, memo), copy.deepcopy(value, memo))
   190             dict.__setitem__(result, copy.deepcopy(key, memo), copy.deepcopy(value, memo))
   191         return result
   191         return result
   246         for k, list_ in self.lists():
   246         for k, list_ in self.lists():
   247             k = smart_str(k, self.encoding)
   247             k = smart_str(k, self.encoding)
   248             output.extend([urlencode({k: smart_str(v, self.encoding)}) for v in list_])
   248             output.extend([urlencode({k: smart_str(v, self.encoding)}) for v in list_])
   249         return '&'.join(output)
   249         return '&'.join(output)
   250 
   250 
       
   251 class CompatCookie(SimpleCookie):
       
   252     """
       
   253     Cookie class that handles some issues with browser compatibility.
       
   254     """
       
   255     def value_encode(self, val):
       
   256         # Some browsers do not support quoted-string from RFC 2109,
       
   257         # including some versions of Safari and Internet Explorer.
       
   258         # These browsers split on ';', and some versions of Safari
       
   259         # are known to split on ', '. Therefore, we encode ';' and ','
       
   260 
       
   261         # SimpleCookie already does the hard work of encoding and decoding.
       
   262         # It uses octal sequences like '\\012' for newline etc.
       
   263         # and non-ASCII chars.  We just make use of this mechanism, to
       
   264         # avoid introducing two encoding schemes which would be confusing
       
   265         # and especially awkward for javascript.
       
   266 
       
   267         # NB, contrary to Python docs, value_encode returns a tuple containing
       
   268         # (real val, encoded_val)
       
   269         val, encoded = super(CompatCookie, self).value_encode(val)
       
   270 
       
   271         encoded = encoded.replace(";", "\\073").replace(",","\\054")
       
   272         # If encoded now contains any quoted chars, we need double quotes
       
   273         # around the whole string.
       
   274         if "\\" in encoded and not encoded.startswith('"'):
       
   275             encoded = '"' + encoded + '"'
       
   276 
       
   277         return val, encoded
       
   278 
   251 def parse_cookie(cookie):
   279 def parse_cookie(cookie):
   252     if cookie == '':
   280     if cookie == '':
   253         return {}
   281         return {}
   254     try:
   282     if not isinstance(cookie, BaseCookie):
   255         c = SimpleCookie()
   283         try:
   256         c.load(cookie)
   284             c = CompatCookie()
   257     except CookieError:
   285             c.load(cookie)
   258         # Invalid cookie
   286         except CookieError:
   259         return {}
   287             # Invalid cookie
   260 
   288             return {}
       
   289     else:
       
   290         c = cookie
   261     cookiedict = {}
   291     cookiedict = {}
   262     for key in c.keys():
   292     for key in c.keys():
   263         cookiedict[key] = c.get(key).value
   293         cookiedict[key] = c.get(key).value
   264     return cookiedict
   294     return cookiedict
   265 
   295 
   284             self._container = content
   314             self._container = content
   285             self._is_string = False
   315             self._is_string = False
   286         else:
   316         else:
   287             self._container = [content]
   317             self._container = [content]
   288             self._is_string = True
   318             self._is_string = True
   289         self.cookies = SimpleCookie()
   319         self.cookies = CompatCookie()
   290         if status:
   320         if status:
   291             self.status_code = status
   321             self.status_code = status
   292 
   322 
   293         # _headers is a mapping of the lower-case name to the original case of
   323         # _headers is a mapping of the lower-case name to the original case of
   294         # the header (required for working with legacy systems) and the header
   324         # the header (required for working with legacy systems) and the header
   402 class HttpResponseRedirect(HttpResponse):
   432 class HttpResponseRedirect(HttpResponse):
   403     status_code = 302
   433     status_code = 302
   404 
   434 
   405     def __init__(self, redirect_to):
   435     def __init__(self, redirect_to):
   406         HttpResponse.__init__(self)
   436         HttpResponse.__init__(self)
   407         self['Location'] = redirect_to
   437         self['Location'] = iri_to_uri(redirect_to)
   408 
   438 
   409 class HttpResponsePermanentRedirect(HttpResponse):
   439 class HttpResponsePermanentRedirect(HttpResponse):
   410     status_code = 301
   440     status_code = 301
   411 
   441 
   412     def __init__(self, redirect_to):
   442     def __init__(self, redirect_to):
   413         HttpResponse.__init__(self)
   443         HttpResponse.__init__(self)
   414         self['Location'] = redirect_to
   444         self['Location'] = iri_to_uri(redirect_to)
   415 
   445 
   416 class HttpResponseNotModified(HttpResponse):
   446 class HttpResponseNotModified(HttpResponse):
   417     status_code = 304
   447     status_code = 304
   418 
   448 
   419 class HttpResponseBadRequest(HttpResponse):
   449 class HttpResponseBadRequest(HttpResponse):