Warning
This post was published 43 days ago. The information described in this article may have changed.
I am attempting to write an implementation of tokio::io::AsyncWrite
that wraps another AsyncWrite
and encodes (well, poorly encrypts) bytes passed to the wrapper's poll_write()
before they are passed on to the inner poll_write()
. The problem is that the encoding mechanism is stateful, and so just passing the input through the encoder on every call would break as soon as the inner poll_write()
returned Pending
, as that would cause the encoded bytes to be discarded, and then when the same input is passed again on the next poll_write()
call, it'd be encoded differently (i.e., wrong).
The simplest solution I can think of is to store the encoded bytes in the wrapper whenever the inner poll_write()
returns Pending
, and then when poll_write()
is called again while the storage is nonempty, another attempt is made to pass the stored bytes to the inner poll_write()
. However, this only works as long as the outer poll_write()
is always called with the same bytes until Ready
is returned — an assumption that is broken by cancellation of writes, and maybe some other things? (I don't think my codebase would continue using a writer after cancelling a write, but I'm not about to audit it right now.) A variation would be to store both the raw and encoded bytes and compare the stored raw bytes against the input to poll_write()
, which would presumably work as long as there are no occurrences of "try to write bytes → cancel write → try to write the same bytes again."
Is there a (more) robust way to pull this off?
2 posts - 1 participant
🏷️ rust_feed