Changeset 8015
- Timestamp:
- 07/21/08 02:57:10 (3 months ago)
- Files:
-
- django/trunk/django/conf/global_settings.py (modified) (1 diff)
- django/trunk/django/core/handlers/base.py (modified) (3 diffs)
- django/trunk/django/core/handlers/modpython.py (modified) (5 diffs)
- django/trunk/django/core/handlers/wsgi.py (modified) (4 diffs)
- django/trunk/django/core/urlresolvers.py (modified) (5 diffs)
- django/trunk/django/http/__init__.py (modified) (2 diffs)
- django/trunk/django/test/client.py (modified) (1 diff)
- django/trunk/django/utils/thread_support.py (added)
- django/trunk/django/utils/translation/trans_real.py (modified) (1 diff)
- django/trunk/docs/fastcgi.txt (modified) (3 diffs)
- django/trunk/docs/modpython.txt (modified) (3 diffs)
- django/trunk/docs/settings.txt (modified) (1 diff)
- django/trunk/tests/regressiontests/requests/tests.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/trunk/django/conf/global_settings.py
r7814 r8015 189 189 PREPEND_WWW = False 190 190 191 # Override the server-derived value of SCRIPT_NAME 192 FORCE_SCRIPT_NAME = None 193 191 194 # List of compiled regular expression objects representing User-Agent strings 192 195 # that are not allowed to visit any page, systemwide. Use this for bad django/trunk/django/core/handlers/base.py
r7995 r8015 4 4 from django.core import signals 5 5 from django.dispatch import dispatcher 6 from django.utils.encoding import force_unicode 6 7 7 8 class BaseHandler(object): … … 74 75 resolver = urlresolvers.RegexURLResolver(r'^/', urlconf) 75 76 try: 76 callback, callback_args, callback_kwargs = resolver.resolve(request.path) 77 callback, callback_args, callback_kwargs = resolver.resolve( 78 request.path_info) 77 79 78 80 # Apply view middleware … … 171 173 return response 172 174 175 def get_script_name(environ): 176 """ 177 Returns the equivalent of the HTTP request's SCRIPT_NAME environment 178 variable. If Apache mod_rewrite has been used, returns what would have been 179 the script name prior to any rewriting (so it's the script name as seen 180 from the client's perspective), unless DJANGO_USE_POST_REWRITE is set (to 181 anything). 182 """ 183 from django.conf import settings 184 if settings.FORCE_SCRIPT_NAME is not None: 185 return force_unicode(settings.FORCE_SCRIPT_NAME) 186 187 # If Apache's mod_rewrite had a whack at the URL, Apache set either 188 # SCRIPT_URL or REDIRECT_URL to the full resource URL before applying any 189 # rewrites. Unfortunately not every webserver (lighttpd!) passes this 190 # information through all the time, so FORCE_SCRIPT_NAME, above, is still 191 # needed. 192 script_url = environ.get('SCRIPT_URL', u'') 193 if not script_url: 194 script_url = environ.get('REDIRECT_URL', u'') 195 if script_url: 196 return force_unicode(script_url[:-len(environ.get('PATH_INFO', ''))]) 197 return force_unicode(environ.get('SCRIPT_NAME', u'')) 198 django/trunk/django/core/handlers/modpython.py
r7995 r8015 5 5 from django.core import signals 6 6 from django.core.handlers.base import BaseHandler 7 from django.core.urlresolvers import set_script_prefix 7 8 from django.dispatch import dispatcher 8 9 from django.utils import datastructures … … 16 17 def __init__(self, req): 17 18 self._req = req 19 # FIXME: This isn't ideal. The request URI may be encoded (it's 20 # non-normalized) slightly differently to the "real" SCRIPT_NAME 21 # and PATH_INFO values. This causes problems when we compute path_info, 22 # below. For now, don't use script names that will be subject to 23 # encoding/decoding. 18 24 self.path = force_unicode(req.uri) 25 root = req.get_options().get('django.root', '') 26 self.django_root = root 27 # req.path_info isn't necessarily computed correctly in all 28 # circumstances (it's out of mod_python's control a bit), so we use 29 # req.uri and some string manipulations to get the right value. 30 if root and req.uri.startswith(root): 31 self.path_info = force_unicode(req.uri[len(root):]) 32 else: 33 self.path_info = self.path 19 34 20 35 def __repr__(self): … … 101 116 'CONTENT_TYPE': self._req.content_type, # This may be wrong 102 117 'GATEWAY_INTERFACE': 'CGI/1.1', 103 'PATH_INFO': self. _req.path_info,118 'PATH_INFO': self.path_info, 104 119 'PATH_TRANSLATED': None, # Not supported 105 120 'QUERY_STRING': self._req.args, … … 109 124 'REMOTE_USER': self._req.user, 110 125 'REQUEST_METHOD': self._req.method, 111 'SCRIPT_NAME': None, # Not supported126 'SCRIPT_NAME': self.django_root, 112 127 'SERVER_NAME': self._req.server.server_hostname, 113 128 'SERVER_PORT': self._req.server.port, … … 154 169 self.load_middleware() 155 170 171 set_script_prefix(req.get_options().get('django.root', '')) 156 172 dispatcher.send(signal=signals.request_started) 157 173 try: django/trunk/django/core/handlers/wsgi.py
r7995 r8015 8 8 from django import http 9 9 from django.core import signals 10 from django.core.handlers.base import BaseHandler 10 from django.core.handlers import base 11 from django.core.urlresolvers import set_script_prefix 11 12 from django.dispatch import dispatcher 12 13 from django.utils import datastructures … … 75 76 class WSGIRequest(http.HttpRequest): 76 77 def __init__(self, environ): 78 script_name = base.get_script_name(environ) 79 path_info = force_unicode(environ.get('PATH_INFO', '/')) 77 80 self.environ = environ 78 self.path = force_unicode(environ['PATH_INFO']) 81 self.path_info = path_info 82 self.path = '%s%s' % (script_name, path_info) 79 83 self.META = environ 84 self.META['PATH_INFO'] = path_info 85 self.META['SCRIPT_NAME'] = script_name 80 86 self.method = environ['REQUEST_METHOD'].upper() 81 87 … … 179 185 raw_post_data = property(_get_raw_post_data) 180 186 181 class WSGIHandler( BaseHandler):187 class WSGIHandler(base.BaseHandler): 182 188 initLock = Lock() 183 189 request_class = WSGIRequest … … 195 201 self.initLock.release() 196 202 203 set_script_prefix(base.get_script_name(environ)) 197 204 dispatcher.send(signal=signals.request_started) 198 205 try: django/trunk/django/core/urlresolvers.py
r7995 r8015 7 7 (view_function, function_args, function_kwargs) 8 8 """ 9 10 import re 9 11 10 12 from django.http import Http404 … … 12 14 from django.utils.encoding import iri_to_uri, force_unicode, smart_str 13 15 from django.utils.functional import memoize 14 import re 16 from django.utils.thread_support import currentThread 15 17 16 18 try: … … 21 23 _resolver_cache = {} # Maps urlconf modules to RegexURLResolver instances. 22 24 _callable_cache = {} # Maps view and url pattern names to their view functions. 25 26 # SCRIPT_NAME prefixes for each thread are stored here. If there's no entry for 27 # the current thread (which is the only one we ever access), it is assumed to 28 # be empty. 29 _prefixes = {} 23 30 24 31 class Resolver404(Http404): … … 292 299 return get_resolver(urlconf).resolve(path) 293 300 294 def reverse(viewname, urlconf=None, args=None, kwargs=None ):301 def reverse(viewname, urlconf=None, args=None, kwargs=None, prefix=None): 295 302 args = args or [] 296 303 kwargs = kwargs or {} 297 return iri_to_uri(u'/' + get_resolver(urlconf).reverse(viewname, *args, **kwargs)) 304 if prefix is None: 305 prefix = get_script_prefix() 306 return iri_to_uri(u'%s%s' % (prefix, get_resolver(urlconf).reverse(viewname, 307 *args, **kwargs))) 298 308 299 309 def clear_url_caches(): … … 302 312 _resolver_cache.clear() 303 313 _callable_cache.clear() 314 315 def set_script_prefix(prefix): 316 """ 317 Sets the script prefix for the current thread. 318 """ 319 if not prefix.endswith('/'): 320 prefix += '/' 321 _prefixes[currentThread()] = prefix 322 323 def get_script_prefix(): 324 """ 325 Returns the currently active script prefix. Useful for client code that 326 wishes to construct their own URLs manually (although accessing the request 327 instance is normally going to be a lot cleaner). 328 """ 329 return _prefixes.get(currentThread(), u'/') 330 django/trunk/django/http/__init__.py
r7995 r8015 32 32 self.GET, self.POST, self.COOKIES, self.META, self.FILES = {}, {}, {}, {}, {} 33 33 self.path = '' 34 self.path_info = '' 34 35 self.method = None 35 36 … … 443 444 else: 444 445 return s 446 django/trunk/django/test/client.py
r7995 r8015 191 191 'QUERY_STRING': '', 192 192 'REQUEST_METHOD': 'GET', 193 'SCRIPT_NAME': None,193 'SCRIPT_NAME': '', 194 194 'SERVER_NAME': 'testserver', 195 195 'SERVER_PORT': 80, django/trunk/django/utils/translation/trans_real.py
r7995 r8015 9 9 10 10 from django.utils.safestring import mark_safe, SafeData 11 12 try: 13 import threading 14 hasThreads = True 15 except ImportError: 16 hasThreads = False 17 18 if hasThreads: 19 currentThread = threading.currentThread 20 else: 21 def currentThread(): 22 return 'no threading' 11 from django.utils.thread_support import currentThread 23 12 24 13 # Translations are cached in a dictionary for every language+app tuple. django/trunk/docs/fastcgi.txt
r7294 r8015 80 80 list of all the available options. 81 81 82 You'll need to specify either a ``socket``, ``protocol`` or both ``host`` and ``port``.83 Then, when you set up your Web server, you'll just need to point it at the host/port84 or socket you specified when starting the FastCGI server.82 You'll need to specify either a ``socket``, ``protocol`` or both ``host`` and 83 ``port``. Then, when you set up your Web server, you'll just need to point it 84 at the host/port or socket you specified when starting the FastCGI server. 85 85 86 86 Protocols … … 209 209 210 210 .. _mod_rewrite: http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html 211 212 Django will automatically use the pre-rewrite version of the URL when 213 constructing URLs with the ``{% url %}`` template tag (and similar methods). 211 214 212 215 lighttpd setup … … 337 340 .. _modpython: ../modpython/#serving-the-admin-files 338 341 342 Forcing the URL prefix to a particular value 343 ============================================ 344 345 Because many of these fastcgi-based solutions require rewriting the URL at 346 some point inside the webserver, the path information that Django sees may not 347 resemble the original URL that was passed in. This is a problem if the Django 348 application is being served from under a particular prefix and you want your 349 URLs from the ``{% url %}`` tag to look like the prefix, rather than the 350 rewritten version, which might contain, for example, ``mysite.fcgi``. 351 352 Django makes a good attempt to work out what the real script name prefix 353 should be. In particular, if the webserver sets the ``SCRIPT_URL`` (specific 354 to Apache's mod_rewrite), or ``REDIRECT_URL`` (set by a few servers, including 355 Apache + mod_rewrite in some situations), Django will work out the original 356 prefix automatically. 357 358 In the cases where Django cannot work out the prefix correctly and where you 359 wan the original value to be used in URLs, you can set the 360 ``FORCE_SCRIPT_NAME`` setting in your main ``settings`` file. This sets the 361 script name uniformly for every URL served via that settings file. Thus you'll 362 need to use different settings files is you want different sets of URLs to 363 have different script names in this case, but that is a rare situation. 364 365 As an example of how to use it, if your Django configuration is serving all of 366 the URLs under ``'/'`` and you wanted to use this setting, you would set 367 ``FORCE_SCRIPT_NAME = ''`` in your settings file. 368 django/trunk/docs/modpython.txt
r7294 r8015 36 36 PythonHandler django.core.handlers.modpython 37 37 SetEnv DJANGO_SETTINGS_MODULE mysite.settings 38 PythonOption django.root /mysite 38 39 PythonDebug On 39 40 </Location> … … 45 46 Django mod_python handler." It passes the value of ``DJANGO_SETTINGS_MODULE`` 46 47 so mod_python knows which settings to use. 48 49 **New in Django development version:** Because mod_python does not know we are 50 serving this site from underneath the ``/mysite/`` prefix, this value needs to 51 be passed through to the mod_python handler in Django, via the ``PythonOption 52 django.root ...`` line. The value set on that line (the last item) should 53 match the string given in the ``<Location ...>`` directive. The effect of this 54 is that Django will automatically strip the ``/mysite`` string from the front 55 of any URLs before matching them against your ``URLConf`` patterns. If you 56 later move your site to live under ``/mysite2``, you will not have to change 57 anything except the ``django.root`` option in the config file. 58 59 When using ``django.root`` you should make sure that what's left, after the 60 prefix has been removed, begins with a slash. Your URLConf patterns that are 61 expecting an initial slash will then work correctly. In the above example, 62 since we want to send things like ``/mysite/admin/`` to ``/admin/``, we need 63 to remove the string ``/mysite`` from the beginning, so that is the 64 ``django.root`` value. It would be an error to use ``/mysite/`` (with a 65 trailing slash) in this case. 47 66 48 67 Note that we're using the ``<Location>`` directive, not the ``<Directory>`` … … 60 79 PythonHandler django.core.handlers.modpython 61 80 SetEnv DJANGO_SETTINGS_MODULE mysite.settings 81 PythonOption django.root /mysite 62 82 PythonDebug On 63 83 **PythonPath "['/path/to/project'] + sys.path"** django/trunk/docs/settings.txt
r7965 r8015 578 578 579 579 .. _Testing Django Applications: ../testing/ 580 581 FORCE_SCRIPT_NAME 582 ------------------ 583 584 Default: ``None`` 585 586 If not ``None``, this will be used as the value of the ``SCRIPT_NAME`` 587 environment variable in any HTTP request. This setting can be used to override 588 the server-provided value of ``SCRIPT_NAME``, which may be a rewritten version 589 of the preferred value or not supplied at all. 580 590 581 591 IGNORABLE_404_ENDS django/trunk/tests/regressiontests/requests/tests.py
r7294 r8015 21 21 ... super(FakeModPythonRequest, self).__init__(*args, **kwargs) 22 22 ... self._get = self._post = self._meta = self._cookies = {} 23 >>> class Dummy: pass 24 ... 23 >>> class Dummy: 24 ... def get_options(self): 25 ... return {} 25 26 >>> req = Dummy() 26 27 >>> req.uri = 'bogus'
