Example #1
0
def connect(location):
    """
    Connect to a Flame server on the given location, for instance localhost:9999 or ./u:unixsock
    This is just a convenience function to creates an appropriate Pyro proxy.
    """
    if config.SERIALIZER != "pickle":
        raise errors.SerializeError("Flame requires the pickle serializer")
    proxy = core.Proxy("PYRO:%s@%s" % (constants.FLAME_NAME, location))
    proxy._pyroBind()
    return proxy
Example #2
0
def return_homepage(environ, start_response):
    try:
        nameserver = get_nameserver(hmac=pyro_app.hmac_key)
    except errors.NamingError as x:
        print("Name server error:", x)
        start_response('500 Internal Server Error',
                       [('Content-Type', 'text/plain')])
        return [
            b"Cannot connect to the Pyro name server. Is it running? Refresh page to retry."
        ]
    start_response('200 OK', [('Content-Type', 'text/html')])
    nslist = [
        "<table><tr><th>Name</th><th>methods</th><th>attributes (zero-param methods)</th></tr>"
    ]
    names = sorted(list(nameserver.list(regex=pyro_app.ns_regex).keys())[:10])
    with core.batch(nameserver) as nsbatch:
        for name in names:
            nsbatch.lookup(name)
        for name, uri in zip(names, nsbatch()):
            attributes = "-"
            try:
                with core.Proxy(uri) as proxy:
                    proxy._pyroHmacKey = pyro_app.hmac_key
                    proxy._pyroBind()
                    methods = " &nbsp; ".join(proxy._pyroMethods) or "-"
                    attributes = [
                        "<a href=\"{name}/{attribute}\" onclick=\"pyro_call('{name}','{attribute}'); return false;\">{attribute}</a>"
                        .format(name=name, attribute=attribute)
                        for attribute in proxy._pyroAttrs
                    ]
                    attributes = " &nbsp; ".join(attributes) or "-"
            except errors.PyroError as x:
                stderr = environ["wsgi.errors"]
                print("ERROR getting metadata for {0}:".format(uri),
                      file=stderr)
                traceback.print_exc(file=stderr)
                methods = "??error:%s??" % str(x)
            nslist.append(
                "<tr><td><a href=\"{name}/$meta\" onclick=\"pyro_call('{name}','$meta'); "
                "return false;\">{name}</a></td><td>{methods}</td><td>{attributes}</td></tr>"
                .format(name=name, methods=methods, attributes=attributes))
    nslist.append("</table>")
    index_page = index_page_template.format(
        ns_regex=pyro_app.ns_regex,
        name_server_contents_list="".join(nslist),
        pyro_version=constants.VERSION,
        hostname=nameserver._pyroUri.location)
    return [index_page.encode("utf-8")]
Example #3
0
 def __init__(self, flameserver, module):
     # store a proxy to the flameserver regardless of autoproxy setting
     self.flameserver = core.Proxy(
         flameserver._pyroDaemon.uriFor(flameserver))
     self.module = module
Example #4
0
 def __init__(self, remoteconsoleuri):
     # store a proxy to the console regardless of autoproxy setting
     self.remoteconsole = core.Proxy(remoteconsoleuri)
Example #5
0
def locateNS(host=None, port=None):
    """Get a proxy for a name server somewhere in the network."""
    if host is None:
        # first try localhost if we have a good chance of finding it there
        if Pyro4.config.NS_HOST in (
                "localhost", "::1") or Pyro4.config.NS_HOST.startswith("127."):
            host = Pyro4.config.NS_HOST
            if ":" in host:  # ipv6
                host = "[%s]" % host
            uristring = "PYRO:%s@%s:%d" % (constants.NAMESERVER_NAME, host,
                                           port or Pyro4.config.NS_PORT)
            log.debug("locating the NS: %s", uristring)
            proxy = core.Proxy(uristring)
            try:
                proxy.ping()
                log.debug("located NS")
                return proxy
            except PyroError:
                pass
        # broadcast lookup
        if not port:
            port = Pyro4.config.NS_BCPORT
        log.debug("broadcast locate")
        sock = Pyro4.socketutil.createBroadcastSocket(
            reuseaddr=Pyro4.config.SOCK_REUSE, timeout=0.7)
        for _ in range(3):
            try:
                for bcaddr in Pyro4.config.parseAddressesString(
                        Pyro4.config.BROADCAST_ADDRS):
                    try:
                        sock.sendto(BroadcastServer.REQUEST_NSURI, 0,
                                    (bcaddr, port))
                    except socket.error:
                        x = sys.exc_info()[1]
                        err = getattr(x, "errno", x.args[0])
                        if err not in Pyro4.socketutil.ERRNO_EADDRNOTAVAIL:  # yeah, windows likes to throw these...
                            if err not in Pyro4.socketutil.ERRNO_EADDRINUSE:  # and jython likes to throw thses...
                                raise
                data, _ = sock.recvfrom(100)
                try:
                    sock.shutdown(socket.SHUT_RDWR)
                except (OSError, socket.error):
                    pass
                sock.close()
                if sys.version_info >= (3, 0):
                    data = data.decode("iso-8859-1")
                log.debug("located NS: %s", data)
                return core.Proxy(data)
            except socket.timeout:
                continue
        try:
            sock.shutdown(socket.SHUT_RDWR)
        except (OSError, socket.error):
            pass
        sock.close()
        log.debug("broadcast locate failed, try direct connection on NS_HOST")
        # broadcast failed, try PYRO directly on specific host
        host = Pyro4.config.NS_HOST
        port = Pyro4.config.NS_PORT
    # pyro direct lookup
    if not port:
        port = Pyro4.config.NS_PORT
    if ":" in host:
        host = "[%s]" % host
    if core.URI.isUnixsockLocation(host):
        uristring = "PYRO:%s@%s" % (constants.NAMESERVER_NAME, host)
    else:
        uristring = "PYRO:%s@%s:%d" % (constants.NAMESERVER_NAME, host, port)
    uri = core.URI(uristring)
    log.debug("locating the NS: %s", uri)
    proxy = core.Proxy(uri)
    try:
        proxy.ping()
        log.debug("located NS")
        return proxy
    except PyroError as x:
        e = NamingError("Failed to locate the nameserver")
        e.__cause__ = x
        raise e
Example #6
0
def process_pyro_request(environ, path, parameters, start_response):
    pyro_options = environ.get("HTTP_X_PYRO_OPTIONS", "").split(",")
    if not path:
        return return_homepage(environ, start_response)
    matches = re.match(r"(.+)/(.+)", path)
    if not matches:
        return not_found(start_response)
    object_name, method = matches.groups()
    if pyro_app.gateway_key:
        gateway_key = environ.get("HTTP_X_PYRO_GATEWAY_KEY",
                                  "") or parameters.get("$key", "")
        gateway_key = gateway_key.encode("utf-8")
        if gateway_key != pyro_app.gateway_key:
            start_response('403 Forbidden', [('Content-Type', 'text/plain')])
            return [b"403 Forbidden - incorrect gateway api key"]
        if "$key" in parameters:
            del parameters["$key"]
    if pyro_app.ns_regex and not re.match(pyro_app.ns_regex, object_name):
        start_response('403 Forbidden', [('Content-Type', 'text/plain')])
        return [
            b"403 Forbidden - access to the requested object has been denied"
        ]
    try:
        nameserver = get_nameserver(hmac=pyro_app.hmac_key)
        uri = nameserver.lookup(object_name)
        with core.Proxy(uri) as proxy:
            header_corr_id = environ.get("HTTP_X_PYRO_CORRELATION_ID", "")
            if header_corr_id:
                core.current_context.correlation_id = uuid.UUID(
                    header_corr_id
                )  # use the correlation id from the request header
            else:
                core.current_context.correlation_id = uuid.uuid4(
                )  # set new correlation id
            proxy._pyroHmacKey = pyro_app.hmac_key
            proxy._pyroGetMetadata()
            if "oneway" in pyro_options:
                proxy._pyroOneway.add(method)
            if method == "$meta":
                result = {
                    "methods": tuple(proxy._pyroMethods),
                    "attributes": tuple(proxy._pyroAttrs)
                }
                reply = json.dumps(result).encode("utf-8")
                start_response(
                    '200 OK',
                    [('Content-Type', 'application/json; charset=utf-8'),
                     ('X-Pyro-Correlation-Id',
                      str(core.current_context.correlation_id))])
                return [reply]
            else:
                proxy._pyroRawWireResponse = True  # we want to access the raw response json
                if method in proxy._pyroAttrs:
                    # retrieve the attribute
                    assert not parameters, "attribute lookup can't have query parameters"
                    msg = getattr(proxy, method)
                else:
                    # call the remote method
                    msg = getattr(proxy, method)(**parameters)
                if msg is None or "oneway" in pyro_options:
                    # was a oneway call, no response available
                    start_response(
                        '200 OK',
                        [('Content-Type', 'application/json; charset=utf-8'),
                         ('X-Pyro-Correlation-Id',
                          str(core.current_context.correlation_id))])
                    return []
                elif msg.flags & message.FLAGS_EXCEPTION:
                    # got an exception response so send a 500 status
                    start_response(
                        '500 Internal Server Error',
                        [('Content-Type', 'application/json; charset=utf-8')])
                    return [msg.data]
                else:
                    # normal response
                    start_response(
                        '200 OK',
                        [('Content-Type', 'application/json; charset=utf-8'),
                         ('X-Pyro-Correlation-Id',
                          str(core.current_context.correlation_id))])
                    return [msg.data]
    except Exception as x:
        stderr = environ["wsgi.errors"]
        print("ERROR handling {0} with params {1}:".format(path, parameters),
              file=stderr)
        traceback.print_exc(file=stderr)
        start_response('500 Internal Server Error',
                       [('Content-Type', 'application/json; charset=utf-8')])
        reply = json.dumps(
            util.SerializerBase.class_to_dict(x)).encode("utf-8")
        return [reply]
Example #7
0
def locateNS(host=None, port=None, broadcast=True, hmac_key=None):
    """Get a proxy for a name server somewhere in the network."""
    if host is None:
        # first try localhost if we have a good chance of finding it there
        if Pyro4.config.NS_HOST in (
                "localhost", "::1") or Pyro4.config.NS_HOST.startswith("127."):
            if ":" in Pyro4.config.NS_HOST:  # ipv6
                hosts = ["[%s]" % Pyro4.config.NS_HOST]
            else:
                # Some systems (Debian Linux) have 127.0.1.1 in the hosts file assigned to the hostname,
                # try this too for convenience sake (only if it's actually used as a valid ip address)
                try:
                    socket.gethostbyaddr("127.0.1.1")
                    hosts = [Pyro4.config.NS_HOST
                             ] if Pyro4.config.NS_HOST == "127.0.1.1" else [
                                 Pyro4.config.NS_HOST, "127.0.1.1"
                             ]
                except socket.error:
                    hosts = [Pyro4.config.NS_HOST]
            for host in hosts:
                uristring = "PYRO:%s@%s:%d" % (Pyro4.constants.NAMESERVER_NAME,
                                               host, port
                                               or Pyro4.config.NS_PORT)
                log.debug("locating the NS: %s", uristring)
                proxy = core.Proxy(uristring)
                proxy._pyroHmacKey = hmac_key
                try:
                    proxy._pyroBind()
                    log.debug("located NS")
                    return proxy
                except PyroError:
                    pass
        if broadcast:
            # broadcast lookup
            if not port:
                port = Pyro4.config.NS_BCPORT
            log.debug("broadcast locate")
            sock = Pyro4.socketutil.createBroadcastSocket(
                reuseaddr=Pyro4.config.SOCK_REUSE, timeout=0.7)
            for _ in range(3):
                try:
                    for bcaddr in Pyro4.config.parseAddressesString(
                            Pyro4.config.BROADCAST_ADDRS):
                        try:
                            sock.sendto(BroadcastServer.REQUEST_NSURI, 0,
                                        (bcaddr, port))
                        except socket.error:
                            x = sys.exc_info()[1]
                            err = getattr(x, "errno", x.args[0])
                            # handle some errno's that some platforms like to throw:
                            if err not in Pyro4.socketutil.ERRNO_EADDRNOTAVAIL and err not in Pyro4.socketutil.ERRNO_EADDRINUSE:
                                raise
                    data, _ = sock.recvfrom(100)
                    sock.close()
                    if sys.version_info >= (3, 0):
                        data = data.decode("iso-8859-1")
                    log.debug("located NS: %s", data)
                    proxy = core.Proxy(data)
                    proxy._pyroHmacKey = hmac_key
                    return proxy
                except socket.timeout:
                    continue
            try:
                sock.shutdown(socket.SHUT_RDWR)
            except (OSError, socket.error):
                pass
            sock.close()
            log.debug(
                "broadcast locate failed, try direct connection on NS_HOST")
        else:
            log.debug("skipping broadcast lookup")
        # broadcast failed or skipped, try PYRO directly on specific host
        host = Pyro4.config.NS_HOST
        port = Pyro4.config.NS_PORT
    # pyro direct lookup
    if not port:
        port = Pyro4.config.NS_PORT
    if core.URI.isUnixsockLocation(host):
        uristring = "PYRO:%s@%s" % (Pyro4.constants.NAMESERVER_NAME, host)
    else:
        # if not a unix socket, check for ipv6
        if ":" in host:
            host = "[%s]" % host
        uristring = "PYRO:%s@%s:%d" % (Pyro4.constants.NAMESERVER_NAME, host,
                                       port)
    uri = core.URI(uristring)
    log.debug("locating the NS: %s", uri)
    proxy = core.Proxy(uri)
    proxy._pyroHmacKey = hmac_key
    try:
        proxy._pyroBind()
        log.debug("located NS")
        return proxy
    except PyroError as x:
        e = NamingError("Failed to locate the nameserver")
        if sys.version_info >= (3, 0):
            e.__cause__ = x
        raise e