连接到RPC服务器的安全方法

时间:2011-01-17 18:39:19

标签: python xmlrpclib

此问题与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'>

1 个答案:

答案 0 :(得分:5)

我只是在寻找它;我的旧方法很糟糕,因为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

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

    N.B:当你if a:时,python将再次搜索方法__nonzero__()以测试a的布尔值,这将失败。

    NB 2:有些xmlrpc服务提供了一个专门用于认证的rpc路径,在这个路径中服务提供方法如login()...,这种方法可以代替我们的_()方法,所以只需调用login(),就足以知道服务是up还是down(socket.error),同时这个login()方法在服务启动时验证用户。