from paste.util import import_string from paste.wsgilib import catch_errors from paste.deploy.converters import asbool from cherrypy._cpwsgi import wsgiApp import cherrypy import cherrypy.filters import threadobject cherrypy_installed = False def install(): global cherrypy_installed, default_config if cherrypy_installed: return import cherrypy import cherrypy.config import cherrypy._cputil cherrypy.server.start(initOnly=True, serverClass=None) try: default_config = cherrypy.config.configs except AttributeError: # CP 2.1 default_config = cherrypy.config.configMap cherrypy.root = FAKE_ROOT cherrypy.config.configs = FAKE_CONFIG cherrypy.config.configMap = FAKE_CONFIG cherrypy_installed = True cherrypy._cputil._cp_filters.insert( 0, PathFixingFilter()) class PathFixingFilter(object): def on_start_resource(self): script_name = FAKE_CONFIG.get('cherrypaste.real_script_name') path = cherrypy.request.object_path if path.startswith(script_name): if path == script_name: new_path = '/' else: new_path = path[len(script_name):] cherrypy.request.object_path = new_path cherrypy.request.app_path = script_name callbacks = FAKE_CONFIG.get('cherrypaste.set_script_name_callbacks') if callbacks: for callback in callbacks: callback(script_name, new_path) else: # @@: For some reason this error messages isn't getting # through...? exc = cherrypy.NotFound(path) exc.args = ( ('%s: Root path did not match WSGI SCRIPT_NAME of %r (got %r)' % (str(exc), script_name, path)), ) exc.message = exc.args[0] raise exc FAKE_ROOT = threadobject.FakeObject('cherrypy.root') FAKE_CONFIG = threadobject.FakeObject('cherrypy.config.configs') class CherryDispatcher(object): def __init__(self, conf, root_object): self.conf = default_config.copy() self.conf.update(conf) self.root_object = root_object def __call__(self, environ, start_response): def deregister(exc_info=None): FAKE_ROOT._FAKE_detach() FAKE_CONFIG._FAKE_detach() conf = self.conf.copy() conf.setdefault('cherrypaste.real_script_name', environ['SCRIPT_NAME']) if environ.get('paste.throw_errors'): conf['server.throw_errors'] = True FAKE_ROOT._FAKE_attach(self.root_object) FAKE_CONFIG._FAKE_attach(conf) return catch_errors(wsgiApp, environ, start_response, deregister, deregister) def make_app( global_conf, root_object, lazy_fake=False, **local_conf): lazy_fake = asbool(lazy_fake) if not lazy_fake: install() if isinstance(root_object, basestring): root_object = import_string.eval_import(root_object) if lazy_fake: install() complete_conf = global_conf.copy() complete_conf.update(local_conf) app = CherryDispatcher(complete_conf, root_object) return app