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

Changeset 1309

Show
Ignore:
Timestamp:
09/02/06 02:09:33
Author:
fumanchu
Message:

Moved _wsgi_callable to _cptree, and we now import _cpwsgi as cherrypy.wsgi. Also made App.__call__ route to App.wsgiapp so the latter can be replaced by user code (i.e. it's not a special method).

Files:

Legend:

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

    r1307 r1309  
    1616tree = _cptree.Tree() 
    1717from cherrypy._cptree import Application 
     18from cherrypy import _cpwsgi as wsgi 
    1819from cherrypy import _cpengine 
    1920engine = _cpengine.Engine() 
  • trunk/cherrypy/_cptree.py

    r1305 r1309  
    1 from cherrypy import _cpconfig, _cplogging, _cpwsgi 
     1"""CherryPy Application and Tree objects.""" 
     2 
     3import sys 
     4import cherrypy 
     5from cherrypy import _cpconfig, _cplogging 
     6from cherrypy._cperror import format_exc, bare_error 
     7from cherrypy.lib import http 
    28 
    39 
     
    6874        return scheme + host + self.script_name 
    6975     
     76    def wsgiapp(self, environ, start_response): 
     77        # This is here instead of __call__ because it's really hard 
     78        # to overwrite special methods like __call__ per instance. 
     79        return wsgi_handler(environ, start_response, app=self) 
     80     
    7081    def __call__(self, environ, start_response): 
    71         return _cpwsgi._wsgi_callable(environ, start_response, app=self) 
     82        return self.wsgiapp(environ, start_response) 
     83 
     84 
     85headerNames = {'HTTP_CGI_AUTHORIZATION': 'Authorization', 
     86               'CONTENT_LENGTH': 'Content-Length', 
     87               'CONTENT_TYPE': 'Content-Type', 
     88               'REMOTE_HOST': 'Remote-Host', 
     89               'REMOTE_ADDR': 'Remote-Addr', 
     90               } 
     91 
     92def translate_headers(environ): 
     93    """Translate CGI-environ header names to HTTP header names.""" 
     94    for cgiName in environ: 
     95        # We assume all incoming header keys are uppercase already. 
     96        if cgiName in headerNames: 
     97            yield headerNames[cgiName], environ[cgiName] 
     98        elif cgiName[:5] == "HTTP_": 
     99            # Hackish attempt at recovering original header names. 
     100            translatedHeader = cgiName[5:].replace("_", "-") 
     101            yield translatedHeader, environ[cgiName] 
     102 
     103 
     104def wsgi_handler(environ, start_response, app): 
     105    request = None 
     106    try: 
     107        env = environ.get 
     108        local = http.Host('', int(env('SERVER_PORT', 80)), 
     109                          env('SERVER_NAME', '')) 
     110        remote = http.Host(env('REMOTE_ADDR', ''), 
     111                           int(env('REMOTE_PORT', -1)), 
     112                           env('REMOTE_HOST', '')) 
     113        request = cherrypy.engine.request(local, remote, 
     114                                          env('wsgi.url_scheme'), 
     115                                          env('ACTUAL_SERVER_PROTOCOL', "HTTP/1.1")) 
     116         
     117        # LOGON_USER is served by IIS, and is the name of the 
     118        # user after having been mapped to a local account. 
     119        # Both IIS and Apache set REMOTE_USER, when possible. 
     120        request.login = env('LOGON_USER') or env('REMOTE_USER') or None 
     121         
     122        request.multithread = environ['wsgi.multithread'] 
     123        request.multiprocess = environ['wsgi.multiprocess'] 
     124        request.wsgi_environ = environ 
     125         
     126        request.app = app 
     127         
     128        path = env('SCRIPT_NAME', '') + env('PATH_INFO', '') 
     129        response = request.run(environ['REQUEST_METHOD'], path, 
     130                               env('QUERY_STRING'), 
     131                               env('SERVER_PROTOCOL'), 
     132                               translate_headers(environ), 
     133                               environ['wsgi.input']) 
     134        s, h, b = response.status, response.header_list, response.body 
     135        exc = None 
     136    except (KeyboardInterrupt, SystemExit), ex: 
     137        try: 
     138            if request: 
     139                request.close() 
     140        except: 
     141            cherrypy.log(traceback=True) 
     142        request = None 
     143        raise ex 
     144    except: 
     145        if request and request.throw_errors: 
     146            raise 
     147        tb = format_exc() 
     148        cherrypy.log(tb) 
     149        if request and not request.show_tracebacks: 
     150            tb = "" 
     151        s, h, b = bare_error(tb) 
     152        exc = sys.exc_info() 
     153     
     154    try: 
     155        start_response(s, h, exc) 
     156        for chunk in b: 
     157            # WSGI requires all data to be of type "str". This coercion should 
     158            # not take any time at all if chunk is already of type "str". 
     159            # If it's unicode, it could be a big performance hit (x ~500). 
     160            if not isinstance(chunk, str): 
     161                chunk = chunk.encode("ISO-8859-1") 
     162            yield chunk 
     163        if request: 
     164            request.close() 
     165        request = None 
     166    except (KeyboardInterrupt, SystemExit), ex: 
     167        try: 
     168            if request: 
     169                request.close() 
     170        except: 
     171            cherrypy.log(traceback=True) 
     172        request = None 
     173        raise ex 
     174    except: 
     175        cherrypy.log(traceback=True) 
     176        try: 
     177            if request: 
     178                request.close() 
     179        except: 
     180            cherrypy.log(traceback=True) 
     181        request = None 
     182        s, h, b = bare_error() 
     183        # CherryPy test suite expects bare_error body to be output, 
     184        # so don't call start_response (which, according to PEP 333, 
     185        # may raise its own error at that point). 
     186        for chunk in b: 
     187            if not isinstance(chunk, str): 
     188                chunk = chunk.encode("ISO-8859-1") 
     189            yield chunk 
    72190 
    73191 
  • trunk/cherrypy/_cpwsgi.py

    r1278 r1309  
    11"""WSGI interface (see PEP 333).""" 
    22 
    3 import sys 
    4 import cherrypy 
     3import cherrypy as _cherrypy 
    54from cherrypy import _cpwsgiserver 
    6 from cherrypy._cperror import format_exc, bare_error 
    7 from cherrypy.lib import http 
     5from cherrypy.lib import http as _http 
    86 
    9  
    10 headerNames = {'HTTP_CGI_AUTHORIZATION': 'Authorization', 
    11                'CONTENT_LENGTH': 'Content-Length', 
    12                'CONTENT_TYPE': 'Content-Type', 
    13                'REMOTE_HOST': 'Remote-Host', 
    14                'REMOTE_ADDR': 'Remote-Addr', 
    15                } 
    16  
    17 def translate_headers(environ): 
    18     """Translate CGI-environ header names to HTTP header names.""" 
    19     for cgiName in environ: 
    20         # We assume all incoming header keys are uppercase already. 
    21         if cgiName in headerNames: 
    22             yield headerNames[cgiName], environ[cgiName] 
    23         elif cgiName[:5] == "HTTP_": 
    24             # Hackish attempt at recovering original header names. 
    25             translatedHeader = cgiName[5:].replace("_", "-") 
    26             yield translatedHeader, environ[cgiName] 
    27  
    28  
    29 def _wsgi_callable(environ, start_response, app): 
    30     request = None 
    31     try: 
    32         env = environ.get 
    33         local = http.Host('', int(env('SERVER_PORT', 80)), 
    34                           env('SERVER_NAME', '')) 
    35         remote = http.Host(env('REMOTE_ADDR', ''), 
    36                            int(env('REMOTE_PORT', -1)), 
    37                            env('REMOTE_HOST', '')) 
    38         request = cherrypy.engine.request(local, remote, 
    39                                           env('wsgi.url_scheme'), 
    40                                           env('ACTUAL_SERVER_PROTOCOL', "HTTP/1.1")) 
    41          
    42         # LOGON_USER is served by IIS, and is the name of the 
    43         # user after having been mapped to a local account. 
    44         # Both IIS and Apache set REMOTE_USER, when possible. 
    45         request.login = env('LOGON_USER') or env('REMOTE_USER') or None 
    46          
    47         request.multithread = environ['wsgi.multithread'] 
    48         request.multiprocess = environ['wsgi.multiprocess'] 
    49         request.wsgi_environ = environ 
    50          
    51         request.app = app 
    52          
    53         path = env('SCRIPT_NAME', '') + env('PATH_INFO', '') 
    54         response = request.run(environ['REQUEST_METHOD'], path, 
    55                                env('QUERY_STRING'), 
    56                                env('SERVER_PROTOCOL'), 
    57                                translate_headers(environ), 
    58                                environ['wsgi.input']) 
    59         s, h, b = response.status, response.header_list, response.body 
    60         exc = None 
    61     except (KeyboardInterrupt, SystemExit), ex: 
    62         try: 
    63             if request: 
    64                 request.close() 
    65         except: 
    66             cherrypy.log(traceback=True) 
    67         request = None 
    68         raise ex 
    69     except: 
    70         if request and request.throw_errors: 
    71             raise 
    72         tb = format_exc() 
    73         cherrypy.log(tb) 
    74         if request and not request.show_tracebacks: 
    75             tb = "" 
    76         s, h, b = bare_error(tb) 
    77         exc = sys.exc_info() 
    78      
    79     try: 
    80         start_response(s, h, exc) 
    81         for chunk in b: 
    82             # WSGI requires all data to be of type "str". This coercion should 
    83             # not take any time at all if chunk is already of type "str". 
    84             # If it's unicode, it could be a big performance hit (x ~500). 
    85             if not isinstance(chunk, str): 
    86                 chunk = chunk.encode("ISO-8859-1") 
    87             yield chunk 
    88         if request: 
    89             request.close() 
    90         request = None 
    91     except (KeyboardInterrupt, SystemExit), ex: 
    92         try: 
    93             if request: 
    94                 request.close() 
    95         except: 
    96             cherrypy.log(traceback=True) 
    97         request = None 
    98         raise ex 
    99     except: 
    100         cherrypy.log(traceback=True) 
    101         try: 
    102             if request: 
    103                 request.close() 
    104         except: 
    105             cherrypy.log(traceback=True) 
    106         request = None 
    107         s, h, b = bare_error() 
    108         # CherryPy test suite expects bare_error body to be output, 
    109         # so don't call start_response (which, according to PEP 333, 
    110         # may raise its own error at that point). 
    111         for chunk in b: 
    112             if not isinstance(chunk, str): 
    113                 chunk = chunk.encode("ISO-8859-1") 
    114             yield chunk 
    1157 
    1168 
     
    12113     
    12214    def parse_request(self): 
    123         mhs = cherrypy.server.max_request_header_size 
     15        mhs = _cherrypy.server.max_request_header_size 
    12416        if mhs > 0: 
    125             self.rfile = http.SizeCheckWrapper(self.rfile, mhs) 
     17            self.rfile = _http.SizeCheckWrapper(self.rfile, mhs) 
    12618         
    12719        try: 
    12820            _cpwsgiserver.HTTPRequest.parse_request(self) 
    129         except http.MaxSizeExceeded: 
     21        except _http.MaxSizeExceeded: 
    13022            self.simple_response("413 Request Entity Too Large") 
    131             cherrypy.log(traceback=True) 
     23            _cherrypy.log(traceback=True) 
    13224     
    13325    def decode_chunked(self): 
    13426        """Decode the 'chunked' transfer coding.""" 
    135         if isinstance(self.rfile, http.SizeCheckWrapper): 
     27        if isinstance(self.rfile, _http.SizeCheckWrapper): 
    13628            self.rfile = self.rfile.rfile 
    137         mbs = cherrypy.server.max_request_body_size 
     29        mbs = _cherrypy.server.max_request_body_size 
    13830        if mbs > 0: 
    139             self.rfile = http.SizeCheckWrapper(self.rfile, mbs) 
     31            self.rfile = _http.SizeCheckWrapper(self.rfile, mbs) 
    14032        try: 
    14133            return _cpwsgiserver.HTTPRequest.decode_chunked(self) 
    142         except http.MaxSizeExceeded: 
     34        except _http.MaxSizeExceeded: 
    14335            self.simple_response("413 Request Entity Too Large") 
    144             cherrypy.log(traceback=True) 
     36            _cherrypy.log(traceback=True) 
    14537            return False 
    14638 
     
    16456     
    16557    def __init__(self): 
    166         server = cherrypy.server 
     58        server = _cherrypy.server 
    16759        sockFile = server.socket_file 
    16860        if sockFile: 
     
    17466        # We could just pass cherrypy.tree, but by passing tree.apps, 
    17567        # we get correct SCRIPT_NAMEs as early as possible. 
    176         s.__init__(self, bind_addr, cherrypy.tree.apps.items(), 
     68        s.__init__(self, bind_addr, _cherrypy.tree.apps.items(), 
    17769                   server.thread_pool, 
    17870                   server.socket_host, 

Hosted by WebFaction

Log in as guest/cpguest to create tickets