Commits

Anonymous committed b225034

[soc2009/http-wsgi-improvements] Refactor setting 406 status codes in HttpResponse. Accessing HttpResponse.content now evaluates the status_code for side effects.

  • Participants
  • Parent commits b9fd9fd
  • Branches soc2009/http-wsgi-improvements

Comments (0)

Files changed (2)

django/http/__init__.py

 from django.utils.datastructures import MultiValueDict, ImmutableList
 from django.utils.encoding import smart_str, iri_to_uri, force_unicode
 from django.http.multipartparser import MultiPartParser
-from django.http.charsets import get_response_encoding, get_codec
+from django.http.charsets import get_response_encoding, get_codec, UnsupportedCharset
 from django.conf import settings
 from django.core.files import uploadhandler
 from utils import *
         self.set_cookie(key, max_age=0, path=path, domain=domain,
                         expires='Thu, 01-Jan-1970 00:00:00 GMT')
 
+    def _configure_body_encoding(self):
+        if not self._codec:
+            self._codec = get_codec(self._charset)
+        if not self._codec:
+            self._codec = UnsupportedCharset
+
     def _get_status_code(self):
-        if not self._valid_codec():
+        self._configure_body_encoding()
+        if self._codec is UnsupportedCharset:
             self._status_code = 406
             self._container = ['']
         return self._status_code
 
     status_code = property(_get_status_code, _set_status_code)
 
-    def _valid_codec(self):
-        if not self._codec:
-            self._codec = get_codec(self._charset)
-        if not self._codec:
-            return False
-        return True
-
     def _get_content(self):
+        # Evaluate status_code for side effects
+        self._get_status_code()
         if self.has_header('Content-Encoding'):
             return ''.join(self._container)
         return smart_str(''.join(self._container), self._codec.name)
     content = property(_get_content, _set_content)
 
     def __iter__(self):
+        # Evaluate status_code for side effects
+        self._get_status_code()
         self._iterator = iter(self._container)
         return self
 

django/http/charsets.py

     'windows-936': 'gbk'
 }
 
+class UnsupportedCharset(object):
+    """
+    Singleton class to indicate that our codec cannot be set due to an
+    unsupported charset in an Accept-Charset header.
+    """
+    pass
+
 def get_codec(charset):
     """
     Given the name or alias of a character set, find its Python codec if there is one.
     if not used_content_type:
         if not accept_charset_header: # No information to find a charset with.
             return None, None
+
         # Get list of matches for Accepted-Charsets.
         # [{ charset : q }, { charset : q }]
         match_iterator = ACCEPT_CHARSET_RE.finditer(accept_charset_header)
 
         # Remove charsets we cannot encode and whose q values are 0
         charsets = _process_accept_charset(accept_charset)
-        
+
         # Establish the prioritized charsets (ones we know about beforehand)
         default_charset = settings.DEFAULT_CHARSET
         fallback_charset = "ISO-8859-1"
         # or defaulting)
         else:
             charset = max_q_charset
-            
+
     codec = get_codec(charset)
+
     # We may reach here with no codec or no charset. We will change the status 
     # code in the HttpResponse.
-    #print charset, codec
     return charset, codec
 
 # NOTE -- make sure we are not duping the processing of q values
     names, and excludes charsets without Python codecs and whose q values are 0.
     '''
     accepted_charsets = {}
-    
+
     default_value = 1
     wildcard = False
-    
+
     for potential in accept_charset:
         charset = potential["charset"].strip()            
         # The default quality value is 1
         elif charset == "*" and q >= 0 and q <= 1:
             default_value = q
             wildcard = True
-            
+
     if settings.DEFAULT_CHARSET not in accepted_charsets:
         accepted_charsets[settings.DEFAULT_CHARSET] = default_value 
     if "ISO-8859-1" not in accepted_charsets and wildcard: 
         accepted_charsets["ISO-8859-1"] = default_value
-      
-      
+
     return accepted_charsets