xmlrpc.server — Servidores XML-RPC básicos

Código-fonte: Lib/xmlrpc/server.py


O módulo xmlrpc.server fornece um framework básico de servidor para servidores XML-RPC escritos em Python. Os servidores podem ser independentes, usando SimpleXMLRPCServer, ou incorporados em um ambiente CGI, usando CGIXMLRPCRequestHandler.

Aviso

O módulo xmlrpc.server não é seguro contra dados criados com códigos maliciosos. Se você precisar analisar dados não confiáveis ou não autenticados, consulte Vulnerabilidades em XML.

class xmlrpc.server.SimpleXMLRPCServer(addr, requestHandler=SimpleXMLRPCRequestHandler, logRequests=True, allow_none=False, encoding=None, bind_and_activate=True, use_builtin_types=False)

Cria uma nova instância do servidor. Esta classe fornece métodos para registro de funções que podem ser chamadas pelo protocolo XML-RPC. O parâmetro requestHandler deve ser uma fábrica para instâncias do tratador de solicitações; o padrão é SimpleXMLRPCRequestHandler. Os parâmetros addr e requestHandler são passados ​​para o construtor socketserver.TCPServer. Se logRequests for true (o padrão), as solicitações serão registradas; definir esse parâmetro como false desativará os registros. Os parâmetros allow_none e encoding são transmitidos para xmlrpc.client e controlam as respostas XML-RPC que serão retornadas do servidor. O parâmetro bind_and_activate controla se server_bind() e server_activate() são chamados imediatamente pelo construtor; o padrão é true. A configuração como false permite que o código manipule a variável de classe allow_reuse_address antes que o endereço seja vinculado. O parâmetro use_builtin_types é passado para a função loads() e controla quais tipos são processados ​​quando valores de data/hora ou dados binários são recebidos; o padrão é false.

Alterado na versão 3.3: O sinalizador use_builtin_types foi adicionado.

class xmlrpc.server.CGIXMLRPCRequestHandler(allow_none=False, encoding=None, use_builtin_types=False)

Cria uma nova instância para manipular solicitações XML-RPC em um ambiente CGI. Os parâmetros allow_none e encoding são transmitidos para xmlrpc.client e controlam as respostas XML-RPC que serão retornadas do servidor. O parâmetro use_builtin_types é passado para a função loads() e controla quais tipos são processados quando valores de data/hora ou dados binários são recebidos; o padrão é false.

Alterado na versão 3.3: O sinalizador use_builtin_types foi adicionado.

class xmlrpc.server.SimpleXMLRPCRequestHandler

Cria uma nova instância do manipulador de solicitações. Este manipulador de solicitação possui suporte a solicitações POST e modifica o registro para que o parâmetro logRequests para o construtor de SimpleXMLRPCServer seja respeitado.

Objetos de SimpleXMLRPCServer

A classe SimpleXMLRPCServer é baseada em socketserver.TCPServer e fornece um meio de criar servidores XML-RPC simples e independentes.

SimpleXMLRPCServer.register_function(function=None, name=None)

Registra uma função que possa responder às solicitações XML-RPC. Se name for fornecido, será o nome do método associado a function, caso contrário, function.__name__ será usado. name é uma string e pode conter caracteres ilegais para identificadores Python, incluindo o caractere de ponto.

Este método também pode ser usado como um decorador. Quando usado como decorador, name só pode ser fornecido como argumento nomeado para registrar function em name. Se nenhum name for fornecido, function.__name__ será usado.

Alterado na versão 3.7: register_function() pode ser usado como um decorador.

SimpleXMLRPCServer.register_instance(instance, allow_dotted_names=False)

Registra um objeto que é usado para expor nomes de métodos que não foram registrados usando register_function(). Se instance contiver um método _dispatch(), ele será chamado com o nome do método solicitado e os parâmetros da solicitação. Sua API é def _dispatch(self, method, params) (observe que params não representa uma lista de argumentos variáveis). Se ele chama uma função subjacente para executar sua tarefa, essa função é chamada como func(*params), expandindo a lista de parâmetros. O valor de retorno de _dispatch() é retornado ao cliente como resultado. Se instance não possui o método _dispatch(), é procurado por um atributo correspondente ao nome do método solicitado.

Se o argumento opcional allow_dotted_names for true e a instância não tiver o método _dispatch(), e se o nome do método solicitado contiver pontos, cada componente do nome do método será pesquisado individualmente, com o efeito de que um simples pesquisa hierárquica é realizada. O valor encontrado nessa pesquisa é chamado com os parâmetros da solicitação e o valor retornado é passado de volta ao cliente.

Aviso

A ativação da opção allow_dotted_names permite que os invasores acessem as variáveis globais do seu módulo e podem permitir que os invasores executem códigos arbitrários em sua máquina. Use esta opção apenas em uma rede fechada e segura.

SimpleXMLRPCServer.register_introspection_functions()

Registra as funções de introspecção XML-RPC system.listMethods, system.methodHelp e system.methodSignature.

SimpleXMLRPCServer.register_multicall_functions()

Registra a função de multichamada XML-RPC system.multicall.

SimpleXMLRPCRequestHandler.rpc_paths

Um valor de atributo que deve ser uma tupla listando partes do caminho válidas da URL para receber solicitações XML-RPC. Solicitações postadas em outros caminhos resultarão em um erro HTTP 404 “página inexistente”. Se esta tupla estiver vazia, todos os caminhos serão considerados válidos. O valor padrão é ('/', '/RPC2').

Exemplo de SimpleXMLRPCServer

Código do servidor:

from xmlrpc.server import SimpleXMLRPCServer
from xmlrpc.server import SimpleXMLRPCRequestHandler

# Restrict to a particular path.
class RequestHandler(SimpleXMLRPCRequestHandler):
    rpc_paths = ('/RPC2',)

# Create server
with SimpleXMLRPCServer(('localhost', 8000),
                        requestHandler=RequestHandler) as server:
    server.register_introspection_functions()

    # Register pow() function; this will use the value of
    # pow.__name__ as the name, which is just 'pow'.
    server.register_function(pow)

    # Register a function under a different name
    def adder_function(x, y):
        return x + y
    server.register_function(adder_function, 'add')

    # Register an instance; all the methods of the instance are
    # published as XML-RPC methods (in this case, just 'mul').
    class MyFuncs:
        def mul(self, x, y):
            return x * y

    server.register_instance(MyFuncs())

    # Run the server's main loop
    server.serve_forever()

O código do cliente a seguir chamará os métodos disponibilizados pelo servidor anterior:

import xmlrpc.client

s = xmlrpc.client.ServerProxy('http://localhost:8000')
print(s.pow(2,3))  # Returns 2**3 = 8
print(s.add(2,3))  # Returns 5
print(s.mul(5,2))  # Returns 5*2 = 10

# Print list of available methods
print(s.system.listMethods())

register_function() também pode ser usado como um decorador. O exemplo anterior do servidor pode registrar funções com um decorador:

from xmlrpc.server import SimpleXMLRPCServer
from xmlrpc.server import SimpleXMLRPCRequestHandler

class RequestHandler(SimpleXMLRPCRequestHandler):
    rpc_paths = ('/RPC2',)

with SimpleXMLRPCServer(('localhost', 8000),
                        requestHandler=RequestHandler) as server:
    server.register_introspection_functions()

    # Register pow() function; this will use the value of
    # pow.__name__ as the name, which is just 'pow'.
    server.register_function(pow)

    # Register a function under a different name, using
    # register_function as a decorator. *name* can only be given
    # as a keyword argument.
    @server.register_function(name='add')
    def adder_function(x, y):
        return x + y

    # Register a function under function.__name__.
    @server.register_function
    def mul(x, y):
        return x * y

    server.serve_forever()

O exemplo a seguir, incluído no módulo Lib/xmlrpc/server.py, mostra um servidor que permite nomes com pontos e registra uma função de várias chamadas.

Aviso

A ativação da opção allow_dotted_names permite que os invasores acessem as variáveis globais do seu módulo e podem permitir que os invasores executem códigos arbitrários em sua máquina. Use este exemplo apenas em uma rede fechada e segura.

import datetime

class ExampleService:
    def getData(self):
        return '42'

    class currentTime:
        @staticmethod
        def getCurrentTime():
            return datetime.datetime.now()

with SimpleXMLRPCServer(("localhost", 8000)) as server:
    server.register_function(pow)
    server.register_function(lambda x,y: x+y, 'add')
    server.register_instance(ExampleService(), allow_dotted_names=True)
    server.register_multicall_functions()
    print('Serving XML-RPC on localhost port 8000')
    try:
        server.serve_forever()
    except KeyboardInterrupt:
        print("\nKeyboard interrupt received, exiting.")
        sys.exit(0)

Esta demonstração ExampleService pode ser chamada na linha de comando:

python -m xmlrpc.server

O cliente que interage com o servidor acima está incluído em Lib/xmlrpc/client.py:

server = ServerProxy("http://localhost:8000")

try:
    print(server.currentTime.getCurrentTime())
except Error as v:
    print("ERROR", v)

multi = MultiCall(server)
multi.getData()
multi.pow(2,9)
multi.add(1,2)
try:
    for response in multi():
        print(response)
except Error as v:
    print("ERROR", v)

Este cliente que interage com o servidor XMLRPC de demonstração pode ser chamado como:

python -m xmlrpc.client

CGIXMLRPCRequestHandler

A classe CGIXMLRPCRequestHandler pode ser usada para manipular solicitações XML-RPC enviadas para scripts CGI Python.

CGIXMLRPCRequestHandler.register_function(function=None, name=None)

Registra uma função que possa responder às solicitações XML-RPC. Se name for fornecido, será o nome do método associado a function, caso contrário, function.__name__ será usado. name é uma string e pode conter caracteres ilegais para identificadores Python, incluindo o caractere de ponto.

Este método também pode ser usado como um decorador. Quando usado como decorador, name só pode ser fornecido como argumento nomeado para registrar function em name. Se nenhum name for fornecido, function.__name__ será usado.

Alterado na versão 3.7: register_function() pode ser usado como um decorador.

CGIXMLRPCRequestHandler.register_instance(instance)

Registra um objeto que é usado para expor nomes de métodos que não foram registrados usando register_function(). Se a instância contiver um método _dispatch(), ela será chamada com o nome do método solicitado e os parâmetros da solicitação; o valor retornado é retornado ao cliente como resultado. Se a instância não tiver um método _dispatch(), será procurado um atributo correspondente ao nome do método solicitado; se o nome do método solicitado contiver pontos, cada componente do nome do método será pesquisado individualmente, com o efeito de que uma pesquisa hierárquica simples é executada. O valor encontrado nessa pesquisa é chamado com os parâmetros da solicitação e o valor retornado é passado de volta ao cliente.

CGIXMLRPCRequestHandler.register_introspection_functions()

Registra as funções de introspecção XML-RPC system.listMethods, system.methodHelp e system.methodSignature.

CGIXMLRPCRequestHandler.register_multicall_functions()

Registra a função de multichamada XML-RPC system.multicall.

CGIXMLRPCRequestHandler.handle_request(request_text=None)

Manipula uma solicitação XML-RPC. Se request_text for fornecido, devem ser os dados POST fornecidos pelo servidor HTTP, caso contrário, o conteúdo do stdin será usado.

Exemplo:

class MyFuncs:
    def mul(self, x, y):
        return x * y


handler = CGIXMLRPCRequestHandler()
handler.register_function(pow)
handler.register_function(lambda x,y: x+y, 'add')
handler.register_introspection_functions()
handler.register_instance(MyFuncs())
handler.handle_request()

Documentando servidor XMLRPC

Essas classes estendem as classes acima para servir a documentação HTML em resposta a solicitações HTTP GET. Os servidores podem ser independentes, usando DocXMLRPCServer ou incorporados em um ambiente CGI, usando DocCGIXMLRPCRequestHandler.

class xmlrpc.server.DocXMLRPCServer(addr, requestHandler=DocXMLRPCRequestHandler, logRequests=True, allow_none=False, encoding=None, bind_and_activate=True, use_builtin_types=True)

Cria uma nova instância do servidor. Todos os parâmetros têm o mesmo significado que para SimpleXMLRPCServer; requestHandler assume como padrão DocXMLRPCRequestHandler.

Alterado na versão 3.3: O sinalizador use_builtin_types foi adicionado.

class xmlrpc.server.DocCGIXMLRPCRequestHandler

Cria uma nova instância para manipular solicitações XML-RPC em um ambiente CGI.

class xmlrpc.server.DocXMLRPCRequestHandler

Cria uma nova instância do manipulador de solicitações. Este manipulador de solicitações possui suporte a solicitações POST de XML-RPC, documenta solicitações GET e modifica o registro para que o parâmetro logRequests no parâmetro DocXMLRPCServer seja respeitado.

Objetos de DocXMLRPCServer

A classe DocXMLRPCServer é derivada de SimpleXMLRPCServer e fornece um meio de criar servidores XML-RPC autodocumentados e independentes. Solicitações HTTP POST são tratadas como chamadas de método XML-RPC. As solicitações HTTP GET são tratadas gerando documentação HTML no estilo pydoc. Isso permite que um servidor forneça sua própria documentação baseada na Web.

DocXMLRPCServer.set_server_title(server_title)

Define o título usado na documentação HTML gerada. Este título será usado dentro do elemento “title” do HTML.

DocXMLRPCServer.set_server_name(server_name)

Define o nome usado na documentação HTML gerada. Este nome aparecerá na parte superior da documentação gerada dentro de um elemento “h1”.

DocXMLRPCServer.set_server_documentation(server_documentation)

Define a descrição usada na documentação HTML gerada. Esta descrição aparecerá na documentação como um parágrafo, abaixo do nome do servidor.

DocCGIXMLRPCRequestHandler

A classe DocCGIXMLRPCRequestHandler é derivada de CGIXMLRPCRequestHandler e fornece um meio de criar scripts CGI XML-RPC autodocumentados. Solicitações HTTP POST são tratadas como chamadas de método XML-RPC. As solicitações HTTP GET são tratadas gerando documentação HTML no estilo pydoc. Isso permite que um servidor forneça sua própria documentação baseada na web.

DocCGIXMLRPCRequestHandler.set_server_title(server_title)

Define o título usado na documentação HTML gerada. Este título será usado dentro do elemento “title” do HTML.

DocCGIXMLRPCRequestHandler.set_server_name(server_name)

Define o nome usado na documentação HTML gerada. Este nome aparecerá na parte superior da documentação gerada dentro de um elemento “h1”.

DocCGIXMLRPCRequestHandler.set_server_documentation(server_documentation)

Define a descrição usada na documentação HTML gerada. Esta descrição aparecerá na documentação como um parágrafo, abaixo do nome do servidor.