diff --git a/django/core/handlers/modpython.py b/django/core/handlers/modpython.py index f0c77015b49..5affea45c51 100644 --- a/django/core/handlers/modpython.py +++ b/django/core/handlers/modpython.py @@ -45,32 +45,6 @@ class ModPythonRequest(http.HttpRequest): self._stream = self._req 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 = '' - if self._post_parse_error: - post = '' - else: - try: - post = pformat(self.POST) - except: - post = '' - try: - cookies = pformat(self.COOKIES) - except: - cookies = '' - try: - meta = pformat(self.META) - except: - meta = '' - return smart_str(u'' % - (self.path, unicode(get), unicode(post), - unicode(cookies), unicode(meta))) - def get_full_path(self): # 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. diff --git a/django/core/handlers/wsgi.py b/django/core/handlers/wsgi.py index 434f91ccf3b..2acb3b1ee75 100644 --- a/django/core/handlers/wsgi.py +++ b/django/core/handlers/wsgi.py @@ -157,31 +157,6 @@ class WSGIRequest(http.HttpRequest): self._stream = self.environ['wsgi.input'] 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 = '' - if self._post_parse_error: - post = '' - else: - try: - post = pformat(self.POST) - except: - post = '' - try: - cookies = pformat(self.COOKIES) - except: - cookies = '' - try: - meta = pformat(self.META) - except: - meta = '' - return '' % \ - (get, post, cookies, meta) - def get_full_path(self): # RFC 3986 requires query string arguments to be in the ASCII range. # Rather than crash if this doesn't happen, we encode defensively. diff --git a/django/http/__init__.py b/django/http/__init__.py index 066346c1810..7f198a7b08e 100644 --- a/django/http/__init__.py +++ b/django/http/__init__.py @@ -134,6 +134,53 @@ class Http404(Exception): 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 = '' + if request._post_parse_error: + post = '' + else: + try: + post = (pformat(POST_override) + if POST_override is not None + else pformat(request.POST)) + except: + post = '' + try: + cookies = (pformat(COOKIES_override) + if COOKIES_override is not None + else pformat(request.COOKIES)) + except: + cookies = '' + try: + meta = (pformat(META_override) + if META_override is not None + else pformat(request.META)) + except: + meta = '' + 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): """A basic HTTP request.""" @@ -146,11 +193,10 @@ class HttpRequest(object): self.path = '' self.path_info = '' self.method = None + self._post_parse_error = False def __repr__(self): - return '' % \ - (pformat(self.GET), pformat(self.POST), pformat(self.COOKIES), - pformat(self.META)) + return build_request_repr(self) def get_host(self): """Returns the HTTP host using the environment or request headers.""" diff --git a/django/views/debug.py b/django/views/debug.py index 7401a51da6d..490d4bbecf3 100644 --- a/django/views/debug.py +++ b/django/views/debug.py @@ -7,7 +7,7 @@ from pprint import pformat from django.conf import settings from django.http import (HttpResponse, HttpResponseServerError, - HttpResponseNotFound, HttpRequest) + HttpResponseNotFound, HttpRequest, build_request_repr) from django.template import (Template, Context, TemplateDoesNotExist, TemplateSyntaxError) from django.template.defaultfilters import force_escape, pprint @@ -96,34 +96,7 @@ class ExceptionReporterFilter(object): if request is None: return repr(None) else: - # Since this is called as part of error handling, we need to be very - # robust against potentially malformed input. - try: - get = pformat(request.GET) - except: - get = '' - if request._post_parse_error: - post = '' - else: - try: - post = pformat(self.get_post_parameters(request)) - except: - post = '' - try: - cookies = pformat(request.COOKIES) - except: - cookies = '' - try: - meta = pformat(request.META) - except: - meta = '' - 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))) + return build_request_repr(request, POST_override=self.get_post_parameters(request)) def get_post_parameters(self, request): if request is None: diff --git a/tests/regressiontests/requests/tests.py b/tests/regressiontests/requests/tests.py index b68201494b4..703e387319b 100644 --- a/tests/regressiontests/requests/tests.py +++ b/tests/regressiontests/requests/tests.py @@ -4,7 +4,7 @@ from StringIO import StringIO from django.core.handlers.modpython import ModPythonRequest 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.http import cookie_date @@ -16,6 +16,18 @@ class RequestsTests(unittest.TestCase): self.assertEqual(request.COOKIES.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"") + 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"") + def test_wsgirequest(self): request = WSGIRequest({'PATH_INFO': 'bogus', 'REQUEST_METHOD': 'bogus', 'wsgi.input': StringIO('')}) self.assertEqual(request.GET.keys(), []) @@ -26,6 +38,17 @@ class RequestsTests(unittest.TestCase): self.assertEqual(request.META['REQUEST_METHOD'], 'bogus') 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"") + 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"") + def test_modpythonrequest(self): class FakeModPythonRequest(ModPythonRequest): def __init__(self, *args, **kwargs): @@ -45,6 +68,22 @@ class RequestsTests(unittest.TestCase): self.assertEqual(request.COOKIES.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"") + 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"") + def test_parse_cookie(self): self.assertEqual(parse_cookie('invalid:key=true'), {})