[Twisted-Python] how to stop dataReceived while waiting a deferred to fire?

Andrew Bennetts andrew-twisted at puzzling.org
Mon Feb 21 00:13:53 EST 2005


On Mon, Feb 21, 2005 at 05:50:16AM +0100, Andrea Arcangeli wrote:
[...]
> 
> The example in the docs is like this:
> 
> -------------------------
> class FingerProtocol(basic.LineReceiver):
>     def lineReceived(self, user):
>         self.factory.getUser(user
>         ).addErrback(lambda _: "Internal error in server"
>         ).addCallback(lambda m:
>             (self.transport.write(m+"\r\n"),
>              self.transport.loseConnection()))
> [..]
> we would have to fetch result from a remote Oracle? Or from the web?
> -------------------------
> 
> But as far as I can tell the above also is broken and it won't wait for
> the deferred to fire, so two of those queries could be invoked if the
> client side is malicious and it sends two lines in one packet and that
> could screwup the server. It'll work only as long as the clients aren't
> malicious.

I don't think it matters if the two lines arrive in the same packet or not;
if the lines arrive before the getUser deferred fires, it will fire multiple
queries, regardless of the exact packets involved.  In this case maybe a
flag should be in the protocol after the first lineReceived event... any
future rawDataReceived events (after call self.setRawMode()) could then be
ignored.  Or if you're more paranoid, it could drop the connection and try
cancel the in-progress getUser operation.

> I really can't see how the reactor could ever wait for the deferred
> returned by GetUser and how could lineReceived being throttled in the
> above example. So I think the above example needs fixing too.
> 
> I need one of those below two solutions:
> 
> 1) something like protocol.transport.removeReader() to call before
[...]

I think the transport's pauseProducing call will do what you want, here.
And resumeProducing when you're ready again.

-Andrew.





More information about the Twisted-Python mailing list