Tom, I guess LineReceiver can help you with that, it's a matter of using a different delimiter. Here is a rough sketch of something you can start exploring:
from __future__ import print_function from twisted.internet import reactor, protocol, endpoints, defer from twisted.protocols import basic class PostfixProtocol(basic.LineReceiver): # Assuming Postfix sends '\r\n' line breaks (does it?) delimiter = '\r\n\r\n' def lineReceived(self, multi_line): input_dict = { k: v for k, v in ( line.split('=') for line in multi_line.split('\r\n') ) } self.gotPostfixRequest(input_dict) def gotPostfixRequest(self, request_dict): # Silly deferred-based implementation. d = defer.Deferred() d.addCallback(self.sendPostfixAction) # Simulate a deferred being fired with success. reactor.callLater(1, d.callback, 'OK') def sendPostfixAction(self, response): # NOTE: Sends self.delimiter after the payload. # Use self.tranport.write if you don't want it. self.sendLine('action={}'.format(response)) if __name__ == '__main__': ep = endpoints.serverFromString(reactor, 'tcp:10000') f = protocol.Factory() f.protocol = PostfixProtocol ep.listen(f) reactor.run() Key ideas: - PostfixProtocol overrides LineReceiver's delimiter (setting it to '\r\n\r\n') - lineReceived parses the muti_line and calls gotPostfixRequest. - gotPostfixRequest should decide (or delegate, you choice) what kind of response to send back. - sendPostfixAction sends a response back to Postfix. Notes: - The multi_line parsing code is short(ish) but not very robust. It may fail in bad ways with invalid input. - The gotPostfixRequest implementation is written for the sake of a deferred-based example. Does this help you in any way? Cheers, -- exvito On Tue, Nov 17, 2015 at 4:56 PM, Tom Boland <t...@t0mb.net> wrote: > Greetings all. > > This may be a very basic question. I'm hoping to implement a postfix > policy check client in twisted. It's a simple protocol. You send > newline separated key value pairs like: > > recipient=em...@ddr.ess > sender=anot...@ddr.ess > size=1024 > helo_name=mail.server > etc.. > > you terminate the request with an additional newline. The response > comes back like > > action=OK > > You can send mutliple requests in the same connection. What I'm > envisaging is a module that can be used to provide a deferred > request/response pairing to my calling application. The module class > will manage the single connection to the postfix policy daemon (I'm > actually going to have persistent connections to a few daemons), and > reconnect when necessary etc. Any requests will return a deferred that > I can add callbacks to. How would you design this with twisted? I can > easily envisage a way of using a clientfactory to instantiate separate > connections for each request/response, but actually being able to simply > send a request and receive the single response for that request is > something I'm struggling to do within a LineReceiver instance (for > instance). Would the twisted.protocols.amp module help given that I > can't change the server-side protocol? > > Any advice much appreciated! > > Thanks. Tom. > > _______________________________________________ > Twisted-Python mailing list > Twisted-Python@twistedmatrix.com > http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python -- -- exvito
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python