miasht/server/
response.rs

1use std::io::{self, Write};
2use futures::{Async, Future, Poll};
3
4use {Error, Status, TransportStream};
5use status::RawStatus;
6use header::{Header, HeadersMut};
7use super::Connection;
8
9pub fn builder<T>(mut connection: Connection<T>, status: RawStatus) -> ResponseBuilder<T>
10where
11    T: TransportStream,
12{
13    connection.inner.buffer.enter_write_phase();
14    let _ = write!(
15        connection.inner.buffer,
16        "{} {}\r\n",
17        connection.version, status
18    );
19    ResponseBuilder(connection)
20}
21
22#[derive(Debug)]
23pub struct ResponseBuilder<T>(Connection<T>);
24impl<T: TransportStream> ResponseBuilder<T> {
25    pub fn headers_mut(&mut self) -> HeadersMut {
26        HeadersMut::new(&mut self.0.inner.buffer)
27    }
28    pub fn add_raw_header(&mut self, name: &str, value: &[u8]) -> &mut Self {
29        self.headers_mut().add_raw_header(name, value);
30        self
31    }
32    pub fn add_header<'a, H: Header<'a>>(&mut self, header: &H) -> &mut Self {
33        self.headers_mut().add_header(header);
34        self
35    }
36    pub fn finish(mut self) -> Response<T> {
37        let _ = write!(self.0.inner.buffer, "\r\n");
38        Response(Some(self.0))
39    }
40}
41
42#[derive(Debug)]
43pub struct Response<T>(Option<Connection<T>>);
44impl<T: TransportStream> Write for Response<T> {
45    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
46        if let Some(ref mut c) = self.0 {
47            c.inner.flush_buffer()?;
48            c.inner.stream.write(buf)
49        } else {
50            Err(io::Error::new(
51                io::ErrorKind::WriteZero,
52                "Cannot write into finished response",
53            ))
54        }
55    }
56    fn flush(&mut self) -> io::Result<()> {
57        if let Some(ref mut c) = self.0 {
58            c.inner.flush_buffer()?;
59            c.inner.stream.flush()?;
60        }
61        Ok(())
62    }
63}
64impl<T: TransportStream> Future for Response<T> {
65    type Item = Connection<T>;
66    type Error = Error;
67    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
68        match self.flush() {
69            Err(e) => {
70                track_assert_eq!(
71                    e.kind(),
72                    io::ErrorKind::WouldBlock,
73                    Status::InternalServerError
74                );
75                Ok(Async::NotReady)
76            }
77            Ok(()) => {
78                let connection = self.0.take().expect("Cannot poll Response twice");
79                Ok(Async::Ready(connection))
80            }
81        }
82    }
83}