1
0
mirror of https://github.com/django/django.git synced 2025-07-04 01:39:20 +00:00

[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
This commit is contained in:
Chris Cahoon 2009-07-09 19:53:18 +00:00
parent e49fd1ff17
commit 9eab31193a
2 changed files with 28 additions and 17 deletions

View File

@ -13,7 +13,7 @@ except ImportError:
from django.utils.datastructures import MultiValueDict, ImmutableList from django.utils.datastructures import MultiValueDict, ImmutableList
from django.utils.encoding import smart_str, iri_to_uri, force_unicode from django.utils.encoding import smart_str, iri_to_uri, force_unicode
from django.http.multipartparser import MultiPartParser 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.conf import settings
from django.core.files import uploadhandler from django.core.files import uploadhandler
from utils import * from utils import *
@ -367,8 +367,15 @@ class HttpResponse(object):
self.set_cookie(key, max_age=0, path=path, domain=domain, self.set_cookie(key, max_age=0, path=path, domain=domain,
expires='Thu, 01-Jan-1970 00:00:00 GMT') 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): def _get_status_code(self):
if not self._valid_codec(): self._configure_body_encoding()
if self._codec is UnsupportedCharset:
self._status_code = 406 self._status_code = 406
self._container = [''] self._container = ['']
return self._status_code return self._status_code
@ -378,14 +385,9 @@ class HttpResponse(object):
status_code = property(_get_status_code, _set_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): def _get_content(self):
# Evaluate status_code for side effects
self._get_status_code()
if self.has_header('Content-Encoding'): if self.has_header('Content-Encoding'):
return ''.join(self._container) return ''.join(self._container)
return smart_str(''.join(self._container), self._codec.name) return smart_str(''.join(self._container), self._codec.name)
@ -397,6 +399,8 @@ class HttpResponse(object):
content = property(_get_content, _set_content) content = property(_get_content, _set_content)
def __iter__(self): def __iter__(self):
# Evaluate status_code for side effects
self._get_status_code()
self._iterator = iter(self._container) self._iterator = iter(self._container)
return self return self

View File

@ -226,6 +226,13 @@ CHARSET_CODECS = {
'windows-936': 'gbk' '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): def get_codec(charset):
""" """
Given the name or alias of a character set, find its Python codec if there is one. 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):
if not used_content_type: if not used_content_type:
if not accept_charset_header: # No information to find a charset with. if not accept_charset_header: # No information to find a charset with.
return None, None return None, None
# Get list of matches for Accepted-Charsets. # Get list of matches for Accepted-Charsets.
# [{ charset : q }, { charset : q }] # [{ charset : q }, { charset : q }]
match_iterator = ACCEPT_CHARSET_RE.finditer(accept_charset_header) match_iterator = ACCEPT_CHARSET_RE.finditer(accept_charset_header)
@ -292,7 +300,7 @@ def get_response_encoding(content_type, accept_charset_header):
# Remove charsets we cannot encode and whose q values are 0 # Remove charsets we cannot encode and whose q values are 0
charsets = _process_accept_charset(accept_charset) charsets = _process_accept_charset(accept_charset)
# Establish the prioritized charsets (ones we know about beforehand) # Establish the prioritized charsets (ones we know about beforehand)
default_charset = settings.DEFAULT_CHARSET default_charset = settings.DEFAULT_CHARSET
fallback_charset = "ISO-8859-1" fallback_charset = "ISO-8859-1"
@ -309,11 +317,11 @@ def get_response_encoding(content_type, accept_charset_header):
# or defaulting) # or defaulting)
else: else:
charset = max_q_charset charset = max_q_charset
codec = get_codec(charset) codec = get_codec(charset)
# We may reach here with no codec or no charset. We will change the status # We may reach here with no codec or no charset. We will change the status
# code in the HttpResponse. # code in the HttpResponse.
#print charset, codec
return charset, codec return charset, codec
# NOTE -- make sure we are not duping the processing of q values # NOTE -- make sure we are not duping the processing of q values
@ -324,10 +332,10 @@ def _process_accept_charset(accept_charset):
names, and excludes charsets without Python codecs and whose q values are 0. names, and excludes charsets without Python codecs and whose q values are 0.
''' '''
accepted_charsets = {} accepted_charsets = {}
default_value = 1 default_value = 1
wildcard = False wildcard = False
for potential in accept_charset: for potential in accept_charset:
charset = potential["charset"].strip() charset = potential["charset"].strip()
# The default quality value is 1 # The default quality value is 1
@ -341,11 +349,10 @@ def _process_accept_charset(accept_charset):
elif charset == "*" and q >= 0 and q <= 1: elif charset == "*" and q >= 0 and q <= 1:
default_value = q default_value = q
wildcard = True wildcard = True
if settings.DEFAULT_CHARSET not in accepted_charsets: if settings.DEFAULT_CHARSET not in accepted_charsets:
accepted_charsets[settings.DEFAULT_CHARSET] = default_value accepted_charsets[settings.DEFAULT_CHARSET] = default_value
if "ISO-8859-1" not in accepted_charsets and wildcard: if "ISO-8859-1" not in accepted_charsets and wildcard:
accepted_charsets["ISO-8859-1"] = default_value accepted_charsets["ISO-8859-1"] = default_value
return accepted_charsets return accepted_charsets