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

Changeset 1731

Show
Ignore:
Timestamp:
09/27/07 16:37:05
Author:
fumanchu
Message:

Finished porting [1711] to trunk.

Files:

Legend:

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

    r1730 r1731  
    6363class AppResponse(object): 
    6464     
    65     throws = (KeyboardInterrupt, SystemExit, _cherrypy.InternalRedirect
     65    throws = (KeyboardInterrupt, SystemExit
    6666    request = None 
    6767     
    68     def __init__(self, environ, start_response, cpapp): 
     68    def __init__(self, environ, start_response, cpapp, recursive=False): 
     69        self.redirections = [] 
     70        self.recursive = recursive 
     71        self.environ = environ 
     72        self.start_response = start_response 
    6973        self.cpapp = cpapp 
    70          
    71         try: 
    72             self.request = self.get_request(environ) 
    73              
    74             meth = environ['REQUEST_METHOD'] 
    75             path = _http.urljoin(environ.get('SCRIPT_NAME', ''), 
    76                                  environ.get('PATH_INFO', '')) 
    77             qs = environ.get('QUERY_STRING', '') 
    78             rproto = environ.get('SERVER_PROTOCOL') 
    79             headers = self.translate_headers(environ) 
    80             rfile = environ['wsgi.input'] 
    81              
    82             response = self.request.run(meth, path, qs, rproto, headers, rfile) 
    83             s, h, b = response.status, response.header_list, response.body 
     74        self.setapp() 
     75     
     76    def setapp(self): 
     77        # Stage 1: by whatever means necessary, obtain a status, header 
     78        #          set and body, with an optional exception object. 
     79        try: 
     80            self.request = self.get_request() 
     81            s, h, b = self.get_response() 
    8482            exc = None 
    8583        except self.throws: 
    8684            self.close() 
    8785            raise 
     86        except _cherrypy.InternalRedirect, ir: 
     87            self.environ['cherrypy.previous_request'] = _cherrypy.serving.request 
     88            self.close() 
     89            self.iredirect(ir.path, ir.query_string) 
     90            return 
    8891        except: 
    8992            if getattr(self.request, "throw_errors", False): 
     
    100103        self.iter_response = iter(b) 
    101104         
    102         try: 
    103             start_response(s, h, exc) 
     105        # Stage 2: now that we have a status, header set, and body, 
     106        #          finish the WSGI conversation by calling start_response. 
     107        try: 
     108            self.start_response(s, h, exc) 
    104109        except self.throws: 
    105110            self.close() 
     
    118123            s, h, b = _cperror.bare_error() 
    119124            self.iter_response = iter(b) 
     125     
     126    def iredirect(self, path, query_string): 
     127        """Doctor self.environ and perform an internal redirect. 
     128         
     129        When cherrypy.InternalRedirect is raised, this method is called. 
     130        It rewrites the WSGI environ using the new path and query_string, 
     131        and calls a new CherryPy Request object. Because the wsgi.input 
     132        stream may have already been consumed by the next application, 
     133        the redirected call will always be of HTTP method "GET"; therefore, 
     134        any params must be passed in the query_string argument, which is 
     135        formed from InternalRedirect.query_string when using that exception. 
     136        If you need something more complicated, make and raise your own 
     137        exception and write your own AppResponse subclass to trap it. ;) 
     138         
     139        It would be a bad idea to redirect after you've already yielded 
     140        response content, although an enterprising soul could choose 
     141        to abuse this. 
     142        """ 
     143        env = self.environ 
     144        if not self.recursive: 
     145            sn = env.get('SCRIPT_NAME', '') 
     146            qs = query_string 
     147            if qs: 
     148                qs = "?" + qs 
     149            if sn + path + qs in self.redirections: 
     150                raise RuntimeError("InternalRedirector visited the " 
     151                                   "same URL twice: %r + %r + %r" % 
     152                                   (sn, path, qs)) 
     153            else: 
     154                # Add the *previous* path_info + qs to redirections. 
     155                p = env.get('PATH_INFO', '') 
     156                qs = env.get('QUERY_STRING', '') 
     157                if qs: 
     158                    qs = "?" + qs 
     159                self.redirections.append(sn + p + qs) 
     160         
     161        # Munge environment and try again. 
     162        env['REQUEST_METHOD'] = "GET" 
     163        env['PATH_INFO'] = path 
     164        env['QUERY_STRING'] = query_string 
     165        env['wsgi.input'] = _StringIO.StringIO() 
     166        env['CONTENT_LENGTH'] = "0" 
     167         
     168        self.setapp() 
    120169     
    121170    def __iter__(self): 
     
    132181            return chunk 
    133182        except self.throws: 
     183            self.close() 
    134184            raise 
     185        except _cherrypy.InternalRedirect, ir: 
     186            self.environ['cherrypy.previous_request'] = _cherrypy.serving.request 
     187            self.close() 
     188            self.iredirect(ir.path, ir.query_string) 
    135189        except StopIteration: 
    136190            raise 
    137191        except: 
    138192            if getattr(self.request, "throw_errors", False): 
     193                self.close() 
    139194                raise 
    140195             
     
    152207        self.cpapp.release_serving() 
    153208     
    154     def get_request(self, environ): 
     209    def get_response(self): 
     210        """Grab a request object from the engine and return its response.""" 
     211        meth = self.environ['REQUEST_METHOD'] 
     212        path = _http.urljoin(self.environ.get('SCRIPT_NAME', ''), 
     213                             self.environ.get('PATH_INFO', '')) 
     214        qs = self.environ.get('QUERY_STRING', '') 
     215        rproto = self.environ.get('SERVER_PROTOCOL') 
     216        headers = self.translate_headers(self.environ) 
     217        rfile = self.environ['wsgi.input'] 
     218        response = self.request.run(meth, path, qs, rproto, headers, rfile) 
     219        return response.status, response.header_list, response.body 
     220     
     221    def get_request(self): 
    155222        """Create a Request object using environ.""" 
    156         env = environ.get 
     223        env = self.environ.get 
    157224         
    158225        local = _http.Host('', int(env('SERVER_PORT', 80)), 
     
    169236        # Both IIS and Apache set REMOTE_USER, when possible. 
    170237        request.login = env('LOGON_USER') or env('REMOTE_USER') or None 
    171         request.multithread = environ['wsgi.multithread'] 
    172         request.multiprocess = environ['wsgi.multiprocess'] 
    173         request.wsgi_environ = environ 
    174         request.prev = env('cherrypy.request') 
    175         environ['cherrypy.request'] = request 
     238        request.multithread = self.environ['wsgi.multithread'] 
     239        request.multiprocess = self.environ['wsgi.multiprocess'] 
     240        request.wsgi_environ = self.environ 
     241        request.prev = env('cherrypy.previous_request', None) 
    176242        return request 
    177243     
     
    213279    """ 
    214280     
    215     pipeline = [('iredir', InternalRedirector)
     281    pipeline = [
    216282    head = None 
    217283    config = {} 
  • trunk/cherrypy/test/benchmark.py

    r1726 r1731  
    101101    } 
    102102app = cherrypy.tree.mount(Root(), SCRIPT_NAME, appconf) 
    103 # Remove internalredirect (nastily on by default) 
    104 app.wsgiapp.pipeline = [] 
    105103 
    106104 

Hosted by WebFaction

Log in as guest/cpguest to create tickets