mirror of
https://github.com/naruxde/revpipyload.git
synced 2026-08-16 13:07:03 +02:00
feat: Add option to use unix socket for xml rpc server
This commit is contained in:
@@ -27,7 +27,7 @@ watchdog = 1
|
|||||||
[XMLRPC]
|
[XMLRPC]
|
||||||
xmlrpc = 1
|
xmlrpc = 1
|
||||||
aclfile = /etc/revpipyload/aclxmlrpc.conf
|
aclfile = /etc/revpipyload/aclxmlrpc.conf
|
||||||
bindip = 127.0.0.1
|
bindip = socket
|
||||||
|
|
||||||
[MQTT]
|
[MQTT]
|
||||||
mqtt = 0
|
mqtt = 0
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ __license__ = "GPLv2"
|
|||||||
import gzip
|
import gzip
|
||||||
import os
|
import os
|
||||||
import signal
|
import signal
|
||||||
|
import socket
|
||||||
import tarfile
|
import tarfile
|
||||||
import zipfile
|
import zipfile
|
||||||
from configparser import ConfigParser
|
from configparser import ConfigParser
|
||||||
@@ -51,7 +52,7 @@ from . import proginit
|
|||||||
from .helper import get_revpiled_address, pi_control_reset, refullmatch
|
from .helper import get_revpiled_address, pi_control_reset, refullmatch
|
||||||
from .shared.ipaclmanager import IpAclManager
|
from .shared.ipaclmanager import IpAclManager
|
||||||
from .watchdogs import ResetDriverWatchdog
|
from .watchdogs import ResetDriverWatchdog
|
||||||
from .xrpcserver import SaveXMLRPCServer
|
from .xrpcserver import SaveXMLRPCServer, UnixStreamXMLRPCServer
|
||||||
|
|
||||||
min_revpimodio = "2.5.0"
|
min_revpimodio = "2.5.0"
|
||||||
|
|
||||||
@@ -314,6 +315,16 @@ class RevPiPyLoad:
|
|||||||
# Bind IP lesen und anpassen
|
# Bind IP lesen und anpassen
|
||||||
self.xmlrpcbindip = \
|
self.xmlrpcbindip = \
|
||||||
self.globalconfig.get("XMLRPC", "bindip", fallback="127.0.0.1")
|
self.globalconfig.get("XMLRPC", "bindip", fallback="127.0.0.1")
|
||||||
|
|
||||||
|
if self.xmlrpcbindip.lower() == "socket":
|
||||||
|
# Unix Domain Socket mit festem Pfad
|
||||||
|
self.xmlrpcbindip = "/run/revpipyload/xmlrpc.socket"
|
||||||
|
self.xmlrpcisunix = True
|
||||||
|
elif self.xmlrpcbindip.startswith("/"):
|
||||||
|
# Unix Domain Socket
|
||||||
|
self.xmlrpcisunix = True
|
||||||
|
else:
|
||||||
|
self.xmlrpcisunix = False
|
||||||
if self.xmlrpcbindip == "*":
|
if self.xmlrpcbindip == "*":
|
||||||
self.xmlrpcbindip = ""
|
self.xmlrpcbindip = ""
|
||||||
elif self.xmlrpcbindip == "":
|
elif self.xmlrpcbindip == "":
|
||||||
@@ -388,12 +399,35 @@ class RevPiPyLoad:
|
|||||||
self.xsrv = None
|
self.xsrv = None
|
||||||
else:
|
else:
|
||||||
proginit.logger.debug("create xmlrpc server")
|
proginit.logger.debug("create xmlrpc server")
|
||||||
|
|
||||||
|
if self.xmlrpcisunix:
|
||||||
|
# Unix Domain Socket Server
|
||||||
|
proginit.logger.info(
|
||||||
|
"starting xmlrpc unix server on {0}".format(self.xmlrpcbindip)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Vorherige Socket-Datei löschen
|
||||||
|
try:
|
||||||
|
os.unlink(self.xmlrpcbindip)
|
||||||
|
except FileNotFoundError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
self.xsrv = UnixStreamXMLRPCServer(
|
||||||
|
self.xmlrpcbindip,
|
||||||
|
requestHandler=UnixStreamXMLRPCRequestHandler,
|
||||||
|
logRequests=False,
|
||||||
|
allow_none=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
else:
|
||||||
|
# Standard IP Server
|
||||||
self.xsrv = SaveXMLRPCServer(
|
self.xsrv = SaveXMLRPCServer(
|
||||||
(self.xmlrpcbindip, self.xmlrpcport),
|
(self.xmlrpcbindip, self.xmlrpcport),
|
||||||
logRequests=False,
|
logRequests=False,
|
||||||
allow_none=True,
|
allow_none=True,
|
||||||
ipacl=self.xmlrpcacl
|
ipacl=self.xmlrpcacl
|
||||||
)
|
)
|
||||||
|
|
||||||
self.xsrv.register_introspection_functions()
|
self.xsrv.register_introspection_functions()
|
||||||
self.xsrv.register_multicall_functions()
|
self.xsrv.register_multicall_functions()
|
||||||
|
|
||||||
@@ -936,8 +970,17 @@ class RevPiPyLoad:
|
|||||||
|
|
||||||
if self.xsrv is not None:
|
if self.xsrv is not None:
|
||||||
proginit.logger.info("close xmlrpc-server")
|
proginit.logger.info("close xmlrpc-server")
|
||||||
|
self.xsrv.shutdown()
|
||||||
self.xsrv.server_close()
|
self.xsrv.server_close()
|
||||||
|
|
||||||
|
# Unix Socket aufräumen
|
||||||
|
if hasattr(self.xsrv, "address_family") and \
|
||||||
|
self.xsrv.address_family == socket.AF_UNIX:
|
||||||
|
try:
|
||||||
|
os.unlink(self.xsrv.server_address)
|
||||||
|
except (FileNotFoundError, AttributeError):
|
||||||
|
pass
|
||||||
|
|
||||||
proginit.logger.debug("leave RevPiPyLoad.stop_xmlrpcserver()")
|
proginit.logger.debug("leave RevPiPyLoad.stop_xmlrpcserver()")
|
||||||
|
|
||||||
def xml_getconfig(self):
|
def xml_getconfig(self):
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ __author__ = "Sven Sager"
|
|||||||
__copyright__ = "Copyright (C) 2023 Sven Sager"
|
__copyright__ = "Copyright (C) 2023 Sven Sager"
|
||||||
__license__ = "GPLv2"
|
__license__ = "GPLv2"
|
||||||
|
|
||||||
|
import socket
|
||||||
from xmlrpc.server import SimpleXMLRPCRequestHandler, SimpleXMLRPCServer
|
from xmlrpc.server import SimpleXMLRPCRequestHandler, SimpleXMLRPCServer
|
||||||
|
|
||||||
from . import proginit
|
from . import proginit
|
||||||
@@ -102,3 +103,44 @@ class SaveXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
|||||||
)
|
)
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
class UnixStreamXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
|
"""XML-RPC Request-Handler fuer Unix Domain Sockets."""
|
||||||
|
|
||||||
|
timeout = 2.0
|
||||||
|
|
||||||
|
def setup(self):
|
||||||
|
"""Initialisiert die Verbindung ohne TCP-spezifische Socket-Optionen."""
|
||||||
|
self.connection = self.request
|
||||||
|
if self.timeout is not None:
|
||||||
|
self.connection.settimeout(self.timeout)
|
||||||
|
self.rfile = self.connection.makefile("rb", self.rbufsize)
|
||||||
|
self.wfile = self.connection.makefile("wb", self.wbufsize)
|
||||||
|
|
||||||
|
def address_string(self):
|
||||||
|
"""Liefert einen Namen fuer Logging bei Unix Domain Sockets."""
|
||||||
|
return "localhost"
|
||||||
|
|
||||||
|
|
||||||
|
class UnixStreamXMLRPCServer(SimpleXMLRPCServer):
|
||||||
|
"""XML-RPC Server fuer Unix Domain Sockets."""
|
||||||
|
address_family = socket.AF_UNIX
|
||||||
|
|
||||||
|
def _dispatch(self, method, params):
|
||||||
|
"""Prueft ACL Level fuer angeforderte Methode.
|
||||||
|
|
||||||
|
@param method Angeforderte Methode
|
||||||
|
@param params Argumente fuer Methode
|
||||||
|
@return Dispatched data
|
||||||
|
|
||||||
|
"""
|
||||||
|
# ACL on a socket is always max level
|
||||||
|
if method == "xmlmodus":
|
||||||
|
params = (4,)
|
||||||
|
|
||||||
|
return super()._dispatch(method, params)
|
||||||
|
|
||||||
|
def register_function(self, acl_level, function, name=None):
|
||||||
|
"""Override register_function to ignore acl_level for unix sockets."""
|
||||||
|
return super().register_function(function, name)
|
||||||
|
|||||||
Reference in New Issue
Block a user