Безопасный способ подключения к серверу RPC - PullRequest
5 голосов
/ 17 января 2011

Этот вопрос относится к Как мы обрабатываем 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 Ответ

5 голосов
/ 17 января 2011

Ну, я просто смотрю на это;мой старый метод отстой, потому что 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 и это не удастся.

Примечание 2. Некоторые службы xmlrpc предлагают путь rpc, специализированный для выполнения аутентификации, в этом пути службы предлагают методы, такие как login () ..., такие методы могут заменитьв нашем случае метода _ (), поэтому достаточно просто вызвать login (), чтобы узнать, работает ли служба или нет (socket.error), и в то же время этот метод login () аутентифицирует пользователя, если службавверх

...