Changed BaseHandler.get_response() to take a single parameter (an HttpRequest object) rather than a URL and the HttpRequest object, which is redundant
git-svn-id: http://code.djangoproject.com/svn/django/trunk@3875 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
0cc1815170
commit
15e7805ae4
|
@ -48,7 +48,7 @@ class BaseHandler(object):
|
||||||
if hasattr(mw_instance, 'process_exception'):
|
if hasattr(mw_instance, 'process_exception'):
|
||||||
self._exception_middleware.insert(0, mw_instance.process_exception)
|
self._exception_middleware.insert(0, mw_instance.process_exception)
|
||||||
|
|
||||||
def get_response(self, path, request):
|
def get_response(self, request):
|
||||||
"Returns an HttpResponse object for the given HttpRequest"
|
"Returns an HttpResponse object for the given HttpRequest"
|
||||||
from django.core import exceptions, urlresolvers
|
from django.core import exceptions, urlresolvers
|
||||||
from django.core.mail import mail_admins
|
from django.core.mail import mail_admins
|
||||||
|
@ -62,7 +62,7 @@ class BaseHandler(object):
|
||||||
|
|
||||||
resolver = urlresolvers.RegexURLResolver(r'^/', settings.ROOT_URLCONF)
|
resolver = urlresolvers.RegexURLResolver(r'^/', settings.ROOT_URLCONF)
|
||||||
try:
|
try:
|
||||||
callback, callback_args, callback_kwargs = resolver.resolve(path)
|
callback, callback_args, callback_kwargs = resolver.resolve(request.path)
|
||||||
|
|
||||||
# Apply view middleware
|
# Apply view middleware
|
||||||
for middleware_method in self._view_middleware:
|
for middleware_method in self._view_middleware:
|
||||||
|
@ -105,7 +105,7 @@ class BaseHandler(object):
|
||||||
exc_info = sys.exc_info()
|
exc_info = sys.exc_info()
|
||||||
receivers = dispatcher.send(signal=signals.got_request_exception)
|
receivers = dispatcher.send(signal=signals.got_request_exception)
|
||||||
# When DEBUG is False, send an error message to the admins.
|
# When DEBUG is False, send an error message to the admins.
|
||||||
subject = 'Error (%s IP): %s' % ((request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS and 'internal' or 'EXTERNAL'), getattr(request, 'path', ''))
|
subject = 'Error (%s IP): %s' % ((request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS and 'internal' or 'EXTERNAL'), request.path)
|
||||||
try:
|
try:
|
||||||
request_repr = repr(request)
|
request_repr = repr(request)
|
||||||
except:
|
except:
|
||||||
|
|
|
@ -150,7 +150,7 @@ class ModPythonHandler(BaseHandler):
|
||||||
dispatcher.send(signal=signals.request_started)
|
dispatcher.send(signal=signals.request_started)
|
||||||
try:
|
try:
|
||||||
request = ModPythonRequest(req)
|
request = ModPythonRequest(req)
|
||||||
response = self.get_response(req.uri, request)
|
response = self.get_response(request)
|
||||||
|
|
||||||
# Apply response middleware
|
# Apply response middleware
|
||||||
for middleware_method in self._response_middleware:
|
for middleware_method in self._response_middleware:
|
||||||
|
|
|
@ -74,7 +74,7 @@ class WSGIRequest(http.HttpRequest):
|
||||||
def __init__(self, environ):
|
def __init__(self, environ):
|
||||||
self.environ = environ
|
self.environ = environ
|
||||||
self.path = environ['PATH_INFO']
|
self.path = environ['PATH_INFO']
|
||||||
self.META = environ
|
self.META = environ
|
||||||
self.method = environ['REQUEST_METHOD'].upper()
|
self.method = environ['REQUEST_METHOD'].upper()
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
@ -186,7 +186,7 @@ class WSGIHandler(BaseHandler):
|
||||||
dispatcher.send(signal=signals.request_started)
|
dispatcher.send(signal=signals.request_started)
|
||||||
try:
|
try:
|
||||||
request = WSGIRequest(environ)
|
request = WSGIRequest(environ)
|
||||||
response = self.get_response(request.path, request)
|
response = self.get_response(request)
|
||||||
|
|
||||||
# Apply response middleware
|
# Apply response middleware
|
||||||
for middleware_method in self._response_middleware:
|
for middleware_method in self._response_middleware:
|
||||||
|
|
|
@ -8,7 +8,7 @@ from django.utils.functional import curry
|
||||||
|
|
||||||
class ClientHandler(BaseHandler):
|
class ClientHandler(BaseHandler):
|
||||||
"""
|
"""
|
||||||
A HTTP Handler that can be used for testing purposes.
|
A HTTP Handler that can be used for testing purposes.
|
||||||
Uses the WSGI interface to compose requests, but returns
|
Uses the WSGI interface to compose requests, but returns
|
||||||
the raw HttpResponse object
|
the raw HttpResponse object
|
||||||
"""
|
"""
|
||||||
|
@ -24,7 +24,7 @@ class ClientHandler(BaseHandler):
|
||||||
dispatcher.send(signal=signals.request_started)
|
dispatcher.send(signal=signals.request_started)
|
||||||
try:
|
try:
|
||||||
request = WSGIRequest(environ)
|
request = WSGIRequest(environ)
|
||||||
response = self.get_response(request.path, request)
|
response = self.get_response(request)
|
||||||
|
|
||||||
# Apply response middleware
|
# Apply response middleware
|
||||||
for middleware_method in self._response_middleware:
|
for middleware_method in self._response_middleware:
|
||||||
|
@ -32,7 +32,7 @@ class ClientHandler(BaseHandler):
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
dispatcher.send(signal=signals.request_finished)
|
dispatcher.send(signal=signals.request_finished)
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def store_rendered_templates(store, signal, sender, template, context):
|
def store_rendered_templates(store, signal, sender, template, context):
|
||||||
|
@ -44,7 +44,7 @@ def encode_multipart(boundary, data):
|
||||||
"""
|
"""
|
||||||
A simple method for encoding multipart POST data from a dictionary of
|
A simple method for encoding multipart POST data from a dictionary of
|
||||||
form values.
|
form values.
|
||||||
|
|
||||||
The key will be used as the form data name; the value will be transmitted
|
The key will be used as the form data name; the value will be transmitted
|
||||||
as content. If the value is a file, the contents of the file will be sent
|
as content. If the value is a file, the contents of the file will be sent
|
||||||
as an application/octet-stream; otherwise, str(value) will be sent.
|
as an application/octet-stream; otherwise, str(value) will be sent.
|
||||||
|
@ -69,7 +69,7 @@ def encode_multipart(boundary, data):
|
||||||
'',
|
'',
|
||||||
str(value)
|
str(value)
|
||||||
])
|
])
|
||||||
|
|
||||||
lines.extend([
|
lines.extend([
|
||||||
'--' + boundary + '--',
|
'--' + boundary + '--',
|
||||||
'',
|
'',
|
||||||
|
@ -78,8 +78,8 @@ def encode_multipart(boundary, data):
|
||||||
|
|
||||||
class Client:
|
class Client:
|
||||||
"""
|
"""
|
||||||
A class that can act as a client for testing purposes.
|
A class that can act as a client for testing purposes.
|
||||||
|
|
||||||
It allows the user to compose GET and POST requests, and
|
It allows the user to compose GET and POST requests, and
|
||||||
obtain the response that the server gave to those requests.
|
obtain the response that the server gave to those requests.
|
||||||
The server Response objects are annotated with the details
|
The server Response objects are annotated with the details
|
||||||
|
@ -88,7 +88,7 @@ class Client:
|
||||||
|
|
||||||
Client objects are stateful - they will retain cookie (and
|
Client objects are stateful - they will retain cookie (and
|
||||||
thus session) details for the lifetime of the Client instance.
|
thus session) details for the lifetime of the Client instance.
|
||||||
|
|
||||||
This is not intended as a replacement for Twill/Selenium or
|
This is not intended as a replacement for Twill/Selenium or
|
||||||
the like - it is here to allow testing against the
|
the like - it is here to allow testing against the
|
||||||
contexts and templates produced by a view, rather than the
|
contexts and templates produced by a view, rather than the
|
||||||
|
@ -98,10 +98,10 @@ class Client:
|
||||||
self.handler = ClientHandler()
|
self.handler = ClientHandler()
|
||||||
self.defaults = defaults
|
self.defaults = defaults
|
||||||
self.cookie = SimpleCookie()
|
self.cookie = SimpleCookie()
|
||||||
|
|
||||||
def request(self, **request):
|
def request(self, **request):
|
||||||
"""
|
"""
|
||||||
The master request method. Composes the environment dictionary
|
The master request method. Composes the environment dictionary
|
||||||
and passes to the handler, returning the result of the handler.
|
and passes to the handler, returning the result of the handler.
|
||||||
Assumes defaults for the query environment, which can be overridden
|
Assumes defaults for the query environment, which can be overridden
|
||||||
using the arguments to the request.
|
using the arguments to the request.
|
||||||
|
@ -112,24 +112,24 @@ class Client:
|
||||||
'PATH_INFO': '/',
|
'PATH_INFO': '/',
|
||||||
'QUERY_STRING': '',
|
'QUERY_STRING': '',
|
||||||
'REQUEST_METHOD': 'GET',
|
'REQUEST_METHOD': 'GET',
|
||||||
'SCRIPT_NAME': None,
|
'SCRIPT_NAME': None,
|
||||||
'SERVER_NAME': 'testserver',
|
'SERVER_NAME': 'testserver',
|
||||||
'SERVER_PORT': 80,
|
'SERVER_PORT': 80,
|
||||||
'SERVER_PROTOCOL': 'HTTP/1.1',
|
'SERVER_PROTOCOL': 'HTTP/1.1',
|
||||||
}
|
}
|
||||||
environ.update(self.defaults)
|
environ.update(self.defaults)
|
||||||
environ.update(request)
|
environ.update(request)
|
||||||
|
|
||||||
# Curry a data dictionary into an instance of
|
# Curry a data dictionary into an instance of
|
||||||
# the template renderer callback function
|
# the template renderer callback function
|
||||||
data = {}
|
data = {}
|
||||||
on_template_render = curry(store_rendered_templates, data)
|
on_template_render = curry(store_rendered_templates, data)
|
||||||
dispatcher.connect(on_template_render, signal=signals.template_rendered)
|
dispatcher.connect(on_template_render, signal=signals.template_rendered)
|
||||||
|
|
||||||
response = self.handler(environ)
|
response = self.handler(environ)
|
||||||
|
|
||||||
# Add any rendered template detail to the response
|
# Add any rendered template detail to the response
|
||||||
# If there was only one template rendered (the most likely case),
|
# If there was only one template rendered (the most likely case),
|
||||||
# flatten the list to a single element
|
# flatten the list to a single element
|
||||||
for detail in ('template', 'context'):
|
for detail in ('template', 'context'):
|
||||||
if data.get(detail):
|
if data.get(detail):
|
||||||
|
@ -139,12 +139,12 @@ class Client:
|
||||||
setattr(response, detail, data[detail])
|
setattr(response, detail, data[detail])
|
||||||
else:
|
else:
|
||||||
setattr(response, detail, None)
|
setattr(response, detail, None)
|
||||||
|
|
||||||
if response.cookies:
|
if response.cookies:
|
||||||
self.cookie.update(response.cookies)
|
self.cookie.update(response.cookies)
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def get(self, path, data={}, **extra):
|
def get(self, path, data={}, **extra):
|
||||||
"Request a response from the server using GET."
|
"Request a response from the server using GET."
|
||||||
r = {
|
r = {
|
||||||
|
@ -155,12 +155,12 @@ class Client:
|
||||||
'REQUEST_METHOD': 'GET',
|
'REQUEST_METHOD': 'GET',
|
||||||
}
|
}
|
||||||
r.update(extra)
|
r.update(extra)
|
||||||
|
|
||||||
return self.request(**r)
|
return self.request(**r)
|
||||||
|
|
||||||
def post(self, path, data={}, **extra):
|
def post(self, path, data={}, **extra):
|
||||||
"Request a response from the server using POST."
|
"Request a response from the server using POST."
|
||||||
|
|
||||||
BOUNDARY = 'BoUnDaRyStRiNg'
|
BOUNDARY = 'BoUnDaRyStRiNg'
|
||||||
|
|
||||||
encoded = encode_multipart(BOUNDARY, data)
|
encoded = encode_multipart(BOUNDARY, data)
|
||||||
|
@ -173,25 +173,25 @@ class Client:
|
||||||
'wsgi.input': stream,
|
'wsgi.input': stream,
|
||||||
}
|
}
|
||||||
r.update(extra)
|
r.update(extra)
|
||||||
|
|
||||||
return self.request(**r)
|
return self.request(**r)
|
||||||
|
|
||||||
def login(self, path, username, password, **extra):
|
def login(self, path, username, password, **extra):
|
||||||
"""
|
"""
|
||||||
A specialized sequence of GET and POST to log into a view that
|
A specialized sequence of GET and POST to log into a view that
|
||||||
is protected by a @login_required access decorator.
|
is protected by a @login_required access decorator.
|
||||||
|
|
||||||
path should be the URL of the page that is login protected.
|
path should be the URL of the page that is login protected.
|
||||||
|
|
||||||
Returns the response from GETting the requested URL after
|
Returns the response from GETting the requested URL after
|
||||||
login is complete. Returns False if login process failed.
|
login is complete. Returns False if login process failed.
|
||||||
"""
|
"""
|
||||||
# First, GET the page that is login protected.
|
# First, GET the page that is login protected.
|
||||||
# This page will redirect to the login page.
|
# This page will redirect to the login page.
|
||||||
response = self.get(path)
|
response = self.get(path)
|
||||||
if response.status_code != 302:
|
if response.status_code != 302:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
login_path, data = response['Location'].split('?')
|
login_path, data = response['Location'].split('?')
|
||||||
next = data.split('=')[1]
|
next = data.split('=')[1]
|
||||||
|
|
||||||
|
@ -199,7 +199,7 @@ class Client:
|
||||||
response = self.get(login_path, **extra)
|
response = self.get(login_path, **extra)
|
||||||
if response.status_code != 200:
|
if response.status_code != 200:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Last, POST the login data.
|
# Last, POST the login data.
|
||||||
form_data = {
|
form_data = {
|
||||||
'username': username,
|
'username': username,
|
||||||
|
|
Loading…
Reference in New Issue