def setup_kws_server(self): """ sets up the KWS server to run on a separate port """ # based on http://docs.cherrypy.org/stable/refman/process/servers.html if not self.config['keyword_search']['kws_service_on']: return # load KWSWebService here since it will be loaded after self.configure # which brings secmodv2 into cherrypy.tools from DAS.web.kws_web_srv import KWSWebService kws_service = KWSWebService(self.config) kws_wsgi_app = _cptree.Tree() kws_wsgi_app.mount(kws_service, '/das') config = self.config['web_server'] port = int(config.get("kws_port", 8214)) host = config.get("kws_host", '0.0.0.0') if CherryPyWSGIServer: kws_server = CherryPyWSGIServer( bind_addr=(host, port), wsgi_app=kws_wsgi_app, numthreads=int(config.get("thread_pool_kws", 10)), request_queue_size=cpconfig["server.socket_queue_size"], # below are cherrypy default settings... # max=-1, # timeout=10, # shutdown_timeout=5 ) srv_adapter = ServerAdapter(engine, kws_server) srv_adapter.subscribe()
def setup_kws_server(self): """ sets up the KWS server to run on a separate port """ # based on http://docs.cherrypy.org/stable/refman/process/servers.html if not self.config['keyword_search']['kws_service_on']: return kws_service = KWSWebService(self.config) kws_wsgi_app = _cptree.Tree() kws_wsgi_app.mount(kws_service, '/das') config = self.config['web_server'] port = int(config.get("kws_port", 8214)) host = config.get("kws_host", '0.0.0.0') kws_server = CherryPyWSGIServer( bind_addr=(host, port), wsgi_app=kws_wsgi_app, numthreads=int(config.get("thread_pool_kws", 10)), request_queue_size=cpconfig["server.socket_queue_size"], # below are cherrypy default settings... # max=-1, # timeout=10, # shutdown_timeout=5 ) srv_adapter = ServerAdapter(engine, kws_server) srv_adapter.subscribe()
def run(self): http_config = self.config['http'] https_config = self.config['https'] wsgi_app = wsgi.WSGIPathInfoDispatcher({'/': self.app}) cherrypy.server.unsubscribe() cherrypy.config.update({'environment': 'production'}) if https_config['enabled']: try: bind_addr_https = (https_config['listen'], https_config['port']) server_https = wsgi.WSGIServer(bind_addr=bind_addr_https, wsgi_app=wsgi_app) server_https.ssl_adapter = http_helpers.ssl_adapter( https_config['certificate'], https_config['private_key']) ServerAdapter(cherrypy.engine, server_https).subscribe() logger.debug( 'WSGIServer starting... uid: %s, listen: %s:%s', os.getuid(), bind_addr_https[0], bind_addr_https[1], ) except IOError as e: logger.warning("HTTPS server won't start: %s", e) else: logger.debug('HTTPS server is disabled') if http_config['enabled']: bind_addr_http = (http_config['listen'], http_config['port']) server_http = wsgi.WSGIServer(bind_addr=bind_addr_http, wsgi_app=wsgi_app) ServerAdapter(cherrypy.engine, server_http).subscribe() logger.debug( 'WSGIServer starting... uid: %s, listen: %s:%s', os.getuid(), bind_addr_http[0], bind_addr_http[1], ) else: logger.debug('HTTP server is disabled') if not http_config['enabled'] and not https_config['enabled']: logger.critical('No HTTP/HTTPS server enabled') exit() list_routes(self.app) try: cherrypy.engine.start() cherrypy.engine.wait(states.EXITING) except KeyboardInterrupt: logger.warning('Stopping wazo-phoned: KeyboardInterrupt') cherrypy.engine.exit()
def run_server(app): http_config = app.config['rest_api']['http'] https_config = app.config['rest_api']['https'] signal.signal(signal.SIGTERM, signal_handler) if app.config['profile']: app.wsgi_app = ProfilerMiddleware(app.wsgi_app, profile_dir=app.config['profile']) wsgi_app = wsgiserver.WSGIPathInfoDispatcher({'/': app}) cherrypy.server.unsubscribe() cherrypy.config.update({'environment': 'production'}) if not (http_config['enabled'] or https_config['enabled']): logger.critical('No HTTP/HTTPS server enabled') exit() if https_config['enabled']: try: bind_addr_https = (https_config['listen'], https_config['port']) server_https = CherryPyWSGIServer(bind_addr=bind_addr_https, wsgi_app=wsgi_app) server_https.ssl_adapter = http_helpers.ssl_adapter(https_config['certificate'], https_config['private_key'], https_config['ciphers']) ServerAdapter(cherrypy.engine, server_https).subscribe() logger.debug('HTTPS server starting on %s:%s', *bind_addr_https) except IOError as e: logger.warning("HTTPS server won't start: %s", e) else: logger.debug('HTTPS server is disabled') if http_config['enabled']: bind_addr_http = (http_config['listen'], http_config['port']) server_http = CherryPyWSGIServer(bind_addr=bind_addr_http, wsgi_app=wsgi_app) ServerAdapter(cherrypy.engine, server_http).subscribe() logger.debug('HTTP server starting on %s:%s', *bind_addr_http) else: logger.debug('HTTP server is disabled') try: cherrypy.engine.start() cherrypy.engine.block() except KeyboardInterrupt: cherrypy.engine.stop()
def run(self): wsgi_app_https = ReverseProxied( ProxyFix(wsgi.WSGIPathInfoDispatcher({'/': app}))) wsgi_app_http = ReverseProxied( ProxyFix(wsgi.WSGIPathInfoDispatcher({'/': adapter_app}))) cherrypy.server.unsubscribe() cherrypy.config.update({'environment': 'production'}) bind_addr = (self.config['listen'], self.config['port']) server_https = wsgi.WSGIServer(bind_addr=bind_addr, wsgi_app=wsgi_app_https) server_https.ssl_adapter = http_helpers.ssl_adapter( self.config['certificate'], self.config['private_key']) ServerAdapter(cherrypy.engine, server_https).subscribe() logger.debug('WSGIServer starting... uid: %s, listen: %s:%s', os.getuid(), bind_addr[0], bind_addr[1]) for route in http_helpers.list_routes(app): logger.debug(route) if self.adapter_config['enabled']: bind_addr = (self.adapter_config['listen'], self.adapter_config['port']) server_adapter = wsgi.WSGIServer(bind_addr=bind_addr, wsgi_app=wsgi_app_http) ServerAdapter(cherrypy.engine, server_adapter).subscribe() logger.debug('WSGIServer starting... uid: %s, listen: %s:%s', os.getuid(), bind_addr[0], bind_addr[1]) for route in http_helpers.list_routes(adapter_app): logger.debug(route) else: logger.debug('Adapter server is disabled') try: cherrypy.engine.start() cherrypy.engine.wait(states.EXITING) except KeyboardInterrupt: logger.warning('Stopping xivo-ctid-ng: KeyboardInterrupt') cherrypy.engine.exit()
def add_server(self, netloc, path, config): """Add a new CherryPy Application for a Virtual Host. Creates a new CherryPy WSGI Server instance if the host resolves to a different IP address or port. """ from cherrypy._cpwsgi_server import CPWSGIServer from cherrypy.process.servers import ServerAdapter host, port = urllib.splitnport(netloc, 80) host = socket.gethostbyname(host) bind_addr = (host, port) if bind_addr not in self.servers: self.servers.append(bind_addr) server = CPWSGIServer() server.bind_addr = bind_addr adapter = ServerAdapter(cherrypy.engine, server, server.bind_addr) adapter.subscribe() self.domains[netloc] = cherrypy.Application( root=None, config={path.rstrip('/') or '/': config})
def add_server(self, netloc, path, config): """Add a new CherryPy Application for a Virtual Host. Creates a new CherryPy WSGI Server instance if the host resolves to a different IP address or port. """ from cherrypy._cpwsgi_server import CPWSGIServer from cherrypy.process.servers import ServerAdapter host, port = urllib.splitnport(netloc, 80) host = socket.gethostbyname(host) bind_addr = (host, port) if bind_addr not in self.servers: self.servers.append(bind_addr) server = CPWSGIServer() server.bind_addr = bind_addr adapter = ServerAdapter(cherrypy.engine, server, server.bind_addr) adapter.subscribe() self.domains[netloc] = cherrypy.Application(root=None, config={path.rstrip('/') or '/': config})
def configure_http_server(port): # Mount the application from kolibri.deployment.default.wsgi import application whitenoise_settings = { "static_root": settings.STATIC_ROOT, "static_prefix": settings.STATIC_URL, # Use 1 day as the default cache time for static assets "max_age": 24 * 60 * 60, # Add a test for any file name that contains a semantic version number # or a 32 digit number (assumed to be a file hash) # these files will be cached indefinitely "immutable_file_test": r"((0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)|[a-f0-9]{32})", "autorefresh": getattr(settings, "DEVELOPER_MODE", False), } # Mount static files application = DjangoWhiteNoise(application, **whitenoise_settings) cherrypy.tree.graft(application, "/") # Mount media files cherrypy.tree.mount( cherrypy.tools.staticdir.handler(section="/", dir=settings.MEDIA_ROOT), settings.MEDIA_URL, ) # Mount content files CONTENT_ROOT = "/" + paths.get_content_url( conf.OPTIONS["Deployment"]["URL_PATH_PREFIX"]).lstrip("/") content_dirs = [paths.get_content_dir_path() ] + paths.get_content_fallback_paths() dispatcher = MultiStaticDispatcher(content_dirs) content_handler = cherrypy.tree.mount( None, CONTENT_ROOT, config={ "/": { "tools.caching.on": False, "request.dispatch": dispatcher } }, ) cherrypy_server_config = { "server.socket_host": LISTEN_ADDRESS, "server.socket_port": port, "server.thread_pool": conf.OPTIONS["Server"]["CHERRYPY_THREAD_POOL"], "server.socket_timeout": conf.OPTIONS["Server"]["CHERRYPY_SOCKET_TIMEOUT"], "server.accepted_queue_size": conf.OPTIONS["Server"]["CHERRYPY_QUEUE_SIZE"], "server.accepted_queue_timeout": conf.OPTIONS["Server"]["CHERRYPY_QUEUE_TIMEOUT"], } # Configure the server cherrypy.config.update(cherrypy_server_config) alt_port_addr = ( LISTEN_ADDRESS, conf.OPTIONS["Deployment"]["ZIP_CONTENT_PORT"], ) # Mount static files alt_port_app = wsgi.PathInfoDispatcher({ "/": get_application(), CONTENT_ROOT: content_handler }) alt_port_app = DjangoWhiteNoise(alt_port_app, **whitenoise_settings) alt_port_server = ServerAdapter( cherrypy.engine, wsgi.Server( alt_port_addr, alt_port_app, numthreads=conf.OPTIONS["Server"]["CHERRYPY_THREAD_POOL"], request_queue_size=conf.OPTIONS["Server"]["CHERRYPY_QUEUE_SIZE"], timeout=conf.OPTIONS["Server"]["CHERRYPY_SOCKET_TIMEOUT"], accepted_queue_size=conf.OPTIONS["Server"]["CHERRYPY_QUEUE_SIZE"], accepted_queue_timeout=conf.OPTIONS["Server"] ["CHERRYPY_QUEUE_TIMEOUT"], ), alt_port_addr, ) # Subscribe these servers cherrypy.server.subscribe() alt_port_server.subscribe()
def configure(): """ Configures the cherrypy server (sets up the tree, cherrypy config, etc.). """ global configured # Setup the session storage directory if it does not exist if config.get('sessions.on') and config.get('sessions.storage_type') == 'file': path = config['sessions.storage_path'] if not os.path.exists(path): try: os.makedirs(path) # By default these will be 0777 except: warnings.warn("Unable to create the session directory: {0}".format(path)) cherrypy.config.update({ "server.socket_host": config['server.socket_host'], "server.socket_port": config['server.socket_port'], "checker.on": False, "log.screen": False, #"engine.autoreload_on": False, "engine.autoreload_on": config.as_bool("debug"), "tools.sessions.on": config.as_bool('sessions.on'), "tools.sessions.persistent": config.as_bool('sessions.persistent'), "tools.sessions.path": config['sessions.path'], "tools.sessions.timeout": config['sessions.timeout'], "tools.sessions.storage_type": config['sessions.storage_type'], "tools.sessions.storage_path": config['sessions.storage_path'], "tools.sessions.secure": config['sessions.secure'], "request.show_tracebacks": config.as_bool("debug"), "checker.on": False, "tools.caching.on": False, "tools.expires.on": True, "tools.expires.secs": 0, "tools.expires.force": True, "tools.log_headers.on": False, "engine.autoreload_on": config.as_bool("debug"), "tools.encode.on": True, "tools.encode.encoding": "utf8", "error_page.default": error_handler }) if config['server.behind_proxy']: cherrypy.config.update({"tools.proxy.on": True}) if config['server.ssl_certificate']: # Make this conditional so we can host behind apache? cherrypy.config.update({ "server.ssl_certificate": config['server.ssl_certificate'], "server.ssl_private_key": config['server.ssl_private_key'], "server.ssl_certificate_chain": config['server.ssl_certificate_chain'], }) def rollback_dbsession(): log.info("Rolling back SA transaction.") session = meta.Session() session.rollback() def commit_dbsession(): log.info("Committing SA transaction.") session = meta.Session() session.commit() cherrypy.tools.dbsession_rollback = cherrypy.Tool('before_error_response', rollback_dbsession) cherrypy.tools.dbsession_commit = cherrypy.Tool('on_end_resource', commit_dbsession) # This is a "flow-control" exception. class _LoginFailed(Exception): pass # TODO: Refactor to combine with the ensconce.webapp.tree methods def checkpassword(realm, username, password): auth_providers = get_configured_providers() try: for auth_provider in auth_providers: try: auth_provider.authenticate(username, password) except exc.InsufficientPrivileges: # Fail fast in this case; we don't want to continue on to try other authenticators. raise _LoginFailed() except exc.AuthError: # Swallow other auth errors so it goes onto next authenticator in the list. pass except: # Other exceptions needs to get logged at least. log.exception("Unexpected error authenticating user using {0!r}".format(auth_provider)) else: log.info("Authentication succeeded for username {0} using provider {1}".format(username, auth_provider)) break else: log.debug("Authenticators exhausted; login failed.") raise _LoginFailed() except _LoginFailed: auditlog.log(auditlog.CODE_AUTH_FAILED, comment=username) return False else: # Resolve the user using the *current value* for auth_provider (as that is the one that passed the auth. user = auth_provider.resolve_user(username) log.debug("Setting up cherrypy session with username={0}, user_id={1}".format(username, user.id)) cherrypy.session['username'] = username # @UndefinedVariable cherrypy.session['user_id'] = user.id # @UndefinedVariable auditlog.log(auditlog.CODE_AUTH_LOGIN) return True app_conf = { "/static": { "tools.staticdir.on": True, "tools.staticdir.dir": config['static_dir'], "tools.staticdir.index": "index.html" }, "/jsonrpc": { 'tools.auth_basic.on': True, 'tools.auth_basic.realm': 'api', 'tools.auth_basic.checkpassword': checkpassword, } } # Add a plugin that will run the Crypto.Random.atfork() method, since this must # be called after forking (and we run this as a daemon in production) util.RNGInitializer(cherrypy.engine).subscribe() # Wire up our daemon tasks background_tasks = [] if config.get('sessions.on'): background_tasks.append(tasks.DaemonTask(tasks.remove_old_session_files, interval=60)) if config.get('backups.on'): backup_interval = config['backups.interval_minutes'] * 60 background_tasks.append(tasks.DaemonTask(tasks.backup_database, interval=backup_interval, wait_first=True)) background_tasks.append(tasks.DaemonTask(tasks.remove_old_backups, interval=3600, wait_first=True)) # This checks a day-granularity interval internally. # Unsubscribe anything that is already there, so that this method is idempotent # (This surfaces as nasty bugs in testing otherwise.) for channel in cherrypy.engine.listeners: for callback in cherrypy.engine.listeners[channel]: log.debug("Unsubscribing {0}:{1!r}".format(channel, callback)) # log.debug("Unsubscribing {0}:{1!r}".format(channel, callback)) # cherrypy.engine.unsubscribe(channel, callback) for task in background_tasks: cherrypy.engine.subscribe("start", task.start, priority=99) cherrypy.engine.subscribe("stop", task.stop) # Setup the basic/top-level webapp API root = tree.Root() # Iterate over all the modules in the ensconce.webapp.tree package and add # their 'Root' classes to the tree pkgpath = os.path.dirname(tree.__file__) for modname in [name for (_, name, _) in pkgutil.iter_modules([pkgpath])]: module = __import__("ensconce.webapp.tree." + modname, fromlist=["Root"]) module_root = module.Root() setattr(root, modname, module_root) # I think this is here because we want to explicitly specify the ServerAdapter below # rather than use a default one. cherrypy.server.unsubscribe() app = cherrypy.tree.mount(root, "/", app_conf) app.log.error_log.level = cherrypy.log.error_log.level # @UndefinedVariable app.log.access_log.level = cherrypy.log.access_log.level # @UndefinedVariable addr = (config["server.socket_host"], config["server.socket_port"]) server = CherryPyWSGIServer(addr, app, numthreads=50, timeout=2) # TODO: make numthreads and keepalive timeout configurable # TODO: This is also mentioned in the cherrypy config above .... ? One of these is probably redundant. server.ssl_certificate = config["server.ssl_certificate"] server.ssl_private_key = config["server.ssl_private_key"] if config["server.ssl_certificate_chain"]: server.ssl_certificate_chain = config["server.ssl_certificate_chain"] adapter = ServerAdapter(cherrypy.engine, server, server.bind_addr) adapter.subscribe() configured = True