[Twisted-Python] better way to do this?

Eli Criffield elicriffield at gmail.com
Tue May 29 18:24:17 EDT 2007


What i want to do is validate the "From" host of an xmlrpc server
against a list of allowed servers.

Sounds easy enough but "connectionMade(self)" Call is way back in
http.HTTPChannel. That is set as the protocol in http.HTTPFactory and
HTTPFactory is inherits by server.Site.

So whats the best way to change one little function in http.HTTPChannel ?

Here is what i have now, but the I have to include all of server.Site
in my example, even though its unchanged except it inherits
myHTTPFactory instead of http.HTTPFactory.

Is there a simpler way to do this?

Eli Criffield

--example---
#!/usr/bin/env python

from twisted.web import xmlrpc, server, http, resource
from twisted.internet import reactor
from twisted.python.log import startLogging
from sys import stdout
import copy

class Example(xmlrpc.XMLRPC):
    """An example object to be published."""

    def xmlrpc_echo(self, x):
        """Return all passed args."""
        print "echo called"
        return x

    def xmlrpc_add(self, a, b):
        """Return sum of arguments."""
        print "add called"
        return a + b

class myHTTPChannel(http.HTTPChannel):
    def connectionMade(self):
        print "Check here if connection is allowed from",
self.transport.getPeer()
        self.setTimeout(self.timeOut)

class myHTTPFactory(http.HTTPFactory):
    protocol = myHTTPChannel


class mySite(myHTTPFactory):

    counter = 0
    requestFactory = server.Request
    displayTracebacks = True

    def __init__(self, resource, logPath=None, timeout=60*60*12):
        """Initialize.
        """
        http.HTTPFactory.__init__(self, logPath=logPath, timeout=timeout)
        self.sessions = {}
        self.resource = resource

    def _openLogFile(self, path):
        from twisted.python import logfile
        return logfile.LogFile(os.path.basename(path), os.path.dirname(path))

    def __getstate__(self):
        d = self.__dict__.copy()
        d['sessions'] = {}
        return d

    def _mkuid(self):
        """(internal) Generate an opaque, unique ID for a user's session.
        """
        import md5, random
        self.counter = self.counter + 1
        return md5.new("%s_%s" % (str(random.random()) ,
str(self.counter))).hexdigest()

    def makeSession(self):
        """Generate a new Session instance, and store it for future reference.
        """
        uid = self._mkuid()
        session = self.sessions[uid] = Session(self, uid)
        session.checkExpiredLoop.start(1800)
        return session

    def getSession(self, uid):
        """Get a previously generated session, by its unique ID.
        This raises a KeyError if the session is not found.
        """
        return self.sessions[uid]

    def buildProtocol(self, addr):
        """Generate a channel attached to this site.
        """
        channel = http.HTTPFactory.buildProtocol(self, addr)
        channel.requestFactory = self.requestFactory
        channel.site = self
        return channel

    isLeaf = 0

    def render(self, request):
        """Redirect because a Site is always a directory.
        """
        request.redirect(request.prePathURL() + '/')
        request.finish()

    def getChildWithDefault(self, pathEl, request):
        """Emulate a resource's getChild method.
        """
        request.site = self
        return self.resource.getChildWithDefault(pathEl, request)

    def getResourceFor(self, request):
        """Get a resource for a request.

        This iterates through the resource heirarchy, calling
        getChildWithDefault on each resource it finds for a path element,
        stopping when it hits an element where isLeaf is true.
        """
        request.site = self
        # Sitepath is used to determine cookie names between distributed
        # servers and disconnected sites.
        request.sitepath = copy.copy(request.prepath)
        return resource.getChildForRequest(self.resource, request)



if __name__ == '__main__':
    r = Example()

    reactor.listenTCP(7080,mySite(r),ctx)
    startLogging(stdout)
    reactor.run()




More information about the Twisted-Python mailing list