diff options
author | David Sommerseth <davids@redhat.com> | 2011-02-04 20:01:41 +0100 |
---|---|---|
committer | David Sommerseth <davids@redhat.com> | 2011-02-04 20:01:41 +0100 |
commit | bcc4f7c2e36e63cda578cb38d52e5c6280c0c949 (patch) | |
tree | 1f6756029ccf119910ff987631023fc9177ee88b | |
parent | aa859529279b695fd6f7ebd5a2f66e42aa7bc066 (diff) | |
download | rteval-bcc4f7c2e36e63cda578cb38d52e5c6280c0c949.tar.gz rteval-bcc4f7c2e36e63cda578cb38d52e5c6280c0c949.tar.xz rteval-bcc4f7c2e36e63cda578cb38d52e5c6280c0c949.zip |
Added mod_wsgi handler
This is an alternative Python handler for the XML-RPC server, making
use of the WSGI platform instead.
If the rteval_xmlrpc.wsgi script is started manually, using python
it will act as a standalone server, listening to localhost:65432
as default.
This script can also be loaded by, f.ex., the mod_wsgi module to
Apache. A template for Apache config is also added.
Signed-off-by: David Sommerseth <davids@redhat.com>
-rw-r--r-- | server/apache-rteval-wsgi.conf.tpl | 41 | ||||
-rw-r--r-- | server/rteval_xmlrpc.wsgi | 113 |
2 files changed, 154 insertions, 0 deletions
diff --git a/server/apache-rteval-wsgi.conf.tpl b/server/apache-rteval-wsgi.conf.tpl new file mode 100644 index 0000000..9bf5fea --- /dev/null +++ b/server/apache-rteval-wsgi.conf.tpl @@ -0,0 +1,41 @@ +# File: apache-rteval.conf +# +# Apache config entry to enable the rteval XML-RPC server +# +# Copyright 2011 David Sommerseth <davids@redhat.com> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# For the avoidance of doubt the "preferred form" of this code is one which +# is in an open unpatent encumbered format. Where cryptographic key signing +# forms part of the process of creating an executable the information +# including keys needed to generate an equivalently functional executable +# are deemed to be part of the source code. +# + +WSGISocketPrefix /var/run/wsgi +WSGIDaemonProcess rtevalxmlrpc processes=3 threads=15 python-path={_INSTALLDIR_} +WSGIScriptAlias /rteval/API1 {_INSTALLDIR_}/rteval_xmlrpc.wsgi + +<Directory "{_INSTALLDIR_}"> + Options Indexes FollowSymLinks + AllowOverride None + Order allow,deny + Allow from all + + WSGIProcessGroup rtevalxmlrpc + WSGICallableObject rtevalXMLRPC_handler +</Directory> + diff --git a/server/rteval_xmlrpc.wsgi b/server/rteval_xmlrpc.wsgi new file mode 100644 index 0000000..f782657 --- /dev/null +++ b/server/rteval_xmlrpc.wsgi @@ -0,0 +1,113 @@ +# +# rteval_xmlrpc.wsgi +# XML-RPC handler for the rteval server, using mod_wsgi +# +# Copyright 2011 David Sommerseth <davids@redhat.com> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# For the avoidance of doubt the "preferred form" of this code is one which +# is in an open unpatent encumbered format. Where cryptographic key signing +# forms part of the process of creating an executable the information +# including keys needed to generate an equivalently functional executable +# are deemed to be part of the source code. +# + +from wsgiref.simple_server import make_server +import types +from xmlrpclib import dumps, loads, Fault +from xmlrpc_API1 import XMLRPC_API1 +from rteval.rtevalConfig import rtevalConfig + +def rtevalXMLRPC_Dispatch(method, args): + # Default configuration + defcfg = {'xmlrpc_server': { 'datadir': './var/lib/rteval', + 'db_server': 'localhost', + 'db_port': 5432, + 'database': 'rteval', + 'db_username': 'rtevxmlrpc', + 'db_password': 'rtevaldb' + } + } + + # Fetch configuration + cfg = rtevalConfig(defcfg) + cfg.Load(append=True) + + # Prepare an object for executing the query + xmlrpc = XMLRPC_API1(config=cfg.GetSection('xmlrpc_server')) + + # Exectute it + result = xmlrpc.Dispatch(method, args) + + # Send the result + if type(result) == types.TupleType: + return dumps(result, None, methodresponse=1) + else: + return dumps((result,), None, methodresponse=1) + + +def rtevalXMLRPC_handler(environ, start_response): + + # the environment variable CONTENT_LENGTH may be empty or missing + try: + request_body_size = int(environ.get('CONTENT_LENGTH', 0)) + except (ValueError): + request_body_size = 0 + + # When the method is POST the query string will be sent + # in the HTTP request body which is passed by the WSGI server + # in the file like wsgi.input environment variable. + try: + if (environ['REQUEST_METHOD'] != 'POST') or (request_body_size < 1): + raise Exception('Error in request') + + request_body = environ['wsgi.input'].read(request_body_size) + try: + args, method = loads(request_body) + except: + raise Exception('Invalid XML-RPC request') + + # Execute the XML-RPC call + status = '200 OK' + cont_type = 'text/xml' + response = [rtevalXMLRPC_Dispatch(method, args)] + except Exception, ex: + status = '500 Internal server error: %s' % str(ex) + cont_type = 'text/plain' + response = [ + '500 Internal server error\n', + 'ERROR: %s' % str(ex) + ] + import traceback, sys + traceback.print_exc(file=sys.stderr) + + response_headers = [('Content-Type', cont_type), + ('Content-Length', str(len("".join(response))))] + start_response(status, response_headers) + return response + + +if __name__ == '__main__': + # + # Simple stand-alone XML-RPC server, if started manually + # Not suitable for production environments, but for testing + # + httpd = make_server('localhost', 65432, rtevalXMLRPC_handler) + try: + httpd.serve_forever() + except KeyboardInterrupt: + print "\nShutting down" + |