Download Install Tutorial Docs FAQ Tools WikiLicense Team IRC Planet Involvement Shop Book

Changeset 1260

Show
Ignore:
Timestamp:
08/21/06 03:10:15
Author:
fumanchu
Message:

Fix for #553 (pure WSGI apps on the tree). Request.app now MUST be a cherrypy.Application instance (not None) before Request.run() is called.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/cherrypy/_cpmodpy.py

    r1251 r1260  
    9191        request.multiprocess = bool(forked) 
    9292         
    93         # Run the CherryPy Request object and obtain the response 
    94         headers = req.headers_in.items() 
    95         rfile = _ReadOnlyRequest(req) 
    96         response = request.run(req.method, req.uri, req.args or "", 
    97                                req.protocol, headers, rfile) 
    98          
    99         send_response(req, response.status, response.header_list, response.body) 
    100         request.close() 
     93        sn = cherrypy.tree.script_name(req.uri or "/") 
     94        if sn is None: 
     95            send_response(req, '404 Not Found', [], '') 
     96        else: 
     97            request.app = cherrypy.tree.apps[sn] 
     98             
     99            # Run the CherryPy Request object and obtain the response 
     100            headers = req.headers_in.items() 
     101            rfile = _ReadOnlyRequest(req) 
     102            response = request.run(req.method, req.uri, req.args or "", 
     103                                   req.protocol, headers, rfile) 
     104             
     105            send_response(req, response.status, response.header_list, response.body) 
     106            request.close() 
    101107    except: 
    102108        tb = format_exc() 
  • trunk/cherrypy/_cprequest.py

    r1254 r1260  
    161161            self.process_headers() 
    162162             
    163             if self.app is None: 
    164                 # Some interfaces (like WSGI) may have already set self.app. 
    165                 # If not, look up the app for this path. 
    166                 self.script_name = sn = cherrypy.tree.script_name(self.path) 
    167                 if sn is None: 
    168                     # No app was found to handle this path. Rather than 
    169                     # abort here, we leave self.app == None so NotFound 
    170                     # can be raised later (with proper error handling 
    171                     # and response finalization). See self.respond. 
    172                     self.script_name = "" 
    173                 else: 
    174                     self.app = cherrypy.tree.apps[sn] 
    175             else: 
    176                 self.script_name = self.app.script_name 
    177              
    178163            # path_info should be the path from the 
    179164            # app root (script_name) to the handler. 
     165            self.script_name = self.app.script_name 
    180166            self.path_info = self.path[len(self.script_name.rstrip("/")):] 
    181167             
  • trunk/cherrypy/_cptree.py

    r1250 r1260  
    11import logging 
    22 
    3 import cherrypy 
    43from cherrypy import config, _cpwsgi 
    54 
    65 
    7 class Application
     6class Application(object)
    87    """A CherryPy Application. 
    98     
     
    3837        if self._script_name is None: 
    3938            # None signals that the script name should be pulled from WSGI environ. 
     39            import cherrypy 
    4040            return cherrypy.request.wsgi_environ['SCRIPT_NAME'] 
    4141        return self._script_name 
    4242    def _set_script_name(self, value): 
    4343        self._script_name = value 
    44     script_name = property(_get_script_name, _set_script_name) 
     44    script_name = property(fget=_get_script_name, fset=_set_script_name) 
    4545     
    4646    def merge(self, conf): 
     
    149149     
    150150    def __call__(self, environ, start_response): 
    151         return _cpwsgi._wsgi_callable(environ, start_response) 
     151        # If you're calling this, then you're probably setting SCRIPT_NAME 
     152        # to '' (some WSGI servers always set SCRIPT_NAME to ''). 
     153        # Try to look up the app using the full path. 
     154        path = environ.get('SCRIPT_NAME', '') + environ.get('PATH_INFO', '') 
     155        sn = self.script_name(path or "/") 
     156        if sn is None: 
     157            start_response('404 Not Found', []) 
     158            return [] 
     159         
     160        app = self.apps[sn] 
     161         
     162        # Correct the SCRIPT_NAME and PATH_INFO environ entries. 
     163        environ = environ.copy() 
     164        environ['SCRIPT_NAME'] = sn 
     165        environ['PATH_INFO'] = path[len(sn.rstrip("/")):] 
     166        return app(environ, start_response) 
    152167 
  • trunk/cherrypy/_cpwsgi.py

    r1259 r1260  
    2727 
    2828 
    29 def _wsgi_callable(environ, start_response, app=None): 
     29def _wsgi_callable(environ, start_response, app): 
    3030    request = None 
    3131    try: 
     
    4747        request.wsgi_environ = environ 
    4848         
    49         if app: 
    50             request.app = app 
     49        request.app = app 
    5150         
    5251        path = env('SCRIPT_NAME', '') + env('PATH_INFO', '') 
     
    175174         
    176175        s = _cpwsgiserver.CherryPyWSGIServer 
    177         s.__init__(self, bind_addr, cherrypy.tree, 
     176        # We could just pass cherrypy.tree, but by passing tree.apps, 
     177        # we get correct SCRIPT_NAMEs as early as possible. 
     178        s.__init__(self, bind_addr, cherrypy.tree.apps.items(), 
    178179                   conf('server.thread_pool'), 
    179180                   conf('server.socket_host'), 
  • trunk/cherrypy/test/test_wsgiapps.py

    r1256 r1260  
    1919        for k in keys: 
    2020            yield '%s: %s\n' % (k,environ[k]) 
    21  
     21     
    2222    def reversing_middleware(app): 
    2323        def _app(environ, start_response): 
     
    5454    cherrypy.tree.graft(test_app, '/hosted/app1') 
    5555     
    56     app = cherrypy.Application(Root(), None) 
     56    # Set script_name explicitly to None to signal CP that it should 
     57    # be pulled from the WSGI environ each time. 
     58    app = cherrypy.Application(Root(), script_name=None) 
    5759    cherrypy.tree.graft(reversing_middleware(app), '/hosted/app2') 
    5860 

Hosted by WebFaction

Log in as guest/cpguest to create tickets