def __build_depot_http(self): """Build a DepotHTTP object to handle the current request.""" self.setup(cherrypy.request) headers = cherrypy.response.headers headers["Content-Type"] = "text/plain; charset=utf-8" toks = cherrypy.request.path_info.lstrip("/").split("/") repo_prefix = toks[0] if repo_prefix not in repositories: raise cherrypy.NotFound() repo = repositories[repo_prefix] depot_bui = depot_buis[repo_prefix] if repo_prefix in depot_https: return depot_https[repo_prefix] def request_pub_func(path_info): """A function that can be called to determine the publisher for a given request. We always want None here, to force DepotHTTP to fallback to the publisher information in the FMRI provided as part of the request, rather than the /publisher/ portion of path_info. """ return None depot_https[repo_prefix] = sd.DepotHTTP( repo, depot_bui.cfg, request_pub_func=request_pub_func) return depot_https[repo_prefix]
def start(self): if not port_available("localhost", self.__port): raise DepotStateException("A depot (or some " + "other network process) seems to be " + "running on port %d already!" % self.__port) # this uses the repo dir as the static content dir, which means that # static content will not work, but we don't need it anyway for what # we are doing. scfg = config.SvrConfig(self.__dir, self.__dir, depot.AUTH_DEFAULT, auto_create=True) scfg.init_dirs() scfg.acquire_in_flight() # we rebuild the catalog in a strange way here to avoid rebuilding # the index, which doesn't work scfg.acquire_catalog(rebuild=False) # prevent this depot from indexing scfg.catalog.searchdb_update_handle = DummyHandle() root = cherrypy.Application(sdepot.DepotHTTP(scfg, None)) cherrypy.config.update({ "environment": "production", "checker.on": True, "log.screen": False, "server.socket_port": self.__port, "server.thread_pool": depot.THREADS_DEFAULT, "server.socket_timeout": depot.SOCKET_TIMEOUT_DEFAULT, "tools.log_headers.on": True }) conf = { "/": { # We have to override cherrypy's default response_class so that # we have access to the write() callable to stream data # directly to the client. "wsgi.response_class": dr.DepotResponse, }, "/robots.txt": { "tools.staticfile.on": True, "tools.staticfile.filename": os.path.join(scfg.web_root, "robots.txt") }, } cherrypy.config.update(conf) cherrypy.tree.mount(root, "", conf) engine = cherrypy.engine if hasattr(engine, "signal_handler"): engine.signal_handler.subscribe() if hasattr(engine, "console_control_handler"): engine.console_control_handler.subscribe() engine.start()
def default(self, *tokens, **params): """ Our default handler is here to make sure we've called setup, grabbing configuration from httpd.conf, then redirecting. It also knows whether a request should be passed off to the BUI, or whether we can just report an error.""" self.setup(cherrypy.request) def request_pub_func(path): """Return the name of the publisher to be used for a given path. This function intentionally returns None for all paths.""" return None if "_themes" in tokens: # manipulate the path to remove everything up to _themes theme_index = tokens.index("_themes") cherrypy.request.path_info = "/".join(tokens[theme_index:]) # When serving theme resources we just choose the first # repository we find, which is fine since we're serving # content that's generic to all repositories, so we repo_prefix = list(repositories.keys())[0] repo = repositories[repo_prefix] depot_bui = depot_buis[repo_prefix] # use our custom request_pub_func, since theme resources # are not publisher-specific dh = sd.DepotHTTP(repo, depot_bui.cfg, request_pub_func=request_pub_func) return dh.default(*tokens[theme_index:]) elif tokens[0] not in repositories: raise cherrypy.NotFound() # Otherwise, we'll try to serve the request from the BUI. repo_prefix = tokens[0] depot_bui = depot_buis[repo_prefix] repo = repositories[repo_prefix] # when serving reources, the publisher is not used # to locate templates, so use our custom # request_pub_func dh = sd.DepotHTTP(repo, depot_bui.cfg, request_pub_func=request_pub_func) # trim the repo_prefix cherrypy.request.path_info = re.sub("^/{0}".format(repo_prefix), "", cherrypy.request.path_info) accept_lang = self.get_accept_lang(cherrypy.request, depot_bui) path = cherrypy.request.path_info.rstrip("/").lstrip("/") toks = path.split("/") pub = None # look for a publisher in the path if toks[0] in repo.publishers: path = "/".join(toks[1:]) pub = toks[0] toks = self.__strip_pub(toks, repo) cherrypy.request.path_info = "/".join(toks) # deal with users browsing directories dirs = ["", accept_lang, repo_prefix] if path in dirs: if not pub: raise cherrypy.HTTPRedirect("/{0}/{1}/index.shtml".format( repo_prefix, accept_lang)) else: raise cherrypy.HTTPRedirect("/{0}/{1}/{2}/index.shtml".format( repo_prefix, pub, accept_lang)) resp = face.respond(depot_bui, cherrypy.request, cherrypy.response, pub, http_depot=repo_prefix) return resp
sys.exit(1) except (search_errors.IndexingException, api_errors.UnknownErrors, api_errors.PermissionsException) as e: emsg(str(e), "INDEX") sys.exit(1) # Ready to start depot; exit now if requested. if exit_ready: sys.exit(0) # Next, initialize depot. if nasty: depot = ds.NastyDepotHTTP(repo, dconf) else: depot = ds.DepotHTTP(repo, dconf) # Now build our site configuration. conf = { "/": { # We have to override cherrypy's default response_class so that # we have access to the write() callable to stream data # directly to the client. "wsgi.response_class": dr.DepotResponse, }, "/robots.txt": { "tools.staticfile.on": True, "tools.staticfile.filename": os.path.join(depot.web_root, "robots.txt") }, }
# Now merge or add our proxy configuration information into the # existing configuration. for entry in proxy_conf: conf["/"][entry] = proxy_conf[entry] scfg.acquire_in_flight() try: scfg.acquire_catalog(rebuild=rebuild, verbose=True) except (catalog.CatalogPermissionsException, errors.SvrConfigError), _e: emsg("pkg.depotd: %s" % _e) sys.exit(1) try: if nasty: root = cherrypy.Application( depot.NastyDepotHTTP(scfg, repo_config_file)) else: root = cherrypy.Application(depot.DepotHTTP( scfg, repo_config_file)) except rc.InvalidAttributeValueError, _e: emsg("pkg.depotd: repository.conf error: %s" % _e) sys.exit(1) try: cherrypy.quickstart(root, config=conf) except Exception, _e: emsg("pkg.depotd: unknown error starting depot server, " \ "illegal option value specified?") emsg(_e) sys.exit(1)