[Twisted-web] Deferred fun
James R. Saker Jr.
cso at netcenturion.biz
Mon Jan 16 18:56:14 MST 2006
Per new years resolution 'I will learn how to use deferreds in twisted', I've
got a little puzzle in an xmlrpc remote nmap tool that I put together to try
to learn deferreds (as well as automate scans on my firewall from outside my
net), figuring the speed of nmap returning the results of a scan can be
excessively long and should make for a good deferred experiment. Except I
keep hitting an AssertionError and think it may have to do with what happens
to my deferred when it completes:
#!/usr/bin/python
"""
pyrscand.py
Python remote scanner: Nmap XML-RPC module for processing scan requests from a
remote host
"""
import os
from twisted.internet import defer
from twisted.web import xmlrpc, server
NMAP_PATH = '/usr/bin/nmap' # location of nmap binary on host
class ScanServer(xmlrpc.XMLRPC):
"""
XMLRPC server for remote scan processing
"""
def handleScan(self, type, ip, detectOS, timing):
"""
Simplistic scans only for now!
"""
result = ''
print "running scanner..."
scandata = os.popen('%s -%s -A -T%s %s -oX -' % \
(NMAP_PATH, type, timing, ip), 'r')
for line in scandata:
result += line # return xml in a string - not a list object
print "got result: \n%s" % result
return result
def handleFailure(self, f):
print "errback"
print "we got an exception: %s" % (f.getTraceback(),)
f.trap(RuntimeError)
return 'Error'
def xmlrpc_scan(self, type, ip, detectOS, timing):
"""
Inputs: type (sS, sT, sP), ip, detectOS flag, timing performance (0-5)
Outputs: XML formatted report value compliant with nmap schema
"""
print "scanner"
d = defer.Deferred()
d.addCallback(self.handleScan(type, ip, detectOS, timing))
d.addErrback(self.handleFailure)
if __name__ == '__main__':
from twisted.internet import reactor
r = ScanServer()
reactor.listenTCP(7080, server.Site(r))
reactor.run()
Running it actually shows the nmap xml output is returned to handleScan but
from there we hit an AssertionError:
Traceback (most recent call last):
File "/usr/lib/python2.4/site-packages/twisted/web/http.py", line 557, in
requestReceived
self.process()
File "/usr/lib/python2.4/site-packages/twisted/web/server.py", line 153, in
process
self.render(resrc)
File "/usr/lib/python2.4/site-packages/twisted/web/server.py", line 160, in
render
body = resrc.render(self)
File "/usr/lib/python2.4/site-packages/twisted/web/xmlrpc.py", line 118, in
render
defer.maybeDeferred(function, *args).addErrback(
--- <exception caught here> ---
File "/usr/lib/python2.4/site-packages/twisted/internet/defer.py", line 107,
in maybeDeferred
result = f(*args, **kw)
File "pyrscand.py", line 39, in xmlrpc_scan
d.addCallback(self.handleScan(type, ip, detectOS, timing))
File "/usr/lib/python2.4/site-packages/twisted/internet/defer.py", line 191,
in addCallback
callbackKeywords=kw)
File "/usr/lib/python2.4/site-packages/twisted/internet/defer.py", line 175,
in addCallbacks
assert callable(callback)
exceptions.AssertionError:
My xmlrpc client is pretty short and taken directly from online howto:
from twisted.web.xmlrpc import Proxy
from twisted.internet import reactor
def printValue(value):
print repr(value)
reactor.stop()
def printError(error):
print 'error', error
reactor.stop()
proxy = Proxy('http://localhost:7080/XMLRPC')
proxy.callRemote('scan', 'sP', '69.63.110.1',\
1, 5).addCallbacks(printValue,printError)
reactor.run()
Any thoughts would be greatly appreciated -
Jamie
More information about the Twisted-web
mailing list