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

Ticket #455: wsgi_modifications_on_rev956.diff

  • cherrypy/_cpserver.py

    old new  
    77import warnings 
    88 
    99import cherrypy 
    10 from cherrypy import _cphttptools, filters 
     10from cherrypy import _cphttptools, filters, _cpwsgi 
    1111from cherrypy.lib import autoreload, profiler, cptools 
    1212 
    1313# Use a flag to indicate the state of the application server. 
     
    4141        self.onStartThreadList = [] 
    4242        self.onStartServerList = [] 
    4343        self.onStopThreadList = [] 
    44      
     44 
     45        self.cp_mount_point = '' 
     46        self.cp_wsgi_app = _cpwsgi.wsgiApp 
     47         
    4548    def start(self, init_only = False, server_class = _missing, **kwargs): 
    4649        """Main function. MUST be called from the main thread. 
    4750         
     
    153156            on_what = "socket file: %s" % cherrypy.config.get('server.socket_file') 
    154157         
    155158        # Instantiate the server. 
    156         self.httpserver = self.httpserverclass() 
     159        if self.httpserverclass == _cpwsgi.WSGIServer: 
     160            if self.cp_mount_point: 
     161                app = None 
     162                self.httpserver = self.httpserverclass(app) 
     163                self.httpserver.add_application(self.cp_mount_point, 
     164                                                self.cp_wsgi_app) 
     165            else: 
     166                self.httpserver = self.httpserverclass(self.cp_wsgi_app) 
     167             
     168        else: 
     169            self.httpserver = self.httpserverclass() 
    157170         
    158171        # HTTP servers MUST be started in a new thread, so that the 
    159172        # main thread persists to receive KeyboardInterrupt's. This 
  • cherrypy/_cpwsgi.py

    old new  
    148148                # Request header is parsed 
    149149                # We prepare the SizeCheckWrapper for the request body 
    150150                self.rfile.bytes_read = 0 
    151                 path = self.environ["SCRIPT_NAME"] 
     151                path = self.environ["PATH_INFO"] 
    152152                if path == "*": 
    153153                    path = "global" 
    154                 else: 
    155                     path = "/" + path 
    156154                mbs = int(cherrypy.config.get('server.max_request_body_size', 
    157155                                              100 * 1024 * 1024, path=path)) 
    158156                self.rfile.maxlen = mbs 
  • cherrypy/_cpwsgiserver.py

    old new  
    2424# de-dupe the list 
    2525socket_errors_to_ignore = dict.fromkeys(socket_errors_to_ignore).keys() 
    2626 
     27def not_found_app(environ, start_response): 
     28    status = '404 Not Found' 
     29    headers = [('Content-type', 'text/html')] 
     30    start_response(status, headers) 
     31    sn = environ.get('SCRIPT_NAME', '') 
     32    pi = environ.get('PATH_INFO', '') 
     33    rp = (sn + pi) or '/' 
     34    return ['Nothing found at %s' % rp] 
    2735 
    2836class HTTPRequest(object): 
    2937     
     
    4452        self.wfile = self.socket.makefile("w", self.bufsize) 
    4553        self.sent_headers = False 
    4654     
     55    def _find_sn_pi(self, path): 
     56        "find SCRIPT_NAME and PATH_INFO for requested path" 
     57        if path == '*': 
     58            return '', '*' 
     59        if path == '/': 
     60            return '', '/' 
     61        candidates = [] 
     62        for loc, app in self.server.apps.iteritems(): 
     63            if path.startswith(loc): 
     64                candidates.append(loc) 
     65        if not candidates: 
     66            return path, '' #, self.server.err_app 
     67        if len(candidates) == 1: 
     68            sn = candidates[0] 
     69            pi = path[len(sn):] 
     70        else: 
     71            sn = max(candidates) 
     72            pi = path[len(sn):] 
     73        return sn, pi #, self.server.apps[sn] 
     74 
    4775    def parse_request(self): 
    4876        self.sent_headers = False 
    4977        self.environ = {} 
     
    6492        else: 
    6593            qs = "" 
    6694        self.environ["REQUEST_METHOD"] = method 
    67         if path == "*": 
    68             self.environ["SCRIPT_NAME"] = path 
    69         else: 
    70             self.environ["SCRIPT_NAME"] = path[1:] 
    71         self.environ["PATH_INFO"] = "" 
     95        sn, pi = self._find_sn_pi(path) 
     96        self.environ["SCRIPT_NAME"] = sn 
     97        self.environ["PATH_INFO"] = pi 
    7298        self.environ["QUERY_STRING"] = qs 
    7399        self.environ["SERVER_PROTOCOL"] = version 
    74100        self.environ["SERVER_NAME"] = self.server.server_name 
     
    151177        self.server = server 
    152178        threading.Thread.__init__(self) 
    153179     
     180    def _get_app(self, mount_point): 
     181        return self.server.apps.get(mount_point, self.server.err_app) 
     182 
    154183    def run(self): 
    155184        try: 
    156185            self.ready = True 
     
    163192                    try: 
    164193                        request.parse_request() 
    165194                        if request.ready: 
    166                             response = self.server.wsgi_app(request.environ, 
    167                                                             request.start_response) 
     195                            mp = request.environ['SCRIPT_NAME'] 
     196                            wsgi_app = self._get_app(mp) 
     197                            response = wsgi_app(request.environ, 
     198                                                request.start_response) 
    168199                            for line in response: 
    169200                                request.write(line) 
    170201                    except socket.error, e: 
     
    188219    interrupt = None 
    189220    RequestHandlerClass = HTTPRequest 
    190221     
    191     def __init__(self, bind_addr, wsgi_app, numthreads=10, server_name=None, 
    192                  max=-1, request_queue_size=5): 
     222    def __init__(self, bind_addr, wsgi_app=None, numthreads=10, server_name=None, 
     223                 max=-1, request_queue_size=5, err_app=not_found_app): 
    193224        ''' 
    194225        be careful w/ max 
    195226        ''' 
    196227        self.requests = Queue.Queue(max) 
    197         self.wsgi_app = wsgi_app 
    198228        self.bind_addr = bind_addr 
    199229        self.numthreads = numthreads or 1 
    200230        if not server_name: 
     
    202232        self.server_name = server_name 
    203233        self.request_queue_size = request_queue_size 
    204234        self._workerThreads = [] 
    205      
     235        self.err_app = err_app 
     236        self.apps = {} 
     237        if wsgi_app: 
     238            self.add_application('', wsgi_app) 
     239         
     240    def add_application(self, mount_point, app): 
     241        self.apps[mount_point] = app 
     242 
    206243    def start(self): 
    207244        """Run the server forever.""" 
    208245        # We don't have to trap KeyboardInterrupt or SystemExit here, 
     
    303340                worker.join() 
    304341         
    305342        self._workerThreads = [] 
     343 
     344if __name__ == '__main__': 
     345    def hello_app(environ, start_response): 
     346        status = '200 OK' 
     347        headers = [('Content-type', 'text/html')] 
     348        start_response(status, headers) 
     349        yield '<h1>Hello, World!</h1>\n' 
     350        keys = environ.keys() 
     351        keys.sort() 
     352        for k in keys: 
     353            yield "%s = %s<br>\n" % (k, environ[k]) 
     354 
     355    server = CherryPyWSGIServer(('127.0.0.1', 8080)) 
     356    server.add_application('/hello', hello_app) 
     357    server.add_application('/test', hello_app) 
     358    try: 
     359        server.start() 
     360    except KeyboardInterrupt: 
     361        server.stop() 
     362 

Hosted by WebFaction

Log in as guest/cpguest to create tickets