use bytes::BytesMut;
use super::{Hmac, StreamCipher};
use futures::prelude::*;
pub struct EncoderMiddleware<S> {
cipher_state: StreamCipher,
hmac: Hmac,
raw_sink: S,
pending: Option<BytesMut> }
impl<S> EncoderMiddleware<S> {
pub fn new(raw: S, cipher: StreamCipher, hmac: Hmac) -> EncoderMiddleware<S> {
EncoderMiddleware {
cipher_state: cipher,
hmac,
raw_sink: raw,
pending: None
}
}
}
impl<S> Sink for EncoderMiddleware<S>
where
S: Sink<SinkItem = BytesMut>,
{
type SinkItem = BytesMut;
type SinkError = S::SinkError;
fn start_send(&mut self, mut data_buf: Self::SinkItem) -> StartSend<Self::SinkItem, Self::SinkError> {
if let Some(data) = self.pending.take() {
if let AsyncSink::NotReady(data) = self.raw_sink.start_send(data)? {
self.pending = Some(data);
return Ok(AsyncSink::NotReady(data_buf))
}
}
debug_assert!(self.pending.is_none());
self.cipher_state.encrypt(&mut data_buf[..]);
let signature = self.hmac.sign(&data_buf[..]);
data_buf.extend_from_slice(signature.as_ref());
if let AsyncSink::NotReady(data) = self.raw_sink.start_send(data_buf)? {
self.pending = Some(data)
}
Ok(AsyncSink::Ready)
}
#[inline]
fn poll_complete(&mut self) -> Poll<(), Self::SinkError> {
if let Some(data) = self.pending.take() {
if let AsyncSink::NotReady(data) = self.raw_sink.start_send(data)? {
self.pending = Some(data);
return Ok(Async::NotReady)
}
}
self.raw_sink.poll_complete()
}
#[inline]
fn close(&mut self) -> Poll<(), Self::SinkError> {
if let Some(data) = self.pending.take() {
if let AsyncSink::NotReady(data) = self.raw_sink.start_send(data)? {
self.pending = Some(data);
return Ok(Async::NotReady)
}
}
self.raw_sink.close()
}
}
impl<S> Stream for EncoderMiddleware<S>
where
S: Stream,
{
type Item = S::Item;
type Error = S::Error;
#[inline]
fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
self.raw_sink.poll()
}
}