freeipa/server/test_server

134 lines
3.9 KiB
Plaintext
Raw Normal View History

2008-09-12 11:36:04 -05:00
#!/usr/bin/env python
import sys
sys.path.insert(0, "..")
sys.path.insert(0, ".")
import SimpleXMLRPCServer
import logging
import xmlrpclib
import re
import threading
import commands
from ipalib import api, conn
from ipalib.conn import context
import ipalib.load_plugins
PORT=8888
class StoppableXMLRPCServer(SimpleXMLRPCServer.SimpleXMLRPCServer):
"""Override of TIME_WAIT"""
allow_reuse_address = True
def serve_forever(self):
self.stop = False
while not self.stop:
self.handle_request()
class LoggingSimpleXMLRPCRequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
"""Overides the default SimpleXMLRPCRequestHander to support logging.
Logs client IP and the XML request and response.
"""
def parse(self, given):
"""Convert the incoming arguments into the format IPA expects"""
args = []
kw = {}
for g in given:
kw[g] = unicode(given[g])
return (args, kw)
def _dispatch(self, method, params):
"""Dispatches the XML-RPC method.
Methods beginning with an '_' are considered private and will
not be called.
"""
if (params):
(args, kw) = self.parse(*params)
else:
args = []
kw = {}
# this is fine for our test server
uid = commands.getoutput('/usr/bin/id -u')
krbccache = "FILE:/tmp/krb5cc_" + uid
func = None
try:
# FIXME: don't hardcode host and port
context.conn = conn.IPAConn("localhost", 389, krbccache)
try:
# check to see if a matching function has been registered
func = funcs[method]
except KeyError:
raise Exception('method "%s" is not supported' % method)
return func(**kw)
finally:
# Clean up any per-request data and connections
for k in context.__dict__.keys():
del context.__dict__[k]
def do_POST(self):
clientIP, port = self.client_address
# Log client IP and Port
logger.info('Client IP: %s - Port: %s' % (clientIP, port))
try:
# get arguments
data = self.rfile.read(int(self.headers["content-length"]))
# unmarshal the XML data
params, method = xmlrpclib.loads(data)
# Log client request
logger.info('Client request: \n%s\n' % data)
response = self.server._marshaled_dispatch(
data, getattr(self, '_dispatch', None))
# Log server response
logger.info('Server response: \n%s\n' % response)
except:
# This should only happen if the module is buggy
# internal error, report as HTTP server error
self.send_response(500)
self.end_headers()
else:
# got a valid XML-RPC response
self.send_response(200)
self.send_header("Content-type", "text/xml")
self.send_header("Content-length", str(len(response)))
self.end_headers()
self.wfile.write(response)
# shut down the connection
self.wfile.flush()
self.connection.shutdown(1)
# Set up our logger
logger = logging.getLogger('xmlrpcserver')
hdlr = logging.FileHandler('xmlrpcserver.log')
formatter = logging.Formatter("%(asctime)s %(levelname)s %(message)s")
hdlr.setFormatter(formatter)
logger.addHandler(hdlr)
logger.setLevel(logging.INFO)
# Set up the server
XMLRPCServer = StoppableXMLRPCServer(("",PORT), LoggingSimpleXMLRPCRequestHandler)
XMLRPCServer.register_introspection_functions()
# Get and register all the methods
api.finalize()
for cmd in api.Method:
logger.info("registering %s" % cmd)
XMLRPCServer.register_function(api.Method[cmd], cmd)
funcs = XMLRPCServer.funcs
print "Listening on port %d" % PORT
try:
XMLRPCServer.serve_forever()
except KeyboardInterrupt:
XMLRPCServer.server_close()
print "Server shutdown."