示例#1
0
文件: server.py 项目: tensor5/conary
            loadSchema = True
        elif dbVersion.major < schema.VERSION.major:  # schema too old
            loadSchema = True
        elif 'migrate' in argSet:  # a migration was asked for
            loadSchema = True
        if loadSchema:
            dbVersion = schema.loadSchema(db, 'migrate' in argSet)
        if dbVersion < schema.VERSION:  # migration failed...
            print "ERROR: schema migration has failed from %s to %s" % (
                dbVersion, schema.VERSION)
        if 'migrate' in argSet:
            logMe(1, "Schema migration complete", dbVersion)
            sys.exit(0)

        netRepos = NetworkRepositoryServer(cfg, baseUrl)
        reqClass.netRepos = proxy.SimpleRepositoryFilter(
            cfg, baseUrl, netRepos)
        reqClass.restHandler = None
        if cfg.baseUri:
            global cresthooks
            if cresthooks is None:
                # we haven't tried to import cresthooks yet - let's give
                # it a try
                try:
                    from crest import webhooks as cresthooks
                except ImportError, e:
                    print 'warning: failed to import crest:', str(e)
                    # fail - let's not try again by setting cresthooks to
                    # False instead of None
                    cresthooks = False
            if cresthooks:
                reqClass.restUri = cfg.baseUri + '/api'
示例#2
0
    def _loadCfg(self):
        """Load configuration and construct repository objects."""
        cfg = self.cfg
        req = self.request
        if cfg.repositoryDB:
            if cfg.proxyContentsDir:
                raise ConfigurationError("Exactly one of repositoryDB or "
                                         "proxyContentsDir must be set.")
            for name in ('contentsDir', 'serverName'):
                if not cfg[name]:
                    raise ConfigurationError("%s must be set." % name)
        else:
            if not cfg.proxyContentsDir:
                raise ConfigurationError("Exactly one of repositoryDB or "
                                         "proxyContentsDir must be set.")

        if os.path.realpath(cfg.tmpDir) != cfg.tmpDir:
            raise ConfigurationError("tmpDir must not contain symbolic links.")

        self._useForwardedHeaders = self._getEnvBool('use_forwarded_headers',
                                                     False)
        if self._useForwardedHeaders:
            for key in ('x-forwarded-scheme', 'x-forwarded-proto'):
                if req.headers.get(key):
                    req.scheme = req.headers[key]
                    break
            for key in ('x-forwarded-host', 'x-forwarded-server'):
                if req.headers.get(key):
                    req.host = req.headers[key]
                    break
        self.isSecure = req.scheme == 'https'

        if req.environ.get('PYTHONPATH'):
            # Allow SetEnv to propagate, so that commit hooks can have the
            # proper environment
            os.environ['PYTHONPATH'] = req.environ['PYTHONPATH']

        for mountPoint in [
                req.environ.get('conary.netrepos.mount_point'), cfg.baseUri,
                'conary'
        ]:
            if mountPoint is not None:
                break
        for elem in mountPoint.split('/'):
            if not elem:
                continue
            if self.request.path_info_pop() != elem:
                raise web_exc.HTTPNotFound(
                    "Path %s is not handled by this application." %
                    self.request.script_name)

        urlBase = req.application_url
        if cfg.closed:
            # Closed repository -- returns an exception for all requests
            self.repositoryServer = netserver.ClosedRepositoryServer(cfg)
            self.shimServer = self.repositoryServer
        elif cfg.proxyContentsDir:
            # Caching proxy (no repository)
            self.repositoryServer = None
            self.shimServer = None
            self.proxyServer = proxy.ProxyRepositoryServer(cfg, urlBase)
        else:
            # Full repository with optional changeset cache
            self.repositoryServer = netserver.NetworkRepositoryServer(
                cfg, urlBase)
            self.shimServer = shimclient.NetworkRepositoryServer(
                cfg, urlBase, db=self.repositoryServer.db)

        if self.repositoryServer:
            self.proxyServer = proxy.SimpleRepositoryFilter(
                cfg, urlBase, self.repositoryServer)
            self.contentsStore = self.repositoryServer.repos.contentsStore
示例#3
0
 class HttpRequestsSubclass(server.HttpRequests):
     tmpDir = cfg.tmpDir
     netRepos = proxy.SimpleRepositoryFilter(cfg, baseUrl, netServer)
     restHandler = None
示例#4
0
def _handler(req):
    log.setupLogging(consoleLevel=logging.INFO, consoleFormat='apache')
    # Keep CONARY_LOG entries from being double-logged
    log.logger.handlers = []

    repName = req.filename
    if repName in repositories:
        repServer, proxyServer, restHandler = repositories[repName]
    else:
        cfg = netserver.ServerConfig()
        cfg.read(req.filename)

        # Throw away any subdir portion.
        if cfg.baseUri:
            baseUri = cfg.baseUri
        else:
            baseUri = req.uri[:-len(req.path_info)] + '/'

        urlBase = "%%(protocol)s://%s:%%(port)d" % \
                        (req.server.server_hostname) + baseUri

        if not cfg.repositoryDB and not cfg.proxyContentsDir:
            log.error("repositoryDB or proxyContentsDir is required in %s" %
                      req.filename)
            return apache.HTTP_INTERNAL_SERVER_ERROR
        elif cfg.repositoryDB and cfg.proxyContentsDir:
            log.error(
                "only one of repositoryDB or proxyContentsDir may be specified "
                "in %s" % req.filename)
            return apache.HTTP_INTERNAL_SERVER_ERROR

        if cfg.repositoryDB:
            if not cfg.contentsDir:
                log.error("contentsDir is required in %s" % req.filename)
                return apache.HTTP_INTERNAL_SERVER_ERROR
            elif not cfg.serverName:
                log.error("serverName is required in %s" % req.filename)
                return apache.HTTP_INTERNAL_SERVER_ERROR

        if os.path.realpath(cfg.tmpDir) != cfg.tmpDir:
            log.error("tmpDir cannot include symbolic links")

        if cfg.closed:
            # Closed repository
            repServer = netserver.ClosedRepositoryServer(cfg)
            proxyServer = proxy.SimpleRepositoryFilter(cfg, urlBase, repServer)
            restHandler = None
        elif cfg.proxyContentsDir:
            # Caching proxy
            repServer = None
            proxyServer = proxy.ProxyRepositoryServer(cfg, urlBase)
            restHandler = None
        else:
            # Full repository with changeset cache
            repServer = netserver.NetworkRepositoryServer(cfg, urlBase)
            proxyServer = proxy.SimpleRepositoryFilter(cfg, urlBase, repServer)
            if cresthooks and cfg.baseUri:
                restUri = cfg.baseUri + '/api'
                restHandler = cresthooks.ApacheHandler(restUri, repServer)
            else:
                restHandler = None

        repositories[repName] = repServer, proxyServer, restHandler

    port = req.connection.local_addr[1]
    # newer versions of mod_python provide a req.is_https() method
    secure = (req.subprocess_env.get('HTTPS', 'off').lower() == 'on')

    method = req.method.upper()

    try:
        try:
            # reopen database connections early to make sure crest gets a
            # working database connection
            if repServer:
                repServer.reopen()

            if method == "POST":
                return post(port,
                            secure,
                            proxyServer,
                            req,
                            repServer=repServer)
            elif method == "GET":
                return get(port,
                           secure,
                           proxyServer,
                           req,
                           restHandler,
                           repServer=repServer)
            elif method == "PUT":
                return putFile(port, secure, proxyServer, req)
            else:
                return apache.HTTP_METHOD_NOT_ALLOWED
        finally:
            # Free temporary resources used by the repserver
            # e.g. pooled DB connections.
            if repServer:
                repServer.reset()

    except apache.SERVER_RETURN:
        # if the exception was an apache server return code,
        # re-raise it and let mod_python handle it.
        raise
    except IOError, e:
        # ignore when the client hangs up on us
        if str(e).endswith('client closed connection.'):
            pass
        else:
            raise