【问题标题】:Safe way to connect to RPC server连接到 RPC 服务器的安全方式
【发布时间】:2011-01-17 18:39:18
【问题描述】:

这个问题与How do we handle Python xmlrpclib Connection Refused?有关

当我尝试使用以下代码时,在我的 RPC 服务器关闭的情况下,_get_rpc() 返回 False,我可以开始了。但是,如果服务器正在运行,它会以未知的方法失败。它是否试图在远程服务器上执行 .connect() ?当我需要使用 .connect() 来检测返回的代理是否有效时,我该如何解决这个问题(请参阅相关问题)?

import xmlrpclib
import socket

def _get_rpc():
    try:
        a = xmlrpclib.ServerProxy('http://dd:LNXFhcZnYshy5mKyOFfy@127.0.0.1:9001')
        a.connect()     # Try to connect to the server
        return a.supervisor
    except socket.error:
        return False


if not _get_rpc():
    print "Failed to connect"

问题来了:

ahiscox@lenovo:~/code/dd$ python xmlrpctest2.py
Failed to connect
ahiscox@lenovo:~/code/dd$ supervisord -c ~/.supervisor # start up RPC server
ahiscox@lenovo:~/code/dd$ python xmlrpctest2.py
Traceback (most recent call last):
  File "xmlrpctest2.py", line 13, in <module>
    if not _get_rpc():
  File "xmlrpctest2.py", line 7, in _get_rpc
    a.connect()     # Try to connect to the server
  File "/usr/lib/python2.6/xmlrpclib.py", line 1199, in __call__
    return self.__send(self.__name, args)
  File "/usr/lib/python2.6/xmlrpclib.py", line 1489, in __request
    verbose=self.__verbose
  File "/usr/lib/python2.6/xmlrpclib.py", line 1253, in request
    return self._parse_response(h.getfile(), sock)
  File "/usr/lib/python2.6/xmlrpclib.py", line 1392, in _parse_response
    return u.close()
  File "/usr/lib/python2.6/xmlrpclib.py", line 838, in close
    raise Fault(**self._stack[0])
xmlrpclib.Fault: <Fault 1: 'UNKNOWN_METHOD'>

【问题讨论】:

    标签: python xmlrpclib


    【解决方案1】:

    嗯,我只是在研究它;我的旧方法很糟糕,因为xmlrpclib.ServerProxy 在调用方法时尝试连接到 XmlRPC 服务器,而不是之前!!!

    试试这个:

    import xmlrpclib
    import socket
    
    def _get_rpc():
        a = xmlrpclib.ServerProxy('http://dd:LNXFhcZnYshy5mKyOFfy@127.0.0.1:9001')
    
        try:
            a._()   # Call a fictive method.
        except xmlrpclib.Fault:
            # connected to the server and the method doesn't exist which is expected.
            pass
        except socket.error:
            # Not connected ; socket error mean that the service is unreachable.
            return False, None
    
        # Just in case the method is registered in the XmlRPC server
        return True, a
    
    connected, server_proxy = _get_rpc():
    if not connected
        print "Failed to connect"
        import sys
        sys.exit(1)
    

    总而言之,我们有 3 个案例:

    1. XmlRPC 服务器已启动,我们在其中定义了一个名为 _() 的方法:
      编辑:我确实选择了名称_,因为它不太可能有具有此名称的方法,但这种情况仍然可能发生)
      在这种情况下,不会捕获异常并且代码将执行 return True

    2. XmlRPC 服务器已启动,其中我们没有任何方法调用 _()
      这次xmlrpclib.Fault 将被提升,我们也将传递给return True

    3. XmlRPC 服务器已关闭
      现在将引发socket.error 异常,并且 当我们打电话给a._() 所以我们应该return False

    我不知道是否有一种简单的方法可以做到这一点,我很乐意在那之前看到它,希望这次能解决问题:)

    注意:当您执行 if a: 时,python 将再次搜索方法 __nonzero__() 来测试 a 的布尔值,这将失败。

    N.B 2: 一些 xmlrpc 服务提供了一个专门用于进行身份验证的 rpc 路径,在这个路径中服务提供了类似 login() ... 的方法,这种方法可以代替我们案例中的 _() 方法,所以只需调用 login(),就足以知道服务是启动还是关闭(socket.error),同时这个 login() 方法验证用户是否启动了服务。

    【讨论】:

    • 谢谢,这似乎运作良好。代码只需要在第一次尝试时使用另一个 except 语句进行更新,以避免引发缩进异常,否则可以正常工作。感谢NB#2,我会检查主管是否支持这一点。
    • @Anthony Hiscox:修复它,感谢您的评论,很高兴它有帮助:)
    • 非常节省时间; xmlrpclib 应该处理这个
    猜你喜欢
    • 1970-01-01
    • 2017-05-08
    • 2014-12-07
    • 2022-01-22
    • 2011-08-29
    • 2011-01-11
    • 2013-01-19
    • 2013-05-29
    • 1970-01-01
    相关资源
    最近更新 更多