If someone here has spare Brain/CPU cycles, could you look at the attached code and provide feedback?

Grisha

---------- Forwarded message ----------
Date: Mon, 30 Jan 2006 18:04:42 -0800
From: Matt Chisholm <[EMAIL PROTECTED]>
Subject: Re: contribution to mod_python: Apache + SimpleXMLRPCServer

On Jan 30 2006, 11:42, Matt Chisholm wrote:
We've written a few classes to use the SimpleXMLRPCServer module in
Python with mod_python instead of the Python CGI module.  We've been
using it internally for a while and we'd like to contribute it back to
the mod_python project; we don't really have the time to create a
separate project for it, but it seems like something that would be
useful to many people.

We agree to assign copyright of this code to the mod_python project
and to license it under the mod_python license.  Our employer,
BitTorrent Inc., also agrees.

I've attached a copy of the code.

Please let me know if this is not the right channel to send
contributions; also, I'm not on this list so please respond to me
individually.

Matt Chisholm

# Written by Matt Chisholm and Greg Hazel

# This should probably be contributed back to the mod_python project

from mod_python import apache

from SimpleXMLRPCServer import    CGIXMLRPCRequestHandler
from    DocXMLRPCServer import DocCGIXMLRPCRequestHandler

import traceback
import xmlrpclib
from xmlrpclib import Fault
import sys

class stderr_mod_python(object):
    def __init__(self, request):
        self.request = request
    def write(self, s):
        l = s.strip('\r\n')
        for e in l.split('\n'):
            s = "%s %s: %s" % (self.request.phase, self.request.hlist.handler, e)
            # this logs in the mod_python fashion to the error log for this request's virtual server
            self.request.log_error(s, apache.APLOG_NOERRNO|apache.APLOG_ERR)        

class ApacheXMLRPCRequestHandler(CGIXMLRPCRequestHandler):
    def _write(self, request, response, content_type='text/xml'):
        request.send_http_header()
        request.content_type = content_type
        request.write(response)

    # SimpleXMLRPCServer doesn't do what we want
    def _marshaled_dispatch(self, data, dispatch_method = None):
        """Dispatches an XML-RPC method from marshalled (XML) data.

        XML-RPC methods are dispatched from the marshalled (XML) data
        using the _dispatch method and the result is returned as
        marshalled data. For backwards compatibility, a dispatch
        function can be provided as an argument (see comment in
        SimpleXMLRPCRequestHandler.do_POST) but overriding the
        existing method through subclassing is the prefered means
        of changing method dispatch behavior.
        """

        params, method = xmlrpclib.loads(data)

        # men have been killed for less
        temp = sys.stderr
        sys.stderr = stderr_mod_python(self.request)
            
        # generate response
        try:
            
            if dispatch_method is not None:
                response = dispatch_method(method, params)
            else:
                response = self._dispatch(method, params)
            # wrap response in a singleton tuple
            response = (response,)
            response = xmlrpclib.dumps(response, methodresponse=1)
        except Fault, fault:
            response = xmlrpclib.dumps(fault)
        except Exception, e:
            # report exception back to server
            response = xmlrpclib.dumps(
                xmlrpclib.Fault(1, "%s:%s" % (sys.exc_type, sys.exc_value))
                )
            # and also log it, duh
            etype, evalue, etb = sys.exc_info()
            
            stack = traceback.format_exception(etype, evalue, etb)             
            for l in stack:
                sys.stderr.write(l)
                
        sys.stderr = temp

        return response
    
    def handle_xmlrpc(self, request):
        xml_request = request.read()
        self.request = request
        response = self._marshaled_dispatch(xml_request)
        self._write(request, response)
        return apache.OK

    def handle_get(self, request):
        return apache.HTTP_BAD_REQUEST

    def handle_request(self, request):
        if request.method == 'POST':
            responsecode = self.handle_xmlrpc(request)
        elif request.method == 'GET':
            responsecode = self.handle_get(request)
        else:
            responsecode = apache.HTTP_BAD_REQUEST
        return responsecode


class DocApacheXMLRPCRequestHandler(ApacheXMLRPCRequestHandler, DocCGIXMLRPCRequestHandler):

    def __init__(self):
        # calling __init__ manually is necessary here
        ApacheXMLRPCRequestHandler.__init__(self)
        DocCGIXMLRPCRequestHandler.__init__(self)

    def handle_get(self, request):
        response = self.generate_html_documentation()
        self._write(request, response, content_type='text/html')
        return apache.OK

Reply via email to