[Twisted-Python] Implementing Postfix Inet Policy Check Client

Tom Boland tom at t0mb.net
Thu Nov 19 09:19:16 MST 2015


Thanks again for this.  It's really useful.  It turns out that the
delimiter is a plain old \n.  Who knows how consistent this will be
between different policy daemons, I don't know!

I've modified it to manage a DeferredQueue which hopefully means I can
just keep throwing requests at it without every being bounced away.  A
stripped down example (with even less error checking!) of what I've
managed to work your example in to is here:

class PostfixPolicyClient(LineReceiver):

    delimiter = '\n'

    def __init__(self):
        self.resultQueue = DeferredQueue()


    def lineReceived(self, line):
        if '=' in line:
            self.resultQueue.put(True if line.split('=')[1] == 'OK' else
False)


    def sendPostfixPolicyClientRequest(self, request_dict):
        for k, v in request_dict.items():
            self.sendLine('{}={}'.format(k, v))
        self.sendLine('')
        return self.resultQueue.get()



Now, this isn't a working example, it's just the minimum that will
demonstrate my idea.  I just wonder if what I've done with the
DeferredQueue is sane.  If I return the .get() entry from the
DeferredQueue when doing the request, and then do a put() in
lineReceived, am I guaranteeing that I will get my results in the
correct order?

Thanks again for all your help!

Many thanks.  Tom.


On 19/11/15 07:53, exvito here wrote:
>
> On Wed, Nov 18, 2015 at 9:28 AM, Tom Boland <tom at t0mb.net
> <mailto:tom at t0mb.net>> wrote:
>
>     I think what you've provided me with is useful for me, but I think
>     it's backwards for my purposes, as I need to be connecting to the
>     policy daemon rather than being the policy daemon!
>
>     I wanted to do this with deferred calls in case one of the policy
>     daemons becomes unreachable and blocks my application.  Do you
>     think I should do something differently in that regard?  My SQL
>     lookups are done synchronously.  If the database server goes away,
>     I've got bigger problems anyway!
>
>
> So maybe something like this is more likely to be useful:
>
> #!/usr/bin/env python
>
> from __future__ import print_function
>
> from twisted.internet import reactor, protocol, endpoints, defer
> from twisted.protocols import basic
>
>
> class PostfixProtocol(basic.LineReceiver):
>
>     # Assuming Postfix uses '\r\n' line breaks (does it?)
>     delimiter = '\r\n'
>
>     def __init__(self):
>         self.action = None
>         self.action_deferred = None
>
>     def lineReceived(self, line):
>         if '=' in line:
>             self.action = line.split('=')[1]
>         elif line == '':
>             self.action_deferred.callback(self.action)
>             self.action_deferred = None
>         else:
>             # oops, bad input
>             pass
>
>     def sendPostfixRequest(self, request_dict):
>         if not self.action_deferred is None:
>             raise Exception('transaction pending')
>         for k, v in request_dict.items():
>             self.sendLine('{}={}'.format(k,v))
>         # Empty line signals we're done
>         self.sendLine('')
>         self.action_deferred = defer.Deferred()
>         return self.action_deferred
>
> @defer.inlineCallbacks
> def checkPostfixPolicy(request_dict):
>     ep = endpoints.clientFromString(reactor,
> 'tcp:host=127.0.0.1:port=10000')
>     p = yield endpoints.connectProtocol(ep, PostfixProtocol())
>     action = yield p.sendPostfixRequest(request_dict)
>     print('got: {}'.format(action))
>     reactor.stop()
>
>
> if __name__ == '__main__':
>
>     request_dict = {
>         'recipient': 'email at ddr.ess',
>         'sender': 'email at ddr.ess',
>     }
>     reactor.callWhenRunning(checkPostfixPolicy, request_dict)
>     reactor.run()
>
> Highlights:
> - This is not the same protocol as before, in particular it uses a
> different delimiter.
> - It assumes the response is also terminated with an empty line (does
> it?).
> - It more than one outstanding response: a different exception should
> be used.
> - The input processing is very rudimentary and failure-prone.
> - checkPostfixPolicy could, of course, return instead of printing. :)
>
> Cheers,
> --
>   exvito
>
>
> _______________________________________________
> Twisted-Python mailing list
> Twisted-Python at twistedmatrix.com
> http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python

-------------- next part --------------
An HTML attachment was scrubbed...
URL: </pipermail/twisted-python/attachments/20151119/8f8b4d9c/attachment-0002.html>


More information about the Twisted-Python mailing list