Search code examples
pythontwisted

Twisted HTTP Client access peer IP (server)


How can I access remote peer IP in this Twisted HTTP Client example? (From Twisted Docs)

Working with this example:

from sys import argv
from pprint import pformat

from twisted.internet.task import react
from twisted.web.client import Agent, readBody
from twisted.web.http_headers import Headers


def cbRequest(response):
    #print 'Response version:', response.version
    #print 'Response code:', response.code
    #print 'Response phrase:', response.phrase
    #print 'Response headers:'
    #print pformat(list(response.headers.getAllRawHeaders()))
    poweredby = response.headers.getRawHeaders("X-Powered-By")
    server = response.headers.getRawHeaders("Server")


    print poweredby
    print server

    d = readBody(response)
    d.addCallback(cbBody)
    return d

def cbBody(body):
    print 'Response body:'
    #print body

def main(reactor, url=b"http://www.example.com/"):
    agent = Agent(reactor)
    d = agent.request(
        'GET', url,
        Headers({'User-Agent': ['Twisted Web Client Example']}),
        None)
    d.addCallback(cbRequest)



    return d

react(main, argv[1:])

After searching on the Internet and SO, I found that it can be read from:

self.xmlstream.transport.getHandle().getpeername()

or

self.transport.getPeer()

However I don't know which Class "self" refers to and where to put it in the example code?

Any help? Tips? Ideas?

Thanks,


Solution

  • It is possible to get the address, though you have to hack through some layers of abstraction and touch a private attribute:

    from __future__ import print_function
    from twisted.web.client import Agent
    from twisted.internet.task import react
    from twisted.internet.protocol import Protocol
    from twisted.internet.defer import Deferred
    
    class ReadAddress(Protocol):
        def __init__(self):
            self.result = Deferred()
    
        def connectionMade(self):
            self.result.callback(self.transport._producer.getPeer())
    
    def readAddress(response):
        p = ReadAddress()
        response.deliverBody(p)
        return p.result
    
    @react
    def main(reactor):
        a = Agent(reactor)
        d = a.request(b"GET", b"http://www.google.com/")
        d.addCallback(readAddress)
        d.addCallback(print)
        return d
    

    Ideally, there would be a simpler (public!) interface to retrieve information like this. It would be excellent if you could file a feature request in the Twisted tracker.