Welcome, guest | Sign In | My Account | Store | Cart
#### server.py 
import uuid
import base64
import socket
import shelve
import Cookie
from SimpleXMLRPCServer import *  

class UserManagement:
    def __init__(self):
        self.d = shelve.open('machines.shv')

        # register a list of valid machine names/email id's 
        validconfig = {'email@address.com':'vaikings'}
        for k,v in validconfig.items():
            self.generateUuid(k,v)

    def generateUuid(self, email_id, machine_name):
        """ return a uuid which uniquely identifies machinename and email id """
        uuidstr = None

        if machine_name not in self.d:
            myNamespace = uuid.uuid3(uuid.NAMESPACE_URL, machine_name)
            uuidstr = str(uuid.uuid3(myNamespace, email_id)) 

            self.d[machine_name] = (machine_name, uuidstr, email_id)
            self.d[uuidstr] = (machine_name, uuidstr ,email_id)
        else:
            (machine_name, uuidstr, email_id) = self.d[machine_name]

        return uuidstr

    def checkMe(self, id):
        if id in self.d:
            return self.d[id]
        return (None,None,None)

    def __del__(self):
        self.d.close()

def authenticate(id):
    sk = UserManagement()
    return sk.checkMe(id)

class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
    def setCookie(self, key=None ,value=None):
        if key :
            c1 = Cookie.SimpleCookie()
            c1[key] = value
            cinfo = self.getDefaultCinfo() 
            for attr,val in cinfo.items():
                c1[key][attr] = val
                            
            if c1 not in self.cookies:
                self.cookies.append(c1)

    def getDefaultCinfo(self):
        cinfo = {}

        cinfo['expires'] = 30*24*60*60
        cinfo['path'] = '/RPC2/'
        cinfo['comment'] = 'comment!'
        cinfo['domain'] = '.localhost.local'
        cinfo['max-age'] = 30*24*60*60
        cinfo['secure'] = ''
        cinfo['version']= 1
        
        return cinfo
                            
    def do_POST(self):
        """Handles the HTTP POST request.

        Attempts to interpret all HTTP POST requests as XML-RPC calls,
        which are forwarded to the server's _dispatch method for handling.
        """
        #Note: this method is the same as in SimpleXMLRPCRequestHandler, 
        #just hacked to handle cookies 

        # Check that the path is legal
        if not self.is_rpc_path_valid():
            self.report_404()
            return

        try:
            # Get arguments by reading body of request.
            # We read this in chunks to avoid straining
            # socket.read(); around the 10 or 15Mb mark, some platforms
            # begin to have problems (bug #792570).
            max_chunk_size = 10*1024*1024
            size_remaining = int(self.headers["content-length"])
            L = []
            while size_remaining:
                chunk_size = min(size_remaining, max_chunk_size)
                L.append(self.rfile.read(chunk_size))
                size_remaining -= len(L[-1])
            data = ''.join(L)

            # In previous versions of SimpleXMLRPCServer, _dispatch
            # could be overridden in this class, instead of in
            # SimpleXMLRPCDispatcher. To maintain backwards compatibility,
            # check to see if a subclass implements _dispatch and dispatch
            # using that method if present.
            response = self.server._marshaled_dispatch(
                    data, getattr(self, '_dispatch', None)
                )
        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)))

            # HACK :start -> sends cookies here 
            if self.cookies:
                for cookie in self.cookies:
                    self.send_header('Set-Cookie',cookie.output(header=''))
            # HACK :end
            
            self.end_headers()
            self.wfile.write(response)

            # shut down the connection
            self.wfile.flush()
            self.connection.shutdown(1)

    def authenticate_client(self):
        validuser = False

        if self.headers.has_key('Authorization'):
            # handle Basic authentication
            (enctype, encstr) =  self.headers.get('Authorization').split()
            (emailid, machine_name) = base64.standard_b64decode(encstr).split(':')
            (auth_machine, auth_uuidstr, auth_email) = authenticate(machine_name)

            if emailid == auth_email:
                print "Authenticated"
                # set authentication cookies on client machines
                validuser = True
                if auth_uuidstr:
                    self.setCookie('UUID',auth_uuidstr)
                    
        elif self.headers.has_key('UUID'):
            # handle cookie based authentication
            id =  self.headers.get('UUID')
            (auth_machine, auth_uuidstr, auth_email) = authenticate(id)

            if auth_uuidstr :
                print "Authenticated"
                validuser = True
        else:
            print 'Authentication failed'

        return validuser

    def _dispatch(self, method, params):    
        self.cookies = []
        
        validuser = self.authenticate_client() 
        # handle request        
        if method == 'hello_world':                
            (input1, input2) = params    
            retstr = XMLRPC_register().hello_world(input1, input2, validuser)
            return retstr
        else:
            return 'Invalid Method [%s]'%method

# functions available as web services
class XMLRPC_register:
    def hello_world(self, t1, t2, validuser):
        if validuser:
            return t1+'-'+t2
        else:
            return "please register ur machine"

if __name__ == '__main__':
    try:
        se = SimpleXMLRPCServer(("localhost",8088), MySimpleXMLRPCRequestHandler, True, True)
        se.register_introspection_functions()
        se.serve_forever()
    except KeyboardInterrupt:
        print "Bye"
    
#--------------------- new file starts here-----------
### client.py 
import os
import base64
import xmlrpclib
import urllib2
import cookielib

class CookieAuthXMLRPCTransport(xmlrpclib.Transport):
    """ xmlrpclib.Transport that sends basic HTTP Authentication"""

    user_agent = '*py*'
    credentials = ()
    cookiefile = 'cookies.lwp'
        
    def send_basic_auth(self, connection):
        """Include HTTP Basic Authentication data in a header"""
        
        auth = base64.encodestring("%s:%s"%self.credentials).strip()
        auth = 'Basic %s' %(auth,)
        connection.putheader('Authorization',auth)

    def send_cookie_auth(self, connection):
        """Include Cookie Authentication data in a header"""
        
        cj = cookielib.LWPCookieJar()
        cj.load(self.cookiefile)

        for cookie in cj:
            if cookie.name == 'UUID':
                uuidstr = cookie.value
            connection.putheader(cookie.name, cookie.value)

    ## override the send_host hook to also send authentication info
    def send_host(self, connection, host):
        xmlrpclib.Transport.send_host(self, connection, host)
        if os.path.exists(self.cookiefile):
            self.send_cookie_auth(connection)
        elif self.credentials != ():
            self.send_basic_auth(connection)
                    
    def request(self, host, handler, request_body, verbose=0):
        # dummy request class for extracting cookies 
        class CookieRequest(urllib2.Request):
            pass
            
        # dummy response class for extracting cookies 
        class CookieResponse:
            def __init__(self, headers):
                self.headers = headers
            def info(self):
                return self.headers 

        crequest = CookieRequest('http://'+host+'/')
            
        # issue XML-RPC request
        h = self.make_connection(host)
        if verbose:
            h.set_debuglevel(1)

        self.send_request(h, handler, request_body)
        self.send_host(h, host)
        self.send_user_agent(h)
        
        # creating a cookie jar for my cookies
        cj = cookielib.LWPCookieJar()
                        
        self.send_content(h, request_body)
            
        errcode, errmsg, headers = h.getreply()

        cresponse = CookieResponse(headers)
        cj.extract_cookies(cresponse, crequest)

        if len(cj) >0 and self.cookiefile != None:
            cj.save(self.cookiefile)
                
        if errcode != 200:
            raise ProtocolError(
                host + handler,
                errcode, errmsg,
                headers
                )

        self.verbose = verbose

        try:
            sock = h._conn.sock
        except AttributeError:
            sock = None
                
        return self._parse_response(h.getfile(), sock)

def getXmlrpcClient(server_uri, auth = ()):
    """ this will return an xmlrpc client which supports
    basic authentication/authentication through cookies 
    """

    trans = CookieAuthXMLRPCTransport()
    if auth!= ():
        trans.credentials = auth
    client = xmlrpclib.Server(server_uri, transport=trans, verbose=False)
    
    return client

if __name__ == "__main__":
    email = 'email@address.com'
    machine_name = 'vaikings'
    
    client = getXmlrpcClient('http://localhost:8088', (email,machine_name))
#    client = getXmlrpcClient('http://localhost:8088')
    inputstr1 = "hello"
    inputstr2 = "world"

    try:
        retstr = client.hello_world(inputstr1, inputstr2)
        print retstr

        print client.hey('hey')
    except Exception, e:
        print e

History