plaso-rubanetra/plaso/multi_processing/rpc_proxy.py
2020-04-06 18:48:34 +02:00

135 lines
4.1 KiB
Python

#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2014 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Simple RPC proxy server and client."""
import logging
import SimpleXMLRPCServer
import SocketServer
import xmlrpclib
from xml.parsers import expat
from plaso.lib import errors
from plaso.lib import proxy
class StandardRpcProxyServer(proxy.ProxyServer):
"""Class that implements a simple XML RPC based proxy server."""
def __init__(self, port=0):
"""Initializes the RPC proxy server object.
Args:
port: The port number the proxy should listen on. Defaults to 0.
"""
super(StandardRpcProxyServer, self).__init__(
proxy.GetProxyPortNumberFromPID(port))
self._proxy = None
def Close(self):
"""Close the proxy object."""
if not self._proxy:
return
self._proxy.shutdown()
self._proxy = None
def Open(self):
"""Set up the proxy so that it can be started."""
try:
self._proxy = SimpleXMLRPCServer.SimpleXMLRPCServer(
('localhost', self.listening_port), logRequests=False,
allow_none=True)
except SocketServer.socket.error as exception:
raise errors.ProxyFailedToStart(
u'Unable to setup a RPC server for listening to port: {0:d} with '
u'error: {1:s}'.format(self.listening_port, exception))
def SetListeningPort(self, new_port_number):
"""Change the port number the proxy listens to."""
# We don't want to change the port after the proxy has been started.
if self._proxy:
logging.warning(
u'Unable to change proxy ports for an already started proxy.')
return
self._port_number = proxy.GetProxyPortNumberFromPID(new_port_number)
def StartProxy(self):
"""Start the proxy."""
if not self._proxy:
raise errors.ProxyFailedToStart(u'Proxy not set up yet.')
self._proxy.serve_forever()
def RegisterFunction(self, function_name, function):
"""Register a function to this RPC proxy.
Args:
function_name: The name of the proxy function.
function: Callback method to the function providing the requested
information.
"""
if not self._proxy:
raise errors.ProxyFailedToStart((
u'Unable to register a function for a proxy that has not been set '
u'up yet.'))
self._proxy.register_function(function, function_name)
class StandardRpcProxyClient(proxy.ProxyClient):
"""Class that implements a simple XML RPC based proxy client."""
def __init__(self, port=0):
"""Initializes the RPC proxy client object.
Args:
port: The port number the proxy should connect to. Defaults to 0.
"""
super(StandardRpcProxyClient, self).__init__(
proxy.GetProxyPortNumberFromPID(port))
self._proxy = None
def Open(self):
"""Set up the proxy so that it can be started."""
try:
self._proxy = xmlrpclib.ServerProxy(
u'http://localhost:{0:d}'.format(self._port_number), allow_none=True)
except SocketServer.socket.error:
self._proxy = None
def GetData(self, call_back_name):
"""Return back data from the RPC proxy using a callback method.
Args:
call_back_name: The name of the callback method that the RPC proxy
supports.
Returns:
The data returned back by the callback method.
"""
if self._proxy is None:
return
call_back = getattr(self._proxy, call_back_name, None)
if call_back is None:
return
try:
return call_back()
except (SocketServer.socket.error, expat.ExpatError):
return