Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

[soc2009/http-wsgi-improvements] Refactor setting 406 status codes in…

… HttpResponse. Accessing HttpResponse.content now evaluates the status_code for side effects.

git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2009/http-wsgi-improvements@11211 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 9eab31193abb8fbc35ecc26b2b1a93bda7e31882 1 parent e49fd1f
Christopher Cahoon authored July 09, 2009
22  django/http/__init__.py
@@ -13,7 +13,7 @@
13 13
 from django.utils.datastructures import MultiValueDict, ImmutableList
14 14
 from django.utils.encoding import smart_str, iri_to_uri, force_unicode
15 15
 from django.http.multipartparser import MultiPartParser
16  
-from django.http.charsets import get_response_encoding, get_codec
  16
+from django.http.charsets import get_response_encoding, get_codec, UnsupportedCharset
17 17
 from django.conf import settings
18 18
 from django.core.files import uploadhandler
19 19
 from utils import *
@@ -367,8 +367,15 @@ def delete_cookie(self, key, path='/', domain=None):
367 367
         self.set_cookie(key, max_age=0, path=path, domain=domain,
368 368
                         expires='Thu, 01-Jan-1970 00:00:00 GMT')
369 369
 
  370
+    def _configure_body_encoding(self):
  371
+        if not self._codec:
  372
+            self._codec = get_codec(self._charset)
  373
+        if not self._codec:
  374
+            self._codec = UnsupportedCharset
  375
+
370 376
     def _get_status_code(self):
371  
-        if not self._valid_codec():
  377
+        self._configure_body_encoding()
  378
+        if self._codec is UnsupportedCharset:
372 379
             self._status_code = 406
373 380
             self._container = ['']
374 381
         return self._status_code
@@ -378,14 +385,9 @@ def _set_status_code(self, value):
378 385
 
379 386
     status_code = property(_get_status_code, _set_status_code)
380 387
 
381  
-    def _valid_codec(self):
382  
-        if not self._codec:
383  
-            self._codec = get_codec(self._charset)
384  
-        if not self._codec:
385  
-            return False
386  
-        return True
387  
-
388 388
     def _get_content(self):
  389
+        # Evaluate status_code for side effects
  390
+        self._get_status_code()
389 391
         if self.has_header('Content-Encoding'):
390 392
             return ''.join(self._container)
391 393
         return smart_str(''.join(self._container), self._codec.name)
@@ -397,6 +399,8 @@ def _set_content(self, value):
397 399
     content = property(_get_content, _set_content)
398 400
 
399 401
     def __iter__(self):
  402
+        # Evaluate status_code for side effects
  403
+        self._get_status_code()
400 404
         self._iterator = iter(self._container)
401 405
         return self
402 406
 
23  django/http/charsets.py
@@ -226,6 +226,13 @@
226 226
     'windows-936': 'gbk'
227 227
 }
228 228
 
  229
+class UnsupportedCharset(object):
  230
+    """
  231
+    Singleton class to indicate that our codec cannot be set due to an
  232
+    unsupported charset in an Accept-Charset header.
  233
+    """
  234
+    pass
  235
+
229 236
 def get_codec(charset):
230 237
     """
231 238
     Given the name or alias of a character set, find its Python codec if there is one.
@@ -285,6 +292,7 @@ def get_response_encoding(content_type, accept_charset_header):
285 292
     if not used_content_type:
286 293
         if not accept_charset_header: # No information to find a charset with.
287 294
             return None, None
  295
+
288 296
         # Get list of matches for Accepted-Charsets.
289 297
         # [{ charset : q }, { charset : q }]
290 298
         match_iterator = ACCEPT_CHARSET_RE.finditer(accept_charset_header)
@@ -292,7 +300,7 @@ def get_response_encoding(content_type, accept_charset_header):
292 300
 
293 301
         # Remove charsets we cannot encode and whose q values are 0
294 302
         charsets = _process_accept_charset(accept_charset)
295  
-        
  303
+
296 304
         # Establish the prioritized charsets (ones we know about beforehand)
297 305
         default_charset = settings.DEFAULT_CHARSET
298 306
         fallback_charset = "ISO-8859-1"
@@ -309,11 +317,11 @@ def get_response_encoding(content_type, accept_charset_header):
309 317
         # or defaulting)
310 318
         else:
311 319
             charset = max_q_charset
312  
-            
  320
+
313 321
     codec = get_codec(charset)
  322
+
314 323
     # We may reach here with no codec or no charset. We will change the status 
315 324
     # code in the HttpResponse.
316  
-    #print charset, codec
317 325
     return charset, codec
318 326
 
319 327
 # NOTE -- make sure we are not duping the processing of q values
@@ -324,10 +332,10 @@ def _process_accept_charset(accept_charset):
324 332
     names, and excludes charsets without Python codecs and whose q values are 0.
325 333
     '''
326 334
     accepted_charsets = {}
327  
-    
  335
+
328 336
     default_value = 1
329 337
     wildcard = False
330  
-    
  338
+
331 339
     for potential in accept_charset:
332 340
         charset = potential["charset"].strip()            
333 341
         # The default quality value is 1
@@ -341,11 +349,10 @@ def _process_accept_charset(accept_charset):
341 349
         elif charset == "*" and q >= 0 and q <= 1:
342 350
             default_value = q
343 351
             wildcard = True
344  
-            
  352
+
345 353
     if settings.DEFAULT_CHARSET not in accepted_charsets:
346 354
         accepted_charsets[settings.DEFAULT_CHARSET] = default_value 
347 355
     if "ISO-8859-1" not in accepted_charsets and wildcard: 
348 356
         accepted_charsets["ISO-8859-1"] = default_value
349  
-      
350  
-      
  357
+
351 358
     return accepted_charsets

0 notes on commit 9eab311

Please sign in to comment.
Something went wrong with that request. Please try again.