summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Sommerseth <davids@redhat.com>2011-02-04 20:01:41 +0100
committerDavid Sommerseth <davids@redhat.com>2011-02-04 20:01:41 +0100
commitbcc4f7c2e36e63cda578cb38d52e5c6280c0c949 (patch)
tree1f6756029ccf119910ff987631023fc9177ee88b
parentaa859529279b695fd6f7ebd5a2f66e42aa7bc066 (diff)
downloadrteval-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.tpl41
-rw-r--r--server/rteval_xmlrpc.wsgi113
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"
+