First part of setting request.path correctly.

Still needs:
    - testing
    - docs changes
    - some way of fixing reverse().


git-svn-id: http://code.djangoproject.com/svn/django/trunk@7991 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Malcolm Tredinnick 2008-07-19 19:32:01 +00:00
parent e8dd3855c1
commit b653cdcfb2
6 changed files with 45 additions and 9 deletions

View File

@ -3,6 +3,7 @@ import sys
from django import http from django import http
from django.core import signals from django.core import signals
from django.dispatch import dispatcher from django.dispatch import dispatcher
from django.utils.encoding import force_unicode
class BaseHandler(object): class BaseHandler(object):
# Changes that are always applied to a response (in this order). # Changes that are always applied to a response (in this order).
@ -73,7 +74,8 @@ class BaseHandler(object):
resolver = urlresolvers.RegexURLResolver(r'^/', urlconf) resolver = urlresolvers.RegexURLResolver(r'^/', urlconf)
try: try:
callback, callback_args, callback_kwargs = resolver.resolve(request.path) callback, callback_args, callback_kwargs = resolver.resolve(
request.path_info)
# Apply view middleware # Apply view middleware
for middleware_method in self._view_middleware: for middleware_method in self._view_middleware:
@ -170,3 +172,20 @@ class BaseHandler(object):
response = func(request, response) response = func(request, response)
return response return response
def get_script_name(environ):
"""
Returns the equivalent of the HTTP request's SCRIPT_NAME environment
variable. If Apache mod_rewrite has been used, returns what would have been
the script name prior to any rewriting (so it's the script name as seen
from the client's perspective).
Note: this isn't used by the mod_python handler, since the equivalent of
SCRIPT_NAME isn't available there.
"""
# If mod_rewrite had a whack at the URL, Apache set SCRIPT_URL to
# SCRIPT_NAME before applying any rewrites.
script_url = force_unicode(environ.get('SCRIPT_URL', ''))
if script_url:
return script_url
return force_unicode(environ.get('SCRIPT_NAME', ''))

View File

@ -16,6 +16,15 @@ class ModPythonRequest(http.HttpRequest):
def __init__(self, req): def __init__(self, req):
self._req = req self._req = req
self.path = force_unicode(req.uri) self.path = force_unicode(req.uri)
root = req.get_options().get('django.root', '')
self._django_root = root
# req.path_info isn't necessarily computed correctly in all
# circumstances (it's out of mod_python's control a bit), so we use
# req.uri and some string manipulations to get the right value.
if root and req.uri.startswith(root):
self.path_info = force_unicode(req.uri[len(root):])
else:
self.path_info = self.path
def __repr__(self): def __repr__(self):
# Since this is called as part of error handling, we need to be very # Since this is called as part of error handling, we need to be very
@ -100,7 +109,7 @@ class ModPythonRequest(http.HttpRequest):
'CONTENT_LENGTH': self._req.clength, # This may be wrong 'CONTENT_LENGTH': self._req.clength, # This may be wrong
'CONTENT_TYPE': self._req.content_type, # This may be wrong 'CONTENT_TYPE': self._req.content_type, # This may be wrong
'GATEWAY_INTERFACE': 'CGI/1.1', 'GATEWAY_INTERFACE': 'CGI/1.1',
'PATH_INFO': self._req.path_info, 'PATH_INFO': self.path_info,
'PATH_TRANSLATED': None, # Not supported 'PATH_TRANSLATED': None, # Not supported
'QUERY_STRING': self._req.args, 'QUERY_STRING': self._req.args,
'REMOTE_ADDR': self._req.connection.remote_ip, 'REMOTE_ADDR': self._req.connection.remote_ip,
@ -108,7 +117,7 @@ class ModPythonRequest(http.HttpRequest):
'REMOTE_IDENT': self._req.connection.remote_logname, 'REMOTE_IDENT': self._req.connection.remote_logname,
'REMOTE_USER': self._req.user, 'REMOTE_USER': self._req.user,
'REQUEST_METHOD': self._req.method, 'REQUEST_METHOD': self._req.method,
'SCRIPT_NAME': None, # Not supported 'SCRIPT_NAME': self._django_root,
'SERVER_NAME': self._req.server.server_hostname, 'SERVER_NAME': self._req.server.server_hostname,
'SERVER_PORT': self._req.server.port, 'SERVER_PORT': self._req.server.port,
'SERVER_PROTOCOL': self._req.protocol, 'SERVER_PROTOCOL': self._req.protocol,

View File

@ -7,7 +7,7 @@ except ImportError:
from django import http from django import http
from django.core import signals from django.core import signals
from django.core.handlers.base import BaseHandler from django.core.handlers import base
from django.dispatch import dispatcher from django.dispatch import dispatcher
from django.utils import datastructures from django.utils import datastructures
from django.utils.encoding import force_unicode from django.utils.encoding import force_unicode
@ -74,9 +74,14 @@ def safe_copyfileobj(fsrc, fdst, length=16*1024, size=0):
class WSGIRequest(http.HttpRequest): class WSGIRequest(http.HttpRequest):
def __init__(self, environ): def __init__(self, environ):
script_name = base.get_script_name()
path_info = force_unicode(environ.get('PATH_INFO', '/'))
self.environ = environ self.environ = environ
self.path = force_unicode(environ['PATH_INFO']) self.path_info = path_info
self.path = '%s%s' % (script_name, path_info)
self.META = environ self.META = environ
self.META['PATH_INFO'] = path_info
self.META['SCRIPT_NAME'] = script_name
self.method = environ['REQUEST_METHOD'].upper() self.method = environ['REQUEST_METHOD'].upper()
def __repr__(self): def __repr__(self):
@ -178,7 +183,7 @@ class WSGIRequest(http.HttpRequest):
REQUEST = property(_get_request) REQUEST = property(_get_request)
raw_post_data = property(_get_raw_post_data) raw_post_data = property(_get_raw_post_data)
class WSGIHandler(BaseHandler): class WSGIHandler(base.BaseHandler):
initLock = Lock() initLock = Lock()
request_class = WSGIRequest request_class = WSGIRequest

View File

@ -291,10 +291,11 @@ class RegexURLResolver(object):
def resolve(path, urlconf=None): def resolve(path, urlconf=None):
return get_resolver(urlconf).resolve(path) return get_resolver(urlconf).resolve(path)
def reverse(viewname, urlconf=None, args=None, kwargs=None): def reverse(viewname, urlconf=None, args=None, kwargs=None, prefix=u'/'):
args = args or [] args = args or []
kwargs = kwargs or {} kwargs = kwargs or {}
return iri_to_uri(u'/' + get_resolver(urlconf).reverse(viewname, *args, **kwargs)) return iri_to_uri(prefix +
get_resolver(urlconf).reverse(viewname, *args, **kwargs))
def clear_url_caches(): def clear_url_caches():
global _resolver_cache global _resolver_cache

View File

@ -31,6 +31,7 @@ class HttpRequest(object):
def __init__(self): def __init__(self):
self.GET, self.POST, self.COOKIES, self.META, self.FILES = {}, {}, {}, {}, {} self.GET, self.POST, self.COOKIES, self.META, self.FILES = {}, {}, {}, {}, {}
self.path = '' self.path = ''
self.path_info = ''
self.method = None self.method = None
def __repr__(self): def __repr__(self):
@ -442,3 +443,4 @@ def str_to_unicode(s, encoding):
return unicode(s, encoding, 'replace') return unicode(s, encoding, 'replace')
else: else:
return s return s

View File

@ -190,7 +190,7 @@ class Client:
'PATH_INFO': '/', 'PATH_INFO': '/',
'QUERY_STRING': '', 'QUERY_STRING': '',
'REQUEST_METHOD': 'GET', 'REQUEST_METHOD': 'GET',
'SCRIPT_NAME': None, 'SCRIPT_NAME': '',
'SERVER_NAME': 'testserver', 'SERVER_NAME': 'testserver',
'SERVER_PORT': 80, 'SERVER_PORT': 80,
'SERVER_PROTOCOL': 'HTTP/1.1', 'SERVER_PROTOCOL': 'HTTP/1.1',