[Twisted-Python] How to get caller’s IP address in Perspective Broker server

Glyph Lefkowitz glyph at twistedmatrix.com
Mon Jan 16 23:50:36 MST 2017


> On Jan 16, 2017, at 6:15 AM, Роман Мещеряков <romanmescheryakov at yandex.ru> wrote:
> 
> Hi everyone! I’m new to Twisted and mailing lists, so please excuse me if I make some mistake.

Hi Roman! Doing great so far, no mistakes I can see.

> My question maybe trivial, but as far as I know it is neither explained on the twistedmatrix.com web site nor easily resolved using Google search. The question is: how can Perspective Broker server get an IP address of the client the server is being called by? For example, let’s consider first PB server example on the Using Perspective Broker <http://twistedmatrix.com/documents/current/core/howto/pb-usage.html> page, pbsimple.py. Inside remote_echo method of the Echoer class, how one could obtain IP address of a client that is calling this method?

This is a great question and really points to a weakness in the PB documentation.

> One of solutions I found in Google requires client to pass some pb.Referenceable object as a parameter to a call, and then server is able to get client’s IP address by calling broker.transport.getPeer().host on that object. But passing pb.Referenceable just for purpose of getting caller’s IP address seems not very convenient. Are there more simple way?

Yeah, adding a Referenceable argument is not really the right way to go; you don't want to have to expose a whole object and thereby change your network protocol just to get access to an object that's already present in the existing implementation.

What you need to do here is take advantage of the remoteMessageReceived method, https://twistedmatrix.com/documents/16.6.0/api/twisted.spread.pb.Referenceable.html#remoteMessageReceived <https://twistedmatrix.com/documents/16.6.0/api/twisted.spread.pb.Referenceable.html#remoteMessageReceived>, which is what actually calls the remote_ method for you.

The documentation isn't entirely clear, as it says it's calling the remote_ method with "the same" arguments, but if you look at the implementation, it is fairly straightforward:

https://github.com/twisted/twisted/blob/3257fbb3504329f603cc9b6e17442d913170b5d1/src/twisted/spread/flavors.py#L104-L124 <https://github.com/twisted/twisted/blob/3257fbb3504329f603cc9b6e17442d913170b5d1/src/twisted/spread/flavors.py#L104-L124>

it deserializes the arguments, calls the method, and serializes the result.

Notice that in order to do this serializing and deserializing, it's called with the broker, which is the object that has the IP you want.  So you could override this method to do its own serialization and deserialization.  But, luckily enough, there's something very close to what you want already: ViewPoint, which already does the insertion-of-an-argument for you.  So here's a little hack which will insert 'broker' as the first argument and call a 'view_' method rather than a 'remote_' one:

from twisted.spread.flavors import Referenceable, ViewPoint
class BrokerizedReferenceable(Referenceable, object):
    def remoteMessageReceived(self, broker, message, args, kw):
        return (ViewPoint(broker, self)
                .remoteMessageReceived(broker, message, args, kw))


This is untested but hopefully it will be close enough to put you on your way.  Make sense?

-glyph
-------------- next part --------------
An HTML attachment was scrubbed...
URL: </pipermail/twisted-python/attachments/20170116/3e9828ee/attachment-0002.html>


More information about the Twisted-Python mailing list