views:

61

answers:

1

Having a code inspired from http://code.djangoproject.com/wiki/XML-RPC :

from SimpleXMLRPCServer import SimpleXMLRPCDispatcher
from django.http import HttpResponse

dispatcher = SimpleXMLRPCDispatcher(allow_none=False, encoding=None) # Python 2.5

def rpc_handler(request):
    """
    the actual handler:
    if you setup your urls.py properly, all calls to the xml-rpc service
    should be routed through here.
    If post data is defined, it assumes it's XML-RPC and tries to process as such
    Empty post assumes you're viewing from a browser and tells you about the service.
    """

    if len(request.POST):
        response = HttpResponse(mimetype="application/xml")
        response.write(dispatcher._marshaled_dispatch(request.raw_post_data))
    else:
        pass # Not interesting
    response['Content-length'] = str(len(response.content))
    return response

def post_log(message = "", tags = []):
    """ Code called via RPC. Want to know here the remote IP (or hostname). """
    pass

dispatcher.register_function(post_log, 'post_log')

How could get the IP address of the client within the "post_log" definition? I have seen http://stackoverflow.com/questions/2129374/ip-address-of-client-in-python-simplexmlrpcserver but can't apply it to my case.

Thanks.

A: 

Ok I could do it ... with some nifty tips ...

First, I created my own copy of SimpleXMLRPCDispatcher which inherit everything from it and overides 2 methods :

class MySimpleXMLRPCDispatcher (SimpleXMLRPCDispatcher) :
    def _marshaled_dispatch(self, data, dispatch_method = None, request = None):
        # copy and paste from /usr/lib/python2.6/SimpleXMLRPCServer.py except
        response = self._dispatch(method, params)
        # which becomes
        response = self._dispatch(method, params, request)

    def _dispatch(self, method, params, request = None):
        # copy and paste from /usr/lib/python2.6/SimpleXMLRPCServer.py except
        return func(*params)
        # which becomes
        return func(request, *params)

Then in my code, all to do is :

# ...
if len(request.POST):
    response = HttpResponse(mimetype="application/xml")
    response.write(dispatcher._marshaled_dispatch(request.raw_post_data, request = request))
# ...
def post_log(request, message = "", tags = []):
    """ Code called via RPC. Want to know here the remote IP (or hostname). """
    ip = request.META["REMOTE_ADDR"]
    hostname = socket.gethostbyaddr(ip)[0]

That's it. I know it's not very clean... Any suggestion for cleaner solution is welcome!

samb