Fixed #16178 - Cleanup request classes' `__repr__()`

Thanks to julien for the patch.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@16350 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Luke Plant 2011-06-09 23:15:42 +00:00
parent dff31de20a
commit db2f9bfae1
5 changed files with 91 additions and 84 deletions

View File

@ -45,32 +45,6 @@ class ModPythonRequest(http.HttpRequest):
self._stream = self._req self._stream = self._req
self._read_started = False self._read_started = False
def __repr__(self):
# Since this is called as part of error handling, we need to be very
# robust against potentially malformed input.
try:
get = pformat(self.GET)
except:
get = '<could not parse>'
if self._post_parse_error:
post = '<could not parse>'
else:
try:
post = pformat(self.POST)
except:
post = '<could not parse>'
try:
cookies = pformat(self.COOKIES)
except:
cookies = '<could not parse>'
try:
meta = pformat(self.META)
except:
meta = '<could not parse>'
return smart_str(u'<ModPythonRequest\npath:%s,\nGET:%s,\nPOST:%s,\nCOOKIES:%s,\nMETA:%s>' %
(self.path, unicode(get), unicode(post),
unicode(cookies), unicode(meta)))
def get_full_path(self): def get_full_path(self):
# RFC 3986 requires self._req.args to be in the ASCII range, but this # RFC 3986 requires self._req.args to be in the ASCII range, but this
# doesn't always happen, so rather than crash, we defensively encode it. # doesn't always happen, so rather than crash, we defensively encode it.

View File

@ -157,31 +157,6 @@ class WSGIRequest(http.HttpRequest):
self._stream = self.environ['wsgi.input'] self._stream = self.environ['wsgi.input']
self._read_started = False self._read_started = False
def __repr__(self):
# Since this is called as part of error handling, we need to be very
# robust against potentially malformed input.
try:
get = pformat(self.GET)
except:
get = '<could not parse>'
if self._post_parse_error:
post = '<could not parse>'
else:
try:
post = pformat(self.POST)
except:
post = '<could not parse>'
try:
cookies = pformat(self.COOKIES)
except:
cookies = '<could not parse>'
try:
meta = pformat(self.META)
except:
meta = '<could not parse>'
return '<WSGIRequest\nGET:%s,\nPOST:%s,\nCOOKIES:%s,\nMETA:%s>' % \
(get, post, cookies, meta)
def get_full_path(self): def get_full_path(self):
# RFC 3986 requires query string arguments to be in the ASCII range. # RFC 3986 requires query string arguments to be in the ASCII range.
# Rather than crash if this doesn't happen, we encode defensively. # Rather than crash if this doesn't happen, we encode defensively.

View File

@ -134,6 +134,53 @@ class Http404(Exception):
RAISE_ERROR = object() RAISE_ERROR = object()
def build_request_repr(request, path_override=None, GET_override=None,
POST_override=None, COOKIES_override=None,
META_override=None):
"""
Builds and returns the request's representation string. The request's
attributes may be overridden by pre-processed values.
"""
# Since this is called as part of error handling, we need to be very
# robust against potentially malformed input.
try:
get = (pformat(GET_override)
if GET_override is not None
else pformat(request.GET))
except:
get = '<could not parse>'
if request._post_parse_error:
post = '<could not parse>'
else:
try:
post = (pformat(POST_override)
if POST_override is not None
else pformat(request.POST))
except:
post = '<could not parse>'
try:
cookies = (pformat(COOKIES_override)
if COOKIES_override is not None
else pformat(request.COOKIES))
except:
cookies = '<could not parse>'
try:
meta = (pformat(META_override)
if META_override is not None
else pformat(request.META))
except:
meta = '<could not parse>'
path = path_override if path_override is not None else request.path
return smart_str(u'<%s\npath:%s,\nGET:%s,\nPOST:%s,\nCOOKIES:%s,\nMETA:%s>' %
(request.__class__.__name__,
path,
unicode(get),
unicode(post),
unicode(cookies),
unicode(meta)))
class HttpRequest(object): class HttpRequest(object):
"""A basic HTTP request.""" """A basic HTTP request."""
@ -146,11 +193,10 @@ class HttpRequest(object):
self.path = '' self.path = ''
self.path_info = '' self.path_info = ''
self.method = None self.method = None
self._post_parse_error = False
def __repr__(self): def __repr__(self):
return '<HttpRequest\nGET:%s,\nPOST:%s,\nCOOKIES:%s,\nMETA:%s>' % \ return build_request_repr(self)
(pformat(self.GET), pformat(self.POST), pformat(self.COOKIES),
pformat(self.META))
def get_host(self): def get_host(self):
"""Returns the HTTP host using the environment or request headers.""" """Returns the HTTP host using the environment or request headers."""

View File

@ -7,7 +7,7 @@ from pprint import pformat
from django.conf import settings from django.conf import settings
from django.http import (HttpResponse, HttpResponseServerError, from django.http import (HttpResponse, HttpResponseServerError,
HttpResponseNotFound, HttpRequest) HttpResponseNotFound, HttpRequest, build_request_repr)
from django.template import (Template, Context, TemplateDoesNotExist, from django.template import (Template, Context, TemplateDoesNotExist,
TemplateSyntaxError) TemplateSyntaxError)
from django.template.defaultfilters import force_escape, pprint from django.template.defaultfilters import force_escape, pprint
@ -96,34 +96,7 @@ class ExceptionReporterFilter(object):
if request is None: if request is None:
return repr(None) return repr(None)
else: else:
# Since this is called as part of error handling, we need to be very return build_request_repr(request, POST_override=self.get_post_parameters(request))
# robust against potentially malformed input.
try:
get = pformat(request.GET)
except:
get = '<could not parse>'
if request._post_parse_error:
post = '<could not parse>'
else:
try:
post = pformat(self.get_post_parameters(request))
except:
post = '<could not parse>'
try:
cookies = pformat(request.COOKIES)
except:
cookies = '<could not parse>'
try:
meta = pformat(request.META)
except:
meta = '<could not parse>'
return smart_str(u'<%s\npath:%s,\nGET:%s,\nPOST:%s,\nCOOKIES:%s,\nMETA:%s>' %
(request.__class__.__name__,
request.path,
unicode(get),
unicode(post),
unicode(cookies),
unicode(meta)))
def get_post_parameters(self, request): def get_post_parameters(self, request):
if request is None: if request is None:

View File

@ -4,7 +4,7 @@ from StringIO import StringIO
from django.core.handlers.modpython import ModPythonRequest from django.core.handlers.modpython import ModPythonRequest
from django.core.handlers.wsgi import WSGIRequest, LimitedStream from django.core.handlers.wsgi import WSGIRequest, LimitedStream
from django.http import HttpRequest, HttpResponse, parse_cookie from django.http import HttpRequest, HttpResponse, parse_cookie, build_request_repr
from django.utils import unittest from django.utils import unittest
from django.utils.http import cookie_date from django.utils.http import cookie_date
@ -16,6 +16,18 @@ class RequestsTests(unittest.TestCase):
self.assertEqual(request.COOKIES.keys(), []) self.assertEqual(request.COOKIES.keys(), [])
self.assertEqual(request.META.keys(), []) self.assertEqual(request.META.keys(), [])
def test_httprequest_repr(self):
request = HttpRequest()
request.path = u'/somepath/'
request.GET = {u'get-key': u'get-value'}
request.POST = {u'post-key': u'post-value'}
request.COOKIES = {u'post-key': u'post-value'}
request.META = {u'post-key': u'post-value'}
self.assertEqual(repr(request), u"<HttpRequest\npath:/somepath/,\nGET:{u'get-key': u'get-value'},\nPOST:{u'post-key': u'post-value'},\nCOOKIES:{u'post-key': u'post-value'},\nMETA:{u'post-key': u'post-value'}>")
self.assertEqual(build_request_repr(request), repr(request))
self.assertEqual(build_request_repr(request, path_override='/otherpath/', GET_override={u'a': u'b'}, POST_override={u'c': u'd'}, COOKIES_override={u'e': u'f'}, META_override={u'g': u'h'}),
u"<HttpRequest\npath:/otherpath/,\nGET:{u'a': u'b'},\nPOST:{u'c': u'd'},\nCOOKIES:{u'e': u'f'},\nMETA:{u'g': u'h'}>")
def test_wsgirequest(self): def test_wsgirequest(self):
request = WSGIRequest({'PATH_INFO': 'bogus', 'REQUEST_METHOD': 'bogus', 'wsgi.input': StringIO('')}) request = WSGIRequest({'PATH_INFO': 'bogus', 'REQUEST_METHOD': 'bogus', 'wsgi.input': StringIO('')})
self.assertEqual(request.GET.keys(), []) self.assertEqual(request.GET.keys(), [])
@ -26,6 +38,17 @@ class RequestsTests(unittest.TestCase):
self.assertEqual(request.META['REQUEST_METHOD'], 'bogus') self.assertEqual(request.META['REQUEST_METHOD'], 'bogus')
self.assertEqual(request.META['SCRIPT_NAME'], '') self.assertEqual(request.META['SCRIPT_NAME'], '')
def test_wsgirequest_repr(self):
request = WSGIRequest({'PATH_INFO': '/somepath/', 'REQUEST_METHOD': 'get', 'wsgi.input': StringIO('')})
request.GET = {u'get-key': u'get-value'}
request.POST = {u'post-key': u'post-value'}
request.COOKIES = {u'post-key': u'post-value'}
request.META = {u'post-key': u'post-value'}
self.assertEqual(repr(request), u"<WSGIRequest\npath:/somepath/,\nGET:{u'get-key': u'get-value'},\nPOST:{u'post-key': u'post-value'},\nCOOKIES:{u'post-key': u'post-value'},\nMETA:{u'post-key': u'post-value'}>")
self.assertEqual(build_request_repr(request), repr(request))
self.assertEqual(build_request_repr(request, path_override='/otherpath/', GET_override={u'a': u'b'}, POST_override={u'c': u'd'}, COOKIES_override={u'e': u'f'}, META_override={u'g': u'h'}),
u"<WSGIRequest\npath:/otherpath/,\nGET:{u'a': u'b'},\nPOST:{u'c': u'd'},\nCOOKIES:{u'e': u'f'},\nMETA:{u'g': u'h'}>")
def test_modpythonrequest(self): def test_modpythonrequest(self):
class FakeModPythonRequest(ModPythonRequest): class FakeModPythonRequest(ModPythonRequest):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@ -45,6 +68,22 @@ class RequestsTests(unittest.TestCase):
self.assertEqual(request.COOKIES.keys(), []) self.assertEqual(request.COOKIES.keys(), [])
self.assertEqual(request.META.keys(), []) self.assertEqual(request.META.keys(), [])
def test_modpythonrequest_repr(self):
class Dummy:
def get_options(self):
return {}
req = Dummy()
req.uri = '/somepath/'
request = ModPythonRequest(req)
request._get = {u'get-key': u'get-value'}
request._post = {u'post-key': u'post-value'}
request._cookies = {u'post-key': u'post-value'}
request._meta = {u'post-key': u'post-value'}
self.assertEqual(repr(request), u"<ModPythonRequest\npath:/somepath/,\nGET:{u'get-key': u'get-value'},\nPOST:{u'post-key': u'post-value'},\nCOOKIES:{u'post-key': u'post-value'},\nMETA:{u'post-key': u'post-value'}>")
self.assertEqual(build_request_repr(request), repr(request))
self.assertEqual(build_request_repr(request, path_override='/otherpath/', GET_override={u'a': u'b'}, POST_override={u'c': u'd'}, COOKIES_override={u'e': u'f'}, META_override={u'g': u'h'}),
u"<ModPythonRequest\npath:/otherpath/,\nGET:{u'a': u'b'},\nPOST:{u'c': u'd'},\nCOOKIES:{u'e': u'f'},\nMETA:{u'g': u'h'}>")
def test_parse_cookie(self): def test_parse_cookie(self):
self.assertEqual(parse_cookie('invalid:key=true'), {}) self.assertEqual(parse_cookie('invalid:key=true'), {})