Ticket #16360: 16360.1.diff

File 16360.1.diff, 10.8 KB (added by jezdez, 4 years ago)

Initial patch from https://github.com/jezdez/django/compare/feature/wsgi

  • django/conf/global_settings.py

    diff --git a/django/conf/global_settings.py b/django/conf/global_settings.py
    index fedea55..ff3b1c7 100644
    a b DEFAULT_INDEX_TABLESPACE = '' 
    412412# Default X-Frame-Options header value
    413413X_FRAME_OPTIONS = 'SAMEORIGIN'
    414414
     415# The import name of the WSGI application. If this is `None` the default
     416# 'django.core.handlers.wsgi.WSGIHandler' is used and instantiated.
     417# Otherwise this shall point to an actual WSGI application.
     418WSGI_APPLICATION = None
     419
    415420##############
    416421# MIDDLEWARE #
    417422##############
  • new file django/conf/project_template/wsgi.py

    diff --git a/django/conf/project_template/wsgi.py b/django/conf/project_template/wsgi.py
    new file mode 100644
    index 0000000..489062d
    - +  
     1"""
     2This module contains the actual WSGI application to be used by Django's
     3development server and the production environment as the global variable
     4named `application`.
     5
     6This can be used to apply WSGI middlewares::
     7
     8    from helloworld.wsgi import HelloWorldApplication
     9    application = HelloWorldApplication(application)
     10
     11Of course usually you would have an actual Django WSGI application there,
     12but it also might make sense to replace the whole Django WSGI application
     13with a custom one that later delegates to the Django one (for instance if
     14you want to combine a Django application with an application of another
     15framework).
     16
     17"""
     18from django.conf import settings
     19
     20# You can wrap the application object here to apply WSGI middlewares.
     21# The `application` object here is used by both the local runserver
     22# command as well as a properly configured WSGI server.
     23from django.core.handlers.wsgi import application
     24
     25# Apply other WSGI middlewares here.
     26# from helloworld.wsgi import HelloWorldApplication
     27# application = HelloWorldApplication(application)
  • django/contrib/staticfiles/handlers.py

    diff --git a/django/contrib/staticfiles/handlers.py b/django/contrib/staticfiles/handlers.py
    index b51b7c8..342ac79 100644
    a b class StaticFilesHandler(WSGIHandler): 
    1212    WSGI middleware that intercepts calls to the static files directory, as
    1313    defined by the STATIC_URL setting, and serves those files.
    1414    """
    15     def __init__(self, application, base_dir=None):
     15    def __init__(self, application, base_dir=None, enabled=True):
     16        # If not enabled this directly proxies to the given application.
     17        self.enabled = enabled
    1618        self.application = application
    1719        if base_dir:
    1820            self.base_dir = base_dir
    class StaticFilesHandler(WSGIHandler): 
    6466        return super(StaticFilesHandler, self).get_response(request)
    6567
    6668    def __call__(self, environ, start_response):
    67         if not self._should_handle(environ['PATH_INFO']):
    68             return self.application(environ, start_response)
    69         return super(StaticFilesHandler, self).__call__(environ, start_response)
     69        if self.enabled and self._should_handle(environ['PATH_INFO']):
     70            return super(StaticFilesHandler, self).__call__(environ, start_response)
     71        return self.application(environ, start_response)
  • django/contrib/staticfiles/management/commands/runserver.py

    diff --git a/django/contrib/staticfiles/management/commands/runserver.py b/django/contrib/staticfiles/management/commands/runserver.py
    index c6e56d2..9697736 100644
    a b class Command(BaseRunserverCommand): 
    2121        handler = super(Command, self).get_handler(*args, **options)
    2222        use_static_handler = options.get('use_static_handler', True)
    2323        insecure_serving = options.get('insecure_serving', False)
    24         if (settings.DEBUG and use_static_handler or
    25                 (use_static_handler and insecure_serving)):
    26             handler = StaticFilesHandler(handler)
    27         return handler
     24        enabled = (settings.DEBUG and use_static_handler or
     25                    (use_static_handler and insecure_serving))
     26        return StaticFilesHandler(handler, enabled=enabled)
  • django/core/handlers/wsgi.py

    diff --git a/django/core/handlers/wsgi.py b/django/core/handlers/wsgi.py
    index 2acb3b1..b7e429a 100644
    a b  
    1 from pprint import pformat
     1"""
     2WSGI entrypoints
     3
     4Overview
     5--------
     6
     7The motivation behind this module is to expose the WSGI application that
     8exists in Django to the actual Django user project. The idea is that you
     9have a documented way to apply WSGI middlewares that are then being used by
     10both the internal WSGI development server as well as any other WSGI server
     11in production.
     12
     13The way it works is that there are a handful of WSGI application objects:
     14
     15-   django.core.handlers.wsgi.WSGIHandler: this is the implementation of the
     16    actual Django WSGI dispatcher and it should be considered an
     17    implementation detail. While users are free to subclass and extend it,
     18    it's not necessarily supported.
     19-   django.core.handlers.wsgi.application: this is the documented WSGI
     20    application which is used by default.
     21-   django.core.handlers.wsgi.django_application: this is the actual WSGI
     22    application that is passed to the servers. It's internally proxying to
     23    the configured WSGI application and will most likely be a (decorated)
     24    version of the `application`.
     25
     26The reason why we have multiple applications here is because of the
     27ability to apply middlewares.  Basically `application` is the WSGI
     28application without any middlewarse applied, `django_application` is a
     29proxy to the base application + all applied middlewares.
     30
     31The middlewares are added according to the WSGI_APPLICATION configuration
     32setting which points to a module that imports the `application` as
     33`application` and can apply middlewares.
     34
     35If the WSGI_APPLICATION setting is ``None`` (which is the case for upgraded
     36applications from before we had exposed WSGI support) instead of the regular
     37application, the `application` is used.
     38
     39The WSGI_APPLICATION
     40--------------------
     41
     42The WSGI_APPLICATION configuration setting points to an actual WSGI
     43application.  By default the project generator will configure that a file
     44called `projectname.wsgi` exists and contains a global variable named
     45`application`. The contents look like this::
     46
     47    from django.core.handlers.wsgi import application
     48
     49This can be used to apply WSGI middlewares::
     50
     51    from helloworld.wsgi import HelloWorldApplication
     52    application = HelloWorldApplication(application)
     53
     54Of course usually you would have an actual Django WSGI application there, but
     55it also might make sense to replace the whole Django WSGI application with
     56a custom one that later delegates to the Django one (for instance if you
     57want to combine a Django application with an application of another framework).
     58
     59"""
     60from __future__ import with_statement
    261import sys
    362from threading import Lock
    463try:
    try: 
    665except ImportError:
    766    from StringIO import StringIO
    867import socket
     68import warnings
    969
    1070from django import http
    1171from django.core import signals
    from django.core.handlers import base 
    1373from django.core.urlresolvers import set_script_prefix
    1474from django.utils import datastructures
    1575from django.utils.encoding import force_unicode, iri_to_uri
     76from django.utils.importlib import import_module
    1677from django.utils.log import getLogger
    1778
    1879logger = getLogger('django.request')
    class WSGIHandler(base.BaseHandler): 
    212273    request_class = WSGIRequest
    213274
    214275    def __call__(self, environ, start_response):
    215         from django.conf import settings
    216 
    217276        # Set up middleware if needed. We couldn't do this earlier, because
    218277        # settings weren't available.
    219278        if self._request_middleware is None:
    class WSGIHandler(base.BaseHandler): 
    259318        start_response(status, response_headers)
    260319        return response
    261320
     321# the base WSGI application
     322application = WSGIHandler()
     323
     324
     325class DjangoWSGIApplication(object):
     326    """
     327    Implements a proxy to the actual WSGI application as configured
     328    by the user in settings.WSGI_APPLICATION which will usually be the
     329    `application`, optionally with middlewares applied.
     330    """
     331
     332    def __init__(self):
     333        self._instance = None
     334        self._instance_lock = Lock()
     335
     336    def __call__(self, environ, start_response):
     337        if self._instance is not None:
     338            application = self._instance
     339        else:
     340            with self._instance_lock:
     341                if self._instance is not None:
     342                    return self._instance
     343                from django.conf import settings
     344                if settings.WSGI_APPLICATION is None:
     345                    warnings.warn(
     346                        "The WSGI_APPLICATION setting has to be specified "
     347                        "to run Django.", PendingDeprecationWarning)
     348                else:
     349                    module_name, attr = settings.WSGI_APPLICATION.rsplit('.', 1)
     350                    application = getattr(import_module(module_name), attr)
     351                self._instance = application
     352        return application(environ, start_response)
     353
     354
     355django_application = DjangoWSGIApplication()
  • django/core/management/commands/runserver.py

    diff --git a/django/core/management/commands/runserver.py b/django/core/management/commands/runserver.py
    index 2e693e7..c84bf30 100644
    a b import sys 
    55import socket
    66
    77from django.core.management.base import BaseCommand, CommandError
    8 from django.core.handlers.wsgi import WSGIHandler
     8from django.core.handlers.wsgi import django_application
    99from django.core.servers.basehttp import AdminMediaHandler, run, WSGIServerException
    1010from django.utils import autoreload
    1111
    class BaseRunserverCommand(BaseCommand): 
    3737        """
    3838        Returns the default WSGI handler for the runner.
    3939        """
    40         return WSGIHandler()
     40        return django_application
    4141
    4242    def handle(self, addrport='', *args, **options):
    4343        self.use_ipv6 = options.get('use_ipv6')
  • django/core/servers/fastcgi.py

    diff --git a/django/core/servers/fastcgi.py b/django/core/servers/fastcgi.py
    index 7e724c2..75ef364 100644
    a b def runfastcgi(argset=[], **kwargs): 
    138138        return False
    139139
    140140    # Prep up and go
    141     from django.core.handlers.wsgi import WSGIHandler
     141    from django.core.handlers.wsgi import django_application
    142142
    143143    if options["host"] and options["port"] and not options["socket"]:
    144144        wsgi_opts['bindAddress'] = (options["host"], int(options["port"]))
    def runfastcgi(argset=[], **kwargs): 
    177177        fp.write("%d\n" % os.getpid())
    178178        fp.close()
    179179
    180     WSGIServer(WSGIHandler(), **wsgi_opts).run()
     180    WSGIServer(django_application, **wsgi_opts).run()
    181181
    182182if __name__ == '__main__':
    183183    runfastcgi(sys.argv[1:])
Back to Top