21.27. 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 XML vulnerabilities.

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á o log. 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 log para que o parâmetro logRequests para o construtor de SimpleXMLRPCServer seja respeitado.

21.27.1. 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, name=None)

Register a function that can respond to XML-RPC requests. If name is given, it will be the method name associated with function, otherwise function.__name__ will be used. name can be either a normal or Unicode string, and may contain characters not legal in Python identifiers, including the period character.

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(), 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()

Registradores de 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').

21.27.1.1. 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())

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

21.27.2. CGIXMLRPCRequestHandler

The CGIXMLRPCRequestHandler class can be used to handle XML-RPC requests sent to Python CGI scripts.

CGIXMLRPCRequestHandler.register_function(function, name=None)

Register a function that can respond to XML-RPC requests. If name is given, it will be the method name associated with function, otherwise function.__name__ will be used. name can be either a normal or Unicode string, and may contain characters not legal in Python identifiers, including the period character.

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()

21.27.3. 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 log para que o parâmetro logRequests no parâmetro DocXMLRPCServer seja respeitado.

21.27.4. 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á como um parágrafo, abaixo do nome do servidor, na documentação.

21.27.5. 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á como um parágrafo, abaixo do nome do servidor, na documentação.