xmlrpc.server --- سرورهای XML-RPC پایه

کد منبع: Lib/xmlrpc/server.py


ماژول xmlrpc.server یک چارچوب سرور پایه برای سرورهای XML-RPC نوشته‌شده با پایتون ارائه می‌دهد. سرورها می‌توانند یا مستقل باشند و از SimpleXMLRPCServer استفاده کنند، یا در یک محیط CGI تعبیه‌شده باشند و از CGIXMLRPCRequestHandler استفاده کنند.

هشدار

ماژول xmlrpc.server در برابر داده‌هایی که بدخواهانه ساخته شده‌اند امن نیست. اگر نیاز به تجزیه داده‌های غیرقابل‌اعتماد یا احراز هویت‌نشده دارید، امنیت XML را ببینید.

دسترس‌پذیری: not WASI.

این ماژول در WebAssembly کار نمی‌کند یا در دسترس نیست. برای اطلاعات بیشتر، سکوهای WebAssembly را ببینید.

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 باید یک کارخانه برای نمونه‌های هندلر درخواست باشد؛ مقدار پیش‌فرض آن SimpleXMLRPCRequestHandler است. پارامترهای addr و requestHandler به سازنده‌ی socketserver.TCPServer منتقل می‌شوند. اگر logRequests مقدار true باشد (مقدار پیش‌فرض)، درخواست‌ها ثبت می‌شوند؛ تنظیم این پارامتر روی false، ثبت را غیرفعال می‌کند. پارامترهای allow_none و encoding به xmlrpc.client منتقل می‌شوند و پاسخ‌های XML-RPC بازگردانده‌شده از سرور را کنترل می‌کنند. پارامتر bind_and_activate تعیین می‌کند که آیا server_bind() و server_activate() بلافاصله توسط سازنده فراخوانی می‌شوند یا خیر؛ مقدار پیش‌فرض آن true است. تنظیم آن روی 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)

یک نمونه جدید برای رسیدگی به درخواست‌های XML-RPC در یک محیط CGI ایجاد کنید. پارامترهای allow_none و encoding به xmlrpc.client ارسال می‌شوند و پاسخ‌های XML-RPC را که از سرور برگردانده می‌شوند کنترل می‌کنند. پارامتر use_builtin_types به تابع loads() ارسال می‌شود و کنترل می‌کند که هنگام دریافت مقادیر تاریخ/زمان یا داده‌های دودویی، کدام انواع پردازش شوند؛ به‌طور پیش‌فرض false است.

تغییر یافته در نسخه‌ی 3.3: پرچم use_builtin_types افزوده شد.

class xmlrpc.server.SimpleXMLRPCRequestHandler

یک نمونه‌ی جدید از هندلر درخواست ایجاد کنید. این مدیر درخواست از درخواست‌های POST پشتیبانی می‌کند و گزارش‌گیری را اصلاح می‌کند تا پارامتر logRequests در سازنده‌ی SimpleXMLRPCServer رعایت شود.

اشیای SimpleXMLRPCServer

کلاس SimpleXMLRPCServer بر پایه‌ی socketserver.TCPServer است و راهی برای ایجاد سرورهای XML-RPC ساده و مستقل فراهم می‌کند.

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

تابعی را ثبت کنید که بتواند به درخواست‌های XML-RPC پاسخ دهد. اگر name داده شود، نام متد مرتبط با function خواهد بود، در غیر این صورت از function.__name__ استفاده می‌شود. name یک رشته است و می‌تواند شامل نویسه‌هایی باشد که در شناسه‌های پایتون مجاز نیستند، از جمله نویسه نقطه.

این متد همچنین می‌تواند به‌عنوان دکوراتور استفاده شود. هنگامی که به‌عنوان دکوراتور استفاده شود، name فقط می‌تواند به‌عنوان آرگومان کلیدواژه‌ای داده شود تا function را با نام name ثبت کند. اگر name داده نشود، از function.__name__ استفاده خواهد شد.

تغییر یافته در نسخه‌ی 3.7: می‌توان از register_function() به‌عنوان دکوراتور استفاده کرد.

SimpleXMLRPCServer.register_instance(instance, allow_dotted_names=False)

شیءای را ثبت می‌کند که برای در معرض قرار دادن نام متدهای ثبت‌نشده با register_function() استفاده می‌شود. اگر instance دارای یک متد _dispatch() باشد، این متد با نام متد درخواست‌شده و پارامترهای درخواست فراخوانی می‌شود. API آن به‌صورت def _dispatch(self, method, params) است (توجه داشته باشید که params نشان‌دهنده‌ی یک فهرست آرگومان متغیر نیست). اگر این متد برای انجام وظیفه‌ی خود یک تابع زیربنایی را فراخوانی کند، آن تابع به‌صورت func(*params) و با واگشایی فهرست پارامترها فراخوانی می‌شود. مقدار بازگشتی از _dispatch() به‌عنوان نتیجه به کلاینت برگردانده می‌شود. اگر instance متد _dispatch() نداشته باشد، در آن به دنبال ویژگی‌ای که با نام متد درخواست‌شده مطابقت دارد جستجو می‌شود.

اگر آرگومان اختیاری allow_dotted_names درست باشد و نمونه متد _dispatch() نداشته باشد، در این صورت اگر نام متد درخواست‌شده حاوی نقاط باشد، هر کامپوننت از نام متد به‌صورت جداگانه جستجو می‌شود، به‌طوری که یک جستجوی سلسله‌مراتبی ساده انجام می‌شود. سپس مقدار یافته‌شده از این جستجو با پارامترهای درخواست فراخوانی می‌شود و مقدار بازگشتی به کلاینت بازگردانده می‌شود.

هشدار

فعال کردن گزینه‌ی allow_dotted_names به نفوذگران اجازه می‌دهد به متغیرهای سراسری ماژول شما دسترسی پیدا کنند و ممکن است به نفوذگران اجازه دهد کد دلخواه را روی ماشین شما اجرا کنند. تنها از این گزینه در یک شبکه‌ی امن و بسته استفاده کنید.

SimpleXMLRPCServer.register_introspection_functions()

توابع درون‌نگری XML-RPC شامل system.listMethods، system.methodHelp و system.methodSignature را ثبت می‌کند.

SimpleXMLRPCServer.register_multicall_functions()

تابع چندفراخوانی (multicall) در XML-RPC با نام system.multicall را ثبت می‌کند.

SimpleXMLRPCRequestHandler.rpc_paths

مقدار یک ویژگی باید تاپلی باشد که بخش‌های مسیر معتبر URL برای دریافت درخواست‌های XML-RPC را فهرست می‌کند. درخواست‌هایی که به مسیرهای دیگر ارسال می‌شوند، منجر به خطای HTTP با کد ۴۰۴ و پیام «چنین صفحه‌ای وجود ندارد» خواهند شد. اگر این تاپل خالی باشد، همه مسیرها معتبر در نظر گرفته خواهند شد. مقدار پیش‌فرض ('/', '/RPC2') است.

مثال SimpleXMLRPCServer

کد سرور:

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

کد کلاینت زیر، متدهایی را که سرور پیشین در دسترس قرار داده است فراخوانی خواهد کرد:

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() به‌عنوان یک دکوراتور استفاده کرد. مثال سرور پیشین می‌تواند توابع را به‌صورت دکوراتور ثبت کند:

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

مثال زیر که در ماژول Lib/xmlrpc/server.py گنجانده شده است، سروری را نشان می‌دهد که نام‌های نقطه‌دار را می‌پذیرد و یک تابع چندفراخوانی (multicall) را ثبت می‌کند.

هشدار

فعال کردن گزینه‌ی allow_dotted_names به مهاجمان اجازه می‌دهد به متغیرهای سراسری ماژول شما دسترسی پیدا کنند و ممکن است به مهاجمان اجازه دهد کد دلخواه را روی رایانه شما اجرا کنند. فقط از این مثال در یک شبکه‌ی امن و بسته استفاده کنید.

import datetime as dt

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

    class currentTime:
        @staticmethod
        def getCurrentTime():
            return dt.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)

این دموی 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

CGIXMLRPCRequestHandler

می‌توان از کلاس CGIXMLRPCRequestHandler برای رسیدگی به درخواست‌های XML-RPC ارسال‌شده به اسکریپت‌های CGI پایتون استفاده کرد.

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

تابعی را ثبت کنید که بتواند به درخواست‌های XML-RPC پاسخ دهد. اگر name داده شود، نام متد مرتبط با function خواهد بود، در غیر این صورت از function.__name__ استفاده می‌شود. name یک رشته است و می‌تواند شامل نویسه‌هایی باشد که در شناسه‌های پایتون مجاز نیستند، از جمله نویسه نقطه.

این متد همچنین می‌تواند به‌عنوان دکوراتور استفاده شود. هنگامی که به‌عنوان دکوراتور استفاده شود، name فقط می‌تواند به‌عنوان آرگومان کلیدواژه‌ای داده شود تا function را با نام name ثبت کند. اگر name داده نشود، از function.__name__ استفاده خواهد شد.

تغییر یافته در نسخه‌ی 3.7: می‌توان از register_function() به‌عنوان دکوراتور استفاده کرد.

CGIXMLRPCRequestHandler.register_instance(instance)

یک شیء را ثبت کنید که برای در معرض قرار دادن نام متدهایی استفاده می‌شود که با register_function() ثبت نشده‌اند. اگر نمونه شامل یک متد _dispatch() باشد، آن متد با نام متد درخواست‌شده و پارامترهای درخواست فراخوانی می‌شود؛ مقدار بازگشتی به‌عنوان نتیجه به کلاینت بازگردانده می‌شود. اگر نمونه متد _dispatch() نداشته باشد، در آن به دنبال ویژگی‌ای که با نام متد درخواست‌شده مطابقت دارد، جستجو می‌شود؛ اگر نام متد درخواست‌شده شامل نقطه باشد، هر کامپوننت از نام متد به‌صورت جداگانه جستجو می‌شود، به‌طوری که یک جستجوی سلسله‌مراتبی ساده انجام می‌شود. سپس مقدار یافته‌شده از این جستجو با پارامترهای درخواست فراخوانی می‌شود و مقدار بازگشتی به کلاینت بازگردانده می‌شود.

CGIXMLRPCRequestHandler.register_introspection_functions()

توابع درون‌نگری XML-RPC یعنی system.listMethods، system.methodHelp و system.methodSignature را ثبت کنید.

CGIXMLRPCRequestHandler.register_multicall_functions()

تابع multicall در XML-RPC یعنی system.multicall را ثبت کنید.

CGIXMLRPCRequestHandler.handle_request(request_text=None)

به یک درخواست XML-RPC رسیدگی می‌کند. اگر request_text داده شده باشد، باید داده‌های POST ارائه‌شده توسط سرور HTTP باشد، در غیر این صورت از محتوای 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()

مستندسازی سرور XMLRPC

این کلاس‌ها کلاس‌های فوق را گسترش می‌دهند تا مستندات HTML را در پاسخ به درخواست‌های HTTP GET ارائه کنند. سرورها می‌توانند مستقل باشند و از DocXMLRPCServer استفاده کنند، یا در یک محیط CGI تعبیه شوند و از DocCGIXMLRPCRequestHandler استفاده کنند.

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

برای رسیدگی به درخواست‌های XML-RPC در یک محیط CGI، یک نمونه جدید ایجاد کنید.

class xmlrpc.server.DocXMLRPCRequestHandler

نمونه‌ی جدیدی از مدیر درخواست (request handler) ایجاد کنید. این مدیر درخواست از درخواست‌های POST مربوط به XML-RPC، درخواست‌های GET مربوط به مستندات پشتیبانی می‌کند و گزارش‌دهی را تغییر می‌دهد تا پارامتر logRequests در سازنده‌ی DocXMLRPCServer رعایت شود.

اشیای DocXMLRPCServer

کلاس DocXMLRPCServer از SimpleXMLRPCServer مشتق شده است و امکان ایجاد سرورهای XML-RPC مستقل و خودمستند را فراهم می‌کند. درخواست‌های HTTP POST به‌عنوان فراخوانی‌های متد XML-RPC پردازش می‌شوند. درخواست‌های HTTP GET با تولید مستندات HTML به سبک pydoc پردازش می‌شوند. این امکان را به سرور می‌دهد تا مستندات مبتنی بر وب خود را ارائه دهد.

DocXMLRPCServer.set_server_title(server_title)

عنوانی را که در مستندات HTML تولیدشده استفاده می‌شود، تنظیم کنید. این عنوان درون المان "title" در HTML استفاده خواهد شد.

DocXMLRPCServer.set_server_name(server_name)

نامی را که در مستندات HTML تولیدشده استفاده می‌شود، تنظیم کنید. این نام در بالای مستندات تولیدشده، درون یک المان "h1" نمایش داده خواهد شد.

DocXMLRPCServer.set_server_documentation(server_documentation)

توضیح مورد استفاده در مستندات HTML تولیدشده را تنظیم کنید. این توضیح به‌صورت یک پاراگراف، زیر نام سرور، در مستندات نمایش داده می‌شود.

DocCGIXMLRPCRequestHandler

کلاس DocCGIXMLRPCRequestHandler از CGIXMLRPCRequestHandler مشتق شده است و امکان ایجاد اسکریپت‌های CGI خودمستند از نوع XML-RPC را فراهم می‌کند. درخواست‌های HTTP POST به‌عنوان فراخوانی‌های متد XML-RPC پردازش می‌شوند. درخواست‌های HTTP GET با تولید مستندات HTML به سبک pydoc پردازش می‌شوند. این امر به سرور اجازه می‌دهد مستندات تحت وب خود را ارائه دهد.

DocCGIXMLRPCRequestHandler.set_server_title(server_title)

عنوانی را که در مستندات HTML تولیدشده استفاده می‌شود، تنظیم کنید. این عنوان درون المان "title" در HTML استفاده خواهد شد.

DocCGIXMLRPCRequestHandler.set_server_name(server_name)

نامی را که در مستندات HTML تولیدشده استفاده می‌شود، تنظیم کنید. این نام در بالای مستندات تولیدشده، درون یک المان "h1" نمایش داده خواهد شد.

DocCGIXMLRPCRequestHandler.set_server_documentation(server_documentation)

توضیح مورد استفاده در مستندات HTML تولیدشده را تنظیم کنید. این توضیح به‌صورت یک پاراگراف، زیر نام سرور، در مستندات نمایش داده می‌شود.