Use Python xmlrpclib with unix domain sockets?

邮差的信 提交于 2019-11-30 18:56:53

xmlrpclib requires that the url passed start with http or https. The way around this is to define a custom transport which ignores that url. Here's some code using the transport from supervisor:

import supervisor.xmlrpc
import xmlrpclib

proxy = xmlrpclib.ServerProxy('http://127.0.0.1',
                               transport=supervisor.xmlrpc.SupervisorTransport(
                                    None, None, serverurl='unix://'+socketpath))

proxy.supervisor.getState()

In case that's not useful, here's an updated version of the code found here:

class UnixStreamHTTPConnection(httplib.HTTPConnection, object):
    def __init__(self, *args, **kwargs):
        self.socketpath = kwargs.pop('socketpath')
        super(UnixStreamHTTPConnection, self).__init__(*args, **kwargs)

    def connect(self):
        self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
        self.sock.connect_ex(self.socketpath)

class UnixStreamTransport(xmlrpclib.Transport, object):
    def __init__(self, *args, **kwargs):
        self.socketpath = kwargs.pop('socketpath')
        super(UnixStreamTransport, self).__init__(*args, **kwargs)

Here's an updated example for using xmlrpclib to talk to supervisor:

import httplib
import socket
import xmlrpclib

class UnixStreamHTTPConnection(httplib.HTTPConnection):
    def connect(self):
        self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
        self.sock.connect(self.host)

class UnixStreamTransport(xmlrpclib.Transport, object):
    def __init__(self, socket_path):
        self.socket_path = socket_path
        super(UnixStreamTransport, self).__init__()

    def make_connection(self, host):
        return UnixStreamHTTPConnection(self.socket_path)


server = xmlrpclib.Server('http://arg_unused', transport=UnixStreamTransport("/var/run/supervisor.sock"))
print(server.supervisor.getState())

As has already been mentioned we have to specify a dummy url with http:// or https:// and then specify a custom transport to handle the domain socket

My version for python3, prepared from versions above.

class UnixStreamHTTPConnection(http.client.HTTPConnection):
    def connect(self):
        self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
        self.sock.connect(self.host)


class UnixStreamTransport(client.Transport, object):
    def __init__(self, socket_path):
        self.socket_path = socket_path
        super(UnixStreamTransport, self).__init__()

    def make_connection(self, host):
        return UnixStreamHTTPConnection(self.socket_path)


 proxy = client.ServerProxy('http://localhost', transport=UnixStreamTransport("/some/supervisor/socket/file/path"))

 print(proxy.supervisor.getState())

Mixing the answers above, here's what works for me...

import httplib
import socket
import xmlrpclib

class UnixStreamHTTPConnection(httplib.HTTPConnection, object):
    def __init__(self, *args, **kwargs):
        self.socketpath = kwargs.pop('socketpath')
        super(UnixStreamHTTPConnection, self).__init__(*args, **kwargs)

    def connect(self):
        self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
        self.sock.connect(self.socketpath)

class UnixStreamTransport(xmlrpclib.Transport, object):
    def __init__(self, *args, **kwargs):
        self.socketpath = kwargs.pop('socketpath')
        super(UnixStreamTransport, self).__init__(*args, **kwargs)

    def make_connection(self, host):
        return UnixStreamHTTPConnection(host, socketpath=self.socketpath)

server = xmlrpclib.ServerProxy('http://arg_unused', transport=UnixStreamTransport(socketpath="path/to/supervisor.sock"))
print server.supervisor.getState()
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!