1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
use futures::{Async, Future};
use tk_bufstream::{ReadBuf, WriteBuf};

use super::{Error, Encoder, EncoderDone, Head};
use super::RecvMode;


#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum BodyKind {
    Fixed(u64),
    Chunked,
    Unsupported,
}

/// This is a low-level interface to the http server
pub trait Dispatcher<S> {
    /// The codec type  for this dispatcher
    ///
    /// In many cases the type is just `Box<Codec<S>>`, but it left as
    /// associated type make different types of middleware cheaper.
    type Codec: Codec<S>;

    /// Received headers of a request
    ///
    /// At this point we already extracted all the headers and other data
    /// that we need to ensure correctness of the protocol. If you need
    /// to handle some data from the headers you need to store them somewhere
    /// (for example on `self`) for further processing.
    fn headers_received(&mut self, headers: &Head)
        -> Result<Self::Codec, Error>;
}

/// The type represents a consumer of a single request and yields a writer of
/// a response (the latter is a ``ResponseFuture``
pub trait Codec<S> {
    /// This is a future returned by `start_response`
    ///
    /// It's fine if it's just `Box<Future<Item=EncoderDone<S>, Error>>` in
    /// most cases.
    type ResponseFuture: Future<Item=EncoderDone<S>, Error=Error>;

    /// Return a mode which will be used to receive request body
    ///
    ///
    /// Note: this mode not only influences the size of chunks that
    /// `data_received` recieves and amount of buffering, but also it
    /// constrains the sequence between calls of `start_response()`
    /// and `data_received()`.
    ///
    /// Called once, right after `headers_received`
    fn recv_mode(&mut self) -> RecvMode;

    /// Chunk of the response body received
    ///
    /// `end` equals to `true` for the last chunk of the data.
    ///
    /// Method returns `Async::Ready(x)` to denote that it has consumed `x`
    /// bytes. If there are some bytes left in the buffer they will be passed
    /// again on the call.
    ///
    /// If the response is empty, or last chunk arrives later and it's empty
    /// we call `c.data_received(b"", true)` on every wakeup,
    /// until `Async::Ready(0)` is returned (this helps to drive future that
    /// might complete on response completion without spawning another ones,
    /// but note that next response can't start writing in the meantime).
    ///
    /// Protocol panics if returned number of bytes larger than `data.len()`.
    ///
    fn data_received(&mut self, data: &[u8], end: bool)
        -> Result<Async<usize>, Error>;

    /// Start writing a response
    ///
    /// This method is called when there all preceding requests are either
    /// send to the network or already buffered. It can be called before
    /// `data_received()` but not before `headers_received()` (that would not
    /// make sense).
    ///
    /// Everything you write into a buffer might be flushed to the network
    /// immediately (or as fast as you yield to main loop). On the other
    /// hand we might buffer/pipeline multiple responses at once.
    fn start_response(&mut self, e: Encoder<S>) -> Self::ResponseFuture;

    /// Called after future retunrted by `start_response` done if recv mode
    /// is `Hijack`
    ///
    /// Note: both input and output buffers can contain some data.
    fn hijack(&mut self, _output: WriteBuf<S>,  _input: ReadBuf<S>) {
        panic!("`Codec::recv_mode` returned `Hijack` but \
            no hijack() method implemented");
    }
}

impl<S, F> Codec<S> for Box<Codec<S, ResponseFuture=F>>
    where F: Future<Item=EncoderDone<S>, Error=Error>,
{
    type ResponseFuture = F;
    fn recv_mode(&mut self) -> RecvMode {
        (**self).recv_mode()
    }
    fn data_received(&mut self, data: &[u8], end: bool)
        -> Result<Async<usize>, Error>
    {
        (**self).data_received(data, end)
    }
    fn start_response(&mut self, e: Encoder<S>) -> Self::ResponseFuture {
        (**self).start_response(e)
    }
    fn hijack(&mut self, output: WriteBuf<S>,  input: ReadBuf<S>) {
        (**self).hijack(output, input)
    }
}