Ticket #7930: handle-force-script-name.diff
File handle-force-script-name.diff, 10.8 KB (added by , 12 years ago) |
---|
-
django/contrib/staticfiles/handlers.py
diff --git a/django/contrib/staticfiles/handlers.py b/django/contrib/staticfiles/handlers.py index 5174586..f041f74 100644
a b except ImportError: # Python 2 7 7 8 8 from django.conf import settings 9 9 from django.core.handlers.base import get_path_info 10 from django.core.handlers.wsgi import WSGIHandler 10 from django.core.handlers.wsgi import WSGIHandler, UrlPrefixAwareMixin 11 11 12 12 from django.contrib.staticfiles import utils 13 13 from django.contrib.staticfiles.views import serve 14 14 15 class StaticFilesHandler( WSGIHandler):15 class StaticFilesHandler(UrlPrefixAwareMixin, WSGIHandler): 16 16 """ 17 17 WSGI middleware that intercepts calls to the static files directory, as 18 18 defined by the STATIC_URL setting, and serves those files. … … class StaticFilesHandler(WSGIHandler): 31 31 32 32 def get_base_url(self): 33 33 utils.check_settings() 34 return se ttings.STATIC_URL34 return self.fix_path(settings.STATIC_URL) 35 35 36 36 def _should_handle(self, path): 37 37 """ … … class StaticFilesHandler(WSGIHandler): 53 53 """ 54 54 Actually serves the request path. 55 55 """ 56 return serve(request, self.file_path(request.path), insecure=True) 56 path = self.fix_path(request.path) 57 return serve(request, self.file_path(path), insecure=True) 57 58 58 59 def get_response(self, request): 59 60 from django.http import Http404 60 61 61 if self._should_handle( request.path):62 if self._should_handle(self.fix_path(request.path)): 62 63 try: 63 64 return self.serve(request) 64 65 except Http404 as e: -
django/core/handlers/wsgi.py
diff --git a/django/core/handlers/wsgi.py b/django/core/handlers/wsgi.py index a9fa094..c25249c 100644
a b class WSGIHandler(base.BaseHandler): 266 266 response_headers.append((str('Set-Cookie'), str(c.output(header='')))) 267 267 start_response(force_str(status), response_headers) 268 268 return response 269 270 271 class UrlPrefixAwareMixin(object): 272 _url_prefix = None 273 _url_prefix_fetched = False 274 275 @property 276 def url_prefix(self): 277 """ 278 Get the FORCE_SCRIPT_NAME from settings or None 279 """ 280 if not self._url_prefix_fetched: 281 from django.conf import settings 282 self._url_prefix = getattr(settings, 'FORCE_SCRIPT_NAME', None) 283 self._url_prefix_fetched = True 284 return self._url_prefix 285 286 def fix_path(self, path): 287 """ 288 Strips FORCE_SCRIPT_NAME from the front of the url 289 """ 290 if self.url_prefix and path.startswith(self.url_prefix): 291 path = path[len(self.url_prefix):] 292 return path 293 294 def is_prefixed(self, path): 295 return not(self.url_prefix) or path.startswith(self.url_prefix) 296 297 298 class UrlPrefixAwareHandler(UrlPrefixAwareMixin, WSGIHandler): 299 """ 300 WSGI middleware that does nothing if FORCE_SCRIPT_NAME is not defined. 301 302 When FORCE_SCRIPT_NAME is defined: 303 * this middleware will strip it from PATH_INFO in the environ before 304 passing environ to the next handler 305 * requests that do not begin with FORCE_SCRIPT_NAME will receive a 306 400 Bad Request response 307 """ 308 def __init__(self, application): 309 self.application = application 310 super(UrlPrefixAwareHandler, self).__init__() 311 312 def get_response(self, request): 313 logger.warning('Bad Request (Prefixed url required when using FORCE_SCRIPT_NAME)', 314 extra={ 315 'status_code': 400, 316 } 317 ) 318 return http.HttpResponseBadRequest() 319 320 def __call__(self, environ, start_response): 321 if self.url_prefix: 322 path_info = base.get_path_info(environ) 323 if not self.is_prefixed(path_info): 324 return super(UrlPrefixAwareHandler, self).__call__(environ, start_response) 325 environ['PATH_INFO'] = self.fix_path(path_info) 326 return self.application(environ, start_response) -
django/core/management/commands/runserver.py
diff --git a/django/core/management/commands/runserver.py b/django/core/management/commands/runserver.py index 391e0b4..a4f71be 100644
a b import socket 7 7 8 8 from django.core.management.base import BaseCommand, CommandError 9 9 from django.core.servers.basehttp import run, WSGIServerException, get_internal_wsgi_application 10 from django.core.handlers.wsgi import UrlPrefixAwareHandler 10 11 from django.utils import autoreload 11 12 12 13 naiveip_re = re.compile(r"""^(?: … … class Command(BaseCommand): 110 111 111 112 try: 112 113 handler = self.get_handler(*args, **options) 114 handler = UrlPrefixAwareHandler(handler) 113 115 run(self.addr, int(self.port), handler, 114 116 ipv6=self.use_ipv6, threading=threading) 115 117 except WSGIServerException as e: -
django/test/signals.py
diff --git a/django/test/signals.py b/django/test/signals.py index a96bdff..3e8caf2 100644
a b def file_storage_changed(**kwargs): 79 79 if kwargs['setting'] in ('MEDIA_ROOT', 'DEFAULT_FILE_STORAGE'): 80 80 from django.core.files.storage import default_storage 81 81 default_storage._wrapped = empty 82 83 @receiver(setting_changed) 84 def fix_script_prefix(**kwargs): 85 if kwargs['setting'] == 'FORCE_SCRIPT_NAME': 86 from django.core.urlresolvers import set_script_prefix 87 set_script_prefix('/') 88 No newline at end of file -
django/test/testcases.py
diff --git a/django/test/testcases.py b/django/test/testcases.py index c311540..12b2151 100644
a b import threading 17 17 import errno 18 18 19 19 from django.conf import settings 20 from django.core.handlers.wsgi import UrlPrefixAwareHandler 20 21 from django.contrib.staticfiles.handlers import StaticFilesHandler 21 22 from django.core import mail 22 23 from django.core.exceptions import ValidationError, ImproperlyConfigured … … class _MediaFilesHandler(StaticFilesHandler): 1014 1015 return settings.MEDIA_ROOT 1015 1016 1016 1017 def get_base_url(self): 1017 return se ttings.MEDIA_URL1018 return self.fix_path(settings.MEDIA_URL) 1018 1019 1019 1020 def serve(self, request): 1020 relative_url = request.path[len(self.base_url[2]):] 1021 path = self.fix_path(request.path) 1022 relative_url = path[len(self.base_url[2]):] 1021 1023 return serve(request, relative_url, document_root=self.get_base_dir()) 1022 1024 1023 1025 … … class LiveServerThread(threading.Thread): 1049 1051 try: 1050 1052 # Create the handler for serving static and media files 1051 1053 handler = StaticFilesHandler(_MediaFilesHandler(WSGIHandler())) 1054 handler = UrlPrefixAwareHandler(handler) 1052 1055 1053 1056 # Go through the list of possible ports, hoping that we can find 1054 1057 # one that is free to use for the WSGI server. -
tests/regressiontests/handlers/tests.py
diff --git a/tests/regressiontests/handlers/tests.py b/tests/regressiontests/handlers/tests.py index 3557a63..5e92062 100644
a b 1 from django.core.handlers.wsgi import WSGIHandler 1 from django.core.handlers.wsgi import WSGIHandler, UrlPrefixAwareHandler 2 2 from django.core import signals 3 3 from django.test import RequestFactory, TestCase 4 4 from django.test.utils import override_settings … … class SignalsTests(TestCase): 58 58 self.assertEqual(self.signals, ['started']) 59 59 self.assertEqual(b''.join(response.streaming_content), b"streaming content") 60 60 self.assertEqual(self.signals, ['started', 'finished']) 61 62 63 @override_settings(FORCE_SCRIPT_NAME='/prefixed-example') 64 class PrefixedHandlerTests(TestCase): 65 urls = 'regressiontests.handlers.urls' 66 67 def test_unprefixed_path(self): 68 environ = RequestFactory().get('/regular/').environ 69 handler = UrlPrefixAwareHandler(WSGIHandler()) 70 response = handler(environ, lambda *a, **k: None) 71 self.assertEqual(response.status_code, 400) 72 73 def test_prefix_path(self): 74 environ = RequestFactory().get('/prefixed-example/regular/').environ 75 handler = UrlPrefixAwareHandler(WSGIHandler()) 76 response = handler(environ, lambda *a, **k: None) 77 self.assertEqual(response.content, b"regular content") -
tests/regressiontests/servers/tests.py
diff --git a/tests/regressiontests/servers/tests.py b/tests/regressiontests/servers/tests.py index 1a7552e..084fd78 100644
a b class LiveServerViews(LiveServerBase): 144 144 self.assertIn(b"QUERY_STRING: 'q=%D1%82%D0%B5%D1%81%D1%82'", f.read()) 145 145 146 146 147 class LiveServerUrlPrefixedViews(LiveServerBase): 148 149 @classmethod 150 def setUpClass(cls): 151 # Override settings 152 newsettings = {} 153 newsettings.update(TEST_SETTINGS) 154 newsettings.update({ 155 'FORCE_SCRIPT_NAME': '/live-example', 156 'MEDIA_URL': '/live-example/media/', 157 'STATIC_URL': '/live-example/static/', 158 }) 159 cls.settings_override = override_settings(**newsettings) 160 cls.settings_override.enable() 161 super(LiveServerBase, cls).setUpClass() 162 163 def test_bad_request(self): 164 """ 165 Ensure that the LiveServerTestCase serves 400s. 166 """ 167 try: 168 self.urlopen('/') 169 except HTTPError as err: 170 self.assertEqual(err.code, 400, 'Expected 400 response') 171 else: 172 self.fail('Expected 400 response') 173 174 def test_404(self): 175 """ 176 Ensure that the LiveServerTestCase serves 404s. 177 Refs #2879. 178 """ 179 try: 180 self.urlopen('/live-example/') 181 except HTTPError as err: 182 self.assertEqual(err.code, 404, 'Expected 404 response') 183 else: 184 self.fail('Expected 404 response') 185 186 def test_view(self): 187 """ 188 Ensure that the LiveServerTestCase serves views. 189 Refs #2879. 190 """ 191 f = self.urlopen('/live-example/example_view/') 192 self.assertEqual(f.read(), b'example view') 193 194 def test_static_files(self): 195 """ 196 Ensure that the LiveServerTestCase serves static files. 197 Refs #2879. 198 """ 199 f = self.urlopen('/live-example/static/example_static_file.txt') 200 self.assertEqual(f.read().rstrip(b'\r\n'), b'example static file') 201 202 def test_media_files(self): 203 """ 204 Ensure that the LiveServerTestCase serves media files. 205 Refs #2879. 206 """ 207 f = self.urlopen('/live-example/media/example_media_file.txt') 208 self.assertEqual(f.read().rstrip(b'\r\n'), b'example media file') 209 210 147 211 class LiveServerDatabase(LiveServerBase): 148 212 149 213 def test_fixtures_loaded(self):