mirror of
https://github.com/naruxde/revpipyload.git
synced 2026-08-16 05:05:52 +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 = 1
|
||||
aclfile = /etc/revpipyload/aclxmlrpc.conf
|
||||
bindip = 127.0.0.1
|
||||
bindip = socket
|
||||
|
||||
[MQTT]
|
||||
mqtt = 0
|
||||
|
||||
@@ -31,6 +31,7 @@ __license__ = "GPLv2"
|
||||
import gzip
|
||||
import os
|
||||
import signal
|
||||
import socket
|
||||
import tarfile
|
||||
import zipfile
|
||||
from configparser import ConfigParser
|
||||
@@ -51,7 +52,7 @@ from . import proginit
|
||||
from .helper import get_revpiled_address, pi_control_reset, refullmatch
|
||||
from .shared.ipaclmanager import IpAclManager
|
||||
from .watchdogs import ResetDriverWatchdog
|
||||
from .xrpcserver import SaveXMLRPCServer
|
||||
from .xrpcserver import SaveXMLRPCServer, UnixStreamXMLRPCServer
|
||||
|
||||
min_revpimodio = "2.5.0"
|
||||
|
||||
@@ -314,6 +315,16 @@ class RevPiPyLoad:
|
||||
# Bind IP lesen und anpassen
|
||||
self.xmlrpcbindip = \
|
||||
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 == "*":
|
||||
self.xmlrpcbindip = ""
|
||||
elif self.xmlrpcbindip == "":
|
||||
@@ -388,12 +399,35 @@ class RevPiPyLoad:
|
||||
self.xsrv = None
|
||||
else:
|
||||
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.xmlrpcbindip, self.xmlrpcport),
|
||||
logRequests=False,
|
||||
allow_none=True,
|
||||
ipacl=self.xmlrpcacl
|
||||
)
|
||||
|
||||
self.xsrv.register_introspection_functions()
|
||||
self.xsrv.register_multicall_functions()
|
||||
|
||||
@@ -936,8 +970,17 @@ class RevPiPyLoad:
|
||||
|
||||
if self.xsrv is not None:
|
||||
proginit.logger.info("close xmlrpc-server")
|
||||
self.xsrv.shutdown()
|
||||
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()")
|
||||
|
||||
def xml_getconfig(self):
|
||||
|
||||
@@ -4,6 +4,7 @@ __author__ = "Sven Sager"
|
||||
__copyright__ = "Copyright (C) 2023 Sven Sager"
|
||||
__license__ = "GPLv2"
|
||||
|
||||
import socket
|
||||
from xmlrpc.server import SimpleXMLRPCRequestHandler, SimpleXMLRPCServer
|
||||
|
||||
from . import proginit
|
||||
@@ -102,3 +103,44 @@ class SaveXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||
)
|
||||
|
||||
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