Skip to content

Commit

Permalink
Fixed #16178 - Cleanup request classes' __repr__()
Browse files Browse the repository at this point in the history
Thanks to julien for the patch.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@16350 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information
lukeplant committed Jun 9, 2011
1 parent 9d4d4bc commit 1c8a27c
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 84 deletions.
26 changes: 0 additions & 26 deletions django/core/handlers/modpython.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,32 +45,6 @@ def __init__(self, req):
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 = '<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):
# 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.
Expand Down
25 changes: 0 additions & 25 deletions django/core/handlers/wsgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,31 +157,6 @@ def __init__(self, environ):
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 = '<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):
# RFC 3986 requires query string arguments to be in the ASCII range.
# Rather than crash if this doesn't happen, we encode defensively.
Expand Down
52 changes: 49 additions & 3 deletions django/http/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 = '<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):
"""A basic HTTP request."""

Expand All @@ -146,11 +193,10 @@ def __init__(self):
self.path = ''
self.path_info = ''
self.method = None
self._post_parse_error = False

def __repr__(self):
return '<HttpRequest\nGET:%s,\nPOST:%s,\nCOOKIES:%s,\nMETA:%s>' % \
(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."""
Expand Down
31 changes: 2 additions & 29 deletions django/views/debug.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

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
Expand Down Expand Up @@ -96,34 +96,7 @@ def get_request_repr(self, request):
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 = '<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)))
return build_request_repr(request, POST_override=self.get_post_parameters(request))

def get_post_parameters(self, request):
if request is None:
Expand Down
41 changes: 40 additions & 1 deletion tests/regressiontests/requests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

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

Expand All @@ -16,6 +16,18 @@ def test_httprequest(self):
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"<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):
request = WSGIRequest({'PATH_INFO': 'bogus', 'REQUEST_METHOD': 'bogus', 'wsgi.input': StringIO('')})
self.assertEqual(request.GET.keys(), [])
Expand All @@ -26,6 +38,17 @@ def test_wsgirequest(self):
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"<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):
class FakeModPythonRequest(ModPythonRequest):
def __init__(self, *args, **kwargs):
Expand All @@ -45,6 +68,22 @@ def get_options(self):
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"<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):
self.assertEqual(parse_cookie('invalid:key=true'), {})

Expand Down

0 comments on commit 1c8a27c

Please sign in to comment.