# 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.