21.27. xmlrpc.server - 基本XML-RPC服务器

源代码: Lib / xmlrpc / server.py

xmlrpc.server模块为使用Python编写的XML-RPC服务器提供了一个基本的服务器框架。服务器可以使用SimpleXMLRPCServer独立运行,也可以使用CGIXMLRPCRequestHandler嵌入CGI环境中。

警告

xmlrpc.server模块对于恶意构造的数据不安全。如果需要解析不受信任或未经身份验证的数据,请参阅XML vulnerabilities

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

创建新服务器实例。此类提供了可以由XML-RPC协议调用的函数的注册方法。requestHandler参数应该是请求处理程序实例的工厂;它默认为SimpleXMLRPCRequestHandleraddrrequestHandler参数传递给socketserver.TCPServer构造函数。如果logRequests为true(默认值),则会记录请求;将此参数设置为false将关闭日志记录。allow_none编码参数传递到xmlrpc.client,并控制将从服务器返回的XML-RPC响应。bind_and_activate参数控制是否由构造函数立即调用server_bind()server_activate()将其设置为false允许代码在绑定地址之前操作allow_reuse_address类变量。use_builtin_types参数传递到loads()函数,并控制在接收到日期/时间值或二进制数据时处理的类型;它默认为false。

在版本3.3中已更改:添加了use_builtin_types标志。

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

创建一个新的实例来处理CGI环境中的XML-RPC请求。allow_none编码参数传递到xmlrpc.client,并控制将从服务器返回的XML-RPC响应。use_builtin_types参数传递到loads()函数,并控制在接收到日期/时间值或二进制数据时处理的类型;它默认为false。

在版本3.3中已更改:添加了use_builtin_types标志。

class xmlrpc.server.SimpleXMLRPCRequestHandler

创建一个新的请求处理程序实例。此请求处理程序支持POST请求并修改日志记录,以便将logRequests参数指向SimpleXMLRPCServer构造函数参数。

21.27.1. SimpleXMLRPCServer Objects

SimpleXMLRPCServer类基于socketserver.TCPServer,并提供了创建简单的独立XML-RPC服务器的方法。

SimpleXMLRPCServer.register_function(function, name=None)

注册可以响应XML-RPC请求的函数。如果给定name,则将是与函数相关联的方法名称,否则将使用function.__name__名称可以是正常字符串或Unicode字符串,并且可能包含Python标识符中不合法的字符,包括句点字符。

SimpleXMLRPCServer.register_instance(instance, allow_dotted_names=False)

注册用于公开未使用register_function()注册的方法名称的对象。如果实例包含_dispatch()方法,则使用请求的方法名称和请求中的参数调用它。其API为def _dispatch(self, 方法, params) params不表示可变参数列表)。如果它调用一个底层函数来执行它的任务,该函数被称为func(*params),扩展参数列表。来自_dispatch()的返回值作为结果返回到客户端。如果实例没有_dispatch()方法,则搜索与所请求方法的名称匹配的属性。

如果可选的allow_dotted_names参数为真,且实例没有_dispatch()方法,则如果请求的方法名称包含句点,则搜索方法名称的每个组件单独地,具有执行简单的分层搜索的效果。然后使用来自请求的参数调用从此搜索中找到的值,并将返回值传递回客户端。

警告

启用allow_dotted_names选项允许入侵者访问您模块的全局变量,并允许入侵者在您的机器上执行任意代码。仅在安全,封闭的网络上使用此选项。

SimpleXMLRPCServer.register_introspection_functions()

注册XML-RPC内省函数system.listMethodssystem.methodHelpsystem.methodSignature

SimpleXMLRPCServer.register_multicall_functions()

注册XML-RPC多元函数system.multicall。

SimpleXMLRPCRequestHandler.rpc_paths

属性值,必须是列出用于接收XML-RPC请求的URL的有效路径部分的元组。发布到其他路径的请求将导致404“无此类网页”HTTP错误。如果此元组为空,所有路径将被视为有效。默认值为('/', '/ RPC2')

21.27.1.1. SimpleXMLRPCServer Example

服务器代码:

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

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

# Create server
server = SimpleXMLRPCServer(("localhost", 8000),
                            requestHandler=RequestHandler)
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()

以下客户端代码将调用前面的服务器提供的方法:

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

包含在Lib/xmlrpc/server.py模块中的以下示例显示允许点名称和注册多元函数的服务器。

警告

启用allow_dotted_names选项允许入侵者访问您模块的全局变量,并允许入侵者在您的机器上执行任意代码。仅在安全,封闭的网络中使用此示例。

import datetime

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

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

server = SimpleXMLRPCServer(("localhost", 8000))
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.")
    server.server_close()
    sys.exit(0)

这个ExampleService演示可以从命令行调用:

python -m xmlrpc.server

与上述服务器交互的客户端包含在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)

与演示XMLRPC服务器交互的此客户端可以调用:

python -m xmlrpc.client

21.27.2. CGIXMLRPCRequestHandler

CGIXMLRPCRequestHandler类可用于处理发送到Python CGI脚本的XML-RPC请求。

CGIXMLRPCRequestHandler.register_function(function, name=None)

注册可以响应XML-RPC请求的函数。如果给定name,它将是与函数关联的方法名,否则将使用函数.__ name __名称可以是正常字符串或Unicode字符串,并且可能包含Python标识符中不合法的字符,包括句点字符。

CGIXMLRPCRequestHandler.register_instance(instance)

注册用于公开未使用register_function()注册的方法名称的对象。如果实例包含_dispatch()方法,则使用请求的方法名称和请求中的参数调用它;返回值作为结果返回到客户端。如果实例没有_dispatch()方法,则搜索与所请求方法的名称匹配的属性;如果所请求的方法名称包含句点,则单独搜索方法名称的每个组件,其效果是执行简单的分层搜索。然后使用来自请求的参数调用从此搜索中找到的值,并将返回值传递回客户端。

CGIXMLRPCRequestHandler.register_introspection_functions()

注册XML-RPC内省功能system.listMethodssystem.methodHelpsystem.methodSignature

CGIXMLRPCRequestHandler.register_multicall_functions()

注册XML-RPC多元函数system.multicall

CGIXMLRPCRequestHandler.handle_request(request_text=None)

处理XML-RPC请求。如果给出request_text,它应该是HTTP服务器提供的POST数据,否则将使用stdin的内容。

例:

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. Documenting XMLRPC server

这些类扩展了上述类来响应HTTP GET请求来提供HTML文档。服务器可以使用DocXMLRPCServer独立运行,也可以使用DocCGIXMLRPCRequestHandler嵌入在CGI环境中。

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

创建新服务器实例。所有参数的含义与SimpleXMLRPCServer相同; requestHandler默认为DocXMLRPCRequestHandler

在版本3.3中已更改:添加了use_builtin_types标志。

class xmlrpc.server.DocCGIXMLRPCRequestHandler

创建一个新的实例来处理CGI环境中的XML-RPC请求。

class xmlrpc.server.DocXMLRPCRequestHandler

创建一个新的请求处理程序实例。This request handler supports XML-RPC POST requests, documentation GET requests, and modifies logging so that the logRequests parameter to the DocXMLRPCServer constructor parameter is honored.

21.27.4. DocXMLRPCServer Objects

DocXMLRPCServer类派生自SimpleXMLRPCServer,并提供了创建自文档,独立XML-RPC服务器的方法。HTTP POST请求作为XML-RPC方法调用处理。HTTP GET请求通过生成pydoc风格的HTML文档来处理。这允许服务器提供其自己的基于Web的文档。

DocXMLRPCServer.set_server_title(server_title)

设置生成的HTML文档中使用的标题。此标题将在HTML“title”元素中使用。

DocXMLRPCServer.set_server_name(server_name)

设置生成的HTML文档中使用的名称。此名称将显示在生成的文档顶部的“h1”元素中。

DocXMLRPCServer.set_server_documentation(server_documentation)

设置生成的HTML文档中使用的描述。此描述将在文档中显示为服务器名称下面的段落。

21.27.5. DocCGIXMLRPCRequestHandler

DocCGIXMLRPCRequestHandler类派生自CGIXMLRPCRequestHandler,并提供了创建自文档,XML-RPC CGI脚本的方法。HTTP POST请求作为XML-RPC方法调用处理。HTTP GET请求通过生成pydoc风格的HTML文档来处理。这允许服务器提供其自己的基于Web的文档。

DocCGIXMLRPCRequestHandler.set_server_title(server_title)

设置生成的HTML文档中使用的标题。此标题将在HTML“title”元素中使用。

DocCGIXMLRPCRequestHandler.set_server_name(server_name)

设置生成的HTML文档中使用的名称。此名称将显示在生成的文档顶部的“h1”元素中。

DocCGIXMLRPCRequestHandler.set_server_documentation(server_documentation)

设置生成的HTML文档中使用的描述。此描述将在文档中显示为服务器名称下面的段落。