mirror of
https://github.com/django/django.git
synced 2025-11-07 07:15:35 +00:00
Fixed #16360 -- Added WSGI entrypoint to startproject layout, and enabled internal servers (runserver and runfcgi) to use an externally-defined WSGI application. Thanks to Armin Ronacher, Jannis Leidel, Alex Gaynor, ptone, and Jacob Kaplan-Moss.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@17022 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
@@ -242,8 +242,8 @@ 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), unless FORCE_SCRIPT_NAME is set (to
|
||||
anything).
|
||||
from the client's perspective), unless the FORCE_SCRIPT_NAME setting is
|
||||
set (to anything).
|
||||
"""
|
||||
from django.conf import settings
|
||||
if settings.FORCE_SCRIPT_NAME is not None:
|
||||
|
||||
@@ -124,6 +124,7 @@ class LimitedStream(object):
|
||||
self.buffer = sio.read()
|
||||
return line
|
||||
|
||||
|
||||
class WSGIRequest(http.HttpRequest):
|
||||
def __init__(self, environ):
|
||||
script_name = base.get_script_name(environ)
|
||||
@@ -202,13 +203,12 @@ class WSGIRequest(http.HttpRequest):
|
||||
FILES = property(_get_files)
|
||||
REQUEST = property(_get_request)
|
||||
|
||||
|
||||
class WSGIHandler(base.BaseHandler):
|
||||
initLock = Lock()
|
||||
request_class = WSGIRequest
|
||||
|
||||
def __call__(self, environ, start_response):
|
||||
from django.conf import settings
|
||||
|
||||
# Set up middleware if needed. We couldn't do this earlier, because
|
||||
# settings weren't available.
|
||||
if self._request_middleware is None:
|
||||
@@ -253,4 +253,3 @@ class WSGIHandler(base.BaseHandler):
|
||||
response_headers.append(('Set-Cookie', str(c.output(header=''))))
|
||||
start_response(status, response_headers)
|
||||
return response
|
||||
|
||||
|
||||
@@ -5,8 +5,7 @@ import sys
|
||||
import socket
|
||||
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
from django.core.handlers.wsgi import WSGIHandler
|
||||
from django.core.servers.basehttp import AdminMediaHandler, run, WSGIServerException
|
||||
from django.core.servers.basehttp import AdminMediaHandler, run, WSGIServerException, get_internal_wsgi_application
|
||||
from django.utils import autoreload
|
||||
|
||||
naiveip_re = re.compile(r"""^(?:
|
||||
@@ -37,7 +36,7 @@ class BaseRunserverCommand(BaseCommand):
|
||||
"""
|
||||
Returns the default WSGI handler for the runner.
|
||||
"""
|
||||
return WSGIHandler()
|
||||
return get_internal_wsgi_application()
|
||||
|
||||
def handle(self, addrport='', *args, **options):
|
||||
self.use_ipv6 = options.get('use_ipv6')
|
||||
|
||||
@@ -18,7 +18,10 @@ from wsgiref import simple_server
|
||||
from wsgiref.util import FileWrapper # for backwards compatibility
|
||||
|
||||
import django
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.core.management.color import color_style
|
||||
from django.core.wsgi import get_wsgi_application
|
||||
from django.utils.importlib import import_module
|
||||
from django.utils._os import safe_join
|
||||
from django.views import static
|
||||
|
||||
@@ -27,6 +30,43 @@ from django.contrib.staticfiles import handlers
|
||||
__all__ = ['WSGIServer', 'WSGIRequestHandler']
|
||||
|
||||
|
||||
def get_internal_wsgi_application():
|
||||
"""
|
||||
Loads and returns the WSGI application as configured by the user in
|
||||
``settings.WSGI_APPLICATION``. With the default ``startproject`` layout,
|
||||
this will be the ``application`` object in ``projectname/wsgi.py``.
|
||||
|
||||
This function, and the ``WSGI_APPLICATION`` setting itself, are only useful
|
||||
for Django's internal servers (runserver, runfcgi); external WSGI servers
|
||||
should just be configured to point to the correct application object
|
||||
directly.
|
||||
|
||||
If settings.WSGI_APPLICATION is not set (is ``None``), we just return
|
||||
whatever ``django.core.wsgi.get_wsgi_application`` returns.
|
||||
|
||||
"""
|
||||
from django.conf import settings
|
||||
app_path = getattr(settings, 'WSGI_APPLICATION')
|
||||
if app_path is None:
|
||||
return get_wsgi_application()
|
||||
module_name, attr = app_path.rsplit('.', 1)
|
||||
try:
|
||||
mod = import_module(module_name)
|
||||
except ImportError, e:
|
||||
raise ImproperlyConfigured(
|
||||
"WSGI application '%s' could not be loaded; "
|
||||
"could not import module '%s': %s" % (app_path, module_name, e))
|
||||
try:
|
||||
app = getattr(mod, attr)
|
||||
except AttributeError, e:
|
||||
raise ImproperlyConfigured(
|
||||
"WSGI application '%s' could not be loaded; "
|
||||
"can't find '%s' in module '%s': %s"
|
||||
% (app_path, attr, module_name, e))
|
||||
|
||||
return app
|
||||
|
||||
|
||||
class WSGIServerException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
@@ -139,7 +139,7 @@ def runfastcgi(argset=[], **kwargs):
|
||||
return False
|
||||
|
||||
# Prep up and go
|
||||
from django.core.handlers.wsgi import WSGIHandler
|
||||
from django.core.servers.basehttp import get_internal_wsgi_application
|
||||
|
||||
if options["host"] and options["port"] and not options["socket"]:
|
||||
wsgi_opts['bindAddress'] = (options["host"], int(options["port"]))
|
||||
@@ -178,7 +178,7 @@ def runfastcgi(argset=[], **kwargs):
|
||||
fp.write("%d\n" % os.getpid())
|
||||
fp.close()
|
||||
|
||||
WSGIServer(WSGIHandler(), **wsgi_opts).run()
|
||||
WSGIServer(get_internal_wsgi_application(), **wsgi_opts).run()
|
||||
|
||||
if __name__ == '__main__':
|
||||
runfastcgi(sys.argv[1:])
|
||||
|
||||
13
django/core/wsgi.py
Normal file
13
django/core/wsgi.py
Normal file
@@ -0,0 +1,13 @@
|
||||
from django.core.handlers.wsgi import WSGIHandler
|
||||
|
||||
|
||||
def get_wsgi_application():
|
||||
"""
|
||||
The public interface to Django's WSGI support. Should return a WSGI
|
||||
callable.
|
||||
|
||||
Allows us to avoid making django.core.handlers.WSGIHandler public API, in
|
||||
case the internal WSGI implementation changes or moves in the future.
|
||||
|
||||
"""
|
||||
return WSGIHandler()
|
||||
Reference in New Issue
Block a user